私のAndroidアプリには、ビットマップ(たとえばb)とボタンがあります。ボタンをクリックすると、ビットマップを共有したいのです。以下のコードを使用していますこれを達成するための私のonClick()
:-
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/png");
intent.putExtra(Intent.EXTRA_STREAM, b);
startActivity(Intent.createChooser(intent , "Share"));
この意図を処理できるすべてのアプリケーションのリストを期待していましたが、何も得られません。アプリのリストも、Android studioにもエラーはありません。私のアプリケーションはしばらくハングアップして終了します。
ビットマップをチェックしましたが、問題ありません(nullではありません)。
どこがおかしいの?
ソリューションの2つのバリエーションを見つけました。どちらもビットマップをストレージに保存していますが、画像はギャラリーに表示されません。
外部ストレージへの保存
タグの前にAndroidManifest.xmlに追加します
<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;
}
外部ストレージにアクセスできない可能性があるため、保存する前に確認する必要があります- 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;
}
FileProviderを使用してcacheDirに保存します。許可は必要ありません。
<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;
}
ファイルプロバイダーの詳細- https://developer.Android.com/reference/Android/support/v4/content/FileProvider
圧縮と保存には時間がかかる可能性があり、これは別のスレッドで行う必要があります
/**
* 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);
}
CommonsWareが述べたように、ビットマップへのURIを取得し、それをExtraとして渡す必要があります。
String bitmapPath = Images.Media.insertImage(getContentResolver(), bitmap,"title", null);
Uri bitmapUri = Uri.parse(bitmapPath);
...
intent.putExtra(Intent.EXTRA_STREAM, bitmapUri );
**最終的に私は解決策を得た。**
ステップ1:インテント処理ブロックを共有します。これにより、携帯電話のアプリケーションのリストがウィンドウに表示されます
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();
}
}
ステップ2:ビューを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;
}
ステップ3:
ビットマップ画像からURIを取得するには
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);
}
引用 ドキュメント :
コンテンツ:インテントに関連付けられたデータのストリームを保持するURI。ACTION_SENDとともに使用して、送信されるデータを提供します。
したがって、b
はBitmap
ではなく、Uri
によって提供されるBitmap
を指すContentProvider
であると想定されています。たとえば、Bitmap
をファイルに書き込み、FileProvider
を使用してファイルを提供できます。
こんにちはコーダーはこれを試してください
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"));
}
});
これに多くの時間を費やした後:
権限が付与されているかどうかを確認します。その後:
ステップ1:アクティビティで必要な画像のImageViewを作成し、ビットマップに変換しない
ImageView imageView = findViewById(R.id.image);
Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap();
//save the image now:
saveImage(bitmap);
//share it
send();
ステップ2:内部フォルダーに画像を保存する:
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();
}
}
ステップ3:保存された画像を送信する:
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();
}
}
送信後、ストレージに保存したくない場合は、保存した画像を削除できます。他のリンクを確認してください。