1. ホーム
  2. android

ビットマップのAndroid共有インテント - 共有前に保存しないことは可能ですか?

2023-09-02 20:07:37

質問

一時的な場所にファイルを保存することなく、共有インテントを使用してアプリからビットマップをエクスポートしようとします。私が見つけたすべての例は、2 つのステップです。 1) SD カードに保存し、そのファイルの Uri を作成します。 2) この Uri を使用してインテントを開始します。

WRITE_EXTERNAL_STORAGE パーミッションを必要とせず、ファイルを保存して [その後削除して] 作ることは可能でしょうか? ExternalStorage のないデバイスに対処する方法は?

どのように解決するのですか?

私もこれと同じ問題を抱えていました。外部ストレージの読み取りと書き込みの権限を要求されるのが嫌でした。また、携帯電話に SD カードがない場合や、カードがアンマウントされる場合に問題が発生することもあります。

次の方法では ContentProvider と呼ばれる ファイルプロバイダ . 技術的には、共有する前にまだビットマップを(内部ストレージに)保存していますが、いかなるパーミッションも要求する必要はありません。また、ビットマップを共有するたびに、画像ファイルは上書きされます。また、内部キャッシュにあるため、ユーザーがアプリをアンインストールすると削除されます。ですから、私見では、画像を保存しないのと同じです。また、この方法は、外部ストレージに保存するよりも安全です。

ドキュメントはかなり良いのですが (下記の「さらに読む」を参照)、いくつかの部分は少し厄介です。以下は、私のために機能した要約です。

マニフェストに FileProvider をセットアップする

<manifest>
    ...
    <application>
        ...
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.myapp.fileprovider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/filepaths" />
        </provider>
        ...
    </application>
</manifest>

置換 com.example.myapp をアプリのパッケージ名に置き換えてください。

res/xml/filepaths.xmlを作成します。

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

これは、FileProviderに共有するファイルをどこで取得するかを伝えます(この場合、キャッシュディレクトリを使用します)。

画像を内部ストレージに保存する

// save bitmap to cache directory
try {

    File cachePath = new File(context.getCacheDir(), "images");
    cachePath.mkdirs(); // don't forget to make the directory
    FileOutputStream stream = new FileOutputStream(cachePath + "/image.png"); // overwrites this image every time
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
    stream.close();

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

画像を共有する

File imagePath = new File(context.getCacheDir(), "images");
File newFile = new File(imagePath, "image.png");
Uri contentUri = FileProvider.getUriForFile(context, "com.example.myapp.fileprovider", newFile);

if (contentUri != null) {
    Intent shareIntent = new Intent();
    shareIntent.setAction(Intent.ACTION_SEND);
    shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); // temp permission for receiving app to read this file
    shareIntent.setDataAndType(contentUri, getContentResolver().getType(contentUri));
    shareIntent.putExtra(Intent.EXTRA_STREAM, contentUri);
    startActivity(Intent.createChooser(shareIntent, "Choose an app"));
}

その他の記事