BroadcastReceiverPao Ding Jie Niu


Introduction to this section:

In the previous section we already had a preliminary understanding of BroadcastReceiver and knew the two broadcast types: standard and ordered. Register broadcast receivers dynamically or statically, listen to system broadcasts, and send broadcasts yourself! Our basic needs have been met~ But the broadcasts written above are all global broadcasts! This also means that the broadcasts sent by our APP will be received by other APPs. Or broadcasts sent by other APPs will also be received by our APP, which can easily cause some security issues! and Android provides us with a local broadcast mechanism. Broadcasts issued using this mechanism will only be propagated within the APP, and Broadcast receivers can only receive broadcasts sent by this application!


1. Local broadcast

1) Core usage:

1.png

PS: Local broadcast cannot Accepted through static registration, it is more efficient than system global broadcast

2) Notes:

2.png

3) Code example (elsewhere Log in to kick the user offline):

Like WeChat, if WeChat is running, if we use another mobile phone to log in to our account again, the previous one will remind the account Log in to another terminal like this, then close all the activities we opened, and then return to the login page like this~
Let’s write a simple example below:

Running rendering:

3.gif

## Code implementation:

Step 1: Prepare an ActivityCollector that closes all activities. The one provided by the previous Activity was used here!

ActivityCollector.java

public class ActivityCollector {
    private static List<Activity> activities = new ArrayList<Activity>();
    public static void addActivity(Activity activity) {
        activities.add(activity);
    }
    public static void removeActivity(Activity activity) {
        activities.remove(activity);
    }
    public static void finishAll() {
        for (Activity activity : activities) {
            if (!activity.isFinishing()) {
                activity.finish();
            }
        }
    }
}

Step 2:先写要给简单的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);
    }
}

LoginActivity.java:


public class LoginActivity extends BaseActivity implements View.OnClickListener{


    private SharedPreferences pref;
    private SharedPreferences.Editor editor;

    private EditText edit_user;
    private EditText edit_pawd;
    private Button btn_login;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);
        pref = PreferenceManager.getDefaultSharedPreferences(this);

        bindViews();
    }

    private void bindViews() {
        edit_user = (EditText) findViewById(R.id.edit_user);
        edit_pawd = (EditText) findViewById(R.id.edit_pawd);
        btn_login = (Button) findViewById(R.id.btn_login);
        btn_login.setOnClickListener(this);
    }

    @Override
    protected void onStart() {
        super.onStart();
        if(!pref.getString("user","").equals("")){
            edit_user.setText(pref.getString("user",""));
            edit_pawd.setText(pref.getString("pawd",""));
        }
    }

    @Override
    public void onClick(View v) {
        String user = edit_user.getText().toString();
        String pawd = edit_pawd.getText().toString();
        if(user.equals("123")&&pawd.equals("123")){
            editor = pref.edit();
            editor.putString("user", user);
editor.putString("pawd", pawd);
editor.commit();
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
To ast .makeText(LoginActivity.this, "Oh, I was right~",Toast.LENGTH_SHORT).show();
                                                                                        . "It's so simple to output, where is your brain?",Toast.LENGTH_SHORT).show();
}

}
}

Step 3: Customize a BroadcastReceiver, in Complete the pop-up dialog box operation in onReceive and start the login page: MyBcReceiver.java

public class MyBcReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(context);
dialogBuilder.setTitle("Warning:");
dialogBuilder.setMessage("Your account is logged in elsewhere, please log in again~");
DialogBuilder.setCancelable(false);
dialogBuilder.setPositiveButton("OK",
new DialogInterface.OnClickListener() {
@Override
                public void onClick(DialogInterface dialog, int which) {
             ActivityCollector.finishAll();
                                                      ActivityCollector.                          
                                                                                                                               ActivityCollector.finishAll();                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        context.startActivity(intent);
                    }
                });
        AlertDialog alertDialog = dialogBuilder.create();
        alertDialog.getWindow().setType(
                WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
        alertDialog.show();
    }
}


Don’t forget to add the system dialog permission in AndroidManifest.xml: < uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

Step 4: In MainActivity, instantiate localBroadcastManager, use it to complete related operations, and destroy it in addition Pay attention to unregisterReceiver!

MainActivity.java

public class MainActivity extends BaseActivity {

    private MyBcReceiver localReceiver;
    private LocalBroadcastManager localBroadcastManager;
    private IntentFilter intentFilter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        localBroadcastManager = LocalBroadcastManager.getInstance(this);

        //初始化广播接收者,设置过滤器
        localReceiver = new MyBcReceiver();
        intentFilter = new IntentFilter();
        intentFilter.addAction("com.jay.mybcreceiver.LOGIN_OTHER");
        localBroadcastManager.registerReceiver(localReceiver, intentFilter);

        Button btn_send = (Button) findViewById(R.id.btn_send);
        btn_send.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent("com.jay.mybcreceiver.LOGIN_OTHER");
                localBroadcastManager.sendBroadcast(intent);
            }
        });
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        localBroadcastManager.unregisterReceiver(localReceiver);
    }
}

Okay, it’s that simple, don’t forget to register the Activity~


2. Solving the problem of monitoring the startup broadcast on Android 4.3 and above:

On Android 4.3 and above version, allowing us to install the application on the SD, we all know that the system boots The SD card is loaded only after a short interval, so our application may not be able to monitor this broadcast! So we need to monitor both the boot broadcast and the SD card mounting broadcast!

In addition, some mobile phones may not have an SD card, so we cannot write these two broadcast monitors into the same Intetn-filter. Instead, it should be written in two, and the configuration code is as follows:

<receiver android:name=".MyBroadcastReceiver">
                                < 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>

3. Summary of commonly used system broadcasts:

Finally, let me provide you with some system broadcasts that we may usually use:

Intent.ACTION_AIRPLANE_MODE_CHANGED;
//Broadcast when turning off or turning on airplane mode

<strong>Intent.ACTION_BATTERY_CHANGED;
//Charging status, or battery power event Change
//The charging status and charge level of the battery change. This broadcast cannot be received through the establishment statement. It can only be registered through Context.registerReceiver()

<strong>Intent.ACTION_BATTERY_LOW;
// Indicates that the battery power is low

<strong>Intent.ACTION_BATTERY_OKAY;
//Indicates that the battery power is sufficient, that is, a broadcast will be issued when the battery power changes from low to full

Intent.ACTION_BOOT_COMPLETED;
//After the system startup is completed, this action is broadcast once (only once).

Intent.ACTION_CAMERA_BUTTON;
//Broadcast when the camera button (hardware button) is pressed when taking pictures

Intent.ACTION_CLOSE_SYSTEM_DIALOGS;
//Lock when the screen times out When the user presses the power button, long presses or short presses (regardless of whether the dialog box pops up), and locks the screen, the android system will broadcast this Action message

Intent.ACTION_CONFIGURATION_CHANGED;
/ /Broadcast emitted when the current settings of the device are changed (including changes: interface language, device orientation, etc., please refer to Configuration.java)

Intent.ACTION_DATE_CHANGED;
//When the device date changes Send this broadcast

Intent.ACTION_DEVICE_STORAGE_LOW;
//Broadcast sent when the device has insufficient memory. This broadcast can only be used by the system and is not available to other APPs?

Intent.ACTION_DEVICE_STORAGE_OK;
//Broadcast sent when the device memory changes from insufficient to sufficient. This broadcast can only be used by the system and is not available to other APPs?

Intent.ACTION_DOCK_EVENT;
//
//The place where this broadcast is issued frameworks\base\services\java\com\android\server\DockObserver.java

Intent. ACTION_EXTERNAL_APPLICATIONS_AVAILABLE;
////The broadcast sent after the mobile APP is completed (mobile refers to: APP2SD)

Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE;
//The broadcast sent when the APP is being moved (mobile refers to Refers to: APP2SD)

Intent.ACTION_GTALK_SERVICE_CONNECTED;
//Broadcast sent when Gtalk has established a connection

Intent.ACTION_GTALK_SERVICE_DISCONNECTED;
//Broadcast sent when Gtalk has disconnected Broadcast

Intent.ACTION_HEADSET_PLUG;
//Broadcast issued when inserting headphones into the headphone jack

Intent.ACTION_INPUT_METHOD_CHANGED;
//Broadcast issued when the input method is changed

Intent.ACTION_LOCALE_CHANGED;
//Broadcast issued when the current locale of the device has changed

Intent.ACTION_MANAGE_PACKAGE_STORAGE;
//

Intent.ACTION_MEDIA_BAD_REMOVAL;
//The SD card was not removed correctly (the correct way to remove the SD card: Settings--SD card and device memory--Uninstall SD card), but the broadcast when the SD card has been taken out
//Broadcast: The expansion media (expansion card) has been removed from the SD card slot, but the mount point has not been unmounted

Intent.ACTION_MEDIA_BUTTON;
//Broadcast when the "Media Button" button is pressed, if there is a "Media Button" button (hardware button)

Intent.ACTION_MEDIA_CHECKING;
//When inserting an external storage device, such as an SD card , the system will check the SD card, the broadcast sent at this time?
Intent.ACTION_MEDIA_EJECT;
//The broadcast sent by the external mass storage device has been unplugged (such as SD card, or mobile hard disk), whether it is correct or not This broadcast will be issued during uninstallation?
//Broadcast: The user wants to remove the expansion media (unplug the expansion card).
Intent.ACTION_MEDIA_MOUNTED;
//Broadcast when the SD card is inserted and correctly installed (recognized)
//Broadcast: The extended media is inserted and has been mounted.
Intent.ACTION_MEDIA_NOFS;
//
Intent.ACTION_MEDIA_REMOVED;
//The external storage device has been removed. Will this broadcast be issued regardless of whether it is uninstalled correctly?
// Broadcast: Extended media removed.
Intent.ACTION_MEDIA_SCANNER_FINISHED;
//Broadcast: A directory of media has been scanned
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE;
//
Intent.ACTION_MEDIA_SCANNER_STARTED;
//Broadcast: Start scanning the media A directory of

Intent.ACTION_MEDIA_SHARED;
// Broadcast: The extended media is unmounted because it has been shared as USB mass storage.
Intent.ACTION_MEDIA_UNMOUNTABLE;
//
Intent.ACTION_MEDIA_UNMOUNTED
// Broadcast: The extended media exists, but has not been mounted (mount).
Intent.ACTION_NEW_OUTGOING_CALL;

Intent.ACTION_PACKAGE_ADDED;
//After successful installation of the APK
//Broadcast: A new application package is installed on the device.
//A new application package has been installed on the device, the data includes the package name (the latest installed package program cannot receive this broadcast)
Intent.ACTION_PACKAGE_CHANGED;
//An existing application package Has been changed, including the package name
Intent.ACTION_PACKAGE_DATA_CLEARED;
//Broadcast emitted when clearing the data of an application (when selecting an application in Settings--Application Management--and then clicking Clear Data?)
//The user has cleared the data of a package, including the package name (the clearing package program cannot receive this broadcast)

Intent.ACTION_PACKAGE_INSTALL;
//A broadcast issued when a download is triggered and the installation is completed. , such as downloading applications in the electronic market?
//
Intent.ACTION_PACKAGE_REMOVED;
//Broadcast issued after successfully deleting an APK
//An existing application package has been removed from the device, including the package name ( The package program being installed cannot receive this broadcast)

Intent.ACTION_PACKAGE_REPLACED;
//Broadcast issued when replacing an existing installation package (regardless of whether the currently installed APP is newer or older than the previous one) , will this broadcast be issued?)
Intent.ACTION_PACKAGE_RESSTARTED;
//The user restarts a package, all processes of the package will be killed, and all runtime states associated with it should be removed, including the package name ( The restart package program cannot receive this broadcast)
Intent.ACTION_POWER_CONNECTED;
//Broadcast emitted when the external power supply is plugged in
Intent.ACTION_POWER_DISCONNECTED;
//Broadcast emitted when the external power supply is disconnected
Intent.ACTION_PROVIDER_CHANGED;
//

Intent.ACTION_REBOOT;
//Broadcast when restarting the device

Intent.ACTION_SCREEN_OFF;
//Broadcast after the screen is turned off

Intent.ACTION_SCREEN_ON;
// Broadcast after the screen is opened

Intent.ACTION_SHUTDOWN;
//Broadcast when the system is turned off

Intent.ACTION_TIMEZONE_CHANGED;
//Broadcast when the time zone changes

Intent.ACTION_TIME_CHANGED;
//Broadcast emitted when the time is set

Intent.ACTION_TIME_TICK;
//Broadcast: The current time has changed (normal time lapse).
//The current time changes and is sent every minute. It cannot be received through component declaration. It can only be registered through the Context.registerReceiver() method.

Intent.ACTION_UID_REMOVED;
//A user ID has been Remove broadcasts sent from the system
//

Intent.ACTION_UMS_CONNECTED;
//Broadcasts sent when the device has entered the USB mass storage state?

Intent.ACTION_UMS_DISCONNECTED;
//Broadcast when the device has changed from USB mass storage state to normal state?

Intent.ACTION_USER_PRESENT;
//

Intent.ACTION_WALLPAPER_CHANGED;
//Broadcast issued when the device wallpaper has been changed

4. Summary of this section:

Okay, that’s it for learning about BroadcastReceiver. If you have any additions or suggestions, please feel free to give them~ Extremely grateful~