react-native-dk-umeng

react native 友盟分享、推送、统计

Usage no npm install needed!

<script type="module">
  import reactNativeDkUmeng from 'https://cdn.skypack.dev/react-native-dk-umeng';
</script>

README

react native 友盟分享、推送、统计

帮助应用或游戏快速具备国内外多平台分享、第三方登录功能,SDK 包最小,集成成本最低,平台覆盖最全,并基于友盟+大数据,提供最为权威、实时的用户画像、分享回流等数据分析,助力产品开发与推广。

基于【友盟+】全域数据建立与用户直接沟通的渠道。极简接入后,即可主动推送消息给 App 的终端用户,让用户实时实地的获取相关信息。可有效提升用户粘性,提高 App 活跃度。

国内专业的移动应用统计分析平台。我们帮助移动应用开发商统计和分析流量来源、内容使用、用户属性和行为数据,以便开发商利用数据进行产品、运营、推广策略的决策。

安装

yarn add react-native-dk-umeng

集成到 android

settings.gradle

include ':react-native-dk-umeng'
project(':react-native-dk-umeng').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-dk-umeng/android')
include ':push'
project(':push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-dk-umeng/android/push')

app/build.gradle

defaultConfig {
  ...
  // Enabling multidex support.
  multiDexEnabled true
}

...

dependencies {
    compile 'com.android.support:multidex:1.0.0'
    compile project(':react-native-dk-umeng')
    ...
}

AndroidManifest.xml

<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.READ_LOGS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- QQ、QQ空间所需权限 -->
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.SET_DEBUG_APP" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS" />

...

<meta-data
    android:name="UMENG_APPKEY"
    android:value="****" >
</meta-data>
<meta-data
    android:name="UMENG_CHANNEL"
    android:value="****" >
</meta-data>
  <meta-data
      android:name="UMENG_MESSAGE_SECRET"
      android:value="****" >
  </meta-data>
<activity
      android:name=".wxapi.WXEntryActivity"
      android:configChanges="keyboardHidden|orientation|screenSize"
      android:exported="true"
      android:screenOrientation="portrait"
      android:theme="@android:style/Theme.Translucent.NoTitleBar" />
<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="tencent1103418210" />
      </intent-filter>
  </activity>
  <activity
      android:name="com.tencent.connect.common.AssistActivity"
      android:screenOrientation="portrait"
      android:theme="@android:style/Theme.Translucent.NoTitleBar"
      android:configChanges="orientation|keyboardHidden|screenSize"/>

包名下添加 wxapi 文件夹,然后添加WXEntryActivity.java 路径 java/com/.../wxapi/WXEntryActivity.java

WXEntryActivity.java

package com.****.wxapi;

import com.umeng.socialize.weixin.view.WXCallbackActivity;

public class WXEntryActivity extends WXCallbackActivity {

}

MainActivity.java

import android.content.Intent;
...
import com.umeng.analytics.MobclickAgent;
import com.umeng.analytics.MobclickAgent.EScenarioType;
import com.umeng.socialize.UMShareAPI;
import com.dk.umeng.PushModule;
import com.dk.umeng.ShareModule;

...

@Override
protected void onCreate(Bundle savedInstanceState) {
    ...
    ShareModule.initSocialSDK(this);
    PushModule.initPushSDK(this);
    MobclickAgent.setSessionContinueMillis(1000);
    MobclickAgent.setScenarioType(this, EScenarioType.E_DUM_NORMAL);
    MobclickAgent.openActivityDurationTrack(false);
}

...

@Override
public void onResume() {
    super.onResume();
    MobclickAgent.onResume(this);
}

@Override
protected void onPause() {
    super.onPause();
    MobclickAgent.onPause(this);
}

@Override
protected void onDestroy() {
    super.onDestroy();
    MobclickAgent.onKillProcess(this);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    UMShareAPI.get(this).onActivityResult(requestCode, resultCode, data);
}

MainApplication.java

import com.dk.umeng.PushApplication;
import com.dk.umeng.DplusReactPackage;
import com.dk.umeng.RNUMConfigure;

...

public class MainApplication extends PushApplication implements ReactApplication {

  ...

  @Override
  protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
        ...

        new DplusReactPackage()
    );
  }

  @Override
  public void onCreate() {
    ...

    if(BuildConfig.DEBUG) {
        RNUMConfigure.setLogEnabled(true);
    }
    //初始化组件化基础库, 统计SDK/推送SDK/分享SDK都必须调用此初始化接口
    RNUMConfigure.init(this, null,null,RNUMConfigure.getDeviceType(1),null);
  }
}

集成到 ios

加入以下系统库

libsqlite3.tbd
CoreGraphics.framework
Photos.framework

配置URL Scheme

URL Scheme是通过系统找到并跳转对应app的一类设置,通过向项目中的info.plist文件中加入URL types可使用第三方平台所注册的appkey信息向系统注册你的app,当跳转到第三方应用授权或分享后,可直接跳转回你的app。

添加URL Types可工程设置面板设置

平台 格式 举例 备注
微信 微信appKey wx****

其他平台请参考umeng官方 https://developer.umeng.com/docs/66632/detail/66825

AppDelegate.m

#import <UserNotifications/UserNotifications.h>
#import "RNUMConfigure.h"
#import "UMPushModule.h"
#import "pushListener.h"
#import "UMShareModule.h"

static NSString * const recivePushNoti = @"recivePushNoti";
static NSString * const openPushNoti = @"openPushNoti";
@interface AppDelegate()<UNUserNotificationCenterDelegate>
@end

...

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
  
  NSString *filePath = [[NSBundle mainBundle]pathForResource:@"Info" ofType:@"plist"];
  NSDictionary *dic = [[NSDictionary alloc]initWithContentsOfFile:filePath];
  NSString *UMENG_APPKEY = dic[@"UMENG_APPKEY"];
  NSString *UMENG_CHANNEL   = dic[@"UMENG_CHANNEL"];
  NSString *UMENG_MESSAGE_SECRET = dic[@"UMENG_MESSAGE_SECRET"];
  
  //友盟sdk公共配置
  [RNUMConfigure initWithAppkey:UMENG_APPKEY channel:UMENG_CHANNEL];
  [UNUserNotificationCenter currentNotificationCenter].delegate=self;
  //友盟注册推送
  [UMPushModule registerWithAppkey:UMENG_MESSAGE_SECRET launchOptions:launchOptions];

  ...
}

//iOS10以下使用这两个方法接收通知,友盟
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
  [UMPushModule setAutoAlert:NO];
  if([[[UIDevice currentDevice] systemVersion]intValue] < 10){
    [UMPushModule didReceiveRemoteNotification:userInfo];
    [[NSNotificationCenter defaultCenter]postNotificationName:recivePushNoti object:nil userInfo:userInfo];
    completionHandler(UIBackgroundFetchResultNewData);
  }
}

//友盟
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
  //关闭友盟自带的弹出框
  [UMPushModule setAutoAlert:NO];
  [UMPushModule didReceiveRemoteNotification:userInfo];
  [[NSNotificationCenter defaultCenter]postNotificationName:recivePushNoti object:nil userInfo:userInfo];
}

//iOS10新增:处理前台收到通知的代理方法 友盟
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler{
  NSDictionary * userInfo = notification.request.content.userInfo;
  if([notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
    //应用处于前台时的远程推送接受
    //关闭U-Push自带的弹出框
    [UMPushModule setAutoAlert:NO];
    //必须加这句代码
    [UMPushModule didReceiveRemoteNotification:userInfo];
    [[NSNotificationCenter defaultCenter]postNotificationName:recivePushNoti object:nil userInfo:userInfo];
  }else{
    //应用处于前台时的本地推送接受
  }
  //当应用处于前台时提示设置,需要哪个可以设置哪一个
  completionHandler(UNNotificationPresentationOptionSound|UNNotificationPresentationOptionBadge|UNNotificationPresentationOptionAlert);
}

//iOS10新增:处理后台点击通知的代理方法 友盟
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)())completionHandler{
  NSDictionary * userInfo = response.notification.request.content.userInfo;
  if([response.notification.request.trigger isKindOfClass:[UNPushNotificationTrigger class]]) {
    //应用处于后台时的远程推送接受
    //必须加这句代码
    [UMPushModule didReceiveRemoteNotification:userInfo];
    [[NSNotificationCenter defaultCenter]postNotificationName:openPushNoti object:nil userInfo:userInfo];
  }else{
    //应用处于后台时的本地推送接受
  }
}

//友盟
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken{
    NSLog(@"token=====%@",[[[[deviceToken description] stringByReplacingOccurrencesOfString: @"<" withString: @""]
                  stringByReplacingOccurrencesOfString: @">" withString: @""]
                 stringByReplacingOccurrencesOfString: @" " withString: @""]);
  [UMPushModule  registerDeviceToken:deviceToken];
}

// 注册deviceToken失败,此处失败,与环信SDK无关,一般是您的环境配置或者证书配置有误 友盟
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
  NSLog(@"注册deviceToken失败%@",error);
}

// 支持所有iOS系统友盟分享回调
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
  //6.3的新的API调用,是为了兼容国外平台(例如:新版facebookSDK,VK等)的调用[如果用6.2的api调用会没有回调],对国内平台没有影响
  BOOL result = [UMShareModule handleOpenURL:url sourceApplication:sourceApplication annotation:annotation];
  if (!result) {
    // 其他如支付等SDK的回调
  }
  return result;
}

//友盟分享回调
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
  BOOL result = [UMShareModule handleOpenURL:url];
  if (!result) {
    // 其他如支付等SDK的回调
  }
  return result;
}

@end

Info.plist

<key>UMENG_APPKEY</key>
<string>****</string>
<key>UMENG_CHANNEL</key>
<string>****</string>
<key>UMENG_MESSAGE_SECRET</key>
<string>****</string>
<key>LSApplicationQueriesSchemes</key>
<array>
  <string>wechat</string>
  <string>weixin</string>
  <string>sinaweibohd</string>
  <string>sinaweibo</string>
  <string>sinaweibosso</string>
  <string>weibosdk</string>
  <string>weibosdk2.5</string>
  ...
  // 更多请在这里添加
</array>

方法

分享

方法名 参数 类型 描述
setAccount {type: 0,appId: '',secret: '',redirectURL: ''} func 设置平台秘钥
type 0: QQ 1:Sina 2:WeiXin
share {title: '',text: '',image:'',weburl: '',sharemedia: 0 } func 无面板分享
type 0:QQ 1:SINA 2:WEIXIN 3:WEIXIN_CIRCLE 4:QZONE 6:SHARE_MEDIA.SMS

推送

方法名 参数 类型 描述
getDeviceToken promise 获取 DeviceToken
didReceiveMessage promise 接收到推送消息回调的方法
didOpenMessage promise 点击推送消息打开应用回调的方法

统计

暂无

集成问题

1.安卓集成获取不到 deviceToken 问题

确定是否将 appkey、MessageSecret、以及包名都更换为开发者所申请的相应值

如果获取不到 deviceToken 也接收不到推送,请查看友盟后台的包名是否一致,当前设备是否添加到测试设备当中

Android Studio 中 gradle 的版本需要在 1.5.0 或者以上

更多 DeviceToken 相关问题,请参考 Device_token 相关问题整理【安卓版】

示例

import { UMPush, UMShare, UMAnalytics } from 'react-native-dk-umeng';

UMPush.getDeviceToken().then(token => {
  console.warn(['getDeviceToken', token]);
});

UMPush.didReceiveMessage().then(res => {
  console.warn(['didReceiveMessage', res]);
});

UMPush.didOpenMessage().then(res => {
  console.warn(['didOpenMessage', res]);
});

UMShare.setAccount({
  type: 0,
  appId: '****',
  secret: '****',
  redirectURL: ''
});
UMShare.setAccount({
  type: 2,
  appId: '****',
  secret: '****',
  redirectURL: ''
});

UMShare.share({
  title: '分享标题',
  text: '分享内容',
  image:'',
  weburl: '',
  sharemedia: 2
}).then(
  res => {
    console.warn(['res', res]);
  },
  err => {
    console.warn(['err', err]);
  }
);