I am working on an App that allows the user to create Custom markers with Custom Images; everything works fine so far, I can pass data and images in intents from one Activity to another.
As I want the image taken in one Activity to be shown in the marker on the other Activity, I need to pass the image.
What my code currently does is drawing a new Canvas next to the Custom Marker bound to the User Location; the new Canvas contains the image that I want to be in the Custom Marker of the User Location. So there is one Custom Marker that should contain the image that is now in the Canvas next to the marker; I am not sure if I need some kind of Background threat when passing the taken image from one Activity back to the Maps Activity, where the Custom Marker is handled and how to pass the image that is in the Intent back to the Maps Activity and to set it on the Marker. Therefore, I would appreciate any help or hints
I tried to set the User image on the marker but that didn´t worked.
Maps Activity
import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.location.Address;
import android.location.Criteria;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.widget.ImageView;
import gmbh.webagenten.myselfieme.PostsDatabaseHelper;
import gmbh.webagenten.myselfieme.SQLiteSampleActivity;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
private static final int EDIT_REQUEST = 1;
private static final int CAMERA_REQUEST = 1888;
static final int REQUEST_IMAGE_CAPTURE = 1;
private ImageView imageView;
Bitmap photo;
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(R.style.AppTheme);
super.onCreate(savedInstanceState);
this.imageView = (ImageView) this.findViewById(R.id.imageView1);
// Get singleton instance of database
PostsDatabaseHelper databaseHelper = PostsDatabaseHelper.getInstance((Context) this);
setContentView(R.layout.activity_maps);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap map) {
this.mMap = map;
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
mMap.setMyLocationEnabled(true);
/*LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
String provider = locationManager.getBestProvider(new Criteria(), true);
Location locations = locationManager.getLastKnownLocation(provider);
List<String> providerList = locationManager.getAllProviders();
if(null!=locations && null!=providerList && providerList.size()>0){
double longitude = locations.getLongitude();
double latitude = locations.getLatitude();
Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
try {
List<Address> listAddresses = geocoder.getFromLocation(latitude, longitude, 1);
if(null!=listAddresses&&listAddresses.size()>0){
String _Location = listAddresses.get(0).getAddressLine(0);
}
} catch (IOException e) {
e.printStackTrace();
}
}*/
GoogleMap.OnMyLocationChangeListener myLocationChangeListener = new GoogleMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange(Location location) {
LatLng loc = new LatLng(location.getLatitude(), location.getLongitude());
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
String provider = locationManager.getBestProvider(new Criteria(), true);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
Location locations = locationManager.getLastKnownLocation(provider);
List<String> providerList = locationManager.getAllProviders();
if(null!=locations && null!=providerList && providerList.size()>0){
double longitude = locations.getLongitude();
double latitude = locations.getLatitude();
Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
try {
List<Address> listAddresses = geocoder.getFromLocation(latitude, longitude, 1);
if(null!=listAddresses&&listAddresses.size()>0){
String _Location = listAddresses.get(0).getAddressLine(0);
}
} catch (IOException e) {
e.printStackTrace();
}
}
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 16.0f));
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
Bitmap bmp = Bitmap.createBitmap(150, 150, conf);
Canvas canvas1 = new Canvas(bmp);
// paint defines the text color, stroke width and size
Paint color = new Paint();
color.setTextSize(30);
color.setColor(Color.BLACK);
// modify canvas
canvas1.drawBitmap(BitmapFactory.decodeResource(getResources(),
R.drawable.custom_marker), 0,0, color);
//canvas1.drawText("Your position", 20, 5, color);
// add marker to Map
mMap.addMarker(new MarkerOptions()
.position(loc)
.icon(BitmapDescriptorFactory.fromBitmap(bmp))
// Specifies the anchor to be at a particular point in the marker image.
.anchor(0.5f, 1).title("Your current position").snippet("You are here"));
}
};
map.setOnMyLocationChangeListener(myLocationChangeListener);
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(final LatLng latLng) {
Intent edit = new Intent(MapsActivity.this, EditActivity.class);
edit.putExtra("location", latLng);
MapsActivity.this.startActivityForResult(edit, EDIT_REQUEST);
}
});
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
GoogleMap.OnMyLocationChangeListener myLocationChangeListener = new GoogleMap.OnMyLocationChangeListener() {
@Override
public void onMyLocationChange (Location location) {
LatLng loc = new LatLng (location.getLatitude(), location.getLongitude());
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(loc, 16.0f));
}
};
}
if (requestCode == CAMERA_REQUEST) {
photo = (Bitmap) data.getExtras().get("data");
this.imageView.setImageBitmap(photo);
}
switch(requestCode) {
case (EDIT_REQUEST) : {
if (resultCode == Activity.RESULT_OK) {
MarkerOptions markerOptions = data.getParcelableExtra("marker");
mMap.addMarker(markerOptions);
}
break;
}
}
}
}
This is the Activity, where the User Input is handled:
Edit Activity
import android.app.Activity;
import android.app.DatePickerDialog;
import android.content.ContentValues;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.text.Editable;
import android.text.InputType;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.Toast;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import java.util.Locale;
import static gmbh.webagenten.myselfieme.R.drawable.marker;
import static gmbh.webagenten.myselfieme.R.id.date;
import static gmbh.webagenten.myselfieme.R.id.time;
import static gmbh.webagenten.myselfieme.R.string.snippet;
public class EditActivity extends Activity {
private static final int CAMERA_REQUEST = 1888;
private EditText etNormalText;
private EditText etName;
private EditText name;
private EditText etLocation;
private EditText etEmailAddrss;
private EditText country;
private EditText etCal;
private Button btnSubmit;
private ImageView imageView;
Bitmap photo;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.editactivity);
PostsDatabaseHelper helper = PostsDatabaseHelper.getInstance(this);
helper.getReadableDatabase();
registerViews();
this.imageView = this.findViewById(R.id.imageView1);
Button photoButton = this.findViewById(R.id.btnCapture);
photoButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
}
});
final Calendar myCalendar = Calendar.getInstance();
EditText edittext= findViewById(R.id.et_cal);
final DatePickerDialog.OnDateSetListener et_cal = new DatePickerDialog.OnDateSetListener() {
@Override
public void onDateSet(DatePicker view, int year, int monthOfYear,
int dayOfMonth) {
// TODO Auto-generated method stub
myCalendar.set(Calendar.YEAR, year);
myCalendar.set(Calendar.MONTH, monthOfYear);
myCalendar.set(Calendar.DAY_OF_MONTH, dayOfMonth);
updateLabel();
}
public void updateLabel() {
String myFormat = "MM/dd/yy"; //In which you need put here
SimpleDateFormat sdf = new SimpleDateFormat(myFormat, Locale.US);
etCal.setText(sdf.format(myCalendar.getTime()));
}
};
edittext.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
new DatePickerDialog(EditActivity.this, et_cal, myCalendar
.get(Calendar.YEAR), myCalendar.get(Calendar.MONTH),
myCalendar.get(Calendar.DAY_OF_MONTH)).show();
}
});
}
private void registerViews() {
etNormalText = findViewById(R.id.et_normal_text);
etName = findViewById(R.id.et_name);
name = findViewById(R.id.name);
country = findViewById(R.id.country);
etCal = findViewById(R.id.et_cal);
etLocation = findViewById(R.id.et_location);
etEmailAddrss = findViewById(R.id.et_email_address);
// TextWatcher would let us check validation error on the fly
etNormalText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
Validation.hasText(etNormalText);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
public void onTextChanged(CharSequence s, int start, int before, int count){}
});
etName.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
Validation.hasText(etName);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
public void onTextChanged(CharSequence s, int start, int before, int count){}
});
name.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
Validation.hasText(name);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
public void onTextChanged(CharSequence s, int start, int before, int count){}
});
country.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
Validation.hasText(country);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
public void onTextChanged(CharSequence s, int start, int before, int count){}
});
etLocation.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
Validation.hasText(etLocation);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
public void onTextChanged(CharSequence s, int start, int before, int count){}
});
etEmailAddrss.addTextChangedListener(new TextWatcher() {
// after every change has been made to this editText, we would like to check validity
public void afterTextChanged(Editable s) {
Validation.isEmailAddress(etEmailAddrss, true);
}
public void beforeTextChanged(CharSequence s, int start, int count, int after){}
public void onTextChanged(CharSequence s, int start, int before, int count){}
});
btnSubmit = findViewById(R.id.btn_submit);
btnSubmit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Log.w("EditActivity", "clicking on btn_submit");
/*
Validation class will check the error and display the error on respective fields
but it won't resist the form submission, so we need to check again before submit
*/
if ( checkValidation () )
submitForm();
else
Toast.makeText(EditActivity.this, "Form contains error", Toast.LENGTH_LONG).show();
}
});
final LatLng latlng = getIntent().getParcelableExtra("location");
final EditText title = findViewById(R.id.et_normal_text);
final EditText cal = findViewById(R.id.et_cal);
final EditText country = findViewById(R.id.country);
final EditText name = findViewById(R.id.name);
Button button = findViewById(R.id.save);
Button cancelbutton = findViewById(R.id.cancel);
Button imagebutton = findViewById(R.id.image);
imagebutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent myIntent = new Intent(EditActivity.this, ImageActivity.class);
myIntent.putExtra("marker", marker);
myIntent.putExtra("BitmapImage", photo);
EditActivity.this.startActivity(myIntent);
setResult(Activity.RESULT_OK, myIntent);
}
});
cancelbutton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Intent myIntent = new Intent(EditActivity.this, ImageActivity.class);
myIntent.putExtra("marker", marker);
myIntent.putExtra("BitmapImage", photo);
EditActivity.this.startActivity(myIntent);
setResult(Activity.RESULT_OK, myIntent);
}
});
cal.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(cal.getText().length()<1){
// Display toast
Toast.makeText(getApplicationContext(), "Please enter a valid date",Toast.LENGTH_LONG).show();
}
}
});
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(final View view) {
Bitmap resized = Bitmap.createScaledBitmap(photo, (int) (photo.getWidth() * 0.5), (int) (photo.getHeight() * 0.5), true);
//Bitmap.Config conf = Bitmap.Config.ARGB_8888;
//Bitmap bmp = Bitmap.createBitmap(150, 150, conf);
Canvas canvas1 = new Canvas();
Rect rectangle = new Rect(0,0,100,100);
canvas1.drawBitmap(resized, new Rect(0,0,100,100), rectangle, null);
resized = addBorderToBitmap(resized, 10, Color.WHITE);
// Add a border around the bitmap as shadow
resized = addBorderToBitmap(resized, 3, Color.LTGRAY);
MarkerOptions marker = new MarkerOptions().position(latlng)
.icon(BitmapDescriptorFactory.fromBitmap(resized))
.draggable(true);
if (title.getText() != null) {
marker.title(title.getText().toString());
}
/*if( date.getText().toString().length() == 0 )
date.setError( "date is required!" );
marker.snippet(date.getText().toString());
*/
if (name.getText() !=null) {
marker.snippet(name.getText().toString());
}
if (country.getText() !=null) {
marker.snippet(country.getText().toString());
}
Intent resultIntent = new Intent();
resultIntent.putExtra("marker", marker);
resultIntent.putExtra("BitmapImage", photo); // passing the bitmap to the next activity . and retrieve it to the next activity
setResult(Activity.RESULT_OK, resultIntent);
finish();
}
});}
public static Bitmap overlay(Bitmap bmp, Bitmap resized) {
Bitmap bmOverlay = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), bmp.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(bmp, new Matrix(), null);
canvas.drawBitmap(resized, 0, 0, null);
return bmOverlay;
}
private void submitForm() {
// Submit your form here. your form is valid
Toast.makeText(this, "Submitting form...", Toast.LENGTH_LONG).show();
Log.w("EditActivity", "submitForm");
}
private boolean checkValidation() {
Log.w("EditActivity", "checkValidation");
boolean ret = true;
if (!Validation.hasText(etNormalText)) ret = false;
if (!Validation.isEmailAddress(etEmailAddrss, true)) ret = false;
return ret;
}
public void onClick(View v) {
// TODO:
// Launch Activity Two
// Hint: use Context's startActivity() method
// Create an intent stating which Activity you would like to start
Intent myIntent = new Intent(EditActivity.this, MapsActivity.class);
// Launch the Activity using the intent
EditActivity.this.startActivity(myIntent);
}
protected Bitmap addBorderToBitmap(Bitmap resized, int borderWidth, int borderColor) {
// Initialize a new Bitmap to make it bordered bitmap
Bitmap dstBitmap = Bitmap.createBitmap(
resized.getWidth() + borderWidth * 2, // Width
resized.getHeight() + borderWidth * 2, // Height
Bitmap.Config.ARGB_8888 // Config
);
/*
Canvas
The Canvas class holds the "draw" calls. To draw something, you need 4 basic
components: A Bitmap to hold the pixels, a Canvas to host the draw calls (writing
into the bitmap), a drawing primitive (e.g. Rect, Path, text, Bitmap), and a paint
(to describe the colors and styles for the drawing).
*/
// Initialize a new Canvas instance
Canvas canvas = new Canvas(dstBitmap);
// Initialize a new Paint instance to draw border
Paint paint = new Paint();
paint.setColor(borderColor);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(borderWidth);
paint.setAntiAlias(true);
Rect rect = new Rect(
borderWidth / 2,
borderWidth / 2,
canvas.getWidth() - borderWidth / 2,
canvas.getHeight() - borderWidth / 2
);
// Draw a rectangle as a border/shadow on canvas
canvas.drawRect(rect, paint);
// Draw source bitmap to canvas
canvas.drawBitmap(resized, borderWidth, borderWidth, null);
resized.recycle();
// Return the bordered circular bitmap
return dstBitmap;
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
photo = (Bitmap) data.getExtras().get("data");
//this.imageView.setImageBitmap(photo);
}
}
}