1. 程式人生 > >android基礎知識---不同app的跳轉,及程序的控制

android基礎知識---不同app的跳轉,及程序的控制

這裡我簡單介紹下跳轉的三個方式,直接上方法了

1、已知包名直接按包名跳轉

  Intent intent = getPackageManager().getLaunchIntentForPackage("com.example.admin.tiaoapp2");
  if (intent){
      startActivity(intent);
  }           

2、已知包名和activity和包名跳轉(Intent.setComponent())

Intent intent = new Intent();
                ComponentName componentName=new
ComponentName("com.example.admin.tiaoapp2","com.example.admin.tiaoapp2.MainActivity"); intent.setComponent(componentName); startActivity(intent);

這裡你可以看到我沒做非空判斷
下面是網上流傳的非常普遍的用法:

String package_name = "xx.xx.xx";
String activity_path = "xx.xx.xx.ab.xxActivity";
Intent intent =
new Intent(); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//可選 ComponentName cn = new ComponentName(package_name,activity_path); intent.setComponent(cn); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } else { //找不到指定的 Activity }

但是經驗證,Intent.resolveActivity() 方法並不能判定此方式所要啟動的 Activity 是否存在,如果此 Activity 不存在,會報 Java.lang.IllegalArgumentException: Unknown component 異常,並導致程式崩潰。
所以我選擇用resolveActivityInfo,這兩種方法非常相似,咱們對比下原始碼

public ComponentName resolveActivity(PackageManager pm) {
    if (mComponent != null) {
        return mComponent;
    }

    ResolveInfo info = pm.resolveActivity(this,
        PackageManager.MATCH_DEFAULT_ONLY);
    if (info != null) {
        return new ComponentName(
            info.activityInfo.applicationInfo.packageName,
            info.activityInfo.name);
    }

    return null;
}

public ActivityInfo resolveActivityInfo(PackageManager pm, int flags) {
    ActivityInfo ai = null;
    if (mComponent != null) {
        try {
            ai = pm.getActivityInfo(mComponent, flags);
        } catch (PackageManager.NameNotFoundException e) {
            // ignore
        }
    } else {
        ResolveInfo info = pm.resolveActivity(this,
            PackageManager.MATCH_DEFAULT_ONLY | flags);
        if (info != null) {
            ai = info.activityInfo;
        }
    }

    return ai;
}

顯而易見,resolveActivityInfo最後還是呼叫了resolveActivity,但是其內部做了處理和判斷不會報IllegalArgumentException

所以最後的使用方式

Intent intent = new Intent();
                ComponentName componentName=new ComponentName("com.example.admin.tiaoapp2","com.example.admin.tiaoapp2.MainActivity");
intent.setComponent(componentName);
if (intent.resolveActivityInfo(getPackageManager(), PackageManager.MATCH_DEFAULT_ONLY) != null) {
    startActivity(intent);
}

3、已知包名跳轉遍歷找到activity跳轉

 private void doStartApplicationWithPackageName(String packagename) {

        // 通過包名獲取此APP詳細資訊,包括Activities、services、versioncode、name等等
        PackageInfo packageinfo = null;
        try {
            packageinfo = getPackageManager().getPackageInfo(packagename, 0);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        if (packageinfo == null) {
            return;
        }

        // 建立一個類別為CATEGORY_LAUNCHER的該包名的Intent
        Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);
        resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        resolveIntent.setPackage(packageinfo.packageName);

        // 通過getPackageManager()的queryIntentActivities方法遍歷
        List<ResolveInfo> resolveinfoList = getPackageManager()
                .queryIntentActivities(resolveIntent, 0);

        ResolveInfo resolveinfo = resolveinfoList.iterator().next();
        if (resolveinfo != null) {
            // packagename = 引數packname
            String packageName = resolveinfo.activityInfo.packageName;
            // 這個就是我們要找的該APP的LAUNCHER的Activity[組織形式:packagename.mainActivityname]
            String className = resolveinfo.activityInfo.name;
            // LAUNCHER Intent
            Intent intent = new Intent(Intent.ACTION_MAIN);
            intent.addCategory(Intent.CATEGORY_LAUNCHER);
            Log.e("測試 :","packageName:"+packageName+"   className:"+className);
            // 設定ComponentName引數1:packagename引數2:MainActivity路徑
            ComponentName cn = new ComponentName(packageName, className);

            intent.setComponent(cn);
            startActivity(intent);
        }

這裡小tips下程序:

如果按包名跳轉會有兩個程序,但是如果按activity跳轉則 只有一個程序。(我就是掉坑了—。——)

4隱式啟動第三方應用

這裡在說下隱式啟動第三方應用
此方式多用於啟動系統中的功能性應用,比如打電話、發郵件、預覽圖片、使用預設瀏覽器開啟一個網頁等。

Intent intent = new Intent();
intent.setAction(action);
intent.addCategory(category);
intent.setDataAndType("abc://www.dfg.com","image/gif");
startActivity(intent);
條件1:IntentFilter 至少有一個action 至少有一個Category 可以沒有DataType

條件2:如果有Data,引數中Data必須符合Data規則

條件3:Action和Category必須同時匹配Activity中的一個Action和一個Category(Category 預設:android.intent.category.DEFAULT)