JPushDemo【极光推送集成,基于v3.1.8版本】
程序员文章站
2022-07-09 14:46:21
版权声明:本文为HaiyuKing原创文章,转载请注明出处! 前言 这个Demo只是记录极光推送的集成,不能运行。 使用步骤 一、项目组织结构图 注意事项: 1、 导入类文件后需要change包名以及重新import R文件路径 2、 Values目录下的文件(strings.xml、dimens. ......
版权声明:本文为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
上一篇: ECharts 高度宽度自适应(转载)