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?
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 );
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.
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.
Ajouter dans AndroidManifest.xml avant la balise
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"Android:maxSdkVersion="18"/>
/**
* 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;
}
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;
}
Enregistrement dans cacheDir à l’aide de FileProvider. Il ne nécessite aucune autorisation.
<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>
<?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>
/**
* 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
/**
* 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);
}
** 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);
}
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.
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"));
}
});
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.