前提・実現したいこと
Androidアプリケーションの開発を行っています。
アプリで実現したいことは
・自身のアプリから他のアプリを起動し、起動先アプリへ画像ファイルを渡す。
・画像ファイルはアプリ内のasset
フォルダに含まれる
です。
私が調べた範囲では、外部アプリとファイルの連携を行う方法として以下の二つがあるようです。
assets
内のファイルを他のアプリから参照できる共有ディレクトリにコピーし、そのパス(URI)をIntentで送る。Content Provider
の仕組みを利用し、他のアプリからasset
内のデータを参照できるようにして、そのパス(URI)をIntentで送る。
今回はなるべく外部にファイルを残したくないので、まず上記の方法2で実装を行いました。
現状、
Twitterアプリでは画像を参照できるのですが、
Gmailアプリの場合は参照同様の方法でファイルが参照できない状態です。
発生している問題・エラーメッセージ
Twitterアプリには画像の受け渡しができることを確認したのですが、
Gmailの場合は
空のファイルを添付することはできません。
と表示されてしまい、添付することができない状態です。
該当のソースコード
- マニフェストファイル(AndroidManifest.xml)
... provider設定の部分のみ抜粋 ...
<provider android:name="com.example.r_tamura.app.AssetFileProvider"
android:authorities="com.example.r_tamura.app.provider.Asset"
android:exported="true"
android:grantUriPermissions="true"
android:multiprocess="true">
</provider>
...
- AssetFileProvider.java
// Content Providerを継承したProviderクラス
public class AssetFileProvider extends ContentProvider {
public static final String PROVIDER_AUTHORITY = "com.example.r_tamura.app.provider.Asset";
public static final String URL = "content://" + PROVIDER_AUTHORITY;
public static final Uri CONTENT_URI = Uri.parse(URL);
... 実装が必要なメソッドはオーバーライドしたデフォルトの処理のままですので省略 ...
@Nullable
@Override
public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
AssetManager am = getContext().getAssets();
AssetFileDescriptor afd = null;
String path = uri.getLastPathSegment();
try {
afd = am.openFd(path);
} catch (IOException e) {
e.printStackTrace();
Log.e(Const.LOGTAG, "Error: " + e);
throw new FileNotFoundException(e.getMessage());
}
return afd;
}
}
- MainActivity.java
メインアクティビティクラスです。画面内のボタンを押すとIntentを発行するイベントを登録しています。
// メインアクティビティのボタンにIntent発行すイベントを登録する
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btn = (Button) findViewById(R.id.btn); // ボタンを取得
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v){
// "sample.png"が共有したい画像で,ファイルは`asset`ディレクトリの直下に配置しております。
Uri theUri = Uri.parse("content://com.example.r_tamura.app.provider.Asset/sample.png");
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_STREAM, theUri);
shareIntent.putExtra(Intent.EXTRA_SUBJECT, "サンプルタイトル");
shareIntent.putExtra(Intent.EXTRA_TEXT, "サンプルメッセージ"));
shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(i, "Chooserタイトル"));
}
}
試したこと
上記のコードで方法2を実装しました。
2016/06/16追記
方法1で実装することでGmail,Twitterに画像を渡すことが一応できました。
補足情報(言語/FW/ツール等のバージョンなど)
■ 事象を確認した実機データ
- モデル番号:Nexus 7
- Androidバージョン: 5.1.1
■ 開発環境
- OS: Windows 10
- IDE: Android Studio 2.1.2
ContentProviderを使用した対応方法をご存知でしたらご教授いただけますと幸いです。よろしくお願いいたします。
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
まだ回答がついていません
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.22%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる