log - tag android studio




FileProvider ne fonctionne pas avec l'appareil photo (2)

J'essaie de créer Camera App pour stocker la sortie sur ma mémoire de stockage interne. Je comprends également que les applications tierces ne peuvent pas accéder au stockage interne de mon application MAIS nous pouvons le faire en exposant le répertoire interne via FileProvider . J'ai suivi le guide ici:

Je spécifie mon AndroidManifest.xml de la manière suivante:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.stackoverflow.test.camerawithfileprovider" >

    <application>
        <activity
            ...
        </activity>

        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.stackoverflow.test.camerawithfileprovider.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true" >
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_provider_path" />
        </provider>
    </application>

</manifest>

J'ai créé un fichier xml nommé file_provider_path.xml dans /res/xml/ :

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="image_capture" path="public/" />
</paths>

Voici comment je crée et appelle l'objectif de la caméra:

private static final int CAMERA_REQUEST_CODE = 5000;
private static final String CAMERA_FP_AUTHORITY = "com.stackoverflow.test.camerawithfileprovider.fileprovider";

Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

Context context = MainActivity.this;
File imagePath = new File(context.getFilesDir(), "public");
if (!imagePath.exists()) imagePath.mkdirs();
File newFile = new File(imagePath, "tmp.jpg");

Uri imageUri = FileProvider.getUriForFile(context, CAMERA_FP_AUTHORITY, newFile);
//context.grantUriPermission("com.google.android.GoogleCamera", imageUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
Log.d("YouQi", "Image URI Passing to Camera: " + imageUri.toString());

intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, CAMERA_REQUEST_CODE);

Lorsque j'exécute l'application, je peux obtenir le résultat Logcat ci-dessous:

    11-11 20:07:39.581 18303-18303/com.stackoverflow.test.camerawithfileprovider D/YouQi: Image URI Passing to Camera: content://com.stackoverflow.test.camerawithfileprovider.fileprovider/image_capture/tmp.jpg

Juste au moment où la caméra se ferme, je clique sur l'exception ci-dessous:

com.google.android.GoogleCamera E/AndroidRuntime: FATAL EXCEPTION: main
com.google.android.GoogleCamera E/AndroidRuntime: Process: com.google.android.GoogleCamera, PID: 19420
com.google.android.GoogleCamera E/AndroidRuntime: java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{42e44f70 19420:com.google.android.GoogleCamera/u0a83} (pid=19420, uid=10083) that is not exported from uid 10312
com.google.android.GoogleCamera E/AndroidRuntime:     at android.os.Parcel.readException(Parcel.java:1465)
com.google.android.GoogleCamera E/AndroidRuntime:     at android.os.Parcel.readException(Parcel.java:1419)
com.google.android.GoogleCamera E/AndroidRuntime:     at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2882)
com.google.android.GoogleCamera E/AndroidRuntime:     at android.app.ActivityThread.acquireProvider(ActivityThread.java:4544)
com.google.android.GoogleCamera E/AndroidRuntime:     at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2274)
com.google.android.GoogleCamera E/AndroidRuntime:     at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1425)
com.google.android.GoogleCamera E/AndroidRuntime:     at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:906)
com.google.android.GoogleCamera E/AndroidRuntime:     at android.content.ContentResolver.openOutputStream(ContentResolver.java:669)
com.google.android.GoogleCamera E/AndroidRuntime:     at android.content.ContentResolver.openOutputStream(ContentResolver.java:645)
com.google.android.GoogleCamera E/AndroidRuntime:     at com.android.camera.PhotoModule.onCaptureDone(PhotoModule.java:1281)
com.google.android.GoogleCamera E/AndroidRuntime:     at com.android.camera.PhotoModule$8.onClick(PhotoModule.java:593)
com.google.android.GoogleCamera E/AndroidRuntime:     at android.view.View.performClick(View.java:4445)
com.google.android.GoogleCamera E/AndroidRuntime:     at android.view.View$PerformClick.run(View.java:18446)
com.google.android.GoogleCamera E/AndroidRuntime:     at android.os.Handler.handleCallback(Handler.java:733)
com.google.android.GoogleCamera E/AndroidRuntime:     at android.os.Handler.dispatchMessage(Handler.java:95)
com.google.android.GoogleCamera E/AndroidRuntime:     at android.os.Looper.loop(Looper.java:136)
com.google.android.GoogleCamera E/AndroidRuntime:     at android.app.ActivityThread.main(ActivityThread.java:5146)
com.google.android.GoogleCamera E/AndroidRuntime:     at java.lang.reflect.Method.invokeNative(Native Method)
com.google.android.GoogleCamera E/AndroidRuntime:     at java.lang.reflect.Method.invoke(Method.java:515)
com.google.android.GoogleCamera E/AndroidRuntime:     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732)
com.google.android.GoogleCamera E/AndroidRuntime:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566)
com.google.android.GoogleCamera E/AndroidRuntime:     at dalvik.system.NativeStart.main(Native Method)

Quelqu'un peut-il aider à expliquer pourquoi le problème se produit? J'ai créé un exemple de projet de mon problème: http://www.axzae.com/downloads/CameraWithFileProvider.zip

Quoi qu'il en soit, l'application fonctionnera si je spécifie explicitement:

context.grantUriPermission(
    "com.google.android.GoogleCamera",
    imageUri,
    Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION
);

Mais cela ne fonctionnera que pour les appareils Nexus / Cyanogen. L'application Appareil photo Samsung peut utiliser un nom de package différent.


  1. S'il vous plaît, n'essayez pas de mettre exported="true" comme l'a souligné pskink , votre application se plantera au moment de son chargement. FileProvider n'est pas conçu pour fonctionner dans cet état.

  2. intent.addFlags essayé la solution intent.addFlags . Ne fonctionne pas ACTION_SEND ne fonctionnera probablement ACTION_SEND type d'intention ACTION_SEND .

  3. J'ai trouvé la réponse dans ce post . Apparemment, le mode d'octroi manuel est la seule solution. Mais nous pouvons toujours parcourir la liste des paquetages candidats et grantPermission à tous.

    List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
    for (ResolveInfo resolveInfo : resInfoList) {
        String packageName = resolveInfo.activityInfo.packageName;
        context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
    }

J'ai eu un problème similaire mais plus tard, j'ai découvert qu'il y avait une faute de frappe dans mon code. La faute de frappe était dans AndroidManifest.xml, précisément dans la balise à la ligne "autorités".

Pour moi,

android:authorities="com..test.camerawithfileprovider.fileprovider"

ne fonctionne pas (lorsque j'appelle l'instance de caméra, l'application se bloque), mais si je supprime "fichier", je remplace cette chaîne comme suit:

android:authorities="com..test.camerawithfileprovider.provider"

mon application fonctionne correctement (l'application prend la photo, la stocke et donne un aperçu de l'activité de l'application client).

Votre application a-t-elle également le même problème?







android-fileprovider