1

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);
        }
    }

}
user8623502
  • 77
  • 2
  • 7

1 Answers1

1

As stated here, you are indeed able to pass the bitmap from one activity to another one with the intent. It is easy, let's see how.

There are two methods, but both do the same process:

  • a) Encode or save the bitmap in the first activity, send it through
    intent.
  • b) Receive the intent and decode or load the image again.

METHOD 1. Save it to disk and load it again.

Activity 1 (image is generated/... here):

    try {
        //Write file
        String filename = "bitmap.png";
        FileOutputStream stream = this.openFileOutput(filename, Context.MODE_PRIVATE);
// Note that your bitmap is called bmp in this example
        bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);

        //Cleanup
        stream.close();
        bmp.recycle();

        // This intent goes from one activity to the next one, you shoul change Activity 2 with the name it has in you project
        Intent in1 = new Intent(this, Activity2.class);
        in1.putExtra("image", filename);
        startActivity(in1);
    } catch (Exception e) {
        e.printStackTrace();
    }

Activity 2 (image is received here):

Bitmap bmp = null;
String filename = getIntent().getStringExtra("image");
try {
    FileInputStream is = this.openFileInput(filename);
    bmp = BitmapFactory.decodeStream(is);
    is.close();
} catch (Exception e) {
    e.printStackTrace();
}

METHOD 2. Pass the bitmap as Byte Array and decode it again to bitmap.

Activity 1 (image is generated/... here):

//Convert to byte array. Again, note that your bitmap is called bmp
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();

Intent in1 = new Intent(this, Activity2.class);
in1.putExtra("image",byteArray);

Activity 2 (image is received here):

byte[] byteArray = getIntent().getByteArrayExtra("image");
Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);
miquelvir
  • 1,748
  • 1
  • 7
  • 21