Android--Android中使用广播BroadcastReceiver进行用户强制下线功能
2017-03-16 20:14
239 查看
利用广播BroadcastReceiver实现登录强制下线功能
在这里面登录界面里面的用户名和密码为默认的“admin””123456” 可以在LoginActivity里面进行修改,该例子只是简单的说明怎么样BroadcastReceiver进行强制性的下线。原理
在应用程序中经常会遇到强制下线的情况,比如qq在别处登录,本机的你就被强制下线了。其实强制下线的原理很简单,就是弹出一个对话框让你没办法进行去他的操作,只能点击对话框的“确定”按钮进行重新登录验证身份,但是我们被通知需要强制下线的时候可能处于任何一个界面,肯定不能在没一个界面都写一个对话框。此时就用到了广播。在本例中点击button后触发广播,然后提交给ForceOfflineReceiver类进行接受广播,进行销毁所有的活动,完成用户强制性下线1、首先创建一个Activity管理类“ActivityCollector”
在这里面进行Activity的添加 删除 和销毁所有,能够在后面强制下线时,销毁所有的Activity,只显示一个对话框package com.example.chencong.broadcastbestpractive; import android.app.Activity; import java.util.ArrayList; import java.util.List; /** * Created by chencong on 2017/3/16. */ public class ActivityCollector { /** * 创建一个Activity类来管理所有的活动 */ public static List<Activity> activities = new ArrayList<Activity>(); /** * 定义泛型数组activities 添加activity活动的方法addActivity * @param activity */ public static void addActivity(Activity activity){ activities.add(activity); } /** * 移除activity活动的方法removeActivity * @param activity */ public static void removeActivity(Activity activity){ activities.remove(activity); } /** * 遍历所有活动将其停止完成 */ public static void findAll(){ for (Activity activity: activities) { if (!activity.isFinishing()){ activity.finish(); } } } }
2、然后创建一个基类BaseActivity
之所以创建这个基类,是为了方便对所有的Activity进行管理(添加 删除 销毁所有),因为在后面创建的Activity是继承此Activity的,能够保证在创建的时候就已添加到ActivityCollector中。package com.example.chencong.broadcastbestpractive; import android.app.Activity; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; /** * 定义父类BaseActivity */ public class BaseActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //创建活动时,将其加入管理器中 ActivityCollector.addActivity(this); } @Override protected void onDestroy() { super.onDestroy(); //销毁活动时,将其从管理器中移除 ActivityCollector.removeActivity(this); } }
3、一个简单的登录界面
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <EditText android:id="@+id/account" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="输入账户"/> <EditText android:id="@+id/password" android:layout_width="match_parent" android:layout_height="wrap_content" android:inputType="textPassword" android:hint="输入密码"/> <Button android:id="@+id/login" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="登录"/> </LinearLayout>
4、为login.xml
编写活动
创建一个Activity继承BaseActivity,命名为LoginActivity.java,在这里使用的账号和密码为默认的“admin”“123456”package com.example.chencong.broadcastbestpractive; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class LoginActivity extends BaseActivity implements View.OnClickListener { private EditText accountEdit; private EditText passwordEdit; private Button loginButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.login); //初始化 注册控件 accountEdit = (EditText)findViewById(R.id.account); passwordEdit = (EditText)findViewById(R.id.password); loginButton = (Button)findViewById(R.id.login); //登录按钮的点击事件 loginButton.setOnClickListener(this); } @Override public void onClick(View v) { String account = accountEdit.getText().toString(); String password = passwordEdit.getText().toString(); //在这里进行默认账户为 admin 密码为123456 if (account.equals("admin") && password.equals("123456")){ //登录成功后 进入MainActivity 并且在这里面提供强制下线的功能 Intent intent = new Intent(LoginActivity.this,MainActivity.class); startActivity(intent); finish(); }else { Toast.makeText(LoginActivity.this,"账户和密码不匹配",Toast.LENGTH_SHORT).show(); } } }
当从LoginActivity.java中登录进去后会进入到MainActivity中,在这里页面中只有一个Button,当然登录进去之后,想实现怎样的功能由你自己去实现了。
5、在MainActivity中进行强制下线
package com.example.chencong.broadcastbestpractive; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button forceOffline = (Button)findViewById(R.id.force_offline); /**点击按钮 发送一个"com.example.chencong.broadcastbestpractive.FORCE_OFFLINE" *强制下线的广播 然后在接受这条广播的类(接收器)中进行强制下线的功能 * 在这里新建一个广播接收器 ForceOfflineReceiver 类 来继承 BroadcastReceiver */ forceOffline.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent("com.example.chencong.broadcastbestpractive.FORCE_OFFLINE"); sendBroadcast(intent); } }); } }
布局很简单啦,就一个Button就行了
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.chencong.broadcastbestpractive.MainActivity"> <!--<TextView--> <!--android:layout_width="wrap_content"--> <!--android:layout_height="wrap_content"--> <!--android:text="Hello World!" />--> <!--提供强制下线的功能--> <Button android:id="@+id/force_offline" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="强制下线账户"/> </RelativeLayout>
不过这里有个重点,在Button的点击事件中,发送了一条广播,广播值为
com.example.chencong.broadcastbestpractive.FORCE_OFFLINE,这条广播就是用于通知程序,将用户强制下线的。
也就是说强制用户下线的功能并不是写在MainActivity中的,而是写在这条广播的广播接收器中,这样强制下线就不会依赖任何界面,不管是在程序的任何地方,只要一发出这样的一条广播,就可以完成强制下线了。
对,现在就来创建一个广播的接收器,新建一个ForceOfflineReceiver类继承BroadcastReceiver
6、新建一个ForceOfflineReceiver类继承BroadcastReceiver
package com.example.chencong.broadcastbestpractive; import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.view.WindowManager; /** * Created by chencong on 2017/3/16. */ public class ForceOfflineReceiver extends BroadcastReceiver { @Override public void onReceive(final Context context, Intent intent) { //构建一个对话框 AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context); dialogBuilder.setTitle("警告"); dialogBuilder.setMessage("你的账号被强制下线,请重新登录"); dialogBuilder.setCancelable(false); //并且对话框不可被取消 //给对话框注册确定按钮 dialogBuilder.setPositiveButton("重新登录", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { ActivityCollector.findAll(); //销毁所有活动 Intent i = new Intent(context,LoginActivity.class); i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //在广播接收器中启动活动 因此需要加上这个标志 context.startActivity(i); //重新启动登录界面 } }); AlertDialog alertDialog = dialogBuilder.create(); //设置AlertDialog 的类型 保证广播接收器中可以正常的弹出 //系统级别的对话框 因此需要在AndroidManifest中进行声明 alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); alertDialog.show(); } }
在onReceiver()方法中,首先使用AlertDialog.Builder构建一个对话框,并且调用setCancelable()方法将对话框设置为不可取消,否则用户按一下返回键就能够关闭对话框就能够继续使用程序了,然后用setPositiveButton()方法为对话框注册确定按钮,并且当用户点击确定按钮时候就调用之前我们创建的ActivityCollector这个类的finishAll()方法类销毁所有的Activity,并且重新启动LoginActivity进行登录。
并且在广播接收器中启动活动时候,一定要给Intent的对象加入FLAG_ACTIVITY_NEW_TASK这个标志,最后将对话框的类型设置为系统级别,否在无法在广播接收器中进行弹出。
7、最后的配置
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.chencong.broadcastbestpractive"> <!--进行权限配置--> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".LoginActivity" android:label="@string/app_login"> <intent-filter android:label="@string/app_name"> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name=".BaseActivity" /> <activity android:name=".MainActivity" android:label="@string/app_mian"/> <receiver android:name=".ForceOfflineReceiver"> <intent-filter> <action android:name="com.example.chencong.broadcastbestpractive.FORCE_OFFLINE"/> </intent-filter> </receiver> </application> </manifest>
前面将对话框设置为系统级别的,因此在这里需要进行声明。然后对广播进行注册,并且指定为哪一个广播。
8、运行看看效果啦
登录界面,输入账户 密码登录进去后 进行点击下线
9、最后附上源码
项目地址:github传送门apk下载:github传送门
喜欢就去做,想到就去做!做自己喜欢的事情 ----by chencong
相关文章推荐
- 小白求助!!!请问Android 使用BroadCast实现强制下线功能,点击强制下线按钮,程序直接奔溃是为什么啊??
- Android 使用BroadCast实现强制下线功能
- 实现记住密码功能(SharedPreferences的使用)与强制下线
- struts做的记录当前在线用户,不可重复登录,并且可对在线用户进行强制下线
- Android学习总结——强制下线功能(广播)
- Android使用广播(BroadCast)实现强制下线的方法
- Android 实现强制下线功能
- 如何使用Android手机进行功能调试?
- Android开发中强制下线功能实现
- Anroid-强制用户下线功能
- Adroid中广播接收者的使用,实现强制下线功能
- Android开发之实现强制下线功能(下)
- 广播实践--强制用户下线功能
- android实现强制下线功能
- Android模拟强制下线通知功能实例代码
- 广播实践--强制用户下线功能
- Android笔记(二十六)广播实践——实现强制下线功能
- Android 强制下线功能 第一行代码
- android: 实现强制下线功能
- 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化