I learned BroadcastReceiver from my teacher today. Let's record it.
Send standard broadcast (use static registration, that is, manually write the registration code in AndroidManifest.xml)
Take a look at my project structure
The MainActivity code is as follows
import android.content.ComponentName; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private final String NORMAL_ACTION = "com.example.broadcastreceiver.MyReceiver"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Send a broadcast Intent intent = new Intent(NORMAL_ACTION); intent.putExtra("Msg", "Hi"); intent.setComponent(new ComponentName("com.example.broadcastreceiver", "com.example.broadcastreceiver.MyReceiver")); sendBroadcast(intent); //It's a standard broadcast } }); } }
MainActivity layout file_ main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:orientation="vertical" android:gravity="center"> <Button android:id="@+id/btn" android:text="Send standard broadcast" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
MyReceiver code is as follows
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class MyReceiver extends BroadcastReceiver { public MyReceiver() { } @Override public void onReceive(Context context, Intent intent) { String msg = intent.getStringExtra("Msg"); Log.e("TAG", msg); } }
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.broadcastreceiver"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyApplication1"> <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> </activity> <!--Register broadcast receiver--> <receiver android:name=".MyReceiver"> <intent-filter> <action android:name="com.example.broadcastreceiver.MyReceiver" /> </intent-filter> </receiver> </application> </manifest>
Run results (I sent multiple broadcasts)
After pasting the code for sending the standard broadcast, each line of code is easy to understand. I won't explain it one by one (I haven't written many lines of code), but I still want to talk about this line of code in MainActivity
intent.setComponent(new ComponentName("com.example.broadcastreceiver", "com.example.broadcastreceiver.MyReceiver"));
Why add this line of code? At the beginning of school, I didn't add this line of code. As soon as I ran it, I found that MyReceiver couldn't receive the broadcast sent by MainActivity, so I checked the Internet https://developer.android.google.cn/about/versions/oreo/background
It roughly means the broadcast regulations of Android 8.0 and above systems: when targetsdkversion > = 26, the Receiver registered in AndroidManifest.xml may not receive the broadcast message. The above line of code needs to be added. The first parameter of this line of code is the package path and the second parameter is the class name. I don't know what this line of code means. If you want to know, you can check the source code.
Send ordered broadcast (or static registration)
Take a look at my project structure
The MainActivity code is as follows
import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { private final String ORDER_ACTION = "com.example.broadcastreceiver2.MyReceiver"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn = findViewById(R.id.btn); btn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(ORDER_ACTION); intent.putExtra("Msg", "awesome"); Log.i("MainActivity", "onClick: MainActivity The message sent is: Aoli to"); intent.setPackage(getPackageName()); //intent.setComponent(new ComponentName("com.example.broadcastreceiver2", "com.example.broadcastreceiver2.MyReceiver1")); //intent.setComponent(new ComponentName("com.example.broadcastreceiver2", "com.example.broadcastreceiver2.MyReceiver2")); //intent.setComponent(new ComponentName("com.example.broadcastreceiver2", "com.example.broadcastreceiver2.MyReceiver3")); sendOrderedBroadcast(intent, null); //The sendorderedbroadcast (intent, String) method is called to send an ordered broadcast. The String parameter value is used when customizing permissions } }); } }
Layout file for MainActivity_ main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:orientation="vertical" android:gravity="center"> <Button android:id="@+id/btn" android:text="Send ordered broadcast" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
MyReceiver1 code is as follows
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; public class MyReceiver1 extends BroadcastReceiver { private String TAG="Receiver1"; @Override public void onReceive(Context context, Intent intent) { Log.e(TAG, "MyReceiver1 Called"); //Take out the data passed from Intent String msg = intent.getStringExtra("Msg"); Log.e(TAG, "MyReceiver1 The value received is: " + msg); //Pass data to the next priority Receiver Bundle bundle = new Bundle(); bundle.putString("Data", "fating"); Log.i(TAG, "MyReceiver1 The message sent is: fating"); setResultExtras(bundle); } }
MyReceiver2 code is as follows
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.util.Log; public class MyReceiver2 extends BroadcastReceiver { private String TAG="Receiver2"; @Override public void onReceive(Context context, Intent intent) { Log.e(TAG, "MyReceiver2 Called"); //Retrieve the data passed by the Receiver of the previous priority String data = getResultExtras(true).getString("Data"); Log.e(TAG, "MyReceiver2 The value received is: " + data); //Pass data to the next priority Receiver Bundle bundle = new Bundle(); bundle.putString("Data", "come on."); Log.i(TAG, "MyReceiver2 The message sent is: come on"); setResultExtras(bundle); } }
MyReceiver3 code is as follows
import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.util.Log; public class MyReceiver3 extends BroadcastReceiver { private String TAG="Receiver3"; @Override public void onReceive(Context context, Intent intent) { Log.e(TAG, "MyReceiver3 Called"); //Retrieve the data passed by the Receiver of the previous priority String data = getResultExtras(true).getString("Data"); Log.e(TAG, "MyReceiver3 The value received is: " + data); } }
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.broadcastreceiver2"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyApplication1"> <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> </activity> <!--Register broadcast receiver--> <receiver android:name=".MyReceiver1"> <intent-filter android:priority="1000"> <action android:name="com.example.broadcastreceiver2.MyReceiver" /> </intent-filter> </receiver> <receiver android:name=".MyReceiver2"> <intent-filter android:priority="900"> <action android:name="com.example.broadcastreceiver2.MyReceiver" /> </intent-filter> </receiver> <receiver android:name=".MyReceiver3"> <intent-filter android:priority="800"> <action android:name="com.example.broadcastreceiver2.MyReceiver" /> </intent-filter> </receiver> </application> </manifest>
Operation results
The code for sending an ordered broadcast is pasted here. If you understand the first one who sends a standard broadcast, you can understand the one who sends an ordered broadcast. The problem here is that I find it useless to add this line of code in MainActivity (I don't need to tell you)
intent.setComponent(new ComponentName("com.example.broadcastreceiver", "com.example.broadcastreceiver.MyReceiver"));
Because the second parameter of this line of code is the class name, I have three classes that receive broadcasts here, so it's difficult to do. So I went online to find the blogs of the big guys (if I don't understand it, I went online to check it). After a long time, I found that adding this line of code in MainActivity is feasible
intent.setPackage(getPackageName());
This line of code means to specify the packet name of the broadcast receiver, that is, to send an explicit broadcast
Dynamic registration (in fact, it is registered with Java code. Here, the broadcast is registered and received in the Service)
Take a look at my project structure
The MainActivity code is as follows
import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { public final static String ACTION = "com.example.broadcastreceiver3"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button btn_startservice = findViewById(R.id.btn_startservice); Button btn_sendbroadcast = findViewById(R.id.btn_sendbroadcast); Button btn_stopservice = findViewById(R.id.btn_stopservice); btn_startservice.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, BroadcastService.class); startService(intent); } }); btn_sendbroadcast.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(ACTION); sendBroadcast(intent); } }); btn_stopservice.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, BroadcastService.class); stopService(intent); } }); } }
Layout file for MainActivity_ main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity" android:orientation="vertical" android:gravity="center"> <Button android:id="@+id/btn_startservice" android:layout_width="290dp" android:layout_height="wrap_content" android:text="Open service" /> <Button android:id="@+id/btn_sendbroadcast" android:layout_width="290dp" android:layout_height="wrap_content" android:text="Send broadcast" android:layout_marginTop="10dp"/> <Button android:id="@+id/btn_stopservice" android:layout_width="290dp" android:layout_height="wrap_content" android:text="Out of Service" android:layout_marginTop="10dp"/> </LinearLayout>
The BroadcastService code is as follows
package com.example.broadcastreceiver3; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.IBinder; import android.util.Log; public class BroadcastService extends Service { private BroadcastReceiver receiver; private final String TAG = "BroadcastService"; public BroadcastService() { } @Override public void onCreate() { IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(MainActivity.ACTION); receiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Log.e(TAG, "BroadcastService Broadcast received"); } }; registerReceiver(receiver, intentFilter); Log.e(TAG, "BroadcastService Registered receiver"); super.onCreate(); } @Override public void onDestroy() { super.onDestroy(); unregisterReceiver(receiver); Log.e(TAG, "BroadcastService Unregister receiver"); } @Override public IBinder onBind(Intent intent) { return null; } }
AndroidManifest.xml (you only need to register the Service here, not the Receiver)
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.broadcastreceiver3"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyApplication1"> <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> </activity> <service android:name=".BroadcastService" android:enabled="true" android:exported="true"> </service> </application> </manifest>
Operation results
Context.registerReceiver() The method is to register the receiver
Context.unregisterReceiver() The method is to cancel the registration
This is the end of the introduction to BroadcastReceiver. The introduction is very shallow, and we have to continue our efforts.