React Native 整合分享第三方登入功能分享第三方登入模組開發(Android)
期待已久的新課上線啦!解鎖React Native開發新姿勢,一網打盡React Native最新與最熱技術,點我Get!!!
在我們常用的App中經常會看到分享與第三方登入的功能,可以說分享與第三方登入已經成為了各大APP的必備功能。對於產品執行與推廣來說,分享與第三方登入不僅能加強使用者粘性,增加流量及新使用者,也能提升使用者存、留優化產品質量等。
各大平臺都有對應的開發平臺來提供分享與第三方登入的服務,比如微信開發平臺/騰訊開發平臺、新浪開發者平臺等。因為各大平臺及相關SDK存在很大的差異,單獨整合起來比較繁瑣,為了快速整合分享與第三方登入我們可以使用相應統一的服務提供商,常用的分享與登入的提供商有umeng與shareSdk。
截止目前,但各大平臺與整合服務的提供方都只提供了Native版本的SDK,沒有對React Native做支援,為此要在React Native應用中新增分享與第三方登入我們需要開發出能供React Native應用使用的分享與登入模組。
在這篇文章中我會向大家分享,在React Native中集分享第與三方登入功能的流程以及分享與第三方登入模組開發。(在本文中我將以umeng為例來進行講解)
除了本篇的教程外你也可以想通過,視訊教程來學習來學習實現分享與第三方登入的具體細節
第一步:整合準備
首先我們需要到umeng官網申請一個開發者賬號。然後建立一個應用並
在之後呢,我們需要進行必不可少的一步就是,到各大平臺申請第三方開發者賬號,關於申請的流程官網文件講解的已經很詳細了,在這裡我不再重複了。
各大平臺申請服務所需要等待的時間不等,通常是1-3天就可以搞定,建議在申請的同時,就進行sdk的整合,等申請通過之後,在換成正式的賬號進行除錯,這樣一來開發申請兩不誤。
第二步:整合SDK
獲取到appkey之後呢,我們接下來就來整合整合SDK。
友盟分享目前還不支援AndroidStudio的Gradle配置,所以我們需要將分享sdk下來然後倒入到專案中。
前往,SDK下載中心,根據提示下載SDK即可,建議下載最新的。
將下載的壓縮檔案解壓,或會看到如下目錄:
其中,umeng_integrate_tool.jar
為,sdk輔助整合功能,雙擊該檔案將開啟如下介面:
然後根據需要勾選相應的平臺,單擊ok即可生成umeng_integratetool_result
資料夾,然後將該資料夾中的檔案匯入到專案中即可,關於詳細的整合說明可以參考快速整合。
第三步:構建分享及登入模組
為了能夠在React Native中使用umeng分享及登入,我們需要為剛才匯出的sdk建立一個Native 模組然後通過橋接的方式供js部分進行呼叫,關於如何開發React Native原生模組,可參考《React Native Android原生模組開發實戰|教程|心得
》。
為了減少我們所整合的分享與統計程式碼對我們專案的入侵,保持模組之間的獨立性,也就是我們經常所提倡的高內聚低耦合,在這裡我們將分享與登入單獨封裝成一個模組,如下圖:
我們通過AndroidStudio新建立了一個名為u_share
的module,然後將umeng_integratetool_result
資料夾中的內容複製到了u_share
的對應位置。
建立UShare.java
在u_share模組中我們建立了一個UShare.java類,該類主要負責umeng分享sdk之間的通訊。
/**
* 分享元件
* 出自:http://www.devio.org
* GitHub:https://github.com/crazycodeboy
* Eamil:[email protected]
*/
public class UShare {
private static WeakReference<Activity> mActivity;
private static WeakReference<ShareModel> mShareModel;
public static void init(Activity activity) {
if (activity == null) return;
mActivity = new WeakReference<>(activity);
}
public static void share(final String title, final String content, final String imageUrl, final String targetUrl, final Callback errorCallback, final Callback successCallback) {
if (mActivity == null) return;
boolean granted = true;
if (!TextUtils.isEmpty(imageUrl)) {
granted = ContextCompat.checkSelfPermission(mActivity.get(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED ? true : false;
}
if (!granted) {
ShareModel shareModel=new ShareModel(title,content,imageUrl,targetUrl,errorCallback,successCallback);
mShareModel=new WeakReference<>(shareModel);
ActivityCompat.requestPermissions(mActivity.get(),new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, Constants.RC_REQUEST_PERMISSIONS);
return;
}
mActivity.get().runOnUiThread(new Runnable() {
@Override
public void run() {
openShare(title, content, imageUrl, targetUrl, errorCallback, successCallback);
}
});
}
//...省略部分程式碼,你也可以通過視訊教程(http://coding.imooc.com/class/304.html)來學習實現分享第三方登入的具體細節
public static void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(mShareModel==null)return;
if (requestCode == Constants.RC_REQUEST_PERMISSIONS) {
for (int i = 0, j = permissions.length; i < j; i++) {
if(TextUtils.equals(permissions[i],Manifest.permission.WRITE_EXTERNAL_STORAGE)){
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
share(mShareModel.get());
}else {
if(mActivity==null)return;
Toast.makeText(mActivity.get(),"沒有使用SD卡的許可權,請在許可權管理中為GitHubPopular開啟使用SD卡的許可權",Toast.LENGTH_SHORT).show();
}
}
}
}
}
}
程式碼解讀:
在上述程式碼中有個public static void init(Activity activity)
方法來對UShare模組進行初始化。
另外,公共方法:
public static void share(final String title, final String content, final String imageUrl, final String targetUrl, final Callback errorCallback, final Callback successCallback)
負責呼叫分享sdk之前的相應許可權的檢查。為了適配Android6.0的動態許可權,我們添加了:
public static void onActivityResult(int requestCode, int resultCode, Intent data) {
if (mActivity == null) return;
UMShareAPI.get(mActivity.get()).onActivityResult(requestCode, resultCode, data);
}
public static void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if(mShareModel==null)return;
if (requestCode == Constants.RC_REQUEST_PERMISSIONS) {
for (int i = 0, j = permissions.length; i < j; i++) {
if(TextUtils.equals(permissions[i],Manifest.permission.WRITE_EXTERNAL_STORAGE)){
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
share(mShareModel.get());
}else {
if(mActivity==null)return;
Toast.makeText(mActivity.get(),"沒有使用SD卡的許可權,請在許可權管理中為GitHubPopular開啟使用SD卡的許可權",Toast.LENGTH_SHORT).show();
}
}
}
}
}
來進行動態許可權的處理。
關於登入:
分享和登入採用的是同一套sdk,如果要在React Native中進第三方登入,只需要在上述程式碼中新增下面的程式碼即可,方法和呼叫分享是一樣的,有需要的朋友可以參考登入整合來新增一下。
mShareAPI.getPlatformInfo(UserinfoActivity.this, SHARE_MEDIA.SINA, umAuthListener);
建立UShareModule.java
然後我們建立了UShareModule.java來暴露分享方法:
/**
* 分享元件
* 出自:http://www.devio.org
* GitHub:https://github.com/crazycodeboy
* Eamil:[email protected]
*/
public class UShareModule extends ReactContextBaseJavaModule{
public UShareModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "UShare";
}
@ReactMethod
public static void share(String title, String content, String imageUrl, String targetUrl, final Callback successCallback, final Callback errorCallback) {
UShare.share(title,content,imageUrl,targetUrl,successCallback,errorCallback);
}
}
在UShareModule.java中我們通過UShare.share(title,content,imageUrl,targetUrl,successCallback,errorCallback);
呼叫了UShare.java
的分享方法來開啟分享對話方塊。
建立UShareReactPackage.java
為了向React Native註冊我們剛才建立的原生模組,我們需要實現ReactPackage,ReactPackage主要為註冊原生模組所存在,只有已經向React Native註冊的模組才能在js模組使用。
/**
* 分享元件
* 出自:http://www.devio.org
* GitHub:https://github.com/crazycodeboy
* Eamil:[email protected]
*/
public class UShareReactPackage implements ReactPackage {
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
@Override
public List<NativeModule> createNativeModules(
ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new UShareModule(reactContext));
return modules;
}
}
環境配置
因為分享與登入SDK需要用到一些許可權、Activity、Appkey及相關第三方key的配置,所以我呢需要在AndroidManifest.xml檔案中新增如下的程式碼:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jph.u_share">
<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" />
<application
android:allowBackup="true"
android:supportsRtl="true">
<!--weixin callback-->
<activity
android:name="com.jph.githubpopular.wxapi.WXEntryActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:exported="true"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<!--qq callback-->
<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="xxx" />
</intent-filter>
</activity>
<activity
android:name="com.tencent.connect.common.AssistActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<!--umeng:-->
<!--分享編輯頁:-->
<activity
android:name="com.umeng.socialize.editorpage.ShareActivity"
android:excludeFromRecents="true"
android:theme="@style/Theme.UMDefault" />
<meta-data
android:name="UMENG_APPKEY"
android:value="UMENG_APPKEY"></meta-data>
</application>
</manifest>
上述程式碼根據所選擇的平臺不同而略有差異,具體可參照快速整合:
第四步:分享模組的使用
到目前為止呢,我們的Android分享模組已經建立好了,接下來呢我們就可以使用它了。
新增依賴
首先我們需要讓我們的應用模組依賴u_share
模組:
在…/xxx/android/app/build.gradle中新增:
dependencies {
+ compile project(':u_share')
}
初始化UShare
接下來我們需要在MainActivity.java
中初始化UShare:
public class MainActivity extends ReactActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+UShare.init(this);
}
//...省略部分程式碼
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+UShare.onRequestPermissionsResult(requestCode,permissions,grantResults);
}
}
註冊UShareReactPackage
然後我們需要在MainApplication.java中註冊UShareReactPackage以及進行Umeng的一些配置。
public class MainApplication extends Application implements ReactApplication {
{
+PlatformConfig.setWeixin(Constants.KEY_WEIXIN,Constants.SECRET_WEIXIN);
+PlatformConfig.setSinaWeibo("xxx", "xxx");
+PlatformConfig.setQQZone("xxx", "xxx");
}
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
@Override
protected boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
+ new UShareReactPackage()
);
}
};
@Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
+UMShareAPI.get(this);
}
}
原生模組匯出一個js模組
我們建立一個UShare.js檔案,然後新增如下程式碼:
import { NativeModules } from 'react-native';
module.exports = NativeModules.UShare;
這樣以來呢,我們就可以在JS模組中來使用分享以及第三方登入了:
import UShare from '../common/UShare'//匯入UShare.js
//...省略部分程式碼
UShare.share(shareApp.title, shareApp.content,
shareApp.imgUrl,shareApp.url,()=>{},()=>{})
現在呢,我們已經在React Native的Android中集成了分享與第三方登入的功能。另外,你也可以通過這裡檢視實現分享與第三方登入的視訊教程。
如果大家在React Native中整合分享與第三方登入過程中有更好的心得或遇到問題可以在本文的下方進行留言,我看到了後會及時回覆的哦。
另外也可以關注我的新浪微博
,或者關注我的Github
來獲取更多有關React Native開發的技術乾貨
。