前人未踏の領域へ Androidアプリ開発編

Androidアプリ開発に関する調査メモ置き場。古い記事にはアプリ以外も含まれます。

Android 10以降でアプリシェア時にEXTRA_INITIAL_INTENTSが機能しない

課題

コンテンツのシェア機能利用時に Intent.createChooser したIntentに対し、EXTRA_INITIAL_INTENTS で ターゲットアプリごとに特別にカスタマイズしたLabeledIntentを渡していたが、Android10端末でシェア対象のアプリが数件しか表示されなくなった。

原因

Android10のChooserActivityのコードを見ると以下のような記述がある

private static final int MAX_EXTRA_INITIAL_INTENTS = 2;

ここで2件に制限されているため、実際に渡した件数よりも少なく表示される。

        Parcelable[] pa = intent.getParcelableArrayExtra(Intent.EXTRA_INITIAL_INTENTS);
        Intent[] initialIntents = null;
        if (pa != null) {
            int count = Math.min(pa.length, MAX_EXTRA_INITIAL_INTENTS);
            initialIntents = new Intent[count];
            for (int i = 0; i < count; i++) {
                if (!(pa[i] instanceof Intent)) {
                    Log.w(TAG, "Initial intent #" + i + " not an Intent: " + pa[i]);
                    finish();
                    super.onCreate(null);
                    return;
                }
                final Intent in = (Intent) pa[i];
                modifyTargetIntent(in);
                initialIntents[i] = in;
            }
        }

実際には同じ場所に3, 4件表示されたりするのだが、これはおすすめアプリをGoogleが自動で選択しているような 気がする。

対応

Androidのフォーラムを見るとバグじゃないかという報告も出ているが、 明示的に制限が記述されている以上、EXTRA_INITIAL_INTENTSの利用はやめるか又は特に重要なアプリのみに制限し、 API Level 29以降は標準の Intent.ACTION_SENDだけを使うようにする。

when {
            Build.VERSION.SDK_INT <= Build.VERSION_CODES.P -> {
                   //これまでのシェア
            }
            else -> { 
                  //新しいシェア
                 val shareIntent: Intent = Intent(Intent.ACTION_SEND)
                 ... 略
                 val chooserIntent = Intent.createChooser(shareIntent, 'share')
                 activity.startActivity(chooserIntent)
         }      
}

Google標準の汎用シェア機能を使おうとすると、アプリごとに受け付けるパラメータが異なったりして うまく動作しないので EXTRA_INITIAL_INTENTS によりカスタマイズする方法が使われていたが、 Googleとしてはこれを制限することによって標準のシェア機能に対応するようアプリ側に促していきたいのかもしれない。 とはいえテキストと画像を同時に扱えるアプリとそうでないのがあったりパラメータの有無で表示されるアプリが変わってきちゃったりするので、 そう上手くは行かないんだよな。

参考