Android入門之BroadCast模擬實現(xiàn)異地登錄事件發(fā)生后的主動退出
簡介
隨著對BroadCast的越來越深入,我們今天要實現(xiàn)一個稍微復(fù)雜一點的BroadCast。即我們常用來有時APP打開時如果多個設(shè)備同時登錄一個帳號,而我們只允許一個設(shè)備登錄一個帳號時,此時我們的APP會彈一個對話框如:您的賬號在別處登錄,請重新登陸!。
設(shè)計
要制作這樣的效果我們依舊是采用BroadCast,而且是一個自定義的Broadcast。此處需要:
1.自定義send一個broadcast;
2.注冊一個receiver,使得它監(jiān)聽我們這個自定義的broadcast;
3.在receiver的onReceive事件中,彈出一個“無窗體懸浮alert dialog”;
4.由于Android6及以后的相應(yīng)權(quán)限問題,你還要添加這個無窗體的懸浮alert dialog的權(quán)限;
5.又由于我們用的是SDK27及以后版本,因此光添加權(quán)限還沒有用,還要使用代碼喚出android關(guān)于這個app的一個“授權(quán)”系統(tǒng)窗口,在這個授權(quán)窗口內(nèi),用戶自己點:allow后再進行打開這個app操作,此時這個懸浮alert dialog才能正確被喚起否則當這個alert dialog一旦被喚出你會得到一個permission denied 2038的錯誤,然后Android App自動退出;
好了,說了這么多我們來看代碼
全代碼
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <Button android:id="@+id/buttonLoginInOtherPlace" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="模擬異地登錄" /> </LinearLayout>
activity_login.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="login_id:" /> <EditText android:width="120dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="password:" /> <EditText android:width="120dp" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout> <LinearLayout android:layout_width="wrap_content" android:layout_height="wrap_content"> <Button android:id="@+id/buttonLoginSubmit" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="點一下代表登錄了" /> </LinearLayout> </LinearLayout>
以上定義了兩個窗體,運行順序如下:
- activity_main先運行,上面顯示一個“模擬異地登錄”按鈕,點一下會彈出一個alert dialog告訴你你現(xiàn)在要登出;
- 用戶點一下這個alert dialog上的【確定】,登錄出登錄,跳轉(zhuǎn)到一個登錄的activity_login界面;
- 在這個activity_login界面直接點【登錄】又登進activity_main
先來看我們的Receiver,它接受來自activity_main的【模擬異地登錄】按鈕發(fā)送過來的broad cast。
BroadCastReceiver.java
package org.mk.android.demo.broadcast; import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.PixelFormat; import android.os.Build; import android.provider.Settings; import android.util.Log; import android.view.Window; import android.view.WindowManager; public class BroadCastReceiver extends BroadcastReceiver { private final String TAG = "BroadCastWithActivity"; @Override public void onReceive(final Context context, Intent intent) { Log.i(TAG, "receive broadcast->" + intent.getAction()); 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.getInstance().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_APPLICATION_OVERLAY); alertDialog.show(); } }
接著,我們來看AndroidManifest.xml文件中的注冊以及相應(yīng)的靜態(tài)權(quán)限申請(這個對話框除了靜態(tài)權(quán)限還需要代碼在彈出對話框前申請動態(tài)權(quán)限,這塊代碼我們寫在了MainActivity.java里的)。
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.SYSTEM_OVERLAY_WINDOW" /> <application android:allowBackup="true" android:dataExtractionRules="@xml/data_extraction_rules" android:fullBackupContent="@xml/backup_rules" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.DemoBroadCastWithActivity" tools:targetApi="31"> <activity android:name=".LoginActivity" android:exported="false"> <meta-data android:name="android.app.lib_name" android:value="" /> </activity> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <meta-data android:name="android.app.lib_name" android:value="" /> </activity> <receiver android:name=".BroadCastReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED"/> </intent-filter> <intent-filter> <action android:name="ANDROID.INTENT.ACTION.MEDIA_MOUNTED"/> <action android:name="ANDROID.INTENT.ACTION.MEDIA_UNMOUNTED"/> <data android:scheme="file"/> </intent-filter> </receiver> </application> </manifest>
接著我們來看我們的BroadCastReceiver寫法。
BroadCastReceiver.java
package org.mk.android.demo.broadcast; import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.PixelFormat; import android.os.Build; import android.provider.Settings; import android.util.Log; import android.view.Window; import android.view.WindowManager; public class BroadCastReceiver extends BroadcastReceiver { private final String TAG = "BroadCastWithActivity"; private static final String BROADCAST_ACTON = "org.mk.android.demo.broadcast"; @Override public void onReceive(final Context context, Intent intent) { if(intent.getAction().equals(BROADCAST_ACTON)) { Log.i(TAG, "receive broadcast->" + intent.getAction()); 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.getInstance().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_APPLICATION_OVERLAY); alertDialog.show(); } } }
我們可以看到,它里面定義了一個alert dialog,這個dialog在彈出時沒有context因此我們把它叫作無activity(窗體)依托dialog,因此這種dialog是必須要申請權(quán)限的,這是Android的規(guī)定。然后這個alert dialog有一個【確定】按鈕,點一下這個【確定】按鈕,就會以startActivity的方式再次打開activity_main界面,此處我們需要注意的是,這個startActivity里的intent的類型必須為Intent.FLAG_ACTIVITY_NEW_TASK),否則你死活從這個登錄界面跳不回activity_main的界面了。
接著看來MainActivity以及里面發(fā)生消息的部分(含代碼動態(tài)申請Android權(quán)限)。
MainActivity.java
package org.mk.android.demo.broadcast; import androidx.appcompat.app.AppCompatActivity; import androidx.localbroadcastmanager.content.LocalBroadcastManager; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.provider.Settings; import android.util.Log; import android.view.View; import android.widget.Button; public class MainActivity extends BaseActivity { private BroadCastReceiver localReceiver; private LocalBroadcastManager localBroadcastManager; private IntentFilter intentFilter; private static final String BROADCAST_ACTON = "org.mk.android.demo.broadcast"; private final String TAG = "BroadCastWithActivity"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button buttonLoginInOtherPlace = (Button) findViewById(R.id.buttonLoginInOtherPlace); localBroadcastManager = LocalBroadcastManager.getInstance(this); //初始化廣播接收者,設(shè)置過濾器 localReceiver = new BroadCastReceiver(); intentFilter = new IntentFilter(); intentFilter.addAction(BROADCAST_ACTON); localBroadcastManager.registerReceiver(localReceiver, intentFilter); buttonLoginInOtherPlace.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (!Settings.canDrawOverlays(MainActivity.this)) { Intent mintent = new Intent(); mintent.setAction(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); startActivity(mintent); } Log.i(TAG, ">>>>>>MainActivity->onClick"); Intent intent = new Intent(BROADCAST_ACTON); localBroadcastManager.sendBroadcast(intent); } }); } @Override protected void onDestroy() { super.onDestroy(); localBroadcastManager.unregisterReceiver(localReceiver); } }
這邊核心注意點:
代碼動代申請權(quán)限
if (!Settings.canDrawOverlays(MainActivity.this)) { Intent mintent = new Intent(); mintent.setAction(Settings.ACTION_MANAGE_OVERLAY_PERMISSION); startActivity(mintent); }
代碼運行到這,Android會打開一個該APP相應(yīng)的系統(tǒng)權(quán)限對話框
然后把這邊的Allow手動啟用。
接著我們重新運行這個APP,效果如下。
運行效果
點擊【確定】登出activity_main切換到activity_login
在這個界面點擊【點一下代表登錄了】按鈕,再次回到activity_main
到此這篇關(guān)于Android入門之BroadCast模擬實現(xiàn)異地登錄事件發(fā)生后的主動退出的文章就介紹到這了,更多相關(guān)Android BroadCast異地登錄事件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Android 2d游戲開發(fā)之貪吃蛇基于surfaceview
這篇文章主要介紹了Android 2d游戲開發(fā)基于surfaceview的貪吃蛇,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-09-09Android?Camera1實現(xiàn)預(yù)覽框顯示
這篇文章主要為大家詳細介紹了Android?Camera1實現(xiàn)預(yù)覽框顯示,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05Android實現(xiàn)布局動畫和共享動畫的結(jié)合效果
今天給大家?guī)砟軌蛱嵘脩趔w驗感的交互動畫,使用起來非常簡單,體驗效果非常贊,其中僅使用到布局動畫和共享動畫,文章通過代碼示例介紹的非常詳細,感興趣的同學可以自己動手試一試2023-09-09Android天氣預(yù)報之基于HttpGet對象解析天氣數(shù)據(jù)的方法
這篇文章主要介紹了Android天氣預(yù)報之基于HttpGet對象解析天氣數(shù)據(jù)的方法,非常實用的功能,需要的朋友可以參考下2014-08-08