Prendre une photo et l'enregistrer

Résolu/Fermé
Angelneonizz Messages postés 784 Date d'inscription mardi 9 décembre 2003 Statut Membre Dernière intervention 19 février 2018 - 16 janv. 2018 à 15:00
BunoCS Messages postés 15472 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 25 mars 2024 - 19 janv. 2018 à 09:23
Bonjour,

j'ai un petit souci pour sauvegarder une image prise avec l'appareil photo via mon appli.

J'ai suivi ce tuto :

https://developer.android.com/training/camera/photobasics.html#TaskPhotoView

Pour la partie thumbnail ça fonctionne mais si je veux sauvegarder l'image full-size mon appli plante.
- Droit dans la manifest : ok
- Provider : je pense que c'est là que ça bloque, voici se que j'ai :

<provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths"/>
        </provider>


et dans mon fichier xml :

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <!--<external-path name="external_files" path="."/>-->
    <external-path
        name="files_root"
        path="Android/data/${applicationId}"/>
    <external-path
        name="external_storage_root"
        path="."/>
</paths>


le reste du code est un copier/coller du tuto.

Voici le log :


E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.sncf.android.internal.beta.outillagenational, PID: 6447
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.res.XmlResourceParser android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager, java.lang.String)' on a null object reference
at android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:584)
at android.support.v4.content.FileProvider.getPathStrategy(FileProvider.java:558)
at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:400)
at com.sncf.android.internal.beta.outillagenational.ui.FormProbleme$override.dispatchTakePictureIntent(FormProbleme.java:158)
at com.sncf.android.internal.beta.outillagenational.ui.FormProbleme$override.static$access$100(FormProbleme.java:47)
at com.sncf.android.internal.beta.outillagenational.ui.FormProbleme$override.access$dispatch(FormProbleme.java)
at com.sncf.android.internal.beta.outillagenational.ui.FormProbleme.access$100(FormProbleme.java:0)
at com.sncf.android.internal.beta.outillagenational.ui.FormProbleme$2.onClick(FormProbleme.java:110)
at android.view.View.performClick(View.java:6213)
at android.widget.TextView.performClick(TextView.java:11074)
at android.view.View$PerformClick.run(View.java:23645)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6692)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)



A voir également:

5 réponses

BunoCS Messages postés 15472 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 25 mars 2024 3 894
Modifié le 16 janv. 2018 à 15:42
Hello,

Je ne suis pas sûr que, dans ton fichier xml, la variable
${applicationId}
soit connue. Il faut explicitement indiquer le package name, non?

@+ 
Buno, Modo CS-CCM 
L'urgent est fait, l'impossible est en cours. Pour les miracles, prévoir un délai... 
The urgent is done, the impossible is underway. For miracles, provide for a delay...
0
Angelneonizz Messages postés 784 Date d'inscription mardi 9 décembre 2003 Statut Membre Dernière intervention 19 février 2018 137
16 janv. 2018 à 17:42
si la variable est connue, je m'en sert déjà dans une autre activité et ça fonctionne.
Demain je testerais tout de même avec le package complet.

Merci pour ta réponse
0
Angelneonizz Messages postés 784 Date d'inscription mardi 9 décembre 2003 Statut Membre Dernière intervention 19 février 2018 137
17 janv. 2018 à 07:41
je viens de tester et ça ne fonctionne pas mieux
0
BunoCS Messages postés 15472 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 25 mars 2024 3 894
17 janv. 2018 à 09:11
Est-ce que, dans ton code Java, tu utilises bien la même authority?
Dans ton xml, je vois:
${applicationId}.provider
. Il faut donc, dans ton code Java:
Uri photoURI = FileProvider.getUriForFile(this, "ICI LA MÊME AUTHORITY", photoFile);

0
Angelneonizz Messages postés 784 Date d'inscription mardi 9 décembre 2003 Statut Membre Dernière intervention 19 février 2018 137
17 janv. 2018 à 09:43
je fais comme ça pour l'intent :
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // Ensure that there's a camera activity to handle the intent
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            // Create the File where the photo should go
            File photoFile = null;
            try {
                photoFile = createImageFile();
            } catch (IOException ex) {
                // Error occurred while creating the File

            }
            // Continue only if the File was successfully created
            if (photoFile != null) {
                Uri photoURI = FileProvider.getUriForFile(this,
                        getPackageName() + ".fileprovider",
                        photoFile);
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
            }
        }

j'ai même essayé de mettre en dur à la place de variable mais ça ne change rien

merci pour ta réponse
0
BunoCS Messages postés 15472 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 25 mars 2024 3 894
17 janv. 2018 à 10:08
Attention,
packageName
est différent de
applicationId
.
Dans ton Manifest, est-ce que ton objet provider est bien dans l'objet application?
Est-ce que le "external path" est bien renseigné? Voir ici: https://stackoverflow.com/questions/46550472/fileprovider-geturiforfile-returns-nullpointerexception/46551475#46551475

Désolé de poser des questions qui semblent triviales ^^
0
Angelneonizz Messages postés 784 Date d'inscription mardi 9 décembre 2003 Statut Membre Dernière intervention 19 février 2018 137
Modifié le 17 janv. 2018 à 11:00
oui provider est bien dans application.

je dois t'avouer que je n'ai pas compris quoi mettre dans mon XML, c'est en fonction de là ou je veux enregistrer mes images ?

voila le code :
private void dispatchTakePictureIntent() {

        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        // Ensure that there's a camera activity to handle the intent
        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            // Create the File where the photo should go
            File photoFile = null;
            try {
                photoFile = createImageFile();
            } catch (IOException ex) {
                // Error occurred while creating the File

            }
            // Continue only if the File was successfully created
            if (photoFile != null) {

                Log.i("Camera", "Packagename: " + BuildConfig.APPLICATION_ID);
                Log.i("Camera", "images: " + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));

                Uri photoURI = FileProvider.getUriForFile(this,
                        BuildConfig.APPLICATION_ID +".fileprovider",
                        photoFile);
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
            }
        }
    }

private File createImageFile() throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,  /* prefix */
                ".jpg",         /* suffix */
                storageDir      /* directory */
        );

        // Save a file: path for use with ACTION_VIEW intents
        mCurrentPhotoPath = image.getAbsolutePath();
        return image;
    }


mon appli plante des que je lance l'intent (au moment ou je clic sur le bouton pour appeler l'intent) donc quelque chose merde dans createImageFile ou quand j'appelle l'intent

edit: j'ai mis des Log partout, donc createImageFile a l'air de fonctionner correctement.
Il plante au niveau de
if (photoFile != null) {

                Log.i("Camera", "Packagename: " + BuildConfig.APPLICATION_ID);
                Log.i("Camera", "images: " + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES));

                Uri photoURI = FileProvider.getUriForFile(this,
                        BuildConfig.APPLICATION_ID +".fileprovider",
                        photoFile);
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
            }


pas de souci, pose toutes les questions que tu veux, je débute donc je ne suis pas à l’abri d'avoir fait une connerie basique.

merci pour ton aide en tout cas
0
BunoCS Messages postés 15472 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 25 mars 2024 3 894
17 janv. 2018 à 14:36
Extrait du tuto:
The path component corresponds to the path that is returned by getExternalFilesDir() when called with Environment.DIRECTORY_PICTURES. Make sure that you replace com.example.package.name with the actual package name of your app. Also, checkout the documentation of FileProvider for an extensive description of path specifiers that you can use besides external-path.

0
Angelneonizz Messages postés 784 Date d'inscription mardi 9 décembre 2003 Statut Membre Dernière intervention 19 février 2018 137
Modifié le 17 janv. 2018 à 15:00
je me suis planté dans le manifest :s le boulet dans autorities j'avais mis .provider et il faut mettre fileprovider, mon code avance un eu plus mais mon appli plante toujours.

l'image maintenant est bien créé sur mon téléphone mais au moment où je retourne dans mon application (donc après avoir pris la photo) ça plante avec comme log:

E/AndroidRuntime: FATAL EXCEPTION: main
                  Process: com.sncf.android.internal.beta.outillagenational, PID: 4943
                  java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=2, result=-1, data=null} to activity {com.sncf.android.internal.beta.outillagenational/com.sncf.android.internal.beta.outillagenational.ui.FormProbleme}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Bundle android.content.Intent.getExtras()' on a null object reference
                      at android.app.ActivityThread.deliverResults(ActivityThread.java:4481)
                      at android.app.ActivityThread.handleSendResult(ActivityThread.java:4524)
                      at android.app.ActivityThread.-wrap22(ActivityThread.java)
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1691)
                      at android.os.Handler.dispatchMessage(Handler.java:102)
                      at android.os.Looper.loop(Looper.java:154)
                      at android.app.ActivityThread.main(ActivityThread.java:6692)
                      at java.lang.reflect.Method.invoke(Native Method)
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
                   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.os.Bundle android.content.Intent.getExtras()' on a null object reference
                      at com.sncf.android.internal.beta.outillagenational.ui.FormProbleme.onActivityResult(FormProbleme.java:254)
                      at android.app.Activity.dispatchActivityResult(Activity.java:7226)
                      at android.app.ActivityThread.deliverResults(ActivityThread.java:4477)
                      at android.app.ActivityThread.handleSendResult(ActivityThread.java:4524) 
                      at android.app.ActivityThread.-wrap22(ActivityThread.java) 
                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1691) 
                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                      at android.os.Looper.loop(Looper.java:154) 
                      at android.app.ActivityThread.main(ActivityThread.java:6692) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358) 


ça plante au niveau de onActivityResult, voici mon code :
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) {
         ImageView imageView = findViewById(R.id.imgView);
        LinearLayout linearFile = findViewById(R.id.linearFile);
        TextView filePath = findViewById(R.id.filePath);

        case REQUEST_TAKE_PHOTO:
                if(resultCode == RESULT_OK) {

                    Log.i("infos", "REQUEST_TAKE_PHOTO" + imageReturnedIntent);

                    Bundle extras = imageReturnedIntent.getExtras();
                    Bitmap imageBitmap = (Bitmap) extras.get("data");

                    linearFile.setOrientation(LinearLayout.VERTICAL);
                    imageView.setImageBitmap(imageBitmap);
                    imageView.setVisibility(ImageView.VISIBLE);

}



comme tu peux le voire j'ai essayé de faire un Log.i en affichant l'intent et il retourne null, c'est normal ça ?
0
BunoCS Messages postés 15472 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 25 mars 2024 3 894
17 janv. 2018 à 15:37
Oui, c'est normal lorsque tu reviens de la caméra.
Il faut que tu ailles chercher ton image via un ContentProvider.

Note: plutôt que de mettre des logs, tu peux lancer ton application en Debug (roue crantée avec une flèche verte) et mettre des breakpoints pour voir ce qui se passe
0
Angelneonizz Messages postés 784 Date d'inscription mardi 9 décembre 2003 Statut Membre Dernière intervention 19 février 2018 137
18 janv. 2018 à 07:39
Merci beaucoup pour ton aide, il ne me reste plus qu'à transformer l'Uri de mon image de content://com.dfdfdfdf.fileprovider/my_images/jpeg_2018.jpg en /external/images/media/8749 par exemple
0
BunoCS Messages postés 15472 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 25 mars 2024 3 894
18 janv. 2018 à 08:58
Voici ce que j'utilise:

    /**
     * Retrieve filename from Uri
     *
     * @param uri             Uri following the schemes: "file" or "content"
     * @param contentResolver ContentResolver to resolve content scheme
     *
     * @return filename if operation succeded. Can be null.
     */
    public static String getFileName(@NonNull final Uri uri, @NonNull final ContentResolver contentResolver) {
        String filename = "";
        if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
            filename = uri.getLastPathSegment();
        } else if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
            try {
                Cursor cursor = contentResolver.query(uri, null, null, null, null);
                int index = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
                cursor.moveToFirst();
                filename = cursor.getString(index);
                cursor.close();
            } catch (Exception e) {
                LogUtils.e(TAG, "Exception when retrieving file name: " + e.getMessage());
            }
        }

        return filename;
    }
0
Angelneonizz Messages postés 784 Date d'inscription mardi 9 décembre 2003 Statut Membre Dernière intervention 19 février 2018 137
18 janv. 2018 à 09:10
merci beaucoup mais à quoi correspond ContentResolver ?
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
BunoCS Messages postés 15472 Date d'inscription lundi 11 juillet 2005 Statut Modérateur Dernière intervention 25 mars 2024 3 894
19 janv. 2018 à 09:23
Problème résolu? Cool!
0