Android点击按钮拍照后如何在另一Activity显示?代码修改咨询
解决方案:将拍摄的照片传递到另一个Activity显示
核心问题说明
你当前的代码仅获取了相机返回的缩略图并在当前Activity显示,要实现传递到下一个Activity,推荐采用「保存图片到本地文件,传递文件路径」的方式(避免直接传Bitmap导致的内存溢出问题),以下是具体修改步骤:
方案一:推荐(传递图片文件路径,支持高清图)
步骤1:配置FileProvider(Android 7.0+ 必填)
因为Android 7.0及以上禁止直接使用file://Uri,需要通过FileProvider共享文件:
- 在
AndroidManifest.xml的<application>标签内添加FileProvider配置:
<provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
- 在
res/xml目录下创建file_paths.xml文件(若xml目录不存在则新建):
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 指定图片保存到应用私有Pictures目录 --> <external-files-path name="my_images" path="Pictures" /> </paths>
步骤2:修改MainActivity的拍照逻辑
添加变量存储图片Uri,并修改拍照Intent指定输出路径:
public class MainActivity extends AppCompatActivity { private static final int pic_id = 123; private Uri imageUri; // 新增:存储图片Uri Button camera_open_id; // 移除:不需要在当前Activity显示图片,可删除click_image_id变量 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); camera_open_id = findViewById(R.id.camera_button); camera_open_id.setOnClickListener(v -> { // 创建保存图片的临时文件 File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); try { File imageFile = File.createTempFile( "JPEG_", // 文件名前缀 ".jpg", // 文件名后缀 storageDir // 存储目录 ); // 通过FileProvider获取合法Uri imageUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", imageFile); // 构建拍照Intent并指定输出Uri Intent camera_intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); camera_intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); startActivityForResult(camera_intent, pic_id); } catch (IOException e) { e.printStackTrace(); } }); verifyStoragePermissions(MainActivity.this); }
步骤3:修改onActivityResult,启动第二个Activity传递路径
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == pic_id && resultCode == RESULT_OK) { // 获取图片文件的绝对路径 String imagePath = new File(imageUri.getPath()).getAbsolutePath(); // 启动第二个Activity并传递路径 Intent intent = new Intent(this, ImageDisplayActivity.class); intent.putExtra("IMAGE_PATH", imagePath); startActivity(intent); } } // 保留原有的权限验证代码不变 private static final int REQUEST_EXTERNAL_STORAGE = 1; private static String[] PERMISSIONS_STORAGE = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE }; public static void verifyStoragePermissions(Activity activity) { int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE); if (permission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions( activity, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE ); } } }
步骤4:创建第二个Activity(ImageDisplayActivity)
- 布局文件
activity_image_display.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center"> <ImageView android:id="@+id/display_image" android:layout_width="wrap_content" android:layout_height="wrap_content" android:scaleType="centerInside"/> </LinearLayout>
- Activity代码:
public class ImageDisplayActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_image_display); ImageView displayImage = findViewById(R.id.display_image); // 获取传递的图片路径 String imagePath = getIntent().getStringExtra("IMAGE_PATH"); if (imagePath != null) { // 优化:采样加载大图,避免OOM Bitmap bitmap = decodeSampledBitmapFromFile(imagePath, 1080, 1920); displayImage.setImageBitmap(bitmap); } } // 大图采样压缩工具方法 private Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight) { final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, options); options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); options.inJustDecodeBounds = false; return BitmapFactory.decodeFile(path, options); } private int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; while ((halfHeight / inSampleSize) >= reqHeight && (halfWidth / inSampleSize) >= reqWidth) { inSampleSize *= 2; } } return inSampleSize; } }
方案二:传递Bitmap(仅适合缩略图)
如果只需要传递相机返回的缩略图,可直接通过Intent传递Parcelable类型的Bitmap,但注意大图会触发TransactionTooLargeException:
修改MainActivity的onActivityResult
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == pic_id && resultCode == RESULT_OK) { Bitmap photo = (Bitmap) data.getExtras().get("data"); // 传递Bitmap到下一个Activity Intent intent = new Intent(this, ImageDisplayActivity.class); intent.putExtra("IMAGE_BITMAP", photo); startActivity(intent); } }
在ImageDisplayActivity接收并显示
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_image_display); ImageView displayImage = findViewById(R.id.display_image); Bitmap bitmap = getIntent().getParcelableExtra("IMAGE_BITMAP"); if (bitmap != null) { displayImage.setImageBitmap(bitmap); } }
额外注意事项
- 相机权限:在
AndroidManifest.xml中添加相机权限声明:
<uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" />
- Android 13+适配:使用应用私有目录(
getExternalFilesDir)无需申请额外存储权限,若需访问公共目录需申请READ_MEDIA_IMAGES权限。
内容的提问来源于stack exchange,提问作者Abm
相关产品推荐
相关产品推荐

