版權聲明:本文源自簡書tianma,轉載請務必注明出處: http://www.lxweimin.com/p/994228144838
最近需要去實現應用內跳轉至微博的個人信息頁面(用戶個人主頁),其本質就是打開并跳轉至第三方App指定的頁面。顯然,我們可以通過調用 startActivity(intent)
來實現該功能,其關鍵就是 intent
中需要攜帶哪些信息。
反編譯 AndroidManifest.xml
將新浪微博的apk文件中的 AndroidManifest.xml
文件解壓提取出來,然后使用 AXMLPrinter2.jar 對清單文件進行反編譯:
java -jar AXMLPrinter2.jar AndroidManifest.xml > weibo.xml
其中 weibo.xml
即反編譯成功的清單文件。
獲取微博個人頁 Activity
因為之前 weibo.xml
中的 Activity
過多,我們需要知道微博的用戶個人信息頁面對應的 Activity
全稱。這里有兩種方法:
- 使用輔助App來獲取當前的 Activity ,例如 當前界面(當前Activity) ,具體用法這里就不介紹了。
- 使用 adb 命令獲取當前 Activity:
adb shell dumpsys activity activities | grep mFocusedActivity
當我們把新浪微博的個人信息頁面切至前臺時, adb 命令的結果為:
mFocusedActivity: ActivityRecord{9063f6f u0 com.sina.weibo/.page.ProfileInfoActivity t1578}
也就是說,新浪微博的個人信息頁對應的 Activity 為 com.sina.weibo.page.ProfileInfoActivity
, 那我們看 weibo.xml
中與該 Activity 對應的 xml 節點:
<activity
android:theme="@7F0B0011"
android:name="com.sina.weibo.page.ProfileInfoActivity"
android:exported="true"
android:configChanges="0x000004A0"
android:windowSoftInputMode="0x00000020">
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:scheme="sinaweibo" android:host="userinfo"></data>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<category android:name="android.intent.category.BROWSABLE"></category>
<data android:scheme="http" android:host="weibo.cn" android:path="/qr/userinfo"></data>
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW"></action>
<category android:name="android.intent.category.DEFAULT"></category>
<data android:mimeType="vnd.android.cursor.item/vnd.com.sina.weibo.profile"></data>
</intent-filter>
</activity>
分析
上面的 xml 節點中,可以看到 android:exported="true"
,也就是說 ProfileInfoActivity
可以被外部程序調用打開。有三個 intent-filter
節點,其中第三個 intent-filter
與 ContentProvider
有關,可以忽略第三個只考慮前兩個。
第一個 intent-filter
接受的 data 格式為 sinaweibo:userinfo
, 第二個 intent-filter
接受的 data 格式為 http://weibo.cn/qr/userinfo
。 我們通過 data 節點的數據可以判斷除,第二個除了可以被新浪微博響應,也可以被瀏覽器之類的應用響應,但第一個只能被新浪微博響應,所以在使用第一個之前,需要判斷新浪微博是否已經安裝,否則會崩潰。
實現
通過查閱相關文檔,ProfileInfoActivity
可以接受的參數為 uid=xxx
, 也就是 sinaweibo://userinfo?uid=xxx
和 http://weibo.cn/qr/userinfo?uid=xxx
,所以最終代碼實現:
// 跳轉至微博個人頁
public void jumpToWeiboProfileInfo(Context context, String uid) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.addCategory(Intent.CATEGORY_BROWSABLE);
boolean weiboInstalled = PackageUtils.isSinaWeiboInstalled(context);
if (weiboInstalled) {
intent.setData(Uri.parse("sinaweibo://userinfo?uid=" + uid));
} else {
intent.setData(Uri.parse("http://weibo.cn/qr/userinfo?uid=" + uid));
}
context.startActivity(intent);
}
// PackageUtils.java
public class PackageUtils {
private PackageUtils(){}
// 新浪微博是否安裝
public static boolean isSinaWeiboInstalled(Context context) {
return isPackageInstalled(context, "com.sina.weibo");
}
// 包名對應的App是否安裝
public static boolean isPackageInstalled(Context context, String packageName) {
PackageManager packageManager = context.getPackageManager();
if (packageManager == null)
return false;
List<PackageInfo> packageInfoList = packageManager.getInstalledPackages(0);
for(PackageInfo info : packageInfoList) {
if (info.packageName.equals(packageName))
return true;
}
return false;
}
}