利用信鸽推送实现登录后强制退出的功能
2015-09-23 12:31
716 查看
首先整理思路,先思考实现逻辑:
1.集成信鸽推送
2.实现自定义推送
3.在自定义推送中,接收推送的方法内启动强制退出功能。
思路逻辑很简单,但是实现起来就得一步一步做,先集成信鸽:
这里主要是参考官方开发文档即可
然后是实现自定义推送接受方,即自定义receiver
CustomReceiver.java
在注册文件中加入该Revceiver的静态注册代码:
然后注意这句代码:
由于目前是测试代码,所以我判断的是如果服务端发送的是“下线”的话,我就将该设备强制下线,在实际开发的过程中,其流程应当是
然后可以注意到,这里是启动了一个Service,然后利用Service进行下线操作的:
别忘了在配置文件中加入Service的注册:
在OnCreate方法中加入了启动强制下线的Receiver的代码:
这里要注意的是,不能直接用Context进行启动下线Receiver的操作,否则会报错:
必须利用getApplicationContext的方式动态注册ForceOfflineRecevier(),不能用静态注册的方式,否则也会报上边同样的错误(但是这里不知道为什么)
具体解决原因参照: http://blog.csdn.net/eimsteim/article/details/7220920
然后启动这个ForceOfflineReceiver,他的内容是这样的:
启动一个窗口,告诉用户你的账户在其他设备登录了,然后强制启动登录界面,并把之前启动的Activity都关闭掉,所以这里的关键类就是
ActivityCollector了:
功能自己看,然后就是在你的基类BaseActivity里加入对应的代码:
这样就把新启动的Activity管理起来了,然后在关闭的时候利用循环关闭对应的Activity即可了。
由于使用的是系统的弹出窗口,所以要在配置文件中加入这么一句权限:
来自为知笔记(Wiz)
1.集成信鸽推送
2.实现自定义推送
3.在自定义推送中,接收推送的方法内启动强制退出功能。
思路逻辑很简单,但是实现起来就得一步一步做,先集成信鸽:
这里主要是参考官方开发文档即可
然后是实现自定义推送接受方,即自定义receiver
CustomReceiver.java
/****/package com.dhcc.gpscarmanager_phone.CustomReceivers;import u.upd.l;import android.content.Context;import android.content.Intent;import com.dhcc.gpscarmanager_phone.CustomServices.ForceOfflineService;import com.dhcc.gpscarmanager_phone.Util.L;import com.tencent.android.tpush.XGPushBaseReceiver;import com.tencent.android.tpush.XGPushClickedResult;import com.tencent.android.tpush.XGPushRegisterResult;import com.tencent.android.tpush.XGPushShowedResult;import com.tencent.android.tpush.XGPushTextMessage;/***GpsCarManager_Phone com.dhcc.gpscarmanager_phone.CustomReceivers*CustomReceiver.java**@author:贾真*@date: 2015-8-21 上午9:26:30*/public class CustomReceiver extends XGPushBaseReceiver {/**(non-Javadoc)**@see*com.tencent.android.tpush.XGPushBaseReceiver#onDeleteTagResult(android*.content.Context, int, java.lang.String)*/@Overridepublic void onDeleteTagResult(Context context, int arg1, String arg2) {// TODO Auto-generated method stub}/**(non-Javadoc)**@see*com.tencent.android.tpush.XGPushBaseReceiver#onNotifactionClickedResult*(android.content.Context, com.tencent.android.tpush.XGPushClickedResult)*/@Overridepublic void onNotifactionClickedResult(Context context,XGPushClickedResult arg1) {// TODO Auto-generated method stub}/**(non-Javadoc)**@see*com.tencent.android.tpush.XGPushBaseReceiver#onNotifactionShowedResult*(android.content.Context, com.tencent.android.tpush.XGPushShowedResult)*/@Overridepublic void onNotifactionShowedResult(Context context,XGPushShowedResult result) {// TODO Auto-generated method stub// 这里是测试代码,在接受到“下线”这两个字后,接收通知的应用强行下线if ("下线".equals(result.getContent())) {L.e(result.getContent());context.getApplicationContext().startService(new Intent(context.getApplicationContext(), ForceOfflineService.class));}}/**(non-Javadoc)**@see*com.tencent.android.tpush.XGPushBaseReceiver#onRegisterResult(android*.content.Context, int, com.tencent.android.tpush.XGPushRegisterResult)*/@Overridepublic void onRegisterResult(Context context, int arg1,XGPushRegisterResult arg2) {// TODO Auto-generated method stub}/**(non-Javadoc)**@see*com.tencent.android.tpush.XGPushBaseReceiver#onSetTagResult(android.content*.Context, int, java.lang.String)*/@Overridepublic void onSetTagResult(Context context, int arg1, String arg2) {// TODO Auto-generated method stub}/**(non-Javadoc)**@see*com.tencent.android.tpush.XGPushBaseReceiver#onTextMessage(android.content*.Context, com.tencent.android.tpush.XGPushTextMessage)*/@Overridepublic void onTextMessage(Context context, XGPushTextMessage message) {// TODO Auto-generated method stub}/**(non-Javadoc)**@see*com.tencent.android.tpush.XGPushBaseReceiver#onUnregisterResult(android*.content.Context, int)*/@Overridepublic void onUnregisterResult(Context context, int arg1) {// TODO Auto-generated method stub}}
在注册文件中加入该Revceiver的静态注册代码:
<receiver android:name="com.dhcc.gpscarmanager_phone.CustomReceivers.CustomReceiver" ><intent-filter><!-- 接收消息透传 --><action android:name="com.tencent.android.tpush.action.PUSH_MESSAGE" /><!-- 监听注册、反注册、设置/删除标签、通知被点击等处理结果 --><action android:name="com.tencent.android.tpush.action.FEEDBACK" /></intent-filter></receiver>
然后注意这句代码:
if ("下线".equals(result.getContent())) {L.e(result.getContent());context.getApplicationContext().startService(new Intent(context.getApplicationContext(), ForceOfflineService.class));}
由于目前是测试代码,所以我判断的是如果服务端发送的是“下线”的话,我就将该设备强制下线,在实际开发的过程中,其流程应当是
用户登录-> 判断当前的Token与数据库中存储的Token是否一致-> 如果不一致,则对数据库中的Token的用户发送约定好的下线通知,可以是参数也可以是字符串-> 手机端接到下线通知后,强制下线-> 服务端将新的Token保存到数据库中去,老的Token销毁
然后可以注意到,这里是启动了一个Service,然后利用Service进行下线操作的:
/****/package com.dhcc.gpscarmanager_phone.CustomServices;import com.dhcc.gpscarmanager_phone.CustomReceivers.ForceOfflineReceiver;import com.dhcc.gpscarmanager_phone.Util.L;import u.upd.l;import android.app.Service;import android.content.Intent;import android.content.IntentFilter;import android.os.IBinder;import android.util.Log;/***GpsCarManager_Phone com.dhcc.gpscarmanager_phone.CustomServices*ForceOfflineService.java**@author:贾真*@date: 2015-8-21 上午10:03:59*/public class ForceOfflineService extends Service {private static final String TAG = "ForceOfflineService";ForceOfflineReceiver forceOfflineReceiver;@Overridepublic void onCreate() {Log.i(TAG, "ExampleService-onCreate");super.onCreate();IntentFilter intentFilter=new IntentFilter();intentFilter.addAction("com.dhcc.AppOffline");forceOfflineReceiver=new ForceOfflineReceiver();registerReceiver(forceOfflineReceiver, intentFilter);Intent intent =new Intent("com.dhcc.AppOffline");getApplicationContext().sendBroadcast(intent);}@Overridepublic void onStart(Intent intent, int startId) {Log.i(TAG, "ExampleService-onStart");super.onStart(intent, startId);}@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {//执行文件的下载或者播放等操作Log.i(TAG, "ExampleService-onStartCommand");/**这里返回状态有三个值,分别是:*1、START_STICKY:当服务进程在运行时被杀死,系统将会把它置为started状态,但是不保存其传递的Intent对象,之后,系统会尝试重新创建服务;*2、START_NOT_STICKY:当服务进程在运行时被杀死,并且没有新的Intent对象传递过来的话,系统将会把它置为started状态,*但是系统不会重新创建服务,直到startService(Intent intent)方法再次被调用;*3、START_REDELIVER_INTENT:当服务进程在运行时被杀死,它将会在隔一段时间后自动创建,并且最后一个传递的Intent对象将会再次传递过来。*/return super.onStartCommand(intent, flags, startId);}@Overridepublic IBinder onBind(Intent intent) {Log.i(TAG, "ExampleService-onBind");return null;}@Overridepublic void onDestroy() {Log.i(TAG, "ExampleService-onDestroy");super.onDestroy();unregisterReceiver(forceOfflineReceiver);}}
别忘了在配置文件中加入Service的注册:
<!-- 强制下线服务 --><service android:name="com.dhcc.gpscarmanager_phone.CustomServices.ForceOfflineService"/
在OnCreate方法中加入了启动强制下线的Receiver的代码:
IntentFilter intentFilter = new IntentFilter();intentFilter.addAction("com.dhcc.AppOffline");forceOfflineReceiver = new ForceOfflineReceiver();registerReceiver(forceOfflineReceiver, intentFilter);Intent intent = new Intent("com.dhcc.AppOffline");getApplicationContext().sendBroadcast(intent);
这里要注意的是,不能直接用Context进行启动下线Receiver的操作,否则会报错:
IntentReceiver components are not allowed to register to receive intents
必须利用getApplicationContext的方式动态注册ForceOfflineRecevier(),不能用静态注册的方式,否则也会报上边同样的错误(但是这里不知道为什么)
具体解决原因参照: http://blog.csdn.net/eimsteim/article/details/7220920
然后启动这个ForceOfflineReceiver,他的内容是这样的:
/****/package com.dhcc.gpscarmanager_phone.CustomReceivers;import com.baidu.navisdk.util.common.Stopwatch;import com.dhcc.gpscarmanager_phone.CustomServices.ForceOfflineService;import com.dhcc.gpscarmanager_phone.CustomView.ActivityCollector;import com.dhcc.gpscarmanager_phone.Module.Welcome.WelcomPage.LoginActivity;import android.app.AlertDialog;import android.content.BroadcastReceiver;import android.content.Context;import android.content.DialogInterface;import android.content.DialogInterface.OnClickListener;import android.content.Intent;import android.view.WindowManager;/***GpsCarManager_Phone com.dhcc.gpscarmanager_phone.CustomReceivers*ForceOfflineReceiver.java**@author:贾真*@date: 2015-8-21 上午9:45:38*/public class ForceOfflineReceiver extends BroadcastReceiver {/**(non-Javadoc)**@see android.content.BroadcastReceiver#onReceive(android.content.Context,*android.content.Intent)*/@Overridepublic void onReceive(final Context context, Intent intent) {// TODO Auto-generated method stubintent = new Intent(context, ForceOfflineService.class);context.stopService(intent);AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);dialogBuilder.setTitle("已下线");dialogBuilder.setMessage("您的账户已在另一个设备登录,请尝试重新登陆");dialogBuilder.setCancelable(false);dialogBuilder.setPositiveButton("登 录", new OnClickListener() {@Overridepublic void onClick(DialogInterface arg0, int arg1) {// TODO Auto-generated method stubActivityCollector.finishAll();Intent intent = new Intent(context, LoginActivity.class);intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);context.startActivity(intent);}});AlertDialog alertDialog = dialogBuilder.create();alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);alertDialog.show();}}
启动一个窗口,告诉用户你的账户在其他设备登录了,然后强制启动登录界面,并把之前启动的Activity都关闭掉,所以这里的关键类就是
ActivityCollector了:
/****/package com.dhcc.gpscarmanager_phone.CustomView;import java.util.ArrayList;import java.util.List;import android.app.Activity;/***GpsCarManager_Phone*com.dhcc.gpscarmanager_phone.CustomView*ActivityCollector.java*@author:贾真*@date: 2015-8-21上午9:09:48*/public class ActivityCollector {public static List<Activity> activities=new ArrayList<Activity>();public static void addActivity(Activity activity){activities.add(activity);}public static void removeActivity(Activity activity){activities.remove(activity);}public static void finishAll(){for(Activity activity:activities){if(activity.isFinishing()){activity.finish();}}}}
功能自己看,然后就是在你的基类BaseActivity里加入对应的代码:
@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);ActivityCollector.addActivity(this);}protected void onDestroy(){super.onDestroy();ActivityCollector.removeActivity(this);}
这样就把新启动的Activity管理起来了,然后在关闭的时候利用循环关闭对应的Activity即可了。
由于使用的是系统的弹出窗口,所以要在配置文件中加入这么一句权限:
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
来自为知笔记(Wiz)
相关文章推荐
- 使用工具类时尽量使用私有的无参构造函数
- C++多线程定时器完整实现
- 随诊医生1---启动流程分析
- 在MyEClipse中的console显示sql语句
- #研发解决方案#基于Apriori算法的Nginx+Lua+ELK异常流量拦截方案
- A possible solution of MySQL workbench cannot connect to local host error on MAC
- java常用设计模式
- Cookie和Session机制
- Chrome浏览器扩展开发系列之十:桌面通知Notification
- 创建对象的几种方式
- *Unique Binary Search Tree
- Jesus Is Here
- app后端开发五:Xampp下配置https服务
- Codeforces Round #321 (Div. 2) E. Kefa and Watch 线段树hash
- hadoop学习笔记(九)——hadoop日志分析系统
- 关联规则(一)Apriori算法
- SOAP Web 服务介绍
- HTML <form> 标签的 enctype 属性
- 服务器如何打开ping命令
- 全面讲解Tomcat下SSL证书的配置(三)