Android學習總結——強制下線功能

KateWyrick 7年前發布 | 10K 次閱讀 安卓開發 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

 

 本文由用戶 KateWyrick 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!