Android--Android中使用廣播BroadcastReceiver進行用戶強制下線功能

利用廣播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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章