分享是APP中很是高頻的操做之一,在Android的開發環境中,第三方分享框架也有不少。比較流行的包括 極光社會化分享(sharesdk)、友盟社會化分享(Ushare)、Mob社會化分享以及在githut上比較流行的 ShareSDK、ShareUtil、BiliShare、ShareLoginLib等等。 本篇文章基於友盟ShareSDK,介紹了其集成過程並對其進行模塊化封裝,以便在項目中更快捷的集成和使用。java
獲取友盟Appkeyandroid
在【友盟+】官網註冊而且添加新應用,得到Appkey。友盟後臺的應用名與實際應用名和包名無關,建議命名爲應用名+平臺(iOS/Android),Android和IOS兩個平臺不能進行共用,須要進行分開。 建議使用企業郵箱註冊,避免使用我的郵箱註冊。git
三方帳號申請github
由於涉及到和各個分享平臺的交互,因此在集成前須要在各個平臺建立應用並提交審覈。建立應用後,分享、登陸操做時顯示的應用icon、名稱和對應開放平臺設置有關,必需要建立應用的平臺爲:微信、新浪、QQ、Facebook、Kakao、LinkeIn、Twitter、釘釘。web
目前集成的內容只包含微信、新浪、QQ三個平臺,申請渠道以下:小程序
平臺 | 申請地址 |
---|---|
微信開放平臺 | open.weixin.qq.com/ |
QQ互聯平臺 | connect.qq.com/ |
微博開放平臺 | open.weibo.com |
注1:申請QQ登陸必定要在QQ互聯平臺,不是在QQ開放平臺(open.qq.com)微信小程序
注2:申請過程當中可能須要企業相關資質,如法人身份證、營業執照、稅務登記證等,須要提早準備好。api
注3:提交應用申請時,須要提交應用相關的信息(應用名稱、介紹、圖標、截圖、受權回調域等),微信還須要提交《微信開放平臺網站信息登記表》。微信
注4: 建議你們用企業帳號申請第三方開放平臺,不要使用我的的QQ、微信、微博和郵箱進行申請,這樣能夠避免申請人在職位變更或者離職後,致使帳號管理的風險和交接麻煩。網絡
注5:開放平臺申請多數須要審覈流程,所以在項目開始時,建議首先申請開放平臺帳號和建立應用,以避免申請時間長影響開發進度。
申請很複雜,因此通常直接找產品經歷要就好啦(#笑)。若是是練習用的話,能夠直接用官方Demo的包名com.umeng.soexample建立一個示例項目,沿用簽名文件、Appkey以及各個三方的Appkey就行了。
在後期模塊化後,直接引入封裝好的模塊便可集成,這裏先介紹一下經過添加sdk的方式集成,以及其中我遇到過的問題。
下載SDK
最新SDK地址,能夠看到友盟的分享包含不少平臺,這裏咱們只用到了微博微信QQ的分享和登陸功能,不包含支付等,因此選擇默認下載的三個精簡版便可。若有需求能夠參考官方開發文檔添加使用。
添加SDK
解壓下載的sdk壓縮包,咱們須要用到其中common和share文件夾下的內容。res顧名思義都是資源文件,複製到項目的res目錄中,其餘全部jar文件複製到項目的app/libs目錄下,並確保在app的gradle依賴中包含implementation fileTree(include: ['*.jar'], dir: 'libs') ,將這個文件夾中全部jar包導入到項目裏。
添加回調Activity
用到的三個平臺中,只有微信須要手動添加Activity。具體作法是,在包名目錄下建立wxapi文件夾,新建一個名爲WXEntryActivity
的Activity繼承WXCallbackActivity
,內容爲空便可。
配置Android Manifest XML
在項目的Manifest中添加各個回調Activity:
<activity
android:name=".wxapi.WXEntryActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<activity
android:name="com.umeng.socialize.media.WBShareCallBackActivity"
android:configChanges="keyboardHidden|orientation"
android:exported="false"
android:theme="@android:style/Theme.Translucent.NoTitleBar"></activity>
<activity
android:name="com.sina.weibo.sdk.web.WeiboSdkWebActivity"
android:configChanges="keyboardHidden|orientation"
android:exported="false"
android:windowSoftInputMode="adjustResize"></activity>
<activity
android:name="com.sina.weibo.sdk.share.WbShareTransActivity"
android:launchMode="singleTask"
android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen">
<intent-filter>
<action android:name="com.sina.weibo.sdk.action.ACTION_SDK_REQ_ACTIVITY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.tencent.tauth.AuthActivity"
android:launchMode="singleTask"
android:noHistory="true">
<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:scheme="tencent100424468" />
</intent-filter>
</activity>
<activity
android:name="com.tencent.connect.common.AssistActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
複製代碼
其中qq的appkey須要替換成本身申請的appkey,這裏用的是友盟官方demo的以做測試用。
添加權限
在AndroidManifest中添加如下權限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
複製代碼
若是項目的目標sdk版本高於Android6.0,即 targetSdkVersion >= 23 ,還須要在項目中添加權限的動態申請:
if (Build.VERSION.SDK_INT >= 23) {
String[] mPermissionList = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CALL_PHONE, Manifest.permission.READ_LOGS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.SET_DEBUG_APP, Manifest.permission.SYSTEM_ALERT_WINDOW, Manifest.permission.GET_ACCOUNTS, Manifest.permission.WRITE_APN_SETTINGS};
ActivityCompat.requestPermissions(this, mPermissionList, 123);
}
複製代碼
初始化設置
將前面的都集成以後,接下來就能夠正式進入到代碼層面的操做啦。在Application中調用友盟的初始化接口,以及設置各個平臺的appkey,這裏所有用的是官方demo測試用的appkey。
public class App extends Application {
@Override
public void onCreate() {
super.onCreate();
//初始化組件化基礎庫, 統計SDK/推送SDK/分享SDK都必須調用此初始化接口
UMConfigure.init(this, "5bed13e1f1f5564655000404", "Umeng", UMConfigure.DEVICE_TYPE_PHONE,
"d9352161be267fb40fb12ad5eb04edf9");
UMShareAPI.get(this);
}
//各個平臺的配置
{
//微信
PlatformConfig.setWeixin("wxdc1e388c3822c80b", "3baf1193c85774b3fd9d18447d76cab0");
//新浪微博(第三個參數爲回調地址)
PlatformConfig.setSinaWeibo("3921700954", "04b48b094faeb16683c32669824ebdad", "http://sns.whalecloud.com");
//QQ
PlatformConfig.setQQZone("100424468", "c7394704798a158208a74ab60104f0ba");
PlatformConfig.setYixin("yxc0614e80c9304c11b0391514d09f13bf");
PlatformConfig.setTwitter("3aIN7fuF685MuZ7jtXkQxalyi", "MK6FEYG63eWcpDFgRYw4w9puJhzDl0tyuqWjZ3M7XJuuG7mMbO");
PlatformConfig.setAlipay("2015111700822536");
PlatformConfig.setLaiwang("laiwangd497e70d4", "d497e70d4c3e4efeab1381476bac4c5e");
PlatformConfig.setPinterest("1439206");
PlatformConfig.setKakao("e4f60e065048eb031e235c806b31c70f");
PlatformConfig.setDing("dingoalmlnohc0wggfedpk");
PlatformConfig.setVKontakte("5764965", "5My6SNliAaLxEm3Lyd9J");
PlatformConfig.setDropbox("oz8v5apet3arcdy", "h7p2pjbzkkxt02a");
}
}
複製代碼
添加簽名文件
部分平臺在申請appkey的時候就須要項目的簽名文件,若是沒有的話會影響受權。常規項目只要正常申請好籤名就能夠了,這裏講一下做爲測試用例如何添加簽名。
將官方demo中app目錄下的debug.keystore複製到本身的練習項目app目錄下
在項目的app.gradle依賴中android條目下添加以下代碼:
buildTypes {
release {
// 是否進行混淆
minifyEnabled false
// 簽名文件
signingConfig signingConfigs.debug
// 混淆文件的位置
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } debug {
minifyEnabled false
signingConfig signingConfigs.debug
proguardFiles 'proguard-rules.pro'
}
}
signingConfigs {
debug {
storeFile file('debug.keystore') storePassword "android" keyAlias "androiddebugkey" keyPassword "android" } } 複製代碼
終於到了分享的步驟,是騾子是馬要牽出來溜溜看看能不能走了,先介紹一下友盟分享的兩種形式:
使用分享面板的分享,用戶能夠調用咱們的打開分享面板的方法,點擊分享面板的對應平臺進行分享。
不使用分享面板的分享,用戶能夠本身寫分享按鈕,或者觸發事件,而後調用咱們的分享方法,進行分享。簡而言之,直接分享就是在用戶本身的界面組件中插入分享行爲,分享面板是打開咱們寫好的一個界面組件,根據點擊事件進行分享。
可分享的內容包括:
平臺 | 受權 | 可分享內容 | 用戶信息 |
---|---|---|---|
是 | 文本 圖片 連接 視頻 音樂 | 是 | |
qq空間 | 同qq | 文字(說說) 圖片(說說) 連接 視頻 音樂 | 同qq |
微信 | 是 | 文本 圖片 連接 視頻 音樂 | 是 |
微信朋友圈 | 同微信 | 文本 圖片 連接 視頻 音樂 (分享連接不顯示描述) | 同微信 |
微信收藏 | 同微信 | 文本 圖片 連接 視頻 音樂 文件 | 同微信 |
新浪微博 | 是 | 文本 圖片 連接 視頻 音樂 文件 | 是 |
下面以直接分享一個網站到微信平臺爲例,看一下具體的代碼實現:
UMWeb web = new UMWeb("https://gank.io/");//建立要分享的Web對象,傳入分享的url地址
web.setTitle("測試分享標題");//設置標題
web.setThumb(new UMImage(this, R.drawable.thumb));//設置傳入顯示的縮略圖
web.setDescription("測試分享內容測試分享內容測試分享內容測試分享內容測試分享內容");//設置描述
new ShareAction(ShareDetailActivity.this)//開啓分享
.withMedia(web) //填入建立好的分享內容
.setPlatform(SHARE_MEDIA.WEIXIN)//選擇分享平臺
.setCallback(shareListener)//設置對分享返回結果的監聽
.share();//啓動分享操做
複製代碼
實現效果以下:
以面板的形式分享這個網站:
ShareBoardlistener boardListener = new ShareBoardlistener() { //建立面板的監聽器
@Override
public void onclick(SnsPlatform snsPlatform, SHARE_MEDIA platform) {
new ShareAction(mActivity)//開啓分享
.withMedia(web) //填入建立好的分享內容
.setPlatform(platform)//填入選擇的平臺
.setCallback(shareListener)//設置對分享返回結果的監聽
.share();//啓動分享操做
}
};
new ShareAction(mActivity)
.setDisplayList(SHARE_MEDIA.WEIXIN, SHARE_MEDIA.WEIXIN_CIRCLE, SHARE_MEDIA.WEIXIN_FAVORITE,
SHARE_MEDIA.SINA, SHARE_MEDIA.QQ, SHARE_MEDIA.QZONE)//設置分享面板顯示的平臺
.setShareboardclickCallback(boardListener)//添加以前建立的面板監聽器
.open(config);//開啓分享面板 其中可傳入能對面板樣式進行自定義操做的config對象
//好比設置面板在底部仍是中部顯示、是否有取消按鈕、圖標形狀、字體大小和背景顏色等等
複製代碼
默認居中的面板效果以下:
最後不要忘記在調用分享的Activity中,添加以下代碼,關閉監聽,防止內存泄露等問題。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
UMShareAPI.get(this).onActivityResult(requestCode, resultCode, data);
}
@Override
protected void onDestroy() {
super.onDestroy();
UMShareAPI.get(this).release();
}
複製代碼
在前面的內容裏,咱們完整的體驗了友盟社會化分享的準備、集成和使用,雖然看起來比較簡單明瞭,但對於初次接觸的人仍是比較容易碰到問題的,在項目中屢次集成也比較繁瑣。因此接下來到了本文的重點內容,對友盟的分享進行模塊化,在須要時直接導入模塊便可使用,並將主要方法進行封裝處理,在開發時提升效率,減小代碼量。
下面記錄一下封裝過程當中的思路和過程,以及封裝後的使用方法。
封裝過程
在前面的使用介紹中,能夠看到每一次分享,都須要提早建立好待分享的內容,須要傳入的數據越多,代碼行數越多,因此首先對待建立的對象進行封裝。
根據分享的類型,分了8個類:
分享類型 | 枚舉參數 |
---|---|
僅文本 | SHARE_TYPE_TEXT |
僅圖片 | SHARE_TYPE_IMAGE |
圖文 | SHARE_TYPE_TEXTANDIMG |
網址 | SHARE_TYPE_WEB |
網絡視頻 | SHARE_TYPE_VIDEO |
網絡音樂 | SHARE_TYPE_MUSIC |
GIF表情 | SHARE_TYPE_EMOJI |
微信小程序 | SHARE_TYPE_MINAPP |
其中圖片能夠經過資源文件id、File文件、網絡地址、Bitmap對象、還有byte[]這些方式來建立,其餘不少類型雖然不須要圖片,但不少須要縮略圖,而縮略圖的本質也是圖片,因此能夠將縮略圖獨立出來:
private static UMImage mThumb;
//建立待分享所用的縮略圖
public static void createThumbImage(int thumbResId) {
mThumb = new UMImage(mActivity, thumbResId);
}
public static void createThumbImage(File thumbFile) {
mThumb = new UMImage(mActivity, thumbFile);
}
public static void createThumbImage(String thumbImageUrl) {
mThumb = new UMImage(mActivity, thumbImageUrl);
}
public static void createThumbImage(Bitmap thumbBitmap) {
mThumb = new UMImage(mActivity, thumbBitmap);
}
public static void createThumbImage(byte[] thumbBytes) {
mThumb = new UMImage(mActivity, thumbBytes);
}
複製代碼
接下來以建立待分享的網址爲例,須要傳入的數據包括視頻地址、標題、描述、縮略圖最少4個內容,前三個都是String對象,最複雜的縮略圖已經經過上面的方法建立好了,因此只須要添加前三個內容就夠了:
private static UMWeb mWeb;
//建立待分享的連接 須要縮略圖
public static void createUrl(String url, String title, String description) {
mWeb = new UMWeb(url);
mWeb.setTitle(title);
mWeb.setDescription(description);
mWeb.setThumb(mThumb);//傳入建立好的縮略圖
}
複製代碼
到此咱們已經建立好了須要分享的網址對象,接下來天然而然就是分享了。實現很是簡單粗暴,直接傳入須要分享的平臺和類型對應的枚舉名便可:
public static void share(SHARE_MEDIA platform, SHARE_TYPE shareType) {
ShareAction action = new ShareAction(mActivity)
.setPlatform(platform).setCallback(mListener);
switch (shareType) {
case SHARE_TYPE_TEXT:
action.withText(mText).share();
break;
case SHARE_TYPE_IMAGE:
action.withMedia(mImage).share();
break;
case SHARE_TYPE_TEXTANDIMG:
action.withText(mText).withMedia(mImage).share();
break;
case SHARE_TYPE_WEB:
action.withMedia(mWeb).share();
break;
case SHARE_TYPE_VIDEO:
action.withMedia(mVideo).share();
break;
case SHARE_TYPE_MUSIC:
action.withMedia(mMusic).share();
break;
case SHARE_TYPE_EMOJI:
action.withMedia(mEmoji).share();
break;
case SHARE_TYPE_MINAPP:
action.withMedia(mMinAPP).share();
break;
}
}
複製代碼
到這裏基本將直接分享的內容進行了封裝,那麼若是用戶不須要咱們已經設好的分享callback,想要自定義呢?因此須要構建一個方法讓用戶傳入自定義的監聽器:
//設置分享監聽 傳入自定義的監聽方式
public static void setShareListener(UMShareListener listener) {
mListener = listener;
}
複製代碼
除了直接分享,還有面板形式的分享,在這裏提供了三種形式的封裝:
直接在中間顯示分享面板
public static void shareBoardAtCenter(SHARE_TYPE shareType) {
ShareBoardConfig config = new ShareBoardConfig();
config.setShareboardPostion(ShareBoardConfig.SHAREBOARD_POSITION_CENTER);
config.setCancelButtonVisibility(true);
shareBoard(config, shareType);
}
複製代碼
在底部顯示分享面板
public static void shareBoardAtBottom(SHARE_TYPE shareType) {
ShareBoardConfig config = new ShareBoardConfig();
config.setShareboardPostion(ShareBoardConfig.SHAREBOARD_POSITION_BOTTOM);
config.setCancelButtonVisibility(true);
shareBoard(config, shareType);
}
複製代碼
用戶自定義分享面板
public static void setBoardWithConfig(ShareBoardConfig config, SHARE_TYPE shareType) {
shareBoard(config, shareType);
}
複製代碼
三種方式,最終都是將面板定義 config 以及要分享的類型 shareType 傳入 shareBoard() 方法中,config的具體自定義方法見官方文檔,下面貼出 shareBoard() 方法:
private static void shareBoard(ShareBoardConfig config, final SHARE_TYPE shareType) {
ShareBoardlistener boardListener = new ShareBoardlistener() {
@Override
public void onclick(SnsPlatform snsPlatform, SHARE_MEDIA platform) {
share(platform, shareType);
}
};
new ShareAction(mActivity)
.setDisplayList(SHARE_MEDIA.WEIXIN, SHARE_MEDIA.WEIXIN_CIRCLE, SHARE_MEDIA.WEIXIN_FAVORITE,
SHARE_MEDIA.SINA, SHARE_MEDIA.QQ, SHARE_MEDIA.QZONE)
.setShareboardclickCallback(boardListener)
.open(config);
}
複製代碼
能夠看出在選擇平臺後,具體分享的實現方法又跳轉到了share()中,實現了代碼的複用,對於用戶須要自定義面板分享哪些平臺,一樣能夠經過setPlatforms()方法實現:
//設置分享面板要分享的內容
public static void setBoardPlatforms(SHARE_MEDIA[] platforms) {
mPlatforms = platforms;
}
複製代碼
使用方法
總體的使用比較簡單明瞭,不過須要注意的是,除了分享文本圖片,其餘類型都要記得先建立縮略圖。
下面以分享一個網址或者視頻爲例:
//首先須要初始化
UShareUtils.init(this);
//建立縮略圖
UShareUtils.createThumbImage(R.drawable.cat80);
//建立待分享的網址,傳入網址、標題和描述
UShareUtils.createUrl("https://gank.io/", "分享標題", "分享描述");
//建立待分享的視頻,傳入視頻地址、標題和描述
UShareUtils.createVideo("http://vfx.mtime.cn/Video/2018/10/26/mp4/181026140242572417.mp4", "《馴龍高手3》中文預告", "《馴龍高手3 》由夢工場動畫出品,馴龍高手是影史上最受歡迎的動畫系列之一,而這部備受期待的新片是該系列的第三部。 ");
//點擊分享
@OnClick({R.id.tv_share_web, R.id.tv_share_video, R.id.tv_share_board, R.id.tv_share_center})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.tv_share_web:
//分享WEB到QQ
UShareUtils.share(SHARE_MEDIA.QQ, SHARE_TYPE.SHARE_TYPE_WEB);
break;
case R.id.tv_share_video:
//分享視頻到微信
UShareUtils.share(SHARE_MEDIA.WEIXIN, SHARE_TYPE.SHARE_TYPE_VIDEO);
break;
case R.id.tv_board_board:
//打開底部分享面板 分享WEB
UShareUtils.shareBoardAtBottom(SHARE_TYPE.SHARE_TYPE_WEB);
break;
case R.id.tv_board_center:
//打開中部分享面板 分享視頻
UShareUtils.shareBoardAtBottom(SHARE_TYPE.SHARE_TYPE_VIDEO);
break;
}
}
複製代碼