Android中使用Intent拍照并固定文件名隐秘存储的技术问询
Alright, let's solve this problem properly. You need to trigger the Android camera via Intent, save the captured photo in a hidden folder, and reuse the same filename every time so other classes in your app can easily access this single photo resource. Here's a step-by-step implementation that follows Android best practices:
To keep the photo "secret", use your app's private external storage directory — this folder is only accessible to your app (no need for external storage permissions on Android 10+), and we can make it hidden by adding a dot prefix to the folder name.
For example, create a folder named .hidden_camera inside your app's external files directory:
// Get the app's private external storage directory val baseDir = context.getExternalFilesDir(null) // Create a hidden folder (dot prefix makes it invisible in default file managers) val hiddenFolder = File(baseDir, ".hidden_camera") if (!hiddenFolder.exists()) { hiddenFolder.mkdirs() } // Define the fixed filename we'll always use val targetPhotoFile = File(hiddenFolder, "secret_photo.jpg")
Note: If you're using Java, the logic is identical — just adjust the syntax.
Android 7.0 (API 24+) blocks direct file URIs from being shared with other apps (like the camera) to prevent security risks. So we need to use FileProvider to generate a content URI for our target file.
Step 2.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.2: Create the file_paths.xml Resource
Create a new folder xml inside res, then add file_paths.xml:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- Grants access to the app's private external files directory --> <external-files-path name="my_files" path="." /> </paths>
Use the modern Activity Result API (since startActivityForResult is deprecated) to launch the camera and handle the result.
Step 3.1: Register the Activity Result Contract
In your Activity/Fragment:
private val takePictureLauncher = registerForActivityResult(ActivityResultContracts.TakePicture()) { success -> if (success) { // Photo was saved successfully to our target file // You can notify other classes here, or just let them access the file directly later Toast.makeText(this, "Photo saved secretly", Toast.LENGTH_SHORT).show() } else { // Camera action was canceled or failed Toast.makeText(this, "Failed to save photo", Toast.LENGTH_SHORT).show() } }
Step 3.2: Trigger the Camera
When you want to take a photo (e.g., from a button click):
// Get the target file we defined earlier val targetPhotoFile = File(getExternalFilesDir(null), ".hidden_camera/secret_photo.jpg") // Generate the content URI using FileProvider val photoUri = FileProvider.getUriForFile( this, "${packageName}.fileprovider", targetPhotoFile ) // Launch the camera — this will overwrite the existing file if it exists takePictureLauncher.launch(photoUri)
Since we're using a fixed file path, any other class in your app can access the photo directly by constructing the same file object:
// In another class, get the photo file fun getSecretPhotoFile(context: Context): File { val baseDir = context.getExternalFilesDir(null) return File(baseDir, ".hidden_camera/secret_photo.jpg") } // To use it, e.g., load into an ImageView val photoFile = getSecretPhotoFile(context) if (photoFile.exists()) { val bitmap = BitmapFactory.decodeFile(photoFile.absolutePath) imageView.setImageBitmap(bitmap) }
- No Storage Permissions Needed: Since we're using the app's private external storage, you don't need to request
READ_EXTERNAL_STORAGEorWRITE_EXTERNAL_STORAGEpermissions (even on Android 13+). - Automatic Overwrite: Every time you launch the camera, it will overwrite the existing
secret_photo.jpgfile — exactly what you need for a single reusable photo resource. - Hidden Folder: The
.hidden_camerafolder won't show up in the default file manager (users would have to enable "show hidden files" to see it), adding an extra layer of secrecy.
内容的提问来源于stack exchange,提问作者Ari Rómulo Guerrero

