Android 7.0平板拍照模糊问题求助(附拍照实现代码)
Hey there! Let's figure out why your Android 7.0 tablet is taking blurry photos while your phone works perfectly. The root cause here is how your current code requests and captures images—let's break down the fixes step by step.
The Core Problem with Your Current Code
Your current intent uses MediaStore.ACTION_IMAGE_CAPTURE without specifying where to save the full-resolution image. By default, this intent only returns a small thumbnail (via the data extra in onActivityResult). On larger tablet screens, this tiny thumbnail gets stretched to fit, making it look blurry. Your phone might seem fine because its screen is smaller, but it's still using the same low-res thumbnail.
Additionally, the camera facing extra you're using ("android.intent.extras.CAMERA_FACING") isn't an official Android API—it's a non-standard extra that might not work reliably on Android 7.0 or across different device manufacturers.
Step-by-Step Fixes
1. Capture Full-Resolution Images by Specifying an Output File
To get a clear, full-size photo, you need to tell the camera app exactly where to save the image file. Here's how to do it:
First, Register a FileProvider (Required for Android 7.0+)
Android 7.0 (API 24) blocks direct file:// URIs for security reasons, so you'll need to use FileProvider to generate a content:// URI instead.
Add this to your AndroidManifest.xml:
<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>
Create a res/xml/file_paths.xml file to define where your app can store images:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-files-path name="my_images" path="Pictures" /> </paths>
2. Update Your Camera Intent Code
Replace your existing intent code with this to capture full-res images:
First, add a helper method to create a temporary image file:
private String mCurrentPhotoPath; private File createImageFile() throws IOException { // Generate a unique filename for the photo String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault()).format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); return File.createTempFile( imageFileName, // File name prefix ".jpg", // File extension storageDir // Directory to save the file ); }
Then, launch the camera with the updated intent:
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // Check if there's a camera app available to handle the intent if (takePictureIntent.resolveActivity(getPackageManager()) != null) { File photoFile = null; try { photoFile = createImageFile(); mCurrentPhotoPath = photoFile.getAbsolutePath(); } catch (IOException ex) { // Handle file creation errors ex.printStackTrace(); } if (photoFile != null) { // Generate a content URI using FileProvider Uri photoURI = FileProvider.getUriForFile( this, getPackageName() + ".fileprovider", // Match the authority in your manifest photoFile ); // Tell the camera where to save the full-res image takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); // Use the official camera facing extra (optional) // Note: Not all devices support this, but it's more reliable than the non-standard one takePictureIntent.putExtra(MediaStore.EXTRA_CAMERA_FACING, Camera.CameraInfo.CAMERA_FACING_BACK); // Use CAMERA_FACING_FRONT for front camera startActivityForResult(takePictureIntent, PIC_CAPTURED); } }
3. Handle the Result in onActivityResult
Instead of pulling a thumbnail from the intent's data extra, load the full-res image directly from the file path you saved:
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == PIC_CAPTURED && resultCode == RESULT_OK) { // Load the full-resolution image from the saved path File imageFile = new File(mCurrentPhotoPath); if (imageFile.exists()) { // Use BitmapFactory or an image loading library like Glide/Picasso to load the image // Example with BitmapFactory: BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = false; // Optional: Scale the image to fit your ImageView to avoid memory issues // options.inSampleSize = 2; // Adjust based on your needs Bitmap fullResBitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, options); yourImageView.setImageBitmap(fullResBitmap); } } }
4. Verify Permissions (If Needed)
If you're targeting Android 6.0 (API 23) or higher, ensure you've requested the WRITE_EXTERNAL_STORAGE permission (though using getExternalFilesDir means you don't need this for app-specific storage). If you do need external storage access, add dynamic permission requests to your code.
Why This Works
- By specifying
MediaStore.EXTRA_OUTPUT, you tell the camera app to save the full-resolution image directly to your app's file, avoiding the low-res thumbnail. FileProviderensures you comply with Android 7.0's security restrictions, preventing URI exposure errors that could break the camera flow.- Using the official
MediaStore.EXTRA_CAMERA_FACING(instead of the non-standard one) improves compatibility across devices, including your Android 7.0 tablet.
内容的提问来源于stack exchange,提问作者Ravi Rajput

