如何在React Native中实现分享和第三方登录的功能

期待已久的新课上线啦!解锁React Native开发新姿势,一网打尽React Native最新与最热技术,点我Get!!!

在我们常用的App中经常会看到分享与第三方登录的功能,可以说分享与第三方登录已经成为了各大APP的必备功能。对于产品运行与推广来说,分享与第三方登录不仅能加强用户粘性,增加流量及新用户,也能提升用户存、留优化产品质量等。

react-native-android-share

各大平台都有对应的开发平台来提供分享与第三方登录的服务,比如微信开发平台/腾讯开发平台、新浪开发者平台等。因为各大平台及相关SDK存在很大的差异,单独集成起来比较繁琐,为了快速集成分享与第三方登录我们可以使用相应统一的服务提供商,常用的分享与登录的提供商有umeng与shareSdk。

截止目前,但各大平台与集成服务的提供方都只提供了Native版本的SDK,没有对React Native做支持,为此要在React Native应用中添加分享与第三方登录我们需要开发出能供React Native应用使用的分享与登录模块。

在这篇文章中我会向大家分享,在React Native中集分享第与三方登录功能的流程以及分享与第三方登录模块开发。(在本文中我将以umeng为例来进行讲解)

除了本篇的教程外你也可以想通过,视频教程学习来学习实现分享与第三方登录的具体细节

第一步:集成准备

首先我们需要到umeng官网申请一个开发者账号。然后创建一个应用并获取appkey
在之后呢,我们需要进行必不可少的一步就是,到各大平台申请第三方开发者账号,关于申请的流程官网文档讲解的已经很详细了,在这里我不再重复了。

各大平台申请服务所需要等待的时间不等,通常是1-3天就可以搞定,建议在申请的同时,就进行sdk的集成,等申请通过之后,在换成正式的账号进行调试,这样一来开发申请两不误。

第二步:集成SDK

获取到appkey之后呢,我们接下来就来集成集成SDK。

友盟分享目前还不支持AndroidStudio的Gradle配置,所以我们需要将分享sdk下来然后倒入到项目中。

前往,SDK下载中心,根据提示下载SDK即可,建议下载最新的。

将下载的压缩文件解压,或会看到如下目录:


umeng-sdk-download

其中,umeng_integrate_tool.jar为,sdk辅助集成功能,双击该文件将打开如下界面:

下载sdk

然后根据需要勾选相应的平台,单击ok即可生成umeng_integratetool_result文件夹,然后将该文件夹中的文件导入到项目中即可,关于详细的集成说明可以参考快速集成

第三步:构建分享及登录模块

为了能够在React Native中使用umeng分享及登录,我们需要为刚才导出的sdk创建一个Native 模块然后通过桥接的方式供js部分进行调用,关于如何开发React Native原生模块,可参考《React Native Android原生模块开发实战|教程|心得

为了减少我们所集成的分享与统计代码对我们项目的入侵,保持模块之间的独立性,也就是我们经常所提倡的高内聚低耦合,在这里我们将分享与登录单独封装成一个模块,如下图:

u-share-module.png

我们通过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:crazycodeboy@gmail.com
 */
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:crazycodeboy@gmail.com
 */
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:crazycodeboy@gmail.com
 */
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开发的技术干货

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容