wonday / react-native-aliyun-push

A react native wrapper for aliyun push SDK
MIT License
218 stars 64 forks source link

接收不到华为通知,求帮助。 #80

Closed 54sword closed 5 years ago

54sword commented 5 years ago

手机设备:华为手机(荣耀畅玩 7A)

根据文档中的android配置,打开app可以接收到通知,杀掉进程后,无法接收到通知。 已在华为开发者联盟,申请了push服务,并将APP ID和APP SECRET,填写到了阿里云移动推送应用配置,还是接收不到,求帮助。

wonday commented 5 years ago

杀掉进程无法收到通知,这本身和这个模块还没关系,再仔细研究一下华为及阿里文档吧,我没有华为手机无法测试

wonday commented 5 years ago

依赖于另外一个库,ShortcutBadger,看还没适配

54sword commented 5 years ago

@wonday 好的,我再研究研究!

54sword commented 5 years ago

对android原生开发不是很了解,研究了一天,华为还是没有搞定...郁闷😒。 iOS、HTC(android)都调通了。

wonday commented 5 years ago

是不是权限给的不够, 比如android.permission.READ_PHONE_STATE 这个看log是需要的。 另外,上述log暴露隐私太多。。。

54sword commented 5 years ago

@wonday 好的,我再试一试,小米我也配置了,日志显示注册成功了,但用阿里云推送接收不到通知,用小米自家的后台推送测试可以收到。也不知道是什么原因,我继续研究研究。

54sword commented 5 years ago

@wonday 还是没有搞定小米和华为的通知,可以的话,可以加一下QQ吗?我想付费请您帮助解决一下。 我的QQ:461616916

wonday commented 5 years ago

付费不必了,我能回答的尽量回答一下。 华为的我找到Mate7手机测试是可以的。 注意点:

  1. 阿里云上填写了华为的AppId, 我这里8位数字, 然后还有华为的AppSecret
  2. 手机上杀死你的app来测试通知,如果不杀死app, 那么通知和消息都走的是阿里云通道(这个你应该可以收到吧?)
  3. 阿里云后台推送通知, 我测试的是指定终端,输入的是DeviceID (这个可以通过我的lib去拿到) 消息只有通过阿里云通道才可传送(app或者或者有其他使用阿里云sdk的app或者)
wonday commented 5 years ago

在MainApplication.java中 关于小米和华为的,也就是下面这里,readme里面有说明,我想你也应该是设置了的。

// 注册方法会自动判断是否支持小米系统推送,如不支持会跳过注册。
    MiPushRegister.register(applicationContext, "小米AppID", "小米AppKey");
    // 注册方法会自动判断是否支持华为系统推送,如不支持会跳过注册。
    HuaWeiRegister.register(applicationContext)
54sword commented 5 years ago

@wonday 感谢作者!

iOS推送比较顺利,app也审核通过了!

Android 卡壳了,1、2、3,我校对测试了多次,没有发现出问题,然后常驻状态可以收到推送,杀死进程以后就接收不到了。

1555944443544

下面是我根据android配置说明,配置的代码,麻烦帮助看看。 build.gradle

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {

    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:3.3.2'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        mavenLocal()
        google()
        jcenter()
        maven {
            // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }

        // aliyun push
        maven {
            url 'http://maven.aliyun.com/nexus/content/repositories/releases/'
        }
        flatDir {
            dirs project(':react-native-aliyun-push').file('libs')
        }

        // ADD THIS
        maven { url 'https://maven.google.com' }

        // ADD THIS
        maven { url "https://jitpack.io" }

    }
}

ext {
    buildToolsVersion = "28.0.3"
    minSdkVersion = 16
    compileSdkVersion = 28
    targetSdkVersion = 28
    supportLibVersion = "28.0.0"
}

subprojects {
    afterEvaluate {project ->
        if (project.hasProperty("android")) {
            android {
                compileSdkVersion 28
                buildToolsVersion '28.0.3'
            }
            dependencies {
                compile "com.android.support:appcompat-v7:28.0.0"
            }
        }
    }
}

settings.gradle

rootProject.name = 'xiaoduyuReactNative'
include ':react-native-splash-screen'
project(':react-native-splash-screen').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-splash-screen/android')
include ':react-native-aliyun-push'
project(':react-native-aliyun-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-aliyun-push/android')
include ':react-native-cookies'
project(':react-native-cookies').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-cookies/android')
include ':react-native-webview'
project(':react-native-webview').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-webview/android')
include ':react-native-qq'
project(':react-native-qq').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-qq/android')
include ':react-native-image-crop-picker'
project(':react-native-image-crop-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-crop-picker/android')
include ':@react-native-community_async-storage'
project(':@react-native-community_async-storage').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/async-storage/android')
include ':react-native-gesture-handler'
project(':react-native-gesture-handler').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-gesture-handler/android')
include ':RCTWeChat'
project(':RCTWeChat').projectDir = new File(rootProject.projectDir,'../node_modules/react-native-wechat/android')
include ':app'

app/build.gradle

apply plugin: "com.android.application"

import com.android.build.OutputFile

/**
 * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
 * and bundleReleaseJsAndAssets).
 * These basically call `react-native bundle` with the correct arguments during the Android build
 * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
 * bundle directly from the development server. Below you can see all the possible configurations
 * and their defaults. If you decide to add a configuration block, make sure to add it before the
 * `apply from: "../../node_modules/react-native/react.gradle"` line.
 *
 * project.ext.react = [
 *   // the name of the generated asset file containing your JS bundle
 *   bundleAssetName: "index.android.bundle",
 *
 *   // the entry file for bundle generation
 *   entryFile: "index.android.js",
 *
 *   // whether to bundle JS and assets in debug mode
 *   bundleInDebug: false,
 *
 *   // whether to bundle JS and assets in release mode
 *   bundleInRelease: true,
 *
 *   // whether to bundle JS and assets in another build variant (if configured).
 *   // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
 *   // The configuration property can be in the following formats
 *   //         'bundleIn${productFlavor}${buildType}'
 *   //         'bundleIn${buildType}'
 *   // bundleInFreeDebug: true,
 *   // bundleInPaidRelease: true,
 *   // bundleInBeta: true,
 *
 *   // whether to disable dev mode in custom build variants (by default only disabled in release)
 *   // for example: to disable dev mode in the staging build type (if configured)
 *   devDisabledInStaging: true,
 *   // The configuration property can be in the following formats
 *   //         'devDisabledIn${productFlavor}${buildType}'
 *   //         'devDisabledIn${buildType}'
 *
 *   // the root of your project, i.e. where "package.json" lives
 *   root: "../../",
 *
 *   // where to put the JS bundle asset in debug mode
 *   jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
 *
 *   // where to put the JS bundle asset in release mode
 *   jsBundleDirRelease: "$buildDir/intermediates/assets/release",
 *
 *   // where to put drawable resources / React Native assets, e.g. the ones you use via
 *   // require('./image.png')), in debug mode
 *   resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
 *
 *   // where to put drawable resources / React Native assets, e.g. the ones you use via
 *   // require('./image.png')), in release mode
 *   resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
 *
 *   // by default the gradle tasks are skipped if none of the JS files or assets change; this means
 *   // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
 *   // date; if you have any other folders that you want to ignore for performance reasons (gradle
 *   // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
 *   // for example, you might want to remove it from here.
 *   inputExcludes: ["android/**", "ios/**"],
 *
 *   // override which node gets called and with what additional arguments
 *   nodeExecutableAndArgs: ["node"],
 *
 *   // supply additional arguments to the packager
 *   extraPackagerArgs: []
 * ]
 */

project.ext.react = [
    entryFile: "index.js"
]

apply from: "../../node_modules/react-native/react.gradle"

/**
 * Set this to true to create two separate APKs instead of one:
 *   - An APK that only works on ARM devices
 *   - An APK that only works on x86 devices
 * The advantage is the size of the APK is reduced by about 4MB.
 * Upload all the APKs to the Play Store and people will download
 * the correct one based on the CPU architecture of their device.
 */
def enableSeparateBuildPerCPUArchitecture = false

/**
 * Run Proguard to shrink the Java bytecode in release builds.
 */
def enableProguardInReleaseBuilds = false

android {

    compileSdkVersion rootProject.ext.compileSdkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    defaultConfig {
        applicationId "com.xiaoduyureactnative"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        versionCode 1
        versionName "1.0"
        vectorDrawables.useSupportLibrary = true
        manifestPlaceholders = [
            QQ_APPID: "***"
        ]
    }

    signingConfigs {
        release {
            if (project.hasProperty('MYAPP_RELEASE_STORE_FILE')) {
                storeFile file(MYAPP_RELEASE_STORE_FILE)
                storePassword MYAPP_RELEASE_STORE_PASSWORD
                keyAlias MYAPP_RELEASE_KEY_ALIAS
                keyPassword MYAPP_RELEASE_KEY_PASSWORD
            }
        }
    }

    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86", "arm64-v8a", "x86-64"
        }
    }
    buildTypes {
        release {
            minifyEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
            signingConfig signingConfigs.release
        }
    }
    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // http://tools.android.com/tech-docs/new-build-system/user-guide/apk-splits
            def versionCodes = ["armeabi-v7a":1, "x86":2, "arm64-v8a": 3, "x86-64": 4]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
            }
        }
    }
}

dependencies {
    implementation project(':react-native-splash-screen')
    implementation project(':react-native-aliyun-push')
    implementation project(':react-native-cookies')
    implementation project(':react-native-webview')
    implementation project(':RCTWeChat')
    implementation project(':react-native-qq')
    implementation project(':react-native-image-crop-picker')
    implementation project(':@react-native-community_async-storage')
    implementation project(':react-native-gesture-handler')
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
    implementation "com.facebook.react:react-native:+"  // From node_modules
}

// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
    from configurations.compile
    into 'libs'
}

MainApplication.java

package com.xiaoduyureactnative;

import android.app.Application;
import com.facebook.react.ReactApplication;
import org.devio.rn.splashscreen.SplashScreenReactPackage;
import com.psykar.cookiemanager.CookieManagerPackage;
import com.reactnativecommunity.webview.RNCWebViewPackage;
import cn.reactnative.modules.qq.QQPackage;
import com.reactnative.ivpusic.imagepicker.PickerPackage;
import com.reactnativecommunity.asyncstorage.AsyncStoragePackage;
import com.swmansion.gesturehandler.react.RNGestureHandlerPackage;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;
import com.theweflex.react.WeChatPackage;

import java.util.Arrays;
import java.util.List;
import android.util.Log;

// aliyun push
// 下面是被添加的代码
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import android.graphics.Color;
import android.os.Build;

import org.wonday.aliyun.push.AliyunPushPackage;

import com.alibaba.sdk.android.push.CloudPushService;
import com.alibaba.sdk.android.push.CommonCallback;
import com.alibaba.sdk.android.push.noonesdk.PushServiceFactory;
import com.alibaba.sdk.android.push.register.HuaWeiRegister;
import com.alibaba.sdk.android.push.register.MiPushRegister;
import com.alibaba.sdk.android.push.register.GcmRegister;
// 添加结束

public class MainApplication extends Application implements ReactApplication {

  private static final String TAG = "Init";

  private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
    @Override
    public boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
    }

    @Override
    protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
            new SplashScreenReactPackage(),
            new AliyunPushPackage(),
            new CookieManagerPackage(),
            new RNCWebViewPackage(),
            new QQPackage(),
            new PickerPackage(),
            new AsyncStoragePackage(),
            new RNGestureHandlerPackage(),
            new WeChatPackage()
      );
    }

    @Override
    protected String getJSMainModuleName() {
      return "index";
    }
  };

  @Override
  public ReactNativeHost getReactNativeHost() {
    return mReactNativeHost;
  }

  @Override
  public void onCreate() {
    super.onCreate();
    SoLoader.init(this, /* native exopackage */ false);

    // aliyun push
    this.initCloudChannel(this);
  }

  // 下面是添加的代码
  private void initCloudChannel(final Context applicationContext) {

    // 创建notificaiton channel
    this.createNotificationChannel();
    PushServiceFactory.init(applicationContext);
    CloudPushService pushService = PushServiceFactory.getCloudPushService();
    pushService.setNotificationSmallIcon(R.mipmap.ic_launcher_s);//设置通知栏小图标, 需要自行添加
    pushService.register(applicationContext, "259***", "37a0e****", new CommonCallback() {
      @Override
      public void onSuccess(String responnse) {
        Log.d(TAG, "init cloudchannel success");
        // success
      }
      @Override
      public void onFailed(String code, String message) {
        Log.d(TAG, "init cloudchannel failed -- errorcode:" + code + " -- errorMessage:" + message);
        // failed
      }
    });

    // 注册方法会自动判断是否支持小米系统推送,如不支持会跳过注册。
    MiPushRegister.register(applicationContext, "28823****", "53917****");
    // 注册方法会自动判断是否支持华为系统推送,如不支持会跳过注册。
    HuaWeiRegister.register(applicationContext);
    // 接入FCM/GCM初始化推送
    // GcmRegister.register(applicationContext, "***", "***");
  }

  private void createNotificationChannel() {
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
          NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
          // 通知渠道的id
          String id = "1";
          // 用户可以看到的通知渠道的名字.
          CharSequence name = "小度鱼";
          // 用户可以看到的通知渠道的描述
          String description = "小度鱼通知";
          int importance = NotificationManager.IMPORTANCE_HIGH;
          NotificationChannel mChannel = new NotificationChannel(id, name, importance);
          // 配置通知渠道的属性
          mChannel.setDescription(description);
          // 设置通知出现时的闪灯(如果 android 设备支持的话)
          mChannel.enableLights(true);
          mChannel.setLightColor(Color.RED);
          // 设置通知出现时的震动(如果 android 设备支持的话)
          mChannel.enableVibration(true);
          mChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
          //最后在notificationmanager中创建该通知渠道
          mNotificationManager.createNotificationChannel(mChannel);
      }
  }
  // 添加结束

}

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  android:supportsRtl="true"
  xmlns:tools="http://schemas.android.com/tools"
  package="com.xiaoduyureactnative">

    <uses-permission android:name="android.permission.INTERNET" />

    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-feature android:name="android.hardware.camera" android:required="false" />
    <uses-feature android:name="android.hardware.camera.front" android:required="false" />

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:allowBackup="false"
      android:theme="@style/AppTheme"
      tools:replace="android:allowBackup"
      android:usesCleartextTraffic="true">

      <activity
        android:name=".wxapi.WXEntryActivity"
        android:label="@string/app_name"
        android:exported="true"
      />

      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>

      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />

    </application>

</manifest>
54sword commented 5 years ago

另外是,我在您的react-native-aliyun-push源码添加了如下代码

AndroidManifest.xml 增加了

 <uses-library android:name="org.apache.http.legacy" android:required="false" />

以及添加了如下文件 android/src/main/res/xml/network_security_config.xml

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
        </trust-anchors>
    </base-config>
</network-security-config>

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="org.wonday.aliyun.push">
    <uses-permission android:name="android.permission.GET_TASKS" />
    <application
            android:label="@string/app_name">
        <uses-library android:name="org.apache.http.legacy" android:required="false" />
        <receiver
                android:name="org.wonday.aliyun.push.AliyunPushMessageReceiver"
                android:exported="true">
            <intent-filter>
                <action android:name="com.alibaba.push2.action.NOTIFICATION_OPENED" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.alibaba.push2.action.NOTIFICATION_REMOVED" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.alibaba.sdk.android.push.RECEIVE" />
            </intent-filter>
        </receiver>
        <activity
                android:name=".ThirdPartMessageActivity"
                android:exported="true" />
    </application>
</manifest>
wonday commented 5 years ago

上面代码没看出有问题,下面的我app就是lib原装的没额外修过。

54sword commented 5 years ago

@wonday 小米调通了,原因是发送通知的时候,需要增加如下参数。

OpenAPI 2.0的推送高级接口提供了AndroidPopupActivity、AndroidPopupTitle和AndroidPopupBody三个参数,分别用于设置辅助弹窗通知打开时跳转的Activity、通知标题以及通知内容(注意:StoreOffline参数也需要设置为true);

华为还是不行,没找到原因,心力憔悴。会不会是版本的原因,目前 alicloud-android-third-push-3.0.5.aar,文档中说是要v3.0.8以上。

当前辅助弹窗已接入小米、华为、OPPO(小米辅助弹窗:v2.3.0及以上支持;华为辅助弹窗:v3.0.8及以上支持;OPPO辅助弹窗:v3.1.4及以上支持);

附上文档地址 https://help.aliyun.com/document_detail/30067.html?spm=5176.11065259.1996646101.searchclickresult.17427071cUZRHL

wonday commented 5 years ago

@54sword 可是我找不到更新的alicloud-android-third-push-3.x.x.aar, 能下载到的版本就是3.0.5

wonday commented 5 years ago

@54sword 想到的注意点:

  1. 华为开发者中心增加了证书指纹的配置
  2. 阿里云移动推送和发送通知并列的地方有一个排查工具。 先启动App一下, 等app向阿里云注册好,使用设备排查,确保能查到这个设备 然后发送一个通知,输入消息ID和设备ID,查看通知状态。

我用发送通知界面给特定设备发送,如果选择立即发送则失败,选择离线发送则成功。 你试试看。

54sword commented 5 years ago

@wonday 感谢作者,华为也调通了。

问题的原因我有点不好意思,耽误作者时间和精力了。

原因是我之前在华为手机里面装了一些乱七八糟的东西,例如google 服务,google play等,影响了华为原生的通知功能。

在找寻问题中突然脑子一闪,华为手机自带的软件怎么都没有推送,不像是国产厂商做产品性格呀,所以我开始怀疑通知是被google 服务影响了(其实在很早也怀疑过,但自己测试QQ通知是正常的,所以就没理了),因此我恢复出厂设置了一下手机,什么代码都没改就通了。

再次感谢作者,谢谢您。

linxianxi commented 4 years ago

@54sword 请问下我们自己的app里的activity是多少在哪看 AndroidPopupActivity我不知道改设置成什么

54sword commented 4 years ago

@54sword 请问下我们自己的app里的activity是多少在哪看 AndroidPopupActivity我不知道改设置成什么

时间有点久,有点忘记了,印象中就是包名+MainActivity,你试一试 例如我的app包名是:com.xiaoduyureactnative AndroidPopupActivity:com.xiaoduyureactnative.MainActivity

woliwa1 commented 4 years ago

您好,请问一下你实现app线程杀死,收到通知么?我好像没看到你按照文档添加 <meta-data android:name="com.huawei.hms.client.appid" android:value="appid=华为开放平台申请的ID信息" / 方便给下提示么

woliwa1 commented 4 years ago

@54sword

54sword commented 4 years ago

@woliwa1 之前RN0.59版本配置好了,但后就不知道怎么就不行了,在服务端发送Android通知的时,总是出现 'Unexpected key \'AndroidNotificationChannel\' found in params' 提示错误,所以这个问题就一直搁浅,没有去研究...可能我也帮不上你,你可以试一试发issue问问作者。

PhantomRay commented 4 years ago

@woliwa1 之前RN0.59版本配置好了,但后就不知道怎么就不行了,在服务端发送Android通知的时,总是出现 'Unexpected key 'AndroidNotificationChannel' found in params' 提示错误,所以这个问题就一直搁浅,没有去研究...可能我也帮不上你,你可以试一试发issue问问作者。

你这个 'Unexpected key 'AndroidNotificationChannel' found in params问题解决了吗?