2011年10月24日月曜日

共有アプリ一覧ダイアログをカスタマイズする

共有アプリ一覧ダイアログをカスタマイズする

他のアプリを「共有」機能を使って起動させる場合、共有が可能なアプリの一覧を表示させて、その一覧の中から、利用者が、お好みのアプリを選択することになります。

Implicit Intentを使って共有コマンドを発行する場合、指定した条件に合致する全てのアプリがアプリ一覧に表示されてしまいます。この時表示される「アプリ一覧表示ダイアログ」は、androidシステムが準備したものです。

自分のアプリが他のアプリから「共有」機能により起動可能な場合であって、かつ自分のアプリで「共有」機能を使う場合、「共有一覧ダイアログ」には自分のアプリも表示されてしまいます。
もし、そこで、自分のアプリを選択した場合、自分のアプリで自分のアプリを共有したことになります。
このような些末な件は、多くのアプリにおいては、どちらでも良いことです。
しかし、アプリの性質上、これは困る場合もあります。

このような問題の場合、共有アプリ一覧表示プログラムをカスタマイズすることになります。

仕掛けの流れは次のようになります。
  1. PackageManagerを使って、指定した条件に合致する、端末内の全てのアプリ情報を取得する。
  2. 取得した情報の中から、任意のアプリを削除する。
  3. 一覧をAlertDialogに表示する。
  4. 利用者が任意のアプリを選択する。
  5. 選択されたアプリをExplicit Intentで実行する。
つまり、Implicit Intentを使わないようにするのです。
PackageManagerのコーディングは次のとおりです。
    PackageManager pm = getPackageManager();
このような書き方だと、自分のアプリだけの情報を取得しただけかと思ってしまいますが、端末の全てのアプリの情報を取り扱う仕掛けになっているので注意しましょう。

参考

下に、上記1~3までを実行するsourceを掲載しておきます。
int i;
Intent it;
PackageManager pm;
List<ResolveInfo> lri;
ArrayList<ResolveInfoList> al;
ArrayAdapter<ResolveInfoList> aa;
AlertDialog.Builder b;
TextView tv;
ResolveInfoList ril;
Resources r;

r = getResources();
al = new ArrayList<ResolveInfoList>();
it = new Intent();
//起動するアプリを限定させて頂きます。
it.setAction(Intent.ACTION_SEND);
it.setType("text/plain");
pm = getPackageManager();
lri = pm.queryIntentActivities(it, PackageManager.MATCH_DEFAULT_ONLY);

switch(lri.size()){
case 0:
    tv = (TextView)findViewById(R.id.TextRegister);
    tv.setText(R.string.noData);
    return;
default: break;
}

//自分自身を含めないようにする。
ApplicationInfo ai = null;
try{
    ai = pm.getApplicationInfo(getPackageName(), 0);
}
catch(PackageManager.NameNotFoundException e){
}
String sLabel;
sLabel = ai.loadLabel(pm).toString();

//AlertDialogに表示させる一覧を作成する。
for(i=0; i<lri.size(); i++){
    String s;
    ResolveInfo ri;
    ri = lri.get(i);
    s = ri.loadLabel(pm).toString();
    if(s.equals(sLabel)==true);
    else{
        ril = new ResolveInfoList();
        ril.sResolveInfo = s ;
        ril.ri = ri;
        al.add(ril);//リストに追加する。
    }
}
ril = new ResolveInfoList();
ril.sResolveInfo = r.getString(R.string.noShare);
al.add(ril);
aa = new ArrayAdapter<ResolveInfoList>(this, 
android.R.layout.select_dialog_singlechoice, al);
aa.sort(new MyComparator());//文字列をキーにして並べ替える。
b = new AlertDialog.Builder(this);
b.setTitle(R.string.DialogTitle);
b.setSingleChoiceItems(aa, 0, this);
b.setNegativeButton(R.string.Close,
    new DialogInterface.OnClickListener(){
        public void onClick(DialogInterface dialog, int id) {
            dialog.cancel();//「閉じる」ボタンを押しても何もしない。
        }
    }
);
adServiceDialog = b.show();//見せる。

0 件のコメント:

コメントを投稿