web-dev-qa-db-de.com

Freigeben von Bitmap über Android Intent

In meiner Android-App habe ich eine Bitmap (sagen Sie b) und eine Schaltfläche. Wenn ich jetzt auf die Schaltfläche klicke, möchte ich die Bitmap freigeben. Ich verwende den folgenden Code in meiner onClick(), um dies zu erreichen: -

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

Ich habe eine Liste aller Anwendungen erwartet, die mit dieser Absicht umgehen können, aber ich bekomme nichts. Es gibt keine Liste von Apps und es gibt auch keine Fehler in Android Studio. Meine Anwendung wird einfach für einige Zeit gehängt und dann beendet.

Ich habe das Bitmap überprüft und es ist in Ordnung (es ist nicht null). 

Wo gehe ich falsch?

20

Wie CommonsWare feststellte, müssen Sie den URI zur Bitmap bringen und als Extra übergeben.

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

Ich habe 2 Varianten der Lösung gefunden. Beide speichern Bitmap im Speicher, das Bild wird jedoch nicht in der Galerie angezeigt.

Erste Variante:

Speichern auf externen Speicher - aber in privaten Ordner der App .- für API <= 18 ist eine Berechtigung erforderlich, für neuere jedoch nicht.

1. Berechtigungen einstellen

Vor dem Tag in AndroidManifest.xml einfügen

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

2. sparmethode:

 /**
 * 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. Überprüfung der Speicherzugänglichkeit

Auf den externen Speicher kann möglicherweise nicht zugegriffen werden. Sie sollten ihn daher vor dem Speichern überprüfen - 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;
}

Zweite Variante

Speichern in cacheDir mit FileProvider. Es bedarf keiner Erlaubnis.

1. Richten Sie FileProvider in AndroidManifest.xml ein

<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. Fügen Sie den Pfad zu res/xml/file_paths.xml hinzu

<?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. sparmethode:

    /**
 * 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;
}

Weitere Informationen zum Dateianbieter - https://developer.Android.com/reference/Android/support/v4/content/FileProvider

Das Komprimieren und Speichern kann zeitaufwändig sein und sollte in einem anderen Thread erfolgen.

Tatsächliches Teilen

/**
 * 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

** endlich habe ich die lösung. ** 

Schritt 1:Blockieren der Freigabe von Absichtsabsichten. Dadurch wird das Fenster mit der Liste der Anwendungen in Ihrem Telefon geöffnet.

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();
    }


}

Schritt 2:Konvertieren Ihrer Ansicht in 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;
}

Schritt 3 :

Um die URI von Bitmap-Bildern zu erhalten

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

Zitieren die Dokumentation :

Ein Inhalt: URI, der einen Datenstrom enthält, der dem Intent zugeordnet ist und mit ACTION_SEND verwendet wird, um die gesendeten Daten bereitzustellen. 

b soll daher keine Bitmap sein, sondern eine Uri, die auf eine Bitmap zeigt, die von einer ContentProvider bedient wird. Sie können beispielsweise die Variable Bitmap in eine Datei schreiben und dann FileProvider verwenden, um sie bereitzustellen.

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

Nachdem ich viel Zeit damit verbracht habe:

Prüfen Sie, ob Berechtigungen erteilt wurden. Dann:

Schritt 1: Erstellen Sie ImageView des Bildes, das Sie in der Aktivität verwenden möchten, und konvertieren Sie es in keine Bitmap

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

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

Schritt 2: Speichern Sie das Bild im internen Ordner:

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();
    }
}

Schritt 3: Senden Sie das gespeicherte Bild:

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();
    }
}

Nach dem Senden können Sie das gespeicherte Bild jetzt löschen, wenn Sie es nicht in Ihrem Speicher ablegen möchten. Überprüfen Sie den anderen Link, um dies zu tun.

0
Arahasya