调用系统分享到指定 App

最近掘金有需求,要把分享到 Pocket 和 EverNote 替换为直接调用客户端分享。之前我们使用 ShareSDK ,分享到 Pocket 和 EverNote 需要在网页版进行登录,样式非常丑陋,而且输入账号密码也非常麻烦。

分享到第三方应用,其实就是调用系统的android.intent.action.ACTION_SEND给其它应用传递数据

//分享数据给第三方应用
//这种分享是直接调用系统的选择器,在安装的程序中选择接收`android.intent.action.SEND`来处理分享
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(Intent.createChooser(sendIntent, "分享到"));

那么,怎么分享到指定的 Activity 呢?我们可以通过

//com.xxx.xx 为 PackageName
//com.xxx.xx.activity.ShareActivity 为 ClassName
intent.setClassName("com.xxx.xx", "com.xxx.xx.activity.ShareActivity");

来指定接收分享的 Activity.

接下来就要获取我们要分享到应用的 PackageName 和要分享到 Activity 的 ClassName 了,由于 XML 文件不能混淆,我们只需要使用 apktool 反编译apk 就可以查看 manifest 文件中应用的 PackageName 和 ClassName 的信息。

//反编译命令
apktool.bat d -f [apk文件] [输出文件夹]
//例子
apktool.bat d c:\test.apk c:\TestApkFolder

EverNote 的 Manifest 文件部分信息:

//package="com.evernote"  ->  PackageName 为 com.evernote
<manifest xmlns:amazon="http://schemas.amazon.com/apk/res/android" xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto" package="com.evernote" platformBuildVersionCode="23" platformBuildVersionName="6.0-2166767">

//IntentFilter 中包含`android.intent.action.ACTION_SEND` 或 `android.intent.action.ACTION_SEND_MULTIPLE`的 Activity 为接收第三方应用信息的 Activity
//android:name="com.evernote.clipper.ClipActivity" -> ClassName 为 com.evernote.clipper.ClipActivity
<activity android:configChanges="keyboardHidden|orientation|screenLayout|screenSize"     android:finishOnTaskLaunch="true" android:name="com.evernote.clipper.ClipActivity" android:theme="@style/Theme.ClipperDialog">
            <intent-filter android:icon="@drawable/ic_launcher" android:label="@string/add_to_evernote">
                <action android:name="com.google.android.gm.action.AUTO_SEND"/>
                <action android:name="android.intent.action.SEND"/>
                <action android:name="android.intent.action.SEND_MULTIPLE"/>
                <data android:mimeType="*/*"/>
                <category android:name="android.intent.category.DEFAULT"/>
                <category android:name="com.google.android.voicesearch.SELF_NOTE"/>
            </intent-filter>
        </activity>

分享到第三方应用:

try {
        Intent intent = new Intent(Intent.ACTION_SEND);
        intent.setClassName("com.evernote", "com.evernote.clipper.ClipActivity");
        //分享到 Pocket
        //intent.setClassName("com.pocket.cn", "com.ideashower.readitlater.activity.AddActivity");
        intent.putExtra(Intent.EXTRA_TEXT, url);
        intent.setType("text/plain");
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        context.startActivity(intent);
    } catch (Exception e) {
        //未安装应用,可以调用第三方或者提示用户未安装应用
}