web-dev-qa-db-fra.com

Partage de bitmap via Android Intent

Dans mon application Android, j'ai un bitmap (disons b) et un bouton. Maintenant, lorsque je clique sur le bouton, je souhaite partager le bitmap. Je me sers du code ci-dessous dans ma onClick() pour y parvenir: -

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/png");
intent.putExtra(Intent.EXTRA_STREAM, b);
startActivity(Intent.createChooser(intent , "Share"));

J'attendais une liste de toutes les applications capables de gérer cette intention, mais je ne reçois rien. Il n'y a pas de liste d'applications ni d'erreur dans Android studio. Mon application vient juste d'être pendue pendant un moment, puis quitte.

J'ai vérifié le bitmap et tout va bien (ce n'est pas nul). 

Où est-ce que je me trompe?

20
Jhilmil Chatterjee

Comme CommonsWare l'a déclaré, vous devez obtenir l'URI du bitmap et le définir comme votre extra.

String bitmapPath = Images.Media.insertImage(getContentResolver(), bitmap,"title", null);
Uri bitmapUri = Uri.parse(bitmapPath);
...
intent.putExtra(Intent.EXTRA_STREAM, bitmapUri );
22
Rick S

J'ai découvert 2 variantes de la solution. Les deux enregistrent Bitmap sur le stockage, mais l'image n'est pas affichée dans la galerie.

Première variante:

Enregistrement sur un stockage externe - mais dans un dossier privé de l'application .- pour l'API <= 18, une autorisation est nécessaire, pour les plus récents, ce n'est pas le cas.

1. Définir les autorisations

Ajouter dans AndroidManifest.xml avant la balise

<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"Android:maxSdkVersion="18"/>

2. Méthode d'économie:

 /**
 * Saves the image as PNG to the app's private external storage folder.
 * @param image Bitmap to save.
 * @return Uri of the saved file or null
 */
private Uri saveImageExternal(Bitmap image) {
    //TODO - Should be processed in another thread
    Uri uri = null;
    try {
        File file = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES), "to-share.png");
        FileOutputStream stream = new FileOutputStream(file);
        image.compress(Bitmap.CompressFormat.PNG, 90, stream);
        stream.close();
        uri = Uri.fromFile(file);
    } catch (IOException e) {
        Log.d(TAG, "IOException while trying to write file for sharing: " + e.getMessage());
    }
    return uri;
}

3. Vérification de l'accessibilité du stockage

Le stockage externe peut ne pas être accessible, vous devriez donc le vérifier avant d'essayer de sauvegarder - https://developer.Android.com/training/data-storage/files

/**
 * Checks wheather the external storage is writable.
 * @return true if storage is writable, false otherwise
 */
public boolean isExternalStorageWritable() {
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        return true;
    }
    return false;
}

Deuxième variante

Enregistrement dans cacheDir à l’aide de FileProvider. Il ne nécessite aucune autorisation.

1. Configurer FileProvider dans AndroidManifest.xml

<manifest>
    ...
    <application>
        ...
        <provider
            Android:name="Android.support.v4.content.FileProvider"
            Android:authorities="com.mydomain.fileprovider"
            Android:exported="false"
            Android:grantUriPermissions="true">
                <meta-data
                    Android:name="Android.support.FILE_PROVIDER_PATHS"
                    Android:resource="@xml/file_paths" />
        </provider>
        ...
    </application>
</manifest>

2. Ajouter un chemin au res/xml/file_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <paths xmlns:Android="http://schemas.Android.com/apk/res/Android">
         <cache-path name="shared_images" path="images/"/>
    </paths>
</resources>

3. Méthode d'économie:

    /**
 * Saves the image as PNG to the app's cache directory.
 * @param image Bitmap to save.
 * @return Uri of the saved file or null
 */
private Uri saveImage(Bitmap image) {
    //TODO - Should be processed in another thread
    File imagesFolder = new File(getCacheDir(), "images");
    Uri uri = null;
    try {
        imagesFolder.mkdirs();
        File file = new File(imagesFolder, "shared_image.png");

        FileOutputStream stream = new FileOutputStream(file);
        image.compress(Bitmap.CompressFormat.PNG, 90, stream);
        stream.flush();
        stream.close();
        uri = FileProvider.getUriForFile(this, "com.mydomain.fileprovider", file);

    } catch (IOException e) {
        Log.d(TAG, "IOException while trying to write file for sharing: " + e.getMessage());
    }
    return uri;
}

Plus d'infos sur le fournisseur de fichier - https://developer.Android.com/reference/Android/support/v4/content/FileProvider

Compresser et économiser peut prendre beaucoup de temps et doit être effectué dans un fil différent

Partage réel

/**
 * Shares the PNG image from Uri.
 * @param uri Uri of image to share.
 */
private void shareImageUri(Uri uri){
    Intent intent = new Intent(Android.content.Intent.ACTION_SEND);
    intent.putExtra(Intent.EXTRA_STREAM, uri);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
    intent.setType("image/png");
    startActivity(intent);
}
18
kjs566

** enfin j'ai eu la solution. ** 

Étape 1: Bloc de traitement de l’intention de partage. Cela fera apparaître votre fenêtre avec la liste des applications dans votre téléphone

public void share_bitMap_to_Apps() {

    Intent i = new Intent(Intent.ACTION_SEND);

    i.setType("image/*");
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    /*compress(Bitmap.CompressFormat.PNG, 100, stream);
    byte[] bytes = stream.toByteArray();*/


    i.putExtra(Intent.EXTRA_STREAM, getImageUri(mContext, getBitmapFromView(relative_me_other)));
    try {
        startActivity(Intent.createChooser(i, "My Profile ..."));
    } catch (Android.content.ActivityNotFoundException ex) {

        ex.printStackTrace();
    }


}

Étape 2: Conversion de votre vue en BItmap

public static Bitmap getBitmapFromView(View view) {
    //Define a bitmap with the same size as the view
    Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(),      view.getHeight(), Bitmap.Config.ARGB_8888);
    //Bind a canvas to it
    Canvas canvas = new Canvas(returnedBitmap);
    //Get the view's background
    Drawable bgDrawable = view.getBackground();
    if (bgDrawable != null)
        //has background drawable, then draw it on the canvas
        bgDrawable.draw(canvas);
    else
        //does not have background drawable, then draw white background on the canvas
        canvas.drawColor(Color.WHITE);
    // draw the view on the canvas
    view.draw(canvas);
    //return the bitmap
    return returnedBitmap;
}

Étape 3 :

Pour obtenir l'URI d'une image bitmap

public Uri getImageUri(Context inContext, Bitmap inImage) {
    ByteArrayOutputStream bytes = new ByteArrayOutputStream();
    inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);

    String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
    return Uri.parse(path);
}
11
AshisParajuli

Citant la documentation :

Un contenu: URI contenant un flux de données associé à l'objectif, utilisé avec ACTION_SEND pour fournir les données en cours d'envoi. 

b n'est donc pas censé être un Bitmap, mais plutôt un Uri désignant un Bitmap, servi par un ContentProvider. Par exemple, vous pouvez écrire la Bitmap dans un fichier, puis utiliser FileProvider pour le servir.

4
CommonsWare
ImageButton capture_share = (ImageButton) findViewById(R.id.share);
capture_share.setOnClickListener(new View.OnClickListener() {
  @Override
  public void onClick(View view) {

    String bitmapPath = MediaStore.Images.Media.insertImage(getContentResolver(), bitmap,"title", null);
    Uri bitmapUri = Uri.parse(bitmapPath);

        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setType("image/png");
        intent.putExtra(Intent.EXTRA_STREAM, bitmapUri);
        startActivity(Intent.createChooser(intent, "Share"));



  }
});
4
Lalit Baghel

Après avoir passé beaucoup de temps sur ceci:

Vérifiez si les autorisations sont données. Ensuite:

Étape 1: Créez ImageView de l'image que vous voulez dans l'activité, puis convertissez-la en bitmap

ImageView imageView = findViewById(R.id.image);
Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();

//save the image now:
saveImage(bitmap);
//share it
send();

Étape 2: enregistrez l'image dans un dossier interne:

private static void saveImage(Bitmap finalBitmap) {

    String root = Environment.getExternalStorageDirectory().getAbsolutePath();
    File myDir = new File(root + "/saved_images");
    Log.i("Directory", "==" + myDir);
    myDir.mkdirs();

    String fname = "Image-test" + ".jpg";
    File file = new File(myDir, fname);
    if (file.exists()) file.delete();
    try {
        FileOutputStream out = new FileOutputStream(file);
        finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
        out.flush();
        out.close();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

Étape 3: envoyez l'image enregistrée:

public void send() {
    try {
        File myFile = new File("/storage/emulated/0/saved_images/Image-test.jpg");
        MimeTypeMap mime = MimeTypeMap.getSingleton();
        String ext = myFile.getName().substring(myFile.getName().lastIndexOf(".") + 1);
        String type = mime.getMimeTypeFromExtension(ext);
        Intent sharingIntent = new Intent("Android.intent.action.SEND");
        sharingIntent.setType(type);
        sharingIntent.putExtra("Android.intent.extra.STREAM", Uri.fromFile(myFile));
        startActivity(Intent.createChooser(sharingIntent, "Share using"));
    } catch (Exception e) {
        Toast.makeText(getBaseContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
    }
}

Maintenant, après l’envoi, vous pouvez supprimer l’image sauvegardée si vous ne le souhaitez pas. Vérifiez autre lien pour le faire.

0
Arahasya