zoukankan      html  css  js  c++  java
  • JPushDemo【极光推送集成,基于v3.1.8版本】

    版权声明:本文为HaiyuKing原创文章,转载请注明出处!

    前言

    这个Demo只是记录极光推送的集成,不能运行。

    使用步骤

    一、项目组织结构图

     

    注意事项:

    1、  导入类文件后需要change包名以及重新import R文件路径

    2、  Values目录下的文件(strings.xml、dimens.xml、colors.xml等),如果项目中存在,则复制里面的内容,不要整个覆盖

    二、导入步骤

    2.1、接入准备

    参考官网《3 分钟快速使用 JPush Android Demo

    创建极光推送开发者帐号——》创建应用——》获取APPkey

    2.2、下载SDK

    如果使用自动集成的话,不需要下载SDK,不过我个人倾向于手动集成,所以需要下载SDK。

    下载地址:https://docs.jiguang.cn/jpush/resources/

    下载后的压缩包解压后的目录:

     

    说明:

    2.3、集成SDK

    为了便于管理,我在Demo中新建了一个ThirdLib的module,用于集成SDK。

    (1)新建ThirdLib的module,并在app的build.gradle中引用

        //引用thirdlib
        implementation project(':thirdlib')

    (2)在ThirdLib这个module中集成SDK

    • 复制 libs/jcore-android-1.x.x.jar 到工程 libs/ 目录下。
    • 复制 libs/jpush-android-3.x.x.jar 到工程 libs/ 目录下。
    • 复制 libs/(cpu-type)/libjcore1xy.so 到你的工程中存放对应 cpu 类型的目录下(使用 jniLibs 文件夹导入 so 文件,则仅需将所有 cpu 类型的文件夹拷进去)。
    • 复制 res/ 中 drawable-hdpi, layout, values 文件夹中的资源文件到你的工程中 res/ 对应同名的目录下。
    • 定义没有阴影和渐变色的 jpush_notification_icon 资源文件并添加到drawable-hdpi目录下(若没有 res/drawable-xxxx/jpush_notification_icon 这个资源默认使用应用图标作为通知 icon,在 5.0 以上系统将应用图标作为 statusbar icon 可能显示不正常)。

     因为是在thirdlib这个module中集成jar包,所以还需要在thirdlib这个module的build.gradle文件中引用libs目录下的jar包。

    apply plugin: 'com.android.library'
    
    android {
        compileSdkVersion 28
    
    
    
        defaultConfig {
            minSdkVersion 16
            targetSdkVersion 28
            versionCode 1
            versionName "1.0"
    
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    
        }
    
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    
    }
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
    
        implementation 'com.android.support:appcompat-v7:28.0.0'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'com.android.support.test:runner:1.0.2'
        androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    
        //极光推送SDK
        api files('libs/jcore-android-1.2.6.jar')
        api files('libs/jpush-android-3.1.8.jar')
    }

    (3)配置 AndroidManifest.xml【注意是app这个module中的,不是thirdlib这个module中的】

     

    注意下面标记橙色代码:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
              package="com.why.project.jpushdemo">
    
        <!-- ======================极光推送SDK====================== -->
        <!-- Required -->
        <permission
            android:name="${applicationId}.permission.JPUSH_MESSAGE"
            android:protectionLevel="signature" />
    
        <!-- Required  一些系统要求的权限,如访问网络等-->
        <uses-permission android:name="${applicationId}.permission.JPUSH_MESSAGE" />
        <uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
        <uses-permission android:name="android.permission.INTERNET" />
        <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.WRITE_SETTINGS" />
        <!--(必须需要,否则设置别名失败)-->
        <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    
        <!-- Optional for location -->
        <uses-permission android:name="android.permission.VIBRATE" />
        <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- 用于开启 debug 版本的应用在6.0 系统上 层叠窗口权限 -->
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
        <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
        <uses-permission android:name="android.permission.GET_TASKS" />
    
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name=".MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN"/>
    
                    <category android:name="android.intent.category.LAUNCHER"/>
                </intent-filter>
            </activity>
    
            <!-- ======================极光推送SDK========================== -->
            <!-- 状态通知栏需要打开的Activity -->
            <activity android:name="com.why.project.jpushdemo.jpush.JpushActivity"
                      android:exported="false">
                <intent-filter>
                    <action android:name="jpush.testAction" />
                    <category android:name="jpush.testCategory" />
                </intent-filter>
            </activity>
    
            <!-- Rich push 核心功能 since 2.0.6-->
            <activity
                android:name="cn.jpush.android.ui.PopWinActivity"
                android:theme="@style/MyDialogStyle"
                android:exported="false">
            </activity>
    
            <!-- Required SDK核心功能-->
            <activity
                android:name="cn.jpush.android.ui.PushActivity"
                android:configChanges="orientation|keyboardHidden"
                android:theme="@android:style/Theme.NoTitleBar"
                android:exported="false">
                <intent-filter>
                    <action android:name="cn.jpush.android.ui.PushActivity" />
                    <category android:name="android.intent.category.DEFAULT" />
                    <category android:name="${applicationId}" />
                </intent-filter>
            </activity>
    
            <!-- Required SDK 核心功能-->
            <!-- 可配置android:process参数将PushService放在其他进程中 -->
            <service
                android:name="cn.jpush.android.service.PushService"
                android:process=":pushcore"
                android:exported="false">
                <intent-filter>
                    <action android:name="cn.jpush.android.intent.REGISTER" />
                    <action android:name="cn.jpush.android.intent.REPORT" />
                    <action android:name="cn.jpush.android.intent.PushService" />
                    <action android:name="cn.jpush.android.intent.PUSH_TIME" />
                </intent-filter>
            </service>
            <!-- since 3.0.9 Required SDK 核心功能-->
            <provider
                android:authorities="${applicationId}.DataProvider"
                android:name="cn.jpush.android.service.DataProvider"
                android:process=":pushcore"
                android:exported="false"
                />
    
            <!-- since 1.8.0 option 可选项。用于同一设备中不同应用的JPush服务相互拉起的功能。 -->
            <!-- 若不启用该功能可删除该组件,将不拉起其他应用也不能被其他应用拉起 -->
            <service
                android:name="cn.jpush.android.service.DaemonService"
                android:enabled="true"
                android:exported="true">
                <intent-filter>
                    <action android:name="cn.jpush.android.intent.DaemonService" />
                    <category android:name="${applicationId}" />
                </intent-filter>
    
            </service>
            <!-- since 3.1.0 Required SDK 核心功能-->
            <provider
                android:authorities="${applicationId}.DownloadProvider"
                android:name="cn.jpush.android.service.DownloadProvider"
                android:exported="true"
                />
            <!-- Required SDK核心功能-->
            <receiver
                android:name="cn.jpush.android.service.PushReceiver"
                android:enabled="true"
                android:exported="false">
                <intent-filter android:priority="1000">
                    <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED_PROXY" />   <!--Required  显示通知栏 -->
                    <category android:name="${applicationId}" />
                </intent-filter>
                <intent-filter>
                    <action android:name="android.intent.action.USER_PRESENT" />
                    <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                </intent-filter>
                <!-- Optional -->
                <intent-filter>
                    <action android:name="android.intent.action.PACKAGE_ADDED" />
                    <action android:name="android.intent.action.PACKAGE_REMOVED" />
    
                    <data android:scheme="package" />
                </intent-filter>
            </receiver>
    
            <!-- Required SDK核心功能-->
            <receiver android:name="cn.jpush.android.service.AlarmReceiver" android:exported="false"/>
    
            <!-- User defined.  For test only  用户自定义的广播接收器-->
            <receiver
                android:name="com.why.project.jpushdemo.jpush.JpushReceiver"
                android:exported="false"
                android:enabled="true">
                <intent-filter>
                    <action android:name="cn.jpush.android.intent.REGISTRATION" /> <!--Required  用户注册SDK的intent-->
                    <action android:name="cn.jpush.android.intent.MESSAGE_RECEIVED" /> <!--Required  用户接收SDK消息的intent-->
                    <action android:name="cn.jpush.android.intent.NOTIFICATION_RECEIVED" /> <!--Required  用户接收SDK通知栏信息的intent-->
                    <action android:name="cn.jpush.android.intent.NOTIFICATION_OPENED" /> <!--Required  用户打开自定义通知栏的intent-->
                    <action android:name="cn.jpush.android.intent.CONNECTION" /><!-- 接收网络变化 连接/断开 since 1.6.3 -->
                    <category android:name="${applicationId}" />
                </intent-filter>
            </receiver>
    
            <!-- User defined.  For test only  用户自定义接收消息器,3.0.7开始支持,目前新tag/alias接口设置结果会在该广播接收器对应的方法中回调-->
            <receiver android:name="com.why.project.jpushdemo.jpush.MyJPushMessageReceiver">
                <intent-filter>
                    <action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />
                    <category android:name="${applicationId}"></category>
                </intent-filter>
            </receiver>
            <!-- Required  . Enable it you can get statistics data with channel -->
            <meta-data android:name="JPUSH_CHANNEL" android:value="developer-default"/>
            <meta-data android:name="JPUSH_APPKEY" android:value="9fed5bcb7b9b87413678c407" /> <!--  </>值来自开发者平台取得的AppKey-->
    
        </application>
    
    </manifest>

     (4)在项目中添加jpush包中的文件

    其中,关键的是JpushActivity和JpushReceiver这两个文件。

    JpushReceiver:主要用于点开通知栏,判断跳转打开的界面

    JpushActivity:主要用于展现点击通知打开的界面;

    package com.why.project.jpushdemo.jpush;
    
    import android.content.Context;
    import android.content.Intent;
    import android.content.res.Resources;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.support.v7.widget.Toolbar;
    import android.view.KeyEvent;
    import android.view.View;
    import android.widget.TextView;
    
    import com.why.project.jpushdemo.R;
    
    import org.json.JSONException;
    import org.json.JSONObject;
    
    import cn.jpush.android.api.JPushInterface;
    
    /**
     * Used 极光推送点开通知后打开的界面
     * 和WebViewPreviewActivity共用一个布局文件
     * 需要先检查是否已经登录,如果没有登录,直接登录即可,不需要返回到登录界面了
     * 极光推送SDK
     */
    public class JpushActivity extends AppCompatActivity {
        private static final String TAG = JpushActivity.class.getSimpleName();
    
        /**从登录界面打开的标记(传递参数用)*/
        public static final String EXTRA_ONLOGIN = "onlogin";
    
        /*Jpush传递过来的参数*/
        private Bundle jPushBundle;
        /**通知标题*/
        private String jPushTitle;
        /**通知内容*/
        private String jPushContent;
        /**通知附加字段*/
        private String jPushExtraJson;
        /**通知id值*/
        private int jPushId;
    
        //展现在导航栏上的标题
        private String bundle_title;
        //网页url地址
        private String bundle_url;
    
        /**标记是否从登录界面打开的状态值*/
        private boolean bundle_onlogin = false;
    
        private Context mContext;
    
        private Toolbar mToolbar;
    
        private MyWebView myWebView;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_webviewpreview);
    
            mContext = this;
    
            //初始化控件
            initViews();
            //初始化数据
            initData();
            initToolBar();//初始化toolbar
        }
    
        @Override
        public void onDestroy()
        {
            //销毁webview控件
            myWebView.removeAllViews();
            myWebView.destroy();
            super.onDestroy();
        }
    
        /**
         * 初始化view
         */
        private void initViews() {
            myWebView = (MyWebView)findViewById(R.id.id_webView);
            myWebView.setCanBackPreviousPage(true,JpushActivity.this);//可以返回上一页
        }
    
        /**
         * 初始化数据【接收点击通知栏传过来的数据:通知、自定义消息两种(这里只需要处理通知的即可)】
         */
        private void initData() {
            Intent intent = getIntent();
            if (null != intent) {
                jPushBundle = getIntent().getExtras();
                jPushTitle = jPushBundle.getString(JPushInterface.EXTRA_NOTIFICATION_TITLE);//保存服务器推送下来的通知的标题
                jPushContent = jPushBundle.getString(JPushInterface.EXTRA_ALERT);//保存服务器推送下来的通知内容
                jPushExtraJson = jPushBundle.getString(JPushInterface.EXTRA_EXTRA);//保存服务器推送下来的附加字段。这是个 JSON 字符串
                jPushId = jPushBundle.getInt(JPushInterface.EXTRA_NOTIFICATION_ID);//SDK 1.3.5 以上版本支持,通知栏的Notification ID,可以用于清除Notification
    
                bundle_onlogin = jPushBundle.getBoolean(EXTRA_ONLOGIN);
            }
    
            if(!jPushExtraJson.equals("")){
                try {
                    JSONObject extraJsonObj = new JSONObject(jPushExtraJson);
                    if(extraJsonObj.has("from")){
                        extraJsonObj = new JSONObject(extraJsonObj.getString("from"));
                    }
                    if(!extraJsonObj.getString("exTraTitle").equals("")){
                        //获取标题
                        bundle_title = extraJsonObj.getString("exTraTitle");
                    }
                    if(!extraJsonObj.getString("url").equals("")){
                        //获取网页地址
                        bundle_url = extraJsonObj.getString("url");
                    }
                } catch (Resources.NotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (JSONException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
    
            if(! bundle_onlogin){//如果是从登录界面打开的话,那么不用验证了
                initCheckLoginState();//验证是否需要重新登录
            }else{
                loadWebUrl();//打开网页
            }
    
        }
    
        private void initToolBar() {
            mToolbar = findViewById(R.id.toolbar_base);
            mToolbar.setTitle("");//这样设置的话,自带的标题就不会显示
            //设置自定义的标题(居中)
            TextView toolBarTitle = mToolbar.findViewById(R.id.toolbarTitle);
            toolBarTitle.setText(bundle_title);
            setSupportActionBar(mToolbar);//由于toolbar只是一个普通控件,我们将ToolBar设置为ActionBar
            //设置导航图标要在setSupportActionBar方法之后
            mToolbar.setNavigationIcon(R.drawable.nav_back);//设置为空的话,就会不显示左侧的图标
            //对NavigationIcon添加点击
            mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //返回到首页界面(重新登录的情况下)或者直接关闭自己(不需要重新登录的情况下)
                    backHomeOrFinish();
                }
            });
        }
    
        /**
         * 点击返回键
         * event.getRepeatCount() == 0:点后退键的时候,为了防止点得过快,触发两次后退事件,故做此设置。
         */
        @Override
        public boolean onKeyDown(int keyCode, KeyEvent event) {
            // TODO Auto-generated method stub
            if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
                //返回到首页界面(如果是从登录界面打开的)或者关闭自己(从通知打开的)
                backHomeOrFinish();
            }
            return super.onKeyDown(keyCode, event);
        }
    
    
        //返回功能
        private void backHomeOrFinish() {
            if (bundle_onlogin) {
                ActivityJump.NormalJumpAndFinish(JpushActivity.this, HomeActivity.class);
            } else {
                ActivityJump.Back(this);
            }
        }
    
    
        /**
         * 网络请求检查登录状态,主要判断是否在线
         */
        private void initCheckLoginState() {
            if(result.indexOf("alert(") != -1){
                //登陆身份失效,请重新登陆
                ActivityJump.BundleJumpAndFinish(JpushActivity.this, LoginActivity.class,jPushBundle);
            }
            else{
                loadWebUrl();//加载网页
            }
        }
    
        /**
         * 加载URL地址
         */
        private void loadWebUrl() {
            syncCookie(JpushActivity.this, ServerApi.SERVER_URL);
    
            if (!bundle_url.equals("")) {
                myWebView.loadWebUrl(ServerApi.SERVER_URL + bundle_url);
            } else {
                myWebView.loadUrl("about:blank");//加载一个空白页
            }
        }
    
        /**
         * Sync Cookie
         */
        public static void syncCookie(Context context, String url){
            //参考本博客的《okhttputils【 Android 一个改善的okHttp封装库】使用(二)》
        }
    }

    (5)初始化SDK

     在MyApplication中执行

    package com.why.project.jpushdemo;
    
    import android.app.Application;
    
    import cn.jpush.android.api.JPushInterface;
    
    /**
     * Created by HaiyuKing
     * Used
     */
    public class MyApplication extends Application {
    
        @Override
        public void onCreate() {
            super.onCreate();
    
            initJpush();//极光推送SDK初始化
        }
    
        //极光推送SDK
        private void initJpush() {
            JPushInterface.setDebugMode(true);// 设置开启日志,发布时请关闭日志
            JPushInterface.init(this);// 初始化 JPush
        }
    } 

    三、使用方法【仅供参考】

    package com.why.project.jpushdemo;
    
    import android.content.Context;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.text.TextUtils;
    
    import com.why.project.jpushdemo.jpush.ExampleUtil;
    import com.why.project.jpushdemo.jpush.TagAliasOperatorHelper;
    
    import cn.jpush.android.api.JPushInterface;
    
    public class MainActivity extends AppCompatActivity {
        private static final String TAG = MainActivity.class.getSimpleName();
    
        private Context mContext;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            mContext = this;
    
            /*=======================================极光推送SDK相关=============================================*/
            //请求服务器删除alias,然后再重新注册alias,这样实现一个别名只能绑定一台设备
            updateJpushDeviceId();
        }
    
        /*=======================================极光推送SDK相关=============================================*/
    
        /**
         * 更新设备id接口
         */
        private void updateJpushDeviceId() {
            String regId = JPushInterface.getRegistrationID(mContext);//可能不会那么快就能获得resId值,所以如果极光推送没有初始化好,那么这里获取到的是null
            requestDeviceId(regId);//判断是请求接口还是弹出对话框
        }
    
        //请求接口存储设备id或者token的方法
        private void requestDeviceId(String regId) {
    
            //首要条件是设备id值或者token值不为空,否则下面的判断没有意义了
            //如果没有设置过别名,或者则需要设置别名
            //如果服务器上的deviceID值是空值,表明当前用户还没有绑定任何设备,则直接请求接口,不需要弹出对话框;
            //如果服务器上的deviceID值不为空,并且客户端获取的设备id值和服务器上的deviceID值相同,则不需要弹出对话框,直接请求接口(这个是卸载重新安装的情况)
            //如果服务器上的deviceid值不为空,并且客户端获取的设备id值和服务器上的deviceID值不同,则需要弹出对话框(这个是换设备的情况)
            if (!TextUtils.isEmpty(regId)) {
                //如果已经设置过别名(存储过了设备id值)了,但是当前的别名(设备id值)和服务器上的不一致,则需要重新设置别名(存储设备id值)(这个是其他设备上登录的情况)
            }
    
            //设置极光推送别名
            setAlias(PreferencesUtils.getString(mContext,Globals.USERNAME_KEY));
        }
    
    
        // 这是来自 JPush Example 的设置别名的 Activity 里的代码。一般 App 的设置的调用入口,在任何方便的地方调用都可以。
        private void setAlias(String alias) {
            if (TextUtils.isEmpty(alias)) {
                ToastUtil.showShortToast(getResources().getString(R.string.error_alias_empty));//alias别名不能为空
                return;
            }
            if (!ExampleUtil.isValidTagAndAlias(alias)) {
                ToastUtil.showShortToast(getResources().getString(R.string.error_tag_gs_empty));//格式不对
                return;
            }
    
            // 调用 JPush 接口来设置别名。
            TagAliasOperatorHelper.TagAliasBean tagAliasBean = new TagAliasOperatorHelper.TagAliasBean();
            tagAliasBean.action = TagAliasOperatorHelper.ACTION_SET;
            tagAliasBean.alias = alias;
            tagAliasBean.isAliasAction = true;
            TagAliasOperatorHelper.getInstance().handleAction(MyApplication.getAppContext(), TagAliasOperatorHelper.sequence++, tagAliasBean);
            //已经设置了别名
            String aliasKey = Globals.UPDATEJPUSHRESID_KEY;
            PreferencesUtils.putBoolean(mContext,aliasKey,true);
        }
    }

    四、发送消息

    混淆配置

    #====极光推送SDK====
    -dontoptimize
    -dontpreverify
    
    -dontwarn cn.jpush.**
    -keep class cn.jpush.** { *; }
    -keep class * extends cn.jpush.android.helpers.JPushMessageReceiver { *; }
    
    -dontwarn cn.jiguang.**
    -keep class cn.jiguang.** { *; }

    参考资料

    暂时空缺

    项目demo下载地址

     链接:https://pan.baidu.com/s/1eHSnRrw07LC9mq1I7IP2gw 提取码:wn99 

  • 相关阅读:
    numpy 矩阵和数组
    python map()
    python matplotlib plot
    python mean()
    预测数值型数据:回归
    散点图
    非均衡分类问题
    AdaBoost元算法
    2.1 n元排列
    1.3 数域
  • 原文地址:https://www.cnblogs.com/whycxb/p/10154002.html
Copyright © 2011-2022 走看看