实现强制下线功能的思路就是弹出一个对话框,让用户无法进行任何操作,必须选择对话框中的确定按钮,然后Intent跳转到Login页面即可。现在存在这样一个问题,我们被通知强制下线的时候可能处于任何一个页面,难道我们需要在每个界面上都编写一个弹出对话框的逻辑?我们可以借助广播,来轻松实现这一功能。
首先我们考虑强制下线功能需要先关闭掉所有的活动,然后回到登录界面,怎么实现关闭所有活动的功能呢?我们可以先创建一个ActivityCollector类用于管理所有的活动:
<p>package com.example.forceoffline;</p><p>import java.util.ArrayList; import java.util.List;</p><p>import android.app.Activity;</p><p>public class ActivityCollector { public static List<Activity> activities = new ArrayList<Activity>();</p><p> public static void addActivity(Activity activity) { activities.add(activity); }</p><p> public static void removeActivity(Activity activity) { activities.remove(activity); }</p><p> public static void finishAll() { for (Activity activity : activities) { if (!activity.isFinishing()) { activity.finish(); } } }</p><p>} </p>
然后创建BaseActivity类作为所有活动的父类。
package com.example.forceoffline; 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() { ActivityCollector.removeActivity(this); super.onDestroy(); } }
登录login.xml代码如下:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.forceoffline.LoginActivity" tools:ignore="MergeRootFrame" > <TableRow> <TextView android:layout_height="wrap_content" android:text="Account:" /> <EditText android:id="@+id/account" android:layout_height="wrap_content" android:minWidth="50dp" /> </TableRow> <TableRow> <TextView android:layout_height="wrap_content" android:text="Password:" /> <EditText android:id="@+id/password" android:layout_height="wrap_content" android:inputType="textPassword" android:minWidth="50dp" /> </TableRow> <TableRow> <Button android:id="@+id/login" android:layout_height="wrap_content" android:layout_span="2" android:text="Login" /> </TableRow> </TableLayout>
新建LoginActivity继承BaseActivity:
package com.example.forceoffline; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast; public class LoginActivity extends BaseActivity { private EditText accEditText = null; private EditText passEditText = null; private Button loginButton = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.login); this.accEditText = (EditText) super.findViewById(R.id.account); this.passEditText = (EditText) super.findViewById(R.id.password); this.loginButton = (Button) super.findViewById(R.id.login); this.loginButton.setOnClickListener(new OnClickListener() { public void onClick(View v) { String account = accEditText.getText().toString(); String passwordString = passEditText.getText().toString(); if (account.equals("admin") && passwordString.equals("admin")) { Intent intent = new Intent(LoginActivity.this, MainActivity.class); startActivity(intent); finish(); } else { Toast.makeText(LoginActivity.this, "account or password is invalid!", Toast.LENGTH_SHORT).show(); } } }); } }
main.xml代码如下:
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/container" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.example.forceoffline.LoginActivity" tools:ignore="MergeRootFrame" > <Button android:id="@+id/offline" android:layout_height="wrap_content" android:layout_span="2" android:text="Offline" /> </TableLayout>
MainActivity.java如下:
package com.example.forceoffline; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends BaseActivity { private Button offlineButton; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); this.offlineButton = (Button) super.findViewById(R.id.offline); offlineButton.setOnClickListener(new OnClickListener() { @Override public void onClick(View arg0) { Intent intent = new Intent("com.example.offline.FORCE_OFFLINE"); sendBroadcast(intent); } }); } }
接下来我们要创建一个广播接收器了:
package com.example.forceoffline; 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("Warning"); dialogBuilder .setMessage("You are forced to be offline.Please try to login again!"); dialogBuilder.setCancelable(false); dialogBuilder.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface arg0, 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.getWindow().setType( WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); alertDialog.show(); } }
最后不要忘了配置manifest:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.forceoffline" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="19" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.example.forceoffline.LoginActivity" android:label="@string/app_name" > <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="com.example.forceoffline.ForceOfflineReceiver" > <intent-filter> <action android:name="com.example.offline.FORCE_OFFLINE" /> </intent-filter> </receiver> </application> </manifest>
运行实例:
输入正确的用户名和密码后进入Main:
点击offline:
点击OK后返回登录界面,实现简单的下线功能。
最后推荐一下我开发的应用:http://openbox.mobilem.360.cn/index/d/sid/2966005
应用看起来很简单,却也用到了不少技术,希望初学者及安卓开发爱好者下载后与我交流学习,谢谢支持。