"21 days of good habits" phase I-4

Keywords: Java Android Android Studio Apache android-studio

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.

Posted by jb489 on Mon, 25 Oct 2021 16:05:37 -0700