简体   繁体   中英

Camera Intent Not Working in Some Devices

In my app, there is a button which launches the camera intent and saves the captured image at given path. It works perfectly fine in Nexus 5X emulator, but when I tried it in my S8 or S9 it does not open the camera nor does it show any error. How can I fix camera intent in my App

private void PictureTakerAction()
    {
        Intent takePic = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if(takePic.resolveActivity(getPackageManager()) != null)
        {
            File photoFile = null;
            photoFile = CreatePhotoFile();

            if(photoFile != null)
            {
                pathToFile = photoFile.getAbsolutePath();
                Uri photoUri = FileProvider.getUriForFile(AddItemActivity.this,"com.airtechsolutions.fileprovider",photoFile);
                takePic.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
                startActivityForResult(takePic,1);
            }
        }
    }

private File CreatePhotoFile()
    {
        String name = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        //File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File storageDir = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File image = null;

        try {
            image = File.createTempFile(name ,".jpg" , storageDir);
        } catch (Exception e) {
            Log.i("File Log", "Exception: " + e.toString());
        }

        return image;
    }

protected void onActivityResult(int requestCode,int resultCode, Intent data)
{   super.onActivityResult(requestCode,resultCode,data);

    if (requestCode == 1)
     {
       Bitmap bitmap = BitmapFactory.decodeFile(pathToFile);
       Image.setImageBitmap(bitmap);
     }
}

You have an error in your app. Which is that you are writing the temp file in a public directory.

Storage Permissions

From the documentation:

Every Android app runs in a limited-access sandbox. If an app needs to use resources or information outside of its own sandbox, the app has to request the appropriate permission. You declare that your app needs a permission by listing the permission in the app manifest and then requesting that the user approve each permission at runtime (on Android 6.0 and higher).

Permissions like using the Internet, etc. are not even required, because they are not considered dangerous. Permissions, however, to use the camera, storage, etc. are dangerous as if given without the users' permission, the app can invade the users' privacy.

What you are doing is creating a temp file in a public directory, something that requires write/read permission. Before Android 6.0, you didn't have to request read/write permissions to read/write. But if you read the above, it says that dangerous permissions are needed to be requested for Android 6.0 and higher, explaining why your code works on some devices.

Instead of storing it in a specific directory, just do this if the temp file you are creating is seen only by you:

String name = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
//File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
//File storageDir = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);

try {
    return File.createTempFile(name ,".jpg");
} catch (Exception e) {
    Log.i("File Log", "Exception: " + e.toString());
    return null;
}

Also, try doing this:

takePic.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

This will create the file in a private directory, meaning that you don't need to request storage permissions. You can continue with the code now.

I have solved the issue :) It was done in 2 steps

Step 1:-

in My Java file I change the storage process from

File storageDir = getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); 
File image = null;
image = File.createTempFile(name ,".jpg", storageDir);

to

File outputDir = getApplicationContext().getCacheDir();
File image = null;
image = File.createTempFile(name ,".jpg", outputDir);

And the Step 2 was that I change my File Path (res/xml/file_paths)

from

<Paths >
<external-path
    name = "logixtraders_images"
    path = "Pictures"/> 
</Paths>

to

<paths>
  <external-path
    name="external"
    path="." />
  <external-files-path
    name="external_files"
    path="." />
  <cache-path
    name="cache"
    path="." />
  <external-cache-path
    name="external_cache"
    path="." />
  <files-path
    name="files"
    path="." />
</paths>

It worked Perfectly fine for me

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM