实现推送接收并在指定页面中处理(涉及推送、service)
需求来源:
在观察QQ以及其他APP在一些场景的处理: APP 在运行期间,不定时的一条推送,然APP 会相应的在当前页面弹出当前信息。
逻辑难点:
app 哪个页面在栈的最顶部不可控。 从开一个栈并不能达到这种需求。
实现过程: 我曾经用过这种方法,在广播接受着中使用:
此方法还需在配置文件中 添加 :uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
-- 弹出系统对话框的权限是有问题的,比如小米就禁用。 并且这个权限也是无法正常签名打包的,为何在此不做深究。
这种 方式 可以实现一些简单的需求。但问题又来了:
比如: APP 重新打开先过广告页,在广告页 dialog 就已经提示出来了,并且因为它是系统级别的,在dialog 显示的时候 你的App 已然执行着此操作: 广告页跳转主界面。
这样 这个对话框的显示流程 和触发时机 就已经错误了。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Service Or Receiver
在整理思路之后 换一种思路: 在接收推送之后,是否可开启一个本地服务, 这个本地服务 过一秒发一次广播, 而在我需要场景弹框的页面 注册这个广播,这样可实现需求,并且在不同页面 接收,也可以做不同的操作,比如:跳转、刷新、关闭。
好了 啰嗦这么多:
首先 自定义广播接收者: 在次代码 以 Jpush通知 为例 。没实现推送的小伙伴先去Jpush官网看下 地址 :https://www.jiguang.cn/push
**
* Jpush 自定义广播接收
*/
public class MyJpushReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (JPushInterface.ACTION_REGISTRATION_ID.equals(intent.getAction())) {
// "JPush用户注册成功"
} else if (JPushInterface.ACTION_MESSAGE_RECEIVED.equals(intent.getAction())) {
//"接受到推送下来的自定义消息"
} else if (JPushInterface.ACTION_NOTIFICATION_RECEIVED.equals(intent.getAction())) {
//"接受到推送下来的通知"
receivingNotification(context, bundle);
} else if (JPushInterface.ACTION_NOTIFICATION_OPENED.equals(intent.getAction())) {
//"用户点击打开了通知"
} else {
//"Unhandled intent - "
}
}
private void receivingNotification(final Context context, Bundle bundle) {
String title = bundle.getString(JPushInterface.EXTRA_NOTIFICATION_TITLE);
Log.d("Bruce", " title : " + title);
String message = bundle.getString(JPushInterface.EXTRA_ALERT);
Log.d("Bruce", "message : " + message);
final String extras = bundle.getString(JPushInterface.EXTRA_EXTRA);
Log.d("Bruce", "extras : " + extras);
try {
JSONObject jsonObject =new JSONObject(extras);
String orderNo = jsonObject.getString("orderNo");
MyJpushOrderBean orderBean = new MyJpushOrderBean(title,message,orderNo);
Intent intent = new Intent(context,MyBroatService.class);
intent.putExtra("JpushMsg",orderBean);
context.startService(intent);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
接收推送通知信息之后开启服务:
**
* 接收jpush 信息 开启服务 发送本地广播
*/
public class MyBroatService extends IntentService {
private MyJpushOrderBean jpushMsg;
private Intent it;
public String RECEIVER_ACTION = "JpushMsg_hint";
private boolean isSend = true;
public MyBroatService() {
super("MyBroatService");
}
private void StartBroatReceiver() {
try {
while (isSend) {
Log.d("service", "----------------一次次----------------");
sendBroadcast(it);
Thread.sleep(1000);
}
} catch (InterruptedException e) {
}
}
@Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
jpushMsg = ((MyJpushOrderBean) intent.getSerializableExtra("JpushMsg"));
Log.d("Bruce", "----------service- 开启-------------" + jpushMsg.toString());
it = new Intent(RECEIVER_ACTION);
it.putExtra("JpushInfo", jpushMsg);
StartBroatReceiver();
}
}
@Override
public void onDestroy() {
isSend = false;
super.onDestroy();
}
}
然后在 BaseActivity 中 注册广播接收者:
/**
* 父类 广播接收
* 接收提示 操作
* 管理类
*/
public class BaseActivity extends Activity {
private String RECEIVER_ACTION = "JpushMsg_hint";
private AlertDialog.Builder builder = null;
private AlertDialog dialog = null;
private MyHttpUtils httpUtils;
private boolean isReceive = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
RegiListener();
}
private void RegiListener() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(RECEIVER_ACTION);
registerReceiver(broadcastReceiver, intentFilter);
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(RECEIVER_ACTION)) {
if (isReceive) {
isReceive = false;
MyJpushOrderBean orderBean = (MyJpushOrderBean) intent.getSerializableExtra("JpushInfo");
Log.d("Bruce", "-----------------我是广播收到的 信息------------" + orderBean.toString());
ShowHintDialog(orderBean);
StopIntentService();
}
}
}
};
private void StopIntentService() {
Intent intent = new Intent(this, MyBroatService.class);
stopService(intent);
Log.d("Bruce", "--------服务停止了------------");
}
private void ShowHintDialog(final MyJpushOrderBean orderBean) {
builder = new AlertDialog.Builder(this);
builder.setTitle(orderBean.getTitle());
builder.setMessage(orderBean.getMessage());
builder.setCancelable(false);
builder.setNegativeButton("不要了", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
recycleDialog();
}
});
builder.setPositiveButton("立即前往", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
StartOrder(orderBean.getExtras());
}
});
dialog = builder.show();
}
private void StartOrder(final String extras) {
recycleDialog();
httpUtils = MyHttpUtils.getInstance();
Map<String, String> map = new HashMap<>();
map.put("orderNo", extras);
httpUtils.asyncGetOrInfo(UrlUtils.GETCARIMGINFO, this, false, null, map, new MyInterFaceUtils.HttpCallBack() {
@Override
public void onError(Request request, IOException e) {
}
@Override
public void onSuccess(Request request, String result) {
Log.d("Bruce", "------------推送 拿数据-------------" + result + "--订单号----" + extras);
Gson gson = new Gson();
GetCarReviewInfoBean getCarReviewInfoBean = gson.fromJson(result, GetCarReviewInfoBean.class);
OrderInfo data = getCarReviewInfoBean.data;
ChangeInfoOfStart(data);
}
});
}
/***
* 子类页面重写此方法
* 不同页面可实现不同操作
* @param data
*/
public void ChangeInfoOfStart(OrderInfo data) {
}
public void recycleDialog() {
if (dialog != null) {
if (dialog.isShowing()) {
dialog.dismiss();
}
dialog = null;
}
builder = null;
}
@Override
protected void onDestroy() {
recycleDialog();
httpUtils = null;
unregisterReceiver(broadcastReceiver);
super.onDestroy();
}
}
以上为主要逻辑代码。还有 对IntentService 不太熟悉的 小伙伴可以去谷歌一下。
IntentService是继承于Service并处理异步请求的一个类。具体有很多博客写得很透彻,在此就不班门弄斧了。
下章会发项目实战中 Recyclerview 根据type 加载复杂布局的简单示例。
转载请注明原创: http://blog.****.net/qq_34062297/article/details/77772442