文章部分內(nèi)容轉(zhuǎn)載于:https://blog.csdn.net/qq_40967402/article/details/82598465
博客原文內(nèi)容
在開發(fā)的過程中 有時(shí)候可能會(huì)需要進(jìn)行應(yīng)用之間的跳轉(zhuǎn) 而跳轉(zhuǎn)又分為顯式意圖和隱式意圖
首先說一下顯示意圖和隱式意圖的區(qū)別
- 顯式意圖:
明確指定組件名的Intent為顯示意圖盏筐,明確了Intent應(yīng)該傳遞給那個(gè)組件簿透。 - 隱式意圖:
沒有明確指定組件名的Intent為隱式意圖。
顯示意圖多用于應(yīng)用內(nèi)到跳轉(zhuǎn) 也就是我們平時(shí)用的跳轉(zhuǎn)方式 而隱式意圖多用于多用于應(yīng)用間的跳轉(zhuǎn)*
因?yàn)轱@示意圖需要明確知道報(bào)名和類名才能進(jìn)行跳轉(zhuǎn) 而跳轉(zhuǎn)其他第三方應(yīng)用 很有可能不知道他的包名和類名 除非是合作應(yīng)用或者進(jìn)行了反編譯
假如 在知道包名類名的情況下 需要跳轉(zhuǎn)到第三方的應(yīng)用 就可以使用顯示意圖跳轉(zhuǎn) 下面是例子
假如我們要跳轉(zhuǎn)到瀏覽器搜索頁面 瀏覽器的包名是 com.android.browser
搜索頁面的類名為com.android.browser.BrowserActivity
那么有兩種方法可以實(shí)現(xiàn)
第一種:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClassName("com.android.browser", "com.android.browser.BrowserActivity");
startActivity(intent);
}
});
第二種:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
ComponentName componentName=new ComponentName("com.android.browser", "com.android.browser.BrowserActivity");
intent.setComponent(componentName);
startActivity(intent);
}
});
如果在不知道指定的Activity界面類名的情況下就需要跳轉(zhuǎn)到指定的界面 這里需要隱式調(diào)用 依然是使用上面的包名
可以這樣寫
通過action和category來進(jìn)行跳轉(zhuǎn)指定的界面(這兩個(gè)參數(shù)在應(yīng)用API文檔里面有標(biāo)注 或者 可以直接網(wǎng)上找)
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction("android.intent.action.SEARCH");
intent.addCategory("android.intent.category.DEFAULT");
intent.setPackage("com.android.browser");
}
});
還有一種情況就是不需要跳轉(zhuǎn)到指定的界面 只需要打開應(yīng)用 而且 只知道包名 怎么辦 別慌 這樣來:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = getPackageManager().getLaunchIntentForPackage("com.android.browser");
startActivity(intent);
}
});
這里需要說明一下Intent的setClass和setClassName的區(qū)別
setClass:跳轉(zhuǎn)到與該工程下的(同一個(gè)Application中的)activity或者service
setClassName:跳轉(zhuǎn)到不同Applicaiton的activity或者service
判斷手機(jī)上有沒有第三方應(yīng)用
/**
* 檢測
*
*/
public static void checkIsInstall(Context ctx, String packageName) {
if ( !isAvilible( packageName , ctx ) ){
//沒有安裝Apk
}else {
//已經(jīng)安裝了Apk
Intent intent = new Intent();
intent.setClassName(packageName, srcActivity);
ctx.startActivity(intent);
}
}
/**
* 檢查是否安裝了某應(yīng)用
*
* @param packageName 包名
* @return
*/
public static boolean isAvilible(String packageName, Context mContext) {
final PackageManager packageManager = mContext.getPackageManager();
// 獲取所有已安裝程序的包信息
List<PackageInfo> pinfo = packageManager.getInstalledPackages(0);
for (int i = 0; i < pinfo.size(); i++) {
if (pinfo.get(i).packageName.equalsIgnoreCase(packageName))
return true;
}
return false;
}
注意點(diǎn)
如果加了上面的內(nèi)容捌治,在 實(shí)現(xiàn)的過程中出現(xiàn)了如下的錯(cuò)誤:
Caused by: java.lang.SecurityException: Permission Denial: starting Intent { cmp=tecsun.jx.yt.phone/.MainActivity } from ProcessRecord{44299e68 11892:com.example.administrator.linkyingtandemo/u0a85} (pid=11892, uid=10085) not exported from uid 10482
這個(gè)應(yīng)該就是第三方的應(yīng)用沒有加許可跳轉(zhuǎn):android:exported="true"
<activity
android:exported="true"
android:name="xxxxxxx.xxxx.xxx.xxx.MainActivity"
android:configChanges="keyboardHidden|orientation"
android:launchMode="singleTask"
android:screenOrientation="portrait" />