Android学习总结(八)———— 广播的最佳实践(实现强制下线功能)
一.基本概念
强制下线功能功能应该算是比较常见的了,很多应用程序都具备这个功能,比如你的QQ号或者微信号在别处登录了,就会将你强制挤下线。只需要在界面上弹出一个对话框,让用户无法进行任何其他的操作,必须要点击对话框中的确定按钮,然后回到登录界面即可。可是这样就存在着一个问题,因为我们被通知需要强制下线时可能正处于任何一个界面,难道需要在每一个界面都编写一个弹出对话框的逻辑吗?如果真的是这样想那么思维就偏远了,我们完全可以借助所学的广播知识来实现这一个功能。
二.代码之旅
强制下线功能需要先关闭所有的活动,然后回到登录界面,代码如下所示:
package com.nyl.nativebroadcast; import android.app.Activity; import java.util.ArrayList;
import java.util.List; public class ActivityCollector { public static List<Activity> activities = new ArrayList<>(); 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类作为所有活动的父类,代码如下所示:
package com.nyl.nativebroadcast; import android.app.Activity;
import android.os.Bundle; public class BaseActivity extends Activity{ @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ActivityCollector.addActivity(this);
} @Override
protected void onDestroy() {
super.onDestroy();
ActivityCollector.removeActivity(this);
}
}
创建一个登录界面的布局,代码如下所示:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_login"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:stretchColumns="1"> <TableRow> <TextView
android:layout_height="wrap_content"
android:text="账号:"/> <EditText
android:id="@+id/etAccount"
android:layout_height="wrap_content"
android:hint="请输入账号"/>
</TableRow> <TableRow> <TextView
android:layout_height="wrap_content"
android:text="密码:"/> <EditText
android:id="@+id/etPassword"
android:layout_height="wrap_content"
android:inputType="textPassword"/>
</TableRow> <TableRow>
<Button
android:id="@+id/btnLogin"
android:layout_height="wrap_content"
android:layout_span="2"
android:text="登录"/>
</TableRow> </TableLayout>
新建一个LoginActivity继承BaseActivity,代码如下所示:
package com.nyl.nativebroadcast; 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 etAccount;
private EditText etPassword;
private Button btnLogin; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_login);
initView(); //初始化布局
} private void initView() {
etAccount = (EditText) findViewById(R.id.etAccount);
etPassword = (EditText) findViewById(R.id.etPassword);
btnLogin = (Button) findViewById(R.id.btnLogin); btnLogin.setOnClickListener(this);
} @Override
public void onClick(View view) {
//获取用户输入的账号,密码的数据
String account = etAccount.getText().toString();
String password = etPassword.getText().toString();
//如果账号是123且密码是123,就登录成功
if (account.equals("123") && password.equals("123")){
Intent intent = new Intent(LoginActivity.this,MainActivity.class);
startActivity(intent);
finish();
}else {
Toast.makeText(LoginActivity.this,"账号或密码是无效的",Toast.LENGTH_SHORT).show();
}
}
}
同样在MainActivity继承BaseActivity,一个非常简单的MainActivity,不过多解释,代码如下所示:
package com.nyl.nativebroadcast; 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 BaseActivity implements View.OnClickListener { private Button btnOffline; @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnOffline = (Button) findViewById(R.id.btnOffline); btnOffline.setOnClickListener(this);
} @Override
public void onClick(View view) {
Intent intent = new Intent("com.nyl.nativebroadcast.ForceOfflineReceiver");
sendBroadcast(intent);
}
}
创建一个广播接收器,代码如下所示:
package com.nyl.nativebroadcast; import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.view.WindowManager; 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 dialogInterface, int i) {
/**
* 调用ActivityCollector的finishAll()方法来销毁掉所有的活动,
* 并重新启动LoginActivity这个活动
*/
ActivityCollector.finishAll();//销毁所以活动
Intent intent = new Intent(context,LoginActivity.class);
/**
* 在广播接收器里启动活动,因此一定要给Intent加入FLAG_ACTIVITY_NEW_TASK这个标准
*/
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
}
});
AlertDialog alertDialog = dialogBuilder.create();
//需要设置AlertDialog的类型,保证在广播接收器中可以正常弹出
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();
}
}
最后不要忘记在AndroidManifest.xml文件进行配置,代码如下所示:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.nyl.nativebroadcast"> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".LoginActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity"></activity> <receiver android:name=".ForceOfflineReceiver">
<intent-filter>
<action android:name="com.nyl.nativebroadcast.ForceOfflineReceiver"/>
</intent-filter>
</receiver>
</application> </manifest>
好了,现在尝试运行一下程序吧,首先进入到登录界面,并可以在这里输入账号和密码,如下图:
如果输入的账号是:123,密码是123,点击登录按钮就会进入到程序的主界面,如下图:
这时点击一下发送强制用户下线的广播按钮,就会发出一条强制下线的广播,ForceOfflineReceiver里收到这条广播后会弹出一个对话框提示用户已被强制下线,如下图所示:
这时用户将无法再对界面的任何元素进行操作,只能点击OK按钮,然后回重新回到登录界面。这样,强制下线功能就已经完整的实现了。
Android学习总结(八)———— 广播的最佳实践(实现强制下线功能)的更多相关文章
- Android学习笔记(十五)——实战:强制下线
//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 实现强制下线功能的思路也比较简单,只需要在界面上弹出一个对话框, 让用户无法进行任何其他操作, 必须要点击对话 ...
- Android学习之基础知识八—Android广播机制实践(实现强制下线功能)
强制下线功能算是比较常见的了,很多的应用程序都具备这个功能,比如你的QQ号在别处登录了,就会将你强制挤下线.实现强制下线功能的思路比较简单,只需要在界面上弹出一个对话框,让用户无法进行任何操作,必须要 ...
- 九、Android学习第八天——广播机制与WIFI网络操作(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 九.Android学习第八天——广播机制与WIFI网络操作 今天熟悉了An ...
- Android学习总结——强制下线功能(广播)
最近一口气买了好几本书,其中Android的<第一行代码>觉得真心不错,学到这个内容,顺便做个总结,加深印象. 强制下线的基本思想就是在界面上弹出一个对话框,让用户必须点击确定按钮跳转到登 ...
- android#boardcast#广播实现强制下线功能
参考自<第一行代码>——郭霖 强制下线功能需要先关闭掉所有的活动(Activity),然后回到登录界面.先创建一个ActivityCollector类用于管理所有的活动,代码如下所示: p ...
- Android广播时间——实现强制下线功能
目录 思路:强制下线功能需要先关闭掉所有的活动,然后回到登录界面. 步骤 1.关闭所有活动 2.创建BaseActivity类作为所有活动的父类,因为需要用ActivityCollector管理所有活 ...
- android: 实现强制下线功能
强制下线功能应该算是比较常见的了,很多的应用程序都具备这个功能,比如你的 QQ 号在别处登录了,就会将你强制挤下线.其实实现强制下线功能的思路也比较简单,只需要 在界面上弹出一个对话框,让用户无法进行 ...
- 《深入理解Android:Telephon原理剖析与最佳实践》学习笔记(系统框架)
Android智能手机的系统结构: 智能手机的硬件基本结构大多采用双处理器架构:主处理器和从处理器,主处理器主要运行开放式操作系统以及操作系统之上的应用,负责整个系统的控制,称之为AP,从处理 ...
- Android 学习笔记 BroadcastReceiver广播...
PS:不断提升自己,是件好事... 学习内容: 1.BroadcastReceiver的使用.. 2.通过BroadcastReceiver去启动Service... 1.BroadcastRecei ...
随机推荐
- bzoj2962
线段树+卷积 这个东西直接算不太好,但是合并两段结果却很方便,假设c[i]表示选i个数乘积的和,那么$a[i]=\sum_{j=0}^{i}{b[j]*c[i-j]}$ 线段树维护即可 #includ ...
- git add . 的时候遇到warning: LF will be replaced by CRLF inXXX 解决办法
$ git add . warning: LF will be replaced by CRLF in shop/Runtime/Cache/86bbc820c9ec1 d314a9c71cf5651 ...
- 【转】C/C++使用心得:enum与int的相互转换
https://blog.csdn.net/lihao21/article/details/6825722 如何正确理解enum类型? 例如: enum Color { red, white, blu ...
- opencv 笔记
http://docs.opencv.org/ opencv 2.x API opencv包含以下模块 core 基本数据机构 imgproc 图像处理方法 video 视频处理方法 ...
- C#字典常用技巧
说明 必须包含名空间System.Collection.Generic Dictionary里面的每一个元素都是一个键值对(由二个元素组成:键和值) 键必须是唯一的,而值不需要唯 ...
- 如何将linux主机接入到网络中
前言: 这篇博客的主旨就想文章题目说的那样,当我们拿到一台新的系统时,我们怎么实现让你的主机连接到网络中.配置网络就是给你的系统配置IP地址,子网掩码,网关以及DNS.也就是说配置好这几项计算机上网的 ...
- unity调android ios 浏览器 uniwebview2.1使用
uniwebview2.1使用 插件下载地址: http://download.csdn.net/detail/onafioo/9576200 示例 public class BrowserMgr { ...
- MongoDb 创建用户以及其他版本造成的一些问题
问题:require auth data to have schema version 3 but found 1 这是可以查看如下链接: http://stackoverflow.com/quest ...
- uoj#283. 直径拆除鸡(构造)
传送门 好神的构造题 vfk巨巨的题解 //minamoto #include<bits/stdc++.h> #define R register #define fp(i,a,b) fo ...
- 安装Net::OpenSSH 库
perl 离线安装 Net::OpenSSH 库 Net::OpenSSH 库 下载地址https://metacpan.org/pod/Net::OpenSSH 直接获取安装包命令 wget htt ...