Android 极光推送API

2022-05-10 11:07:17 浏览数 (1)

前言

  发现现在的Android开发中很少有不用第三方SDK的,为什么呢?就是因为实现一个功能的速度快呀,比如说客服、聊天、直播等一些功能,用第三方SDK可以最快解决问题,我在实际开发中也对接过很多SDK,不过仔细写过这方便到的博客,前段时间我写了一个关于udesk SDK的文章,实现IM的,写的不算太详细,不过你如果看了也够用了,好了,进入正文。

正文

效果图,源码在文章最后

今天要对接的这个SDK是极光系列中的推送服务SDK,当然极光还有其他的服务,进入极光官网了解一下,我这里放个图说明一下

主要看我标注的这个,因为主要讲这个,为什么文章会说是详细到令人发指呢?下面你就明白了。

注册极光账号

无论你用什么SDK,你都会需要注册账号的,为了写个博客我都重新注册了一个账号了,点击注册

进入注册页面

输入个人信息,

然后提交

然后要进入邮箱去验证一下,不然怎么知道你这个邮箱有没有用呢,点击立即登录邮箱,进入之后打开收件箱

可以看到最新的邮件是极光发过来的,打开这个邮件

然后进行邮箱验证

有的电脑可能又会这根访问拦截,点继续访问即可,没出现的当我没说过。

邮箱验证成功,登录极光吧!

输入信息之后登录

这个信息现在是可以随便输入的,不过如果你要升级为开发者的话就要真实个人信息了。

进入开发者平台

创建应用,需要名称和图标

这里需要用到一个图标

点击确认,然后应用就创建好了

接下来进行推送设置

应用包名,现在去Android Studio创建一个项目

Next

Finish,等待项目创建完成,打开AndroidManifest.xml

复制包名

保存

确认

查看集成文档

主要看这个自动集成的,简单快捷,So Easy! 文档你可以自己去看,因为我已经看过很多遍了,所以下面以项目的环境为主。

步骤

① 确认 android studio 的 Project 根目录的主 gradle 中配置了 jcenter 支持。(新建 project 默认配置就支持)
② 在 module 的 gradle 中添加依赖。

然后右上角Sync Now点击同步一下刚才改变的配置,否则改动不生效。

③ 然后新建两个包,servicereceiver

然后在service包下创建一个PushService类,然后继承JCommonService,代码如下:

代码语言:javascript复制
package com.llw.pushdemo.service;

import cn.jpush.android.service.JCommonService;

public class PushService extends JCommonService {

}

在receiver包下创建一个PushReceiver类,然后继承JPushMessageReceiver,代码如下:

代码语言:javascript复制
package com.llw.pushdemo.receiver;

import cn.jpush.android.service.JPushMessageReceiver;

public class PushReceiver extends JPushMessageReceiver {
    
}

都只是简单的继承而已。

④ 配置AndroidManifest.xml

然后现在回到AndroidManifest.xml

代码语言:javascript复制
		<!--极光推送 服务-->
        <service
            android:name=".service.PushService"
            android:enabled="true"
            android:exported="false"
            android:process=":pushcore">
            <intent-filter>
                <action android:name="cn.jiguang.user.service.action" />
            </intent-filter>
        </service>
        <!--极光推送 接收器-->
        <receiver
            android:name=".receiver.PushReceiver"
            android:enabled="true"
            android:exported="false" >
            <intent-filter>
                <action android:name="cn.jpush.android.intent.RECEIVE_MESSAGE" />
                <category android:name="com.llw.pushdemo" />
            </intent-filter>
        </receiver>

这里会用到一个工具类ExampleUtil.java,代码如下:

代码语言:javascript复制
package com.llw.pushdemo;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Looper;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.widget.Toast;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import cn.jpush.android.api.JPushInterface;
import cn.jpush.android.helper.Logger;

public class ExampleUtil {
    public static final String PREFS_NAME = "JPUSH_EXAMPLE";
    public static final String PREFS_DAYS = "JPUSH_EXAMPLE_DAYS";
    public static final String PREFS_START_TIME = "PREFS_START_TIME";
    public static final String PREFS_END_TIME = "PREFS_END_TIME";
    public static final String KEY_APP_KEY = "JPUSH_APPKEY";

    public static boolean isEmpty(String s) {
        if (null == s)
            return true;
        if (s.length() == 0)
            return true;
        if (s.trim().length() == 0)
            return true;
        return false;
    }
    /**
     * 只能以 “ ” 或者 数字开头;后面的内容只能包含 “-” 和 数字。
     * */
    private final static String MOBILE_NUMBER_CHARS = "^[ 0-9][-0-9]{1,}$";
    public static boolean isValidMobileNumber(String s) {
        if(TextUtils.isEmpty(s)) return true;
        Pattern p = Pattern.compile(MOBILE_NUMBER_CHARS);
        Matcher m = p.matcher(s);
        return m.matches();
    }
    // 校验Tag Alias 只能是数字,英文字母和中文
    public static boolean isValidTagAndAlias(String s) {
        Pattern p = Pattern.compile("^[u4E00-u9FA50-9a-zA-Z_!@#$&* =.|] $");
        Matcher m = p.matcher(s);
        return m.matches();
    }

    // 取得AppKey
    public static String getAppKey(Context context) {
        Bundle metaData = null;
        String appKey = null;
        try {
            ApplicationInfo ai = context.getPackageManager().getApplicationInfo(
                    context.getPackageName(), PackageManager.GET_META_DATA);
            if (null != ai)
                metaData = ai.metaData;
            if (null != metaData) {
                appKey = metaData.getString(KEY_APP_KEY);
                if ((null == appKey) || appKey.length() != 24) {
                    appKey = null;
                }
            }
        } catch (NameNotFoundException e) {

        }
        return appKey;
    }

    // 取得版本号
    public static String GetVersion(Context context) {
		try {
			PackageInfo manager = context.getPackageManager().getPackageInfo(
					context.getPackageName(), 0);
			return manager.versionName;
		} catch (NameNotFoundException e) {
			return "Unknown";
		}
	}

    public static void showToast(final String toast, final Context context)
    {
    	new Thread(new Runnable() {

			@Override
			public void run() {
				Looper.prepare();
				Toast.makeText(context, toast, Toast.LENGTH_SHORT).show();
				Looper.loop();
			}
		}).start();
    }

    public static boolean isConnected(Context context) {
        ConnectivityManager conn = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo info = conn.getActiveNetworkInfo();
        return (info != null && info.isConnected());
    }

	public static String getImei(Context context, String imei) {
        String ret = null;
		try {
			TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            ret = telephonyManager.getDeviceId();
		} catch (Exception e) {
			Logger.e(ExampleUtil.class.getSimpleName(), e.getMessage());
		}
		if (isReadableASCII(ret)){
            return ret;
        } else {
            return imei;
        }
	}

    private static boolean isReadableASCII(CharSequence string){
        if (TextUtils.isEmpty(string)) return false;
        try {
            Pattern p = Pattern.compile("[\x20-\x7E] ");
            return p.matcher(string).matches();
        } catch (Throwable e){
            return true;
        }
    }

    public static String getDeviceId(Context context) {
        return JPushInterface.getUdid(context);
    }
}
⑤ 修改MainActivity.java

然后是MainActiviity.java

代码语言:javascript复制
//for receive customer msg from jpush server
    private MessageReceiver mMessageReceiver;
    public static final String MESSAGE_RECEIVED_ACTION = "com.example.jpushdemo.MESSAGE_RECEIVED_ACTION";
    public static final String KEY_TITLE = "title";
    public static final String KEY_MESSAGE = "message";
    public static final String KEY_EXTRAS = "extras";
    private EditText msgText;

注册消息接收和设置自定义消息

代码语言:javascript复制
public void registerMessageReceiver() {
        mMessageReceiver = new MessageReceiver();
        IntentFilter filter = new IntentFilter();
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        filter.addAction(MESSAGE_RECEIVED_ACTION);
        LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, filter);
    }

    public class MessageReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                if (MESSAGE_RECEIVED_ACTION.equals(intent.getAction())) {
                    String messge = intent.getStringExtra(KEY_MESSAGE);
                    String extras = intent.getStringExtra(KEY_EXTRAS);
                    StringBuilder showMsg = new StringBuilder();
                    showMsg.append(KEY_MESSAGE   " : "   messge   "n");
                    if (!ExampleUtil.isEmpty(extras)) {
                        showMsg.append(KEY_EXTRAS   " : "   extras   "n");
                    }
                    setCostomMsg(showMsg.toString());
                }
            } catch (Exception e){
            }
        }
    }

    //设置自定义消息
    private void setCostomMsg(String msg){
        if (null != msgText) {
            msgText.setText(msg);
            msgText.setVisibility(View.VISIBLE);
        }
    }

然后在onCreate中初始化和调用

代码语言:javascript复制
		JPushInterface.init(getApplicationContext());//极光接口初始化,否则用不了
        registerMessageReceiver();//注册消息接收器

现在你就可以运行了

⑥ 发送通知

很好,看到Hello World!了,现在打开极光的控制台

点击进入

因为我已经安装了应用,所以在平台上可以看到新增了一个用户。 设置推送消息

滑动到最下面,广播所有人的意思就是只要是安装了这个应用的人都会收到通知

然后预览

然后你会看到预估人数1,就算你这里是0也没有关系,因为这个平台的数据有时候会有延时,不用担心,大胆的勇敢的点击确认发送通知吧!

发送成功! 而且手机上也收到了通知了

⑦ 点击通知跳转页面

  在使用其他的APP的时候点击通知的时候通常会打开不同的页面或者不同的URL,而目前你要是点击这个通知的话就是重新打开当前应用,这显然不是那么的合理,所以当我们需要点击通知跳转到不同页面时,要怎么做呢?

这个方面的功能极光中并没有详细说明,我也是经过反复测试和摸索才总结出来的,回到PushReceiver,在这里之前只做了一个简单的继承,而且是也是在这里做通知点击之后的业务处理的。

因此我需要重写onNotifyMessageOpened方法。它是一个通知栏点击的监听,我只要在点击的时候跳转到其他页面就行了,非常的简单吧。

不过呢?首先需要新建一个页面才行,就取名TestActivity。

然后进入到PushReceiver

代码语言:javascript复制
package com.llw.pushdemo.receiver;

import android.content.Context;
import android.content.Intent;

import com.llw.pushdemo.TestActivity;

import cn.jpush.android.api.NotificationMessage;
import cn.jpush.android.service.JPushMessageReceiver;

public class PushReceiver extends JPushMessageReceiver {

    @Override
    public void onNotifyMessageOpened(Context context, NotificationMessage notificationMessage) {

        Intent intent = new Intent(context, TestActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP );
        context.startActivity(intent);
    }
}

很简单的代码对不对,就是跳转页面而已。 下面直接运行吧,通过极光平台发送通知,App收到通知,然后点击通知栏。

这样它就可以跳转到TestActivity页面了。而如果你要携带一些参数呢? 也很简单,

在极光平台上发送通知的时候,配置附加字段。然后回到PushReceiver

然后修改一些activity_test.xml

代码语言:javascript复制
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    tools:context=".TestActivity">

    <TextView
    	android:id="@ id/tv_test"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textColor="#000"
        android:textSize="20sp" />
</LinearLayout>

然后在TestActivity中

代码语言:javascript复制
package com.llw.pushdemo;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class TestActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        
        TextView tvTest = findViewById(R.id.tv_test);
        
        String extras = getIntent().getStringExtra("extras");
        if(extras !=null){
            tvTest.setText(extras);
        }
        
    }
}

代码也很简单,通过getIntent拿到传递过来的数据,然后显示在TextView上,下面来试试吧。

OK,内容就有了。

⑧ 拓展 应用通知开关监听

你看,就这样实现了。你以为就完了吗?

  当然没有完!注意到上面的图是推送消息的记录,目标1,成功1,当然有的手机会收不到通知,这是为什么呢?因为国内的很多手机厂商对Android系统进行了自家系统开发,导致,Android的兼容比较难做,因为有的手机默认应用就不允许接收通知,所以你收不到也不要觉得奇怪,在手机设置里打开通知开关就可以了。

我的是荣耀 20i,默认安装应用就自动打开了这个开关的。

这里就涉及到另一个知识点了,那就是通知开关的监听。举个例子,爱奇艺APP,平时老是给我推送通知,烦得很,然后我就给它关了通知,下次进入APP是会有一个提示

就像这样,基本每个成熟的APP,都会有这个监听的。下面来看看怎么做吧。 无非就是两个方法而已

代码语言:javascript复制
//是否开启通知接收
private boolean isNotificationEnabled(Context context) {
        boolean isOpened = false;
        try {
            isOpened = NotificationManagerCompat.from(context).areNotificationsEnabled();
        } catch (Exception e) {
            e.printStackTrace();
            isOpened = false;
        }
        return isOpened;

    }
	//去设置
    private void gotoSet() {
        Intent intent = new Intent();
        if (Build.VERSION.SDK_INT >= 26) {
            // android 8.0引导
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("android.provider.extra.APP_PACKAGE", getPackageName());
        } else if (Build.VERSION.SDK_INT >= 21) {
            // android 5.0-7.0
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("app_package", getPackageName());
            intent.putExtra("app_uid", getApplicationInfo().uid);
        } else {
            // 其他
            intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
            intent.setData(Uri.fromParts("package", getPackageName(), null));
        }
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);

    }

然后就是使用方法了

这个时候如果你的这个Demo通知是关闭的话,那么你一打开这个页面就会跳转到通知开启那里去。OK,你以为完了吗? 真的完了! 最后贴一下MainActiviy.java的完整代码

代码语言:javascript复制
package com.llw.pushdemo;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationManagerCompat;
import androidx.localbroadcastmanager.content.LocalBroadcastManager;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;

import cn.jpush.android.api.JPushInterface;

public class MainActivity extends AppCompatActivity {


    //for receive customer msg from jpush server
    private MessageReceiver mMessageReceiver;
    public static final String MESSAGE_RECEIVED_ACTION = "com.example.jpushdemo.MESSAGE_RECEIVED_ACTION";
    public static final String KEY_TITLE = "title";
    public static final String KEY_MESSAGE = "message";
    public static final String KEY_EXTRAS = "extras";
    private EditText msgText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        JPushInterface.init(getApplicationContext());//极光接口初始化,否则用不了
        registerMessageReceiver();//注册消息接收器

        //判断该app是否打开了通知,如果没有的话就打开手机设置页面
        if (!isNotificationEnabled(this)) {
            //开启通知弹窗
            gotoSet();
        } else {
            //当前app允许消息通知
        }
    }



    public void registerMessageReceiver() {
        mMessageReceiver = new MessageReceiver();
        IntentFilter filter = new IntentFilter();
        filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
        filter.addAction(MESSAGE_RECEIVED_ACTION);
        LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, filter);
    }

    public class MessageReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            try {
                if (MESSAGE_RECEIVED_ACTION.equals(intent.getAction())) {
                    String messge = intent.getStringExtra(KEY_MESSAGE);
                    String extras = intent.getStringExtra(KEY_EXTRAS);
                    StringBuilder showMsg = new StringBuilder();
                    showMsg.append(KEY_MESSAGE   " : "   messge   "n");
                    if (!ExampleUtil.isEmpty(extras)) {
                        showMsg.append(KEY_EXTRAS   " : "   extras   "n");
                    }
                    setCostomMsg(showMsg.toString());
                }
            } catch (Exception e){
            }
        }
    }

    //设置自定义消息
    private void setCostomMsg(String msg){
        if (null != msgText) {
            msgText.setText(msg);
            msgText.setVisibility(View.VISIBLE);
        }
    }

    //是否开启通知接收
    private boolean isNotificationEnabled(Context context) {
        boolean isOpened = false;
        try {
            isOpened = NotificationManagerCompat.from(context).areNotificationsEnabled();
        } catch (Exception e) {
            e.printStackTrace();
            isOpened = false;
        }
        return isOpened;

    }
    //去设置
    private void gotoSet() {
        Intent intent = new Intent();
        if (Build.VERSION.SDK_INT >= 26) {
            // android 8.0引导
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("android.provider.extra.APP_PACKAGE", getPackageName());
        } else if (Build.VERSION.SDK_INT >= 21) {
            // android 5.0-7.0
            intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS");
            intent.putExtra("app_package", getPackageName());
            intent.putExtra("app_uid", getApplicationInfo().uid);
        } else {
            // 其他
            intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS");
            intent.setData(Uri.fromParts("package", getPackageName(), null));
        }
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);

    }
}
⑨ 源码

源码地址:PushDemo

0 人点赞