Android新手求助:拍照后无法将临时图片传递至另一个Activity
Hey there! Let's figure out why your image isn't passing between Activities and solve your core question about getting a JPG URL-like reference without saving to the gallery.
First: Fix Your Current File-Writing Code
The immediate issue with your code is that you're not actually writing the Bitmap to the file! You commented out the compress() call, so the file you're referencing is empty. Let's fix that first:
Updated CameraUtility Code
try{ // Write File String filename="bitmap.png"; FileOutputStream stream = getApplicationContext().openFileOutput(filename, Context.MODE_PRIVATE); // 1. Decode the byte array to Bitmap bitmapPicture = BitmapFactory.decodeByteArray(arg0 , 0, arg0.length); // 2. Actually compress and write the Bitmap to the stream (this was missing!) bitmapPicture.compress(Bitmap.CompressFormat.JPEG, 50, stream); // Cleanup stream.close(); Toast.makeText(getApplicationContext(), "Saved", Toast.LENGTH_LONG).show(); bitmapPicture.recycle(); // Pop intent Intent in1 = new Intent(CameraUtility.this, Receiver.class); in1.putExtra("image", filename); startActivity(in1); }catch (Exception e){ e.printStackTrace(); }
This will properly write the Bitmap to your app's internal storage (which is private and won't show up in the gallery). Your Receiver code should work once you do this, since it's reading the correct file.
Alternative 1: Pass the Byte Array Directly (Simpler for Small Images)
If your image isn't too large, you can skip writing to a file entirely and pass the raw byte array directly via the Intent. This avoids file I/O overhead:
CameraUtility Side
Intent in1 = new Intent(CameraUtility.this, Receiver.class); in1.putExtra("image_bytes", arg0); // Pass the original byte array directly startActivity(in1);
Receiver Side
@Override protected void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.receive_bitmap); byte[] imageBytes = getIntent().getByteArrayExtra("image_bytes"); Bitmap bitmapPicture = null; if (imageBytes != null) { bitmapPicture = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length); } ImageView viewBitmap = findViewById(R.id.bitmapview); viewBitmap.setImageBitmap(bitmapPicture); }
Note: Intent has a size limit (usually around 1MB), so this works best for smaller images. For larger photos, use the file approach below.
Alternative 2: Use a Temporary File + FileProvider (For Larger Images)
If you need a "URL-like" reference (a content URI) that doesn't save to the gallery, use a temporary file in your app's cache directory and FileProvider to generate a shareable URI. This follows Android's best practices for larger images.
Step 1: Add FileProvider to AndroidManifest.xml
Add this inside the <application> tag:
<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>
Step 2: Create file_paths.xml in res/xml
Create the xml folder if it doesn't exist, then add this file:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <cache-path name="temp_images" path="images/" /> </paths>
Step 3: Update CameraUtility to Create Temporary File and Pass URI
try{ // Create a temporary file in cache directory (won't show in gallery) File tempDir = new File(getCacheDir(), "images"); if (!tempDir.exists()) tempDir.mkdirs(); File tempFile = File.createTempFile("camera_temp", ".jpg", tempDir); // Write Bitmap to temp file bitmapPicture = BitmapFactory.decodeByteArray(arg0 , 0, arg0.length); FileOutputStream stream = new FileOutputStream(tempFile); bitmapPicture.compress(Bitmap.CompressFormat.JPEG, 50, stream); stream.close(); bitmapPicture.recycle(); // Generate content URI using FileProvider Uri imageUri = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", tempFile); // Pass URI to Receiver (grant read permission) Intent in1 = new Intent(CameraUtility.this, Receiver.class); in1.setData(imageUri); in1.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); startActivity(in1); }catch (Exception e){ e.printStackTrace(); }
Step 4: Update Receiver to Load from URI
@Override protected void onCreate (Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.receive_bitmap); Uri imageUri = getIntent().getData(); Bitmap bitmapPicture = null; if (imageUri != null) { try { InputStream is = getContentResolver().openInputStream(imageUri); bitmapPicture = BitmapFactory.decodeStream(is); is.close(); } catch (IOException e) { e.printStackTrace(); } } ImageView viewBitmap = findViewById(R.id.bitmapview); viewBitmap.setImageBitmap(bitmapPicture); }
This gives you a proper content URI (like content://com.your.app.fileprovider/temp_images/camera_temp_123.jpg) that acts as a "URL" for the image, without saving it to the user's gallery.
Key Notes
- Internal storage (used in your original code) is private to your app, so files there won't show up in the gallery.
- Cache directory files can be deleted by the system when storage is low, so use this for temporary images only.
- For permanent images that don't show in the gallery, use
getFilesDir()instead ofgetCacheDir().
内容的提问来源于stack exchange,提问作者qwerty

