当前位置: 移动技术网 > IT编程>移动开发>Android > JPushDemo【极光推送集成,基于v3.1.8版本】

JPushDemo【极光推送集成,基于v3.1.8版本】

2019年04月24日  | 移动技术网IT编程  | 我要评论

越狱第五季第六集,mimibibi,义乌韩国饰品批发网

版权声明:本文为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。

下载地址:

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

 

说明:

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 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网