赞
踩
Android 跳转手机已安装的应用市场,APP大多数都会引导用户去应用市场进行评分或者评论,正常的跳转协议已经可以满足大部分手机应用市场,但是在三星、索尼、红米上也会出现一些不一样的效果,本文记录如何适配跳转。
/**
* 跳转应用商店.
*
* @param context {@link Context}
* @param appPkg 包名
* @param marketPkg 应用商店包名
* @return {@code true} 跳转成功 <br> {@code false} 跳转失败
*/
public static boolean toMarket(Context context, String appPkg, String marketPkg) {
Uri uri = Uri.parse("market://details?id=" + appPkg);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
if (marketPkg != null) {// 如果没给市场的包名,则系统会弹出市场的列表让你进行选择。
intent.setPackage(marketPkg);
}
try {
context.startActivity(intent);
return true;
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
正常跳转如果手机安装了多个应用市场,例如:应用宝、360手机助手,则会弹出系统选择框给用户进行选择,用户也可以勾选是否默认选择(某些机型是:始终/仅此一次)
HUAWEI | Xiaomi |
---|---|
上述正常方法未能打开三星的官方应用商店,也就是如果要跳转三星应用商店则需要单独适配。正确打开方式如下:
/**
* 跳转三星应用商店
* @param context {@link Context}
* @param packageName 包名
* @return {@code true} 跳转成功 <br> {@code false} 跳转失败
*/
public static boolean goToSamsungMarket(Context context, String packageName) {
Uri uri = Uri.parse("http://www.samsungapps.com/appquery/appDetail.as?appId=" + packageName);
// Uri uri = Uri.parse("http://apps.samsung.com/appquery/appDetail.as?appId=" + packageName);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
intent.setPackage("com.sec.android.app.samsungapps");
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(intent);
return true;
} catch (ActivityNotFoundException e) {
e.printStackTrace();
return false;
}
}
上述正常方法未能打开索尼的官方应用商店-索尼精选,也有人指出索尼并无单独的应用商店,采用的是Google的Google Play,国内才推出索尼精选。正确的打开方式如下:
/**
* 跳转索尼精选
* @param context {@link Context}
* @param appId 索尼精选中分配得appId
* @return {@code true} 跳转成功 <br> {@code false} 跳转失败
*/
public static boolean goToSonyMarket(Context context, String appId) {
Uri uri = Uri.parse("http://m.sonyselect.cn/" + appId);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
// Intent intent = new Intent();
// intent.setAction("com.sonymobile.playnowchina.android.action.NOTIFICATION_APP_DETAIL_PAGE");
// intent.setAction("com.sonymobile.playnowchina.android.action.APP_DETAIL_PAGE");
// intent.putExtra("app_id", 9115);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
try {
context.startActivity(intent);
return true;
} catch (Exception ex) {
ex.printStackTrace();
return false;
}
}
跳转索尼精选,附带APPID,但是这个值是索尼精选分配的,也就是上传了索尼精选后的id,例如微信的id是9115。
上述正常方式跳转应用市场,无论手机是否安装其他应用市场,均跳转至小米商店。(本人测试手机红米4X,属于正常跳转)
由于上述情况多变,但是大多数情况下,正常写法已经满足要求。如果想仅仅跳转应用宝或者小米商店,而不进行系统弹窗选择,可以直接指定包名,这样就可以直接跳转。
/**
* 直接跳转至应用宝
*
* @param context {@link Context}
* @param appPkg 包名
* @return {@code true} 跳转成功 <br> {@code false} 跳转失败
*/
public static boolean toQQDownload(Context context, String appPkg) {
return toMarket(context, appPkg, "com.tencent.android.qqdownloader");
}
/**
* 直接跳转至360手机助手
*
* @param context {@link Context}
* @param appPkg 包名
* @return {@code true} 跳转成功 <br> {@code false} 跳转失败
*/
public static boolean to360Download(Context context, String appPkg) {
return toMarket(context, appPkg, "com.qihoo.appstore");
}
/**
* 直接跳转至豌豆荚
*
* @param context {@link Context}
* @param appPkg 包名
* @return {@code true} 跳转成功 <br> {@code false} 跳转失败
*/
public static boolean toWandoujia(Context context, String appPkg) {
return toMarket(context, appPkg, "com.wandoujia.phoenix2");
}
/**
* 直接跳转至小米应用商店
*
* @param context {@link Context}
* @param appPkg 包名
* @return {@code true} 跳转成功 <br> {@code false} 跳转失败
*/
public static boolean toXiaoMi(Context context, String appPkg) {
return toMarket(context, appPkg, "com.xiaomi.market");
}
/**
* 直接跳转至魅族应用商店
*
* @param context {@link Context}
* @param appPkg 包名
* @return {@code true} 跳转成功 <br> {@code false} 跳转失败
*/
public static boolean toMeizu(Context context, String appPkg) {
return toMarket(context, appPkg, "com.meizu.mstore");
}
鉴于说上述机型差异,如果想自定义弹窗,那必须检测手机安装的应用商店有哪些,检测方式如下:(未详细测试)
/**
* 检查已安装的应用商店
* 但是小米商店目前检测不出,先定义为bug
*
* @param context {@link Context}
* @return 返回包名列表
*/
public static List<String> checkMarket(Context context) {
List<String> packageNames = new ArrayList<>();
Intent intent = new Intent();
intent.setAction("android.intent.action.MAIN");
intent.addCategory("android.intent.category.APP_MARKET");
PackageManager pm = context.getPackageManager();
List<ResolveInfo> infos = pm.queryIntentActivities(intent, 0);
int size = infos.size();
for (int i = 0; i < size; i++) {
ActivityInfo activityInfo = infos.get(i).activityInfo;
String packageName = activityInfo.packageName;
Log.d(TAG, "packageName : " + packageName);
packageNames.add(packageName);
}
return packageNames;
}
按照正常的写法,三星和索尼都无法跳转。下面将分析方法记录起来,便于以后还有其他机型要适配时也知道如何进行适配。
Intent跳转方式分为显式和隐式,正常跳转属于隐式跳转,正常写法未跳转的需要去寻找其应用商店APP的跳转协议。
1.下载对应的应用商店APK,然后进行反编译。
2.主要查看AndroidManifest.xml文件,分析跳转协议。
3.使用jd-gui查看源码,分析是否会附带额外参数。
三星应用商店:
AndroidManifest.xml
<activity android:configChanges="keyboard|keyboardHidden|orientation|screenSize" android:exported="true" android:name="com.sec.android.app.samsungapps.Main" android:screenOrientation="unspecified" android:theme="@style/SamsungAppsTranslucentNoTitleBarTheme">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="www.samsungapps.com" android:pathPrefix="/appquery/appDetail.as" android:scheme="http"/>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:host="apps.samsung.com" android:pathPrefix="/appquery/appDetail.as" android:scheme="http"/>
</intent-filter>
</activity>
ContentDetailActivity.java
结合AndroidManifest.xml以及源码,可以分析出三星的跳转协议,经测试两中host都可以成功跳转,测试机型:三星C5,Android 7.1.1。
索尼精选
<activity android:alwaysRetainTaskState="true" android:clearTaskOnLaunch="false" android:configChanges="fontScale|keyboard|keyboardHidden|locale|screenLayout|uiMode" android:name="com.sonyericsson.playnowchina.android.phone.AppDetailActivity" android:screenOrientation="portrait">
<intent-filter>
<category android:name="android.intent.category.BROWSABLE"/>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:host="m.sonyselect.cn" android:scheme="http"/>
</intent-filter>
<intent-filter>
<action android:name="com.sonymobile.playnowchina.android.action.NOTIFICATION_APP_DETAIL_PAGE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
<intent-filter>
<action android:name="com.sonymobile.playnowchina.android.action.APP_DETAIL_PAGE"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
AppDetailActivity.java
结合AndroidManifest.xml和源码,很容易得出Action+app_id
这个额外参数,但是这样的跳转无论app_id
传的是包名还是上架索尼精选后的id,跳转后都Toast显示网络异常。最后按照<data>
得出结果。
机型 | 版本 | 效果 |
---|---|---|
索尼xm50t | 4.3 | 需要单独适配索尼精选 |
三星C5 | 7.1.1 | 需要单独适配三星应用商店 |
红米4X | 7.1.2,MIUI 9 | 正常 |
华为Mate8 | 7.0,EMUI 5.0.1 | 正常 |
魅族note3 | 7.0,flyme 6.2.0.1 | 正常 |
OPPOA37m | 5.1,ColorOs 3.0 | 正常 |
https://github.com/scauzhangpeng/Sample/blob/master/util/src/main/java/com/xyz/util/MarketUtil.java
本篇记录如何进行适配应用商店的方法,索尼精选这类在开发过程中也可以不进行适配,视情况而定。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。