2012年6月17日日曜日

続:startActivity()実行時のSecurityExceptionに悩まされる

startActivity()実行時のSecurityExceptionに悩まされる問題があったが、
ランチャーとなるActivityで起動する事で問題を回避する事が出来た。
今まで取得したRecentTaskInfoのbaseIntentをそのままstartActivity()に
渡していたが、この方法では起動できない外部アプリが存在するのは確かだ。

ここに例として、タスク履歴を取得して一番古いタスクを起動する
方法をメモしておく。
@Override
public void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    startOldestActivity();
}

// タスク情報(インテント)格納クラス
public class AppData{
    Intent intent;

    public Intent getIntent(){
        return intent;
    }

    public void setIntent(Intent intent){
        this.intent = intent;
    }
}

// タスク履歴情報を取得して一番古いタスクを起動するメソッド
public void startOldestActivity(){
    ActivityManager activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    List<recenttaskinfo> recentTasks = activityManager.getRecentTasks(100, 0);
    List<AppData> appList = new ArrayList<AppData>();

    for(RecentTaskInfo recentTask : recentTasks){
        // オリジナルインテントで初期化
        Intent startIntent = recentTask.baseIntent;
        ComponentName componentName = recentTask.origActivity;

        if(componentName != null){
            startIntent = new Intent(Intent.ACTION_MAIN);
            startIntent.addCategory(Intent.CATEGORY_LAUNCHER);
            startIntent.setComponent(componentName);
        }

        String packageName = startIntent.getComponent().getPackageName();

        // ランチャーActivityとなるインテントを取得
        Intent launchIntent = getPackageManager().getLaunchIntentForPackage(packageName);

        if(launchIntent != null) {    
            componentName = launchIntent.getComponent();

            // 一意に決まる場合はそのコンポネント情報でインテントを作成
            if(componentName != null && !componentName.getClassName().equals(com.android.internal.app.ResolverActivity)){
                launchIntent = new Intent(Intent.ACTION_MAIN);
                launchIntent.addCategory(Intent.CATEGORY_LAUNCHER);
                launchIntent.setComponent(componentName);
                startIntent = launchIntent;
            }
        }

        startIntent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_NEW_TASK);
        AppData appData = new AppData();
        appData.setIntent(startIntent);
        appList.add(appData);
    }

    try{
        if(appList.size() > 0){
            Intent intent = appList.get(appList.size()-1).getIntent();
            startActivity(intent);
        }
    } catch(ActivityNotFoundException e){
        // エラーメッセージなど
    }
}

0 件のコメント:

コメントを投稿