`

利用广播实现强制下线功能

阅读更多
      最近一口气买了8本书,其中Android方面的书就买了一本----《第一行代码》第2版,litepal的作者,本人一直在使用litepal开发项目,所以买android只认准这个:)

     强制下线的基本思想就是在界面上弹出一个对话框,让用户必须点击确定按钮跳转到登录界面,这里就有一个问题,通知强制下线时可能处于任何一个界面,我们总不能在每个界面都要实现弹出对话框的逻辑,所以这里可以利用广播来实现。

  首先强制下线需要关闭所有活动,然后回到登录界面,所以我们这里创建一个ActivityCollector集合类来管理所有的活动,代码如下:
package com.example.xch.broadcastpractice;

import android.app.Activity;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by xch on 2016/12/15.
 */

public class ActivityCollector {
    public static List<Activity> activityList=new ArrayList<Activity>();
    //将Activity加入集合
    public static void addActivity(Activity activity){
        activityList.add(activity);
    }
    //将Activity移除集合
    public static void removeActivity(Activity activity){
        activityList.remove(activity);
    }
    //关闭所有Activity
    public static void finishAll(){
        for(Activity activity:activityList){
            if(!activity.isFinishing()){
                activity.finish();
            }
        }
    }
}

  然后创建BaseActivity类作为所有活动的父类:这个类继承自Activity,然后重写onCreate()方法调用ActivityCollector的addActivity()方法将当前正在创建的活动添加到活动管理器中,同理在onDestroy()中移除活动。
package com.example.xch.broadcastpractice;

import android.app.Activity;
import android.os.Bundle;

/**
 * 作为所有活动的父类
 * Created by xch on 2016/12/15.
 */

public class BaseActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ActivityCollector.addActivity(this);//将Activity加入集合
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        ActivityCollector.removeActivity(this);//将Activity从集合移除
    }
}

现在我们就可以随时随地将所有活动移除了。

下面我们模拟一个简单的登录功能,首先创建登录布局:activity_login.xml
<LinearLayout 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:gravity="center_horizontal"
    android:orientation="vertical"
    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.xch.broadcastpractice.LoginActivity">

    <!-- Login progress -->
    <ProgressBar
        android:id="@+id/login_progress"
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="8dp"
        android:visibility="gone" />

    <ScrollView
        android:id="@+id/login_form"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:id="@+id/email_login_form"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <AutoCompleteTextView
                    android:id="@+id/username"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/prompt_email"
                    android:inputType="textEmailAddress"
                    android:maxLines="1"
                    android:singleLine="true" />

            </android.support.design.widget.TextInputLayout>

            <android.support.design.widget.TextInputLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content">

                <EditText
                    android:id="@+id/password"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:hint="@string/prompt_password"
                    android:imeActionId="@+id/login"
                    android:imeActionLabel="@string/action_sign_in_short"
                    android:imeOptions="actionUnspecified"
                    android:inputType="textPassword"
                    android:maxLines="1"
                    android:singleLine="true" />

            </android.support.design.widget.TextInputLayout>

            <Button
                android:id="@+id/login"
                style="?android:textAppearanceSmall"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_marginTop="16dp"
                android:text="@string/action_sign_in"
                android:textStyle="bold" />

        </LinearLayout>
    </ScrollView>
</LinearLayout>

接下来编写登录界面的活动,新建LoginActivity继承自BaseActivity,代码如下:
package com.example.xch.broadcastpractice;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

/**
 * Created by xch on 2016/12/15.
 */

public class LoginActivity extends BaseActivity {
    private TextView usename;
    private EditText password;
    private Button login;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        usename= (TextView) findViewById(R.id.username);
        password= (EditText) findViewById(R.id.password);
        login= (Button) findViewById(R.id.login);
        login.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String account=usename.getText().toString();
                String pwd=password.getText().toString();
                if(account.equals("xch_yang@126.com")&&pwd.equals("123456")){
                    Intent intent=new Intent(LoginActivity.this,MainActivity.class);
                    startActivity(intent);
                    finish();
                }else{
                    Toast.makeText(LoginActivity.this,"用户名或密码错误!",Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

这里直接使用一个默认值,如果登录成功就跳到MainActivity,否则就登录失败。所以我们在MainActivity中添加强制下线的功能。activity_main:
<?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:id="@+id/activity_main"
    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.xch.broadcastpractice.MainActivity">

    <TextView
        android:text="恭喜你,登录成功!"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="119dp"
        android:layout_marginStart="119dp"
        android:layout_marginTop="15dp"
        android:id="@+id/textView"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <Button
        android:text="强制下线"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="35dp"
        android:id="@+id/force_offline"
        android:layout_below="@+id/textView"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginLeft="105dp"
        android:layout_marginStart="105dp" />
</RelativeLayout>

MainActivity.class:
package com.example.xch.broadcastpractice;

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 {
    private Button force_offline;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        force_offline=(Button) findViewById(R.id.force_offline);
        force_offline.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent("com.example.FORCE_OFFLINE");//发送广播,在广播接收器里实现强制下线的逻辑
                sendBroadcast(intent);
            }
        });
    }
}

这里很简单,就是在按钮事件里发送了一条广播,然后在广播接收器里实现强制下线的逻辑。接下来创建广播接收器ForceOfflineReceiver继承自Broadcast。
package com.example.xch.broadcastpractice;

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 xch on 2016/12/15.
 */

public class ForceOfflineReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(final Context context, Intent intent) {
        //实现强制下线的逻辑
        AlertDialog.Builder dialogBuilder=new AlertDialog.Builder(context);//使用AlertDialog.Builder构建一个对话框
        dialogBuilder.setTitle("warning");
        dialogBuilder.setMessage("你已经被强制下线,请重新登录");
        dialogBuilder.setCancelable(false);//将对话框设置为不可取消
        dialogBuilder.setPositiveButton("确定", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                ActivityCollector.finishAll(); //销毁所有活动
                Intent intent=new Intent(context,LoginActivity.class);
                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();
    }
}

  这里要注意的是,由于我们是在广播中启动活动LoginActivity,因此一定要给Intent加上FLAG_ACTIVITY_NEW_TASK标志。最后还要把对话框的类型设置成TYPE_SYSTEM_ALERT,不然它将无法在广播接受器中弹出。

   接下来对AndroidManifest.xml进行配置:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.xch.broadcastpractice">

    <!-- To auto-complete the email text field in the login form with the user's emails -->
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.READ_PROFILE" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />

    <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.example.FORCE_OFFLINE"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>

  由于我们在广播接收器里弹出了一个系统级别的对话框,因此要声明权限:android.permission.SYSTEM_ALERT_WINDOW,最后别忘了注册广播ForceOfflineReceiver和活动LoginActivity。

原帖:
http://www.cnblogs.com/xch-yang/p/6182848.html
分享到:
评论

相关推荐

    安卓初学者教程-利用广播实现强制下线功能实例

    本教程针对初学者,将深入讲解如何利用广播实现强制下线功能,确保用户安全和应用的稳定运行。 首先,我们需要理解广播的基本概念。在Android系统中,BroadcastReceiver是接收并处理广播的类。当你注册了一个...

    Broadcast广播实现强制下线功能

    在“Broadcast广播实现强制下线功能”这个主题中,我们将深入探讨如何利用Broadcast来实现在用户未正常操作时强制结束应用,确保系统的稳定性和安全性。 首先,我们需要了解BroadcastReceiver,它是接收广播消息的...

    andorid 广播的最佳实践-实现强制下线功能

    本文将深入探讨如何利用Android广播最佳实践来实现强制下线功能,帮助开发者更好地理解和应用这一关键机制。 一、Android广播基础知识 1. 系统广播:由Android系统触发,如设备开机、网络状态变化等。 2. 自定义...

    Android之简单的登录界面的实现、使用 AlertDialog和全局广播实现被强制下线功能、自定义一个带有清除按钮的EditText

    3. **全局广播实现被强制下线功能**:全局广播是Android系统的一种通信机制,可以跨进程传递消息。当服务器通知用户需要强制下线时,可以通过发送一个全局广播来接收此信息。首先,注册一个BroadcastReceiver来监听...

    Android中使用广播接收者组件实现简单强迫用户下线功能

    本教程将详细解析如何利用广播接收者来实现一个简单的强制用户下线功能。 首先,理解广播接收者的概念。在Android中,广播是一种全局的消息传递机制,任何应用都可以发送广播,其他应用可以注册广播接收者来监听并...

    android使用广播实现账号异常强制下线功能demo

    本示例“android使用广播实现账号异常强制下线功能demo”主要展示了如何利用广播来检测并处理账号异常情况,确保应用的安全性和用户体验。下面我们将深入探讨相关知识点。 首先,我们了解什么是Android广播。广播是...

    使用广播机制仿制QQ强制下线功能

    在这个“使用广播机制仿制QQ强制下线功能”的场景中,我们主要探讨如何利用BroadcastReceiver来模拟类似QQ的用户强制下线操作,并且这个过程会涉及到用户界面的弹窗提示。 首先,我们需要创建一个BroadcastReceiver...

    BroadcastBestPractice强制下线demo

    总的来说,BroadcastBestPractice强制下线demo提供了一个实用的示例,展示了如何利用Android的BroadcastReceiver和自定义的Activity管理类来实现用户强制下线的功能。这对于大型应用的会话管理和用户体验优化具有很...

    安卓课程作业 实验一广播强制下线 实验二内容提供器 实验三服务下载 AS

    首先,我们来看“实验一:广播强制下线”。广播接收者(BroadcastReceiver)在安卓系统中扮演着消息传递者的角色。它可以监听系统或应用发送的广播意图(Intent),并在接收到特定广播时执行相应的操作。例如,当...

    强制当前账号下线

    这个项目可能包含源代码、配置文件和相关文档,帮助开发者理解并实践强制下线的实现步骤。通过学习和分析这个项目,开发者可以了解如何在自己的应用中实现类似的机制,增强系统的安全性。 总的来说,"强制当前账号...

    Android使用广播(BroadCast)实现强制下线的方法

    通过以上步骤,我们就可以在Android应用中实现使用广播强制下线的功能。这种方式灵活且高效,能够确保无论用户当前在哪个Activity,都能立即响应并执行下线操作。同时,注意处理好权限和安全问题,避免不必要的广播...

    Android强制下线功能实现的代码示例

    通过以上步骤,我们就可以实现一个高效且易于维护的Android强制下线功能。当服务器发送强制下线指令时,应用会立即结束当前会话,用户在任何界面都能被引导到登录界面重新验证身份,从而保障了应用的安全性和用户...

    ForceOfflineDemo:Android--利用BroadcastReceiver实现APP强制下线Demo

    Android--利用BroadcastReceiver实现APP强制下线Demo 类似于QQ异地登陆后,会强制下线,并要求重新登录的功能。 Demo采用主动触发的方式,发送强制下线的广播,具体业务场景可以是从服务器发来的数据进行判断,如果...

    仿制QQ下线功能.zip

    在Android应用开发中,"仿制QQ下线功能.zip"是一个示例项目,它演示了如何实现一个类似于QQ应用的强制下线功能。这个功能的关键在于利用Android系统的BroadcastReceiver组件来监听特定的事件,比如用户点击了“强制...

    安卓XMPP聊天通讯Socket相关-模拟服务器用户二次登陆消息然后发送强制下线广播弹出对话框让用户重新登陆.rar

    总结来说,这个项目展示了如何在Android中利用XMPP和Socket技术处理用户二次登录的问题,通过广播机制实现用户通知。对于开发者来说,这涉及到XMPP协议的理解、Socket编程技巧、Android的BroadcastReceiver机制以及...

    BroadcaseTest.rar

    总的来说,“BroadcastTest.rar”中的实例展示了如何利用本地广播在Android应用中实现强制下线功能,通过理解本地广播的工作原理和使用方法,开发者可以更好地控制应用的交互和状态管理。同时,这个实例也提醒我们在...

    采用Websocket实现的单设备登录的SpringBoot的后端部分

    在本文中,我们将深入探讨如何使用SpringBoot框架和WebSocket技术来实现单设备登录功能。SpringBoot简化了Java应用的开发过程,而WebSocket则提供了一种双向通信机制,使得服务器和客户端可以实时交换数据。 首先,...

    沈晨玙 20190921211

    在实验中,可能用广播机制来触发强制下线功能。 7. **界面设计与布局**:为了保持界面的整洁和扩展性,开发者并未完全复制参考界面的所有子项,而是选择了关键元素进行实现。同时,对比了不同实现方式的优缺点,...

    Java即时通讯聊天室

    【Java即时通讯聊天室】是一个基于Java开发的小型局域网通信应用,旨在提供一个集登录注册、单聊、群聊、窗口抖动以及强制下线等多功能于一体的聊天平台,为用户创造更丰富的互动体验。 在即时通讯系统中,基础架构...

    银企通案例

    此外,管理员还可以对特定用户进行操作,如强制下线、单独发送消息等。 7. **安全机制**:为保障通讯的安全性,银企通规定同一账号不能在多台设备上同时登录,并且能够在客户端异常退出时自动更新用户状态。 8. **...

Global site tag (gtag.js) - Google Analytics