将图像作为意图传递给其他 Activity 中的自定义标记

Passing an image as intent to a custom marker in other Activity

我正在开发一款允许用户使用自定义图像创建自定义标记的应用程序;到目前为止一切正常,我可以将意图中的数据和图像从一个 Activity 传递到另一个。

因为我希望在一个 Activity 中拍摄的图像显示在另一个 Activity 的标记中,所以我需要传递图像。

我的代码目前所做的是在绑定到用户位置的自定义标记旁边绘制一个新的 Canvas;新的 Canvas 包含我想要在用户位置的自定义标记中的图像。所以有一个自定义标记应该包含现在位于标记旁边 Canvas 中的图像;我不确定在将拍摄的图像从一个 Activity 传回处理自定义标记的地图 Activity 时是否需要某种背景威胁,以及如何传递图像中的图像Intent 回到地图 Activity 并将其设置在标记上。因此,我将不胜感激任何帮助或提示

我尝试在标记上设置用户图像,但没有成功。

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

这是处理用户输入的 Activity:

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

}

here 所述,您确实可以有意地将位图从一个 activity 传递到另一个 activity。很简单,一起来看看吧。

有两种方法,但是都是一样的过程:

  • a) 编码或保存第一个activity中的位图,通过
    发送 意图。
  • b) 接收意图并再次解码或加载图像。

方法 1. 将其保存到磁盘并再次加载。

Activity 1(生成图像/...此处):

    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(此处接收图片):

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

方法 2. 将位图作为字节数组传递并再次解码为位图。

Activity 1(生成图像/...此处):

//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(此处接收图片):

byte[] byteArray = getIntent().getByteArrayExtra("image");
Bitmap bmp = BitmapFactory.decodeByteArray(byteArray, 0, byteArray.length);