android基礎知識---不同app的跳轉,及程序的控制
阿新 • • 發佈:2019-02-20
這裡我簡單介紹下跳轉的三個方式,直接上方法了
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 可以沒有Data和Type
條件2:如果有Data,引數中Data必須符合Data規則
條件3:Action和Category必須同時匹配Activity中的一個Action和一個Category(Category 預設:android.intent.category.DEFAULT)