前言
这种需求太常见了,产品采用众多三方分享来达到向移动端引流,分享出去的h5页面点击可以打开App甚至是App的某个指定页面。
本文并没有提供什么特别的解决方案,并且只是Android要做的设置,只能满足简单的产品需求,如果需求复杂,可以不看了。。。
存在的问题
微信大概是所有国内产品最需要分享到的第三方应用,但是偏偏微信禁用了除自己产品系外的schema协议(自己产品系的是设置了白名单的,如果能和微信合作设置进白名单也是ok的)
普通且平凡的解决方案一
在微信内的浏览器提示已安装该产品的用户在浏览器中打开该网页,然后再去跳转到App
-
Android端设置
在AndroidManifest.xml中,给目标Activity增加<intent-filter>,com.dhasa.test用来标识schema,最好能保证唯一,那样就可以打开应用,而不用再弹出一个选择框,所以可以用自己的包名来命名
<activity
android:name="com.dhasa.MainActivity"
android:screenOrientation="portrait" >
<intent-filter>
...其他过滤设置 ...
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<category android:name="android.intent.category.DEFAULT"/>
<!-- 【example one】简单的,这样h5只需要指定 com.dhasa.test:// 就可以打开App了-->
<data android:scheme="com.dhasa.test" />
</intent-filter>
</activity>
在上述例子中 h5只端只需要指定 com.dhasa.test:// 就可以打开App了
普通且平凡的解决方案二
上面方案在手机浏览器下是没问题的,但是在Android WebView加载的h5中是存在问题的,起码我的遇到问题了,是因为设置了WebViewClient的shouldOverrideUrlLoading方法(起码我的调不起来是因为设置了这个,也许不设置本身也有问题,如果遇到问题知道用这个去解决就行了)
Android内WebView加载h5链接中打开第三方APP:
- h5中设置一个包含intent格式的链接
intent:#Intent;scheme=【xxx】;package=【xxx】;end
【】中替换为你APP设置的scheme和应用的包名即可,其他部分和方案一相同
- Android中在shouldOverrideUrlLoading中加入这部分处理代码:
if(url.startsWith("intent:")){//这个部分是用来处理特定格式的url来打开其他APP,前端目前不再用这种方式了,而是通过通信调用原生方式打开其他APP
try {
Intent intent = Intent.parseUri(url,Intent.URI_INTENT_SCHEME);
intent.setComponent(null);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if(getContext().getPackageManager().resolveActivity(intent,0) != null){
getContext().startActivity(intent);
}else{
UiUtil.showToast(getContext(),"暂未安装App,请先去下载哦~");
}
return true;
} catch (URISyntaxException e) {
e.printStackTrace();
}
return true;
}
这个方法的其他逻辑保持之前的代码逻辑即可,就是新增了这个处理分支而已。
-
补充
因为自己目前没有做过这方面其他复杂的需求,也不会特意去花费时间去尝试这种,但是在查询过程中也发现了几篇,在这里列出,在需要的时候作参考:
附一份打开第三方APP的代码,如果没安装就打开手机上默认的应用商店:
/**
* 打开第三方的app
*/
private void startNewApp(String data) {
try {
JSONObject jsonObject = new JSONObject(data);
String packageName = jsonObject.optString("packageName");
if(!TextUtils.isEmpty(packageName)){
if(PackageManagerUtil.hasThisApp(packageName)){
Intent intent = mContext.getPackageManager().getLaunchIntentForPackage(packageName);
if(intent == null) return;
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}else{
MarketNavUtil.launchMarketAppDetail(mContext,packageName,"");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
找本地包
private static void initPackageManager() {
List<PackageInfo> packageInfos = mPackageManager.getInstalledPackages(0);
if (packageInfos != null) {
for (int i = 0; i < packageInfos.size(); i++) {
mPackageNames.add(packageInfos.get(i).packageName);
}
}
}
public static boolean hasThisApp(String packageName){
initPackageManager();
return mPackageNames.contains(packageName);
}
打开手机上的应用市场
/**
* @param context 上下文
* @param desAppPkg 目标App
* @param marketPkg 应用市场,填写空则为手机上默认
*/
public static void launchMarketAppDetail(Context context, String desAppPkg, String marketPkg){
if(TextUtils.isEmpty(desAppPkg))return;
Uri uri = Uri.parse("market://details?id="+desAppPkg);
Intent intent = new Intent(Intent.ACTION_VIEW,uri);
if(!TextUtils.isEmpty(marketPkg)){
intent.setPackage(marketPkg);
}
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
网友评论