亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Android入門(mén)之BroadCast模擬實(shí)現(xiàn)異地登錄事件發(fā)生后的主動(dòng)退出

 更新時(shí)間:2022年12月14日 09:30:23   作者:TGITCIC  
隨著對(duì)BroadCast的越來(lái)越深入,我們今天要實(shí)現(xiàn)一個(gè)稍微復(fù)雜一點(diǎn)的BroadCast。即只允許一個(gè)設(shè)備登錄一個(gè)帳號(hào)時(shí),APP會(huì)彈一個(gè)對(duì)話框如:您的賬號(hào)在別處登錄,請(qǐng)重新登陸!感興趣的可以了解一下

簡(jiǎn)介

隨著對(duì)BroadCast的越來(lái)越深入,我們今天要實(shí)現(xiàn)一個(gè)稍微復(fù)雜一點(diǎn)的BroadCast。即我們常用來(lái)有時(shí)APP打開(kāi)時(shí)如果多個(gè)設(shè)備同時(shí)登錄一個(gè)帳號(hào),而我們只允許一個(gè)設(shè)備登錄一個(gè)帳號(hào)時(shí),此時(shí)我們的APP會(huì)彈一個(gè)對(duì)話框如:您的賬號(hào)在別處登錄,請(qǐng)重新登陸!。

設(shè)計(jì)

要制作這樣的效果我們依舊是采用BroadCast,而且是一個(gè)自定義的Broadcast。此處需要:

1.自定義send一個(gè)broadcast;

2.注冊(cè)一個(gè)receiver,使得它監(jiān)聽(tīng)我們這個(gè)自定義的broadcast;

3.在receiver的onReceive事件中,彈出一個(gè)“無(wú)窗體懸浮alert dialog”;

4.由于Android6及以后的相應(yīng)權(quán)限問(wèn)題,你還要添加這個(gè)無(wú)窗體的懸浮alert dialog的權(quán)限;

5.又由于我們用的是SDK27及以后版本,因此光添加權(quán)限還沒(méi)有用,還要使用代碼喚出android關(guān)于這個(gè)app的一個(gè)“授權(quán)”系統(tǒng)窗口,在這個(gè)授權(quán)窗口內(nèi),用戶自己點(diǎn):allow后再進(jìn)行打開(kāi)這個(gè)app操作,此時(shí)這個(gè)懸浮alert dialog才能正確被喚起否則當(dāng)這個(gè)alert dialog一旦被喚出你會(huì)得到一個(gè)permission denied 2038的錯(cuò)誤,然后Android App自動(dòng)退出;

好了,說(shuō)了這么多我們來(lái)看代碼

全代碼

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="點(diǎn)一下代表登錄了" />
    </LinearLayout>
</LinearLayout>

以上定義了兩個(gè)窗體,運(yùn)行順序如下:

  • activity_main先運(yùn)行,上面顯示一個(gè)“模擬異地登錄”按鈕,點(diǎn)一下會(huì)彈出一個(gè)alert dialog告訴你你現(xiàn)在要登出;
  • 用戶點(diǎn)一下這個(gè)alert dialog上的【確定】,登錄出登錄,跳轉(zhuǎn)到一個(gè)登錄的activity_login界面;
  • 在這個(gè)activity_login界面直接點(diǎn)【登錄】又登進(jìn)activity_main

先來(lái)看我們的Receiver,它接受來(lái)自activity_main的【模擬異地登錄】按鈕發(fā)送過(guò)來(lái)的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("您的賬號(hào)在別處登錄,請(qǐng)重新登陸!");
        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();
    }
}

接著,我們來(lái)看AndroidManifest.xml文件中的注冊(cè)以及相應(yīng)的靜態(tài)權(quán)限申請(qǐng)(這個(gè)對(duì)話框除了靜態(tài)權(quán)限還需要代碼在彈出對(duì)話框前申請(qǐng)動(dòng)態(tài)權(quán)限,這塊代碼我們寫(xiě)在了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>

接著我們來(lái)看我們的BroadCastReceiver寫(xiě)法。

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("您的賬號(hào)在別處登錄,請(qǐng)重新登陸!");
            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();
        }
    }
}

我們可以看到,它里面定義了一個(gè)alert dialog,這個(gè)dialog在彈出時(shí)沒(méi)有context因此我們把它叫作無(wú)activity(窗體)依托dialog,因此這種dialog是必須要申請(qǐng)權(quán)限的,這是Android的規(guī)定。然后這個(gè)alert dialog有一個(gè)【確定】按鈕,點(diǎn)一下這個(gè)【確定】按鈕,就會(huì)以startActivity的方式再次打開(kāi)activity_main界面,此處我們需要注意的是,這個(gè)startActivity里的intent的類型必須為Intent.FLAG_ACTIVITY_NEW_TASK),否則你死活從這個(gè)登錄界面跳不回activity_main的界面了。

接著看來(lái)MainActivity以及里面發(fā)生消息的部分(含代碼動(dòng)態(tài)申請(qǐng)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è)置過(guò)濾器
        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);
    }
}

這邊核心注意點(diǎn):

代碼動(dòng)代申請(qǐng)權(quán)限

if (!Settings.canDrawOverlays(MainActivity.this)) {
    Intent mintent = new Intent();
    mintent.setAction(Settings.ACTION_MANAGE_OVERLAY_PERMISSION);
    startActivity(mintent);
}

代碼運(yùn)行到這,Android會(huì)打開(kāi)一個(gè)該APP相應(yīng)的系統(tǒng)權(quán)限對(duì)話框

然后把這邊的Allow手動(dòng)啟用。

接著我們重新運(yùn)行這個(gè)APP,效果如下。

運(yùn)行效果

點(diǎn)擊【確定】登出activity_main切換到activity_login

在這個(gè)界面點(diǎn)擊【點(diǎn)一下代表登錄了】按鈕,再次回到activity_main

到此這篇關(guān)于Android入門(mén)之BroadCast模擬實(shí)現(xiàn)異地登錄事件發(fā)生后的主動(dòng)退出的文章就介紹到這了,更多相關(guān)Android BroadCast異地登錄事件內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論