[解決済み】ACTION_SENDインテントを特定のアプリでフィルタリングする方法(アプリごとに異なるテキストを設定することも可能です)
質問
ACTION_SENDインテントを使用する際に、特定のアプリをフィルタリングするにはどうすればよいですか? この質問はいろいろとされていますが、与えられた回答から解決策を収集することができません。誰かが助けてくれるといいのですが。アプリ内で共有する機能を提供したいと思います。以下 Android DevのAlexander Lucasのアドバイス FacebookやTwitterのAPIを使わず、インテントを使うことを希望しています。
ACTION_SENDインテントを使った共有は素晴らしいが 問題は、(1) すべての共有オプションが必要なわけではなく、FB、Twitter、メールに限定したいこと、(2) それぞれの共有アプリに同じものを共有したくないことです。 . 例えば、twitterの共有では、140文字以内に限定して言及やハッシュタグを入れ、facebookの共有では、リンクと特徴的な画像を入れる予定です。
ACTION_SEND(共有)インテントのオプションを制限することは可能でしょうか?PackageManagerとqueryIntentActivitiesの使用について何かで見たことがありますが、PackageManagerとACTION_SENDインテントの間の関連性を把握することができていません。
または
共有アプリをフィルタリングするのではなく、ACTION_SENDインテントを使用して、ダイアログをポップアップするのではなく、直接facebookやtwitterに移動できれば、私の問題は解決されるでしょう。その場合、独自のダイアログを作成し、ユーザーが "Facebook" をクリックすると、Facebook 固有のインテントを作成し、Facebook に直接送信することができます。Twitterでも同じです。
それとも不可能なのでしょうか?FacebookとTwitterのAPIが唯一の方法なのでしょうか?
解決方法は?
私の知る限り、StackOverflowにはたくさんの人が様々な方法でこの質問を投げかけていますが、まだ誰も完全に答えてはいません。
私の仕様では、ユーザーがメール、Twitter、Facebook、SMSを選択でき、それぞれにカスタムテキストを設定できるようにする必要がありました。以下は、それを実現する方法です。
public void onShareClick(View v) {
Resources resources = getResources();
Intent emailIntent = new Intent();
emailIntent.setAction(Intent.ACTION_SEND);
// Native email client doesn't currently support HTML, but it doesn't hurt to try in case they fix it
emailIntent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(resources.getString(R.string.share_email_native)));
emailIntent.putExtra(Intent.EXTRA_SUBJECT, resources.getString(R.string.share_email_subject));
emailIntent.setType("message/rfc822");
PackageManager pm = getPackageManager();
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/plain");
Intent openInChooser = Intent.createChooser(emailIntent, resources.getString(R.string.share_chooser_text));
List<ResolveInfo> resInfo = pm.queryIntentActivities(sendIntent, 0);
List<LabeledIntent> intentList = new ArrayList<LabeledIntent>();
for (int i = 0; i < resInfo.size(); i++) {
// Extract the label, append it, and repackage it in a LabeledIntent
ResolveInfo ri = resInfo.get(i);
String packageName = ri.activityInfo.packageName;
if(packageName.contains("android.email")) {
emailIntent.setPackage(packageName);
} else if(packageName.contains("twitter") || packageName.contains("facebook") || packageName.contains("mms") || packageName.contains("android.gm")) {
Intent intent = new Intent();
intent.setComponent(new ComponentName(packageName, ri.activityInfo.name));
intent.setAction(Intent.ACTION_SEND);
intent.setType("text/plain");
if(packageName.contains("twitter")) {
intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.share_twitter));
} else if(packageName.contains("facebook")) {
// Warning: Facebook IGNORES our text. They say "These fields are intended for users to express themselves. Pre-filling these fields erodes the authenticity of the user voice."
// One workaround is to use the Facebook SDK to post, but that doesn't allow the user to choose how they want to share. We can also make a custom landing page, and the link
// will show the <meta content ="..."> text from that page with our link in Facebook.
intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.share_facebook));
} else if(packageName.contains("mms")) {
intent.putExtra(Intent.EXTRA_TEXT, resources.getString(R.string.share_sms));
} else if(packageName.contains("android.gm")) { // If Gmail shows up twice, try removing this else-if clause and the reference to "android.gm" above
intent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(resources.getString(R.string.share_email_gmail)));
intent.putExtra(Intent.EXTRA_SUBJECT, resources.getString(R.string.share_email_subject));
intent.setType("message/rfc822");
}
intentList.add(new LabeledIntent(intent, packageName, ri.loadLabel(pm), ri.icon));
}
}
// convert intentList to array
LabeledIntent[] extraIntents = intentList.toArray( new LabeledIntent[ intentList.size() ]);
openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
startActivity(openInChooser);
}
この方法の断片はいろいろなところで見つけましたが、すべてを一箇所にまとめたものは他では見たことがありません。
この方法では、無線LANやブルートゥースでの共有のような、私が望まないバカげたオプションもすべて隠されていることに注意してください。
これが誰かの役に立つといいのですが。
編集する
コメントで、このコードが何をしているのか説明してほしいと言われました。基本的には、このコードは
ACTION_SEND
インテントをネイティブのメールクライアント専用にし、他のインテントをチューザーに追加しています。元のインテントをメール専用にすることで、wifi や bluetooth などの余分なジャンクをすべて取り除き、次に、必要な他のインテントを一般的な
ACTION_SEND
をplain-text型で表示し、chooserを表示する前にそれらを貼り付けます。
追加インテントを取得する際に、それぞれにカスタムテキストを設定しました。
Edit2: 投稿からしばらく経ち、少し状況が変わりました。もし、オプションのリストに2回gmailが表示される場合は、以下の@h_kさんのコメントにあるように、"android.gm"の特別な処理を削除してみてください。
この回答が私のstackoverflowの評価ポイントのほぼ全ての源なので、少なくとも最新の状態に保つよう努力しなければならないのです。
関連
-
[解決済み] TextViewでテキストを水平・垂直方向にセンタリングするには?
-
Gradle のエラーです。gradle-core.jar (com.android.tools.build:gradle-core:x.x.x) を見つけられませんでした。
-
AndroidがMainActivityが包含クラスでないというエラーを報告する
-
Android: インポートモジュールエラー Android リソースのリンクに失敗しました
-
Google PlayデバイスはPlay保護機構の認証を受けていません。
-
アンドロイドスタジオのエラーを解決する --> Error:(1, 0) id 'com.android.application' を持つプラグインが見つかりません。
-
アンドロイドのエリプサイズを使用する
-
ConstraintLayoutのいくつかのプロパティの概要(RelativeLayoutの強化版、LinearLayoutの比例プロパティを含む、階層ツールの削減)。
-
問題 ---- Android ---- ActivityManager: Error: アクティビティクラス{xx/xx.MainActivity}が存在しない
-
アンドロイドシェイプ、グラデーション、角丸、ボーダーラインの設定
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
adb シェルがデバイスのオフラインを求めるプロンプトを表示する
-
armeabi-v7a armeabi arm64-v8a パラメータの意味説明
-
AndroidでAttempt to invoke virtual method... on null object referenceの例外が発生する。
-
Android Studio を 3.6.3 にアップデートした後、構成 :classpath のアーティファクトをすべて解決できない。
-
プログラム "git.exe "を実行できない場合の正しい解決方法です。CreateProcessエラー=2
-
GIF、Lottie、SVGA
-
RuntimeException: アクティビティを開始できません ComponentInfo solution
-
GoogleMapと連携し、位置情報の取得が可能
-
Android--shape--描画のコーナー、グラデーション、パディング、サイズ、ソリッド、ストロークのプロパティを指定する。
-
[解決済み] メール送信インテント