android oreo_Android Oreo隐式和显式广播接收器

android oreo

In this tutorial, we’ll discuss the changes in Broadcast Receiver since Android Oreo. We’ll see why the restrictions have been put on Background Operations in Android.

在本教程中,我们将讨论自Android Oreo以来Broadcast Receiver中的更改。 我们将了解为什么对Android的后台操作设置了限制。

安德罗广播接收机 (Androd Broadcast Receivers)

Broadcast Receivers are like Antennas. Just like Antennas can be tuned to catch certain frequencies, broadcast receivers can be registered to certain intent actions. When that action event triggers, the BroadcastReceiver gets called.

广播接收器就像天线。 就像可以调整天线以捕获某些频率一样,可以将广播接收器注册为某些意图动作。 当该动作事件触发时,将调用BroadcastReceiver。

隐式与显式广播接收器 (Implicit vs Explicit BroadcastReceivers)

Before we differentiate, let’s know the difference between Implicit and Explicit Intents.

在进行区分之前,让我们知道隐式意图和显式意图之间的区别。

Explicit Intents are used to call a particular component that you know of.
Implicit Intents are used when you don’t know the exact component to invoke.

显式意图用于调用您知道的特定组件。
当您不知道要调用的确切组件时,将使用隐式意图

Take the example of capturing a photo from camera or gallery. It’s an implicit intent, since calling the intent shows you a dialog of different applications to choose from. Same goes for email/browser intents (if they show you a dialog chooser).

以从相机或画廊捕获照片为例。 这是一个隐式意图,因为调用该意图会显示一个对话框,供您选择不同的应用程序。 电子邮件/浏览器的意图也是如此(如果它们向您显示对话框选择器)。

Implicit Broadcast Receivers aren’t exclusive to your application.
Actions such as ACTION_BOOT_COMPLETED or CONNECTIVITY_CHANGE are categorised in implicit broadcast receivers. This is because when these events happen, all the applications registered with the event will get the information.

隐式广播接收器并非仅适用于您的应用程序。
ACTION_BOOT_COMPLETEDCONNECTIVITY_CHANGE类的操作在隐式广播接收器中分类。 这是因为当这些事件发生时,向该事件注册的所有应用程序都将获取该信息。

Explicit Broadcast Receivers are exclusive to your application. Only your application’s broadcast receiver will get triggered when the custom intent action you define, gets called.

显式广播接收器是您的应用程序专有的。 调用您定义的自定义意图操作时,只会触发应用程序的广播接收器。

处理Android Oreo广播接收器 (Handling Android Oreo Broadcast Receivers)

Now, broadcast receivers run in the background. Hence it drains the battery. Imagine every application has registered android.net.conn.CONNECTIVITY_CHANGE in the receiver which is implicit.

现在,广播接收器在后台运行。 因此,它会耗尽电池电量。 想象每个应用程序都在接收者中隐式注册了android.net.conn.CONNECTIVITY_CHANGE

Now, whenever the wifi/mobile internet connection toggles, all the applications, with the receiver would get triggered. Imagine what happens when your wifi router is unstable. It can cause battery issues.

现在,每当wifi /移动互联网连接切换时,所有应用程序以及接收器都将被触发。 想象一下,当您的wifi路由器不稳定时会发生什么。 可能会导致电池问题。

AndroidManifest.xmlAndroidManifest.xml注册后,隐式广播接收器将无法工作

How to handle Implicit Receivers in Android Oreo?

如何在Android Oreo中处理隐式接收器?

To use Implicit Receivers in your application, you need to define them programmatically in your code, using registerReceiver().

要在应用程序中使用隐式接收器,您需要使用registerReceiver()在代码中以编程方式定义它们。

Using registerReceiver() we can programmatically register and unregisterReceiver() during the lifecycle of the activity. This way implicit receivers would only be called when our activity/application is alive and not at other times.

使用registerReceiver()我们可以在活动的生命周期中以编程方式注册和unregisterReceiver() 。 这样,隐式接收器仅在我们的活动/应用程序处于活动状态时才被调用,而在其他时间则不会被调用。

Besides registering receivers programmatically, we can use JobSchedulers too.

除了以编程方式注册接收者之外,我们还可以使用JobSchedulers

Several Implicit Broadcasts are exempted and can be declared in the Manifest:

某些隐式广播被豁免,可以在清单中声明:

Note: Beginning with Android Pie, The NETWORK_STATE_CHANGED_ACTION broadcast doesn’t receive information about the user’s location or personally identifiable data.

注意 :从Android Pie开始, NETWORK_STATE_CHANGED_ACTION广播不会接收到有关用户位置或个人身份数据的信息。

In the next section, we’ll be creating an application which implements Broadcast Receivers keeping the Android Oreo limitations.

在下一节中,我们将创建一个应用程序,该应用程序实现广播接收器,并保持Android Oreo的限制。

项目结构 (Project Structure)

(Code)

The AndroidManifest.xml file looks like the following:

AndroidManifest.xml文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    package="com.journaldev.androidoreobroadcastreceiver">

    <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/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">

        <receiver android:name="com.journaldev.androidoreobroadcastreceiver.MyReceiver"
            android:enabled="true">

            <intent-filter>
                <action android:name="com.journaldev.AN_INTENT" />
            </intent-filter>

        </receiver>

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

    </application>

</manifest>

We’ve defined an intent filter with an action which is explicit.

我们用一个明确的动作定义了一个意图过滤器。

Implicit ones will be defined in the code only:

隐式代码仅在代码中定义:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/btnExplicitBroadcast"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Explicit Broadcast" />


</LinearLayout>

The code for the MainActivity.java class is given below:

MainActivity.java类的代码如下:

package com.journaldev.androidoreobroadcastreceiver;

import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    Button btnExplicitBroadcast;

    MyReceiver myReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        btnExplicitBroadcast = findViewById(R.id.btnExplicitBroadcast);
        btnExplicitBroadcast.setOnClickListener(this);
        myReceiver= new MyReceiver();
    }

    @Override
    protected void onResume() {
        super.onResume();

        IntentFilter filter = new IntentFilter();
        filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");


        registerReceiver(myReceiver, filter);
    }

    public void broadcastIntent() {
        Intent intent = new Intent();
        intent.setAction("com.journaldev.AN_INTENT");
        intent.setComponent(new ComponentName(getPackageName(),"com.journaldev.androidoreobroadcastreceiver.MyReceiver"));
        getApplicationContext().sendBroadcast(intent);
    }

    @Override
    protected void onStop() {
        super.onStop();
        unregisterReceiver(myReceiver);
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btnExplicitBroadcast:
                broadcastIntent();
                break;
        }
    }
}

On button click sendBroadcast() is called to send the explicit broadcast.

单击按钮后,将调用sendBroadcast()以发送显式广播。

Note: sendStickyBroadcasts() were used to send broadcast intents that stayed around for other receivers to access them at a later point. The method was deprecated in API 21.

注意: sendStickyBroadcasts()用于发送广播意图,这些意图sendStickyBroadcasts()其他接收者在以后使用。 该方法已在API 21中弃用。

The code for the MyReceiver.java BroadcastReceiver class is given below:

下面给出了MyReceiver.java BroadcastReceiver类的代码:

package com.journaldev.androidoreobroadcastreceiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {


    @Override
    public void onReceive(Context context, Intent intent) {

        String action = intent.getAction();
        if (action.equals("com.journaldev.AN_INTENT")) {
            Toast.makeText(context, "Explicit Broadcast was triggered", Toast.LENGTH_SHORT).show();
        }

        if (("android.net.conn.CONNECTIVITY_CHANGE").equals(action)) {
            Toast.makeText(context, "Implicit Broadcast was triggered using registerReceiver", Toast.LENGTH_SHORT).show();
        }

    }
}

The output of the above application in action is given below:

上面应用程序的输出如下:

LocalBroadcastManager (LocalBroadcastManager)

A LocalBroadcastManager is used to send or receive events locally within the current application only.

LocalBroadcastManager仅用于在当前应用程序中本地发送或接收事件。

LocalBroadcastManager does not listen to system-wide broadcasts and is more secure than BroadcastReceiver.
Plus it has a less overhead hence communication speed is faster.

LocalBroadcastManager不收听系统范围的广播,并且比BroadcastReceiver更安全。
加上它具有较少的开销,因此通信速度更快。

It can be initialised as:

可以初始化为:

LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(context);

localBroadcastManager.sendBroadcast(intent);

LocalBroadcastManager would fail if you make events that are system wide.

如果您进行系统范围的事件,LocalBroadcastManager将失败。

<receiver android:name=".MyReciever"
          android:permission="android.permission.SEND_SMS">
    <intent-filter>
    <action android:name="MY_ACTION"/>
    </intent-filter>
</receiver>
sendBroadcast(new Intent("MY_ACTION"), Manifest.permission.SEND_SMS);

Set the android:exported attribute to “false” in the receiver tag in the manifest restricts the application from receiving broadcasts from other applications.

在清单的接收器标签中将android:exported属性设置为“ false”,以限制该应用程序接收来自其他应用程序的广播。

This brings an end to this tutorial. You can download the project from the below link:

本教程到此结束。 您可以从以下链接下载项目:

翻译自: https://www.journaldev.com/23653/android-oreo-implicit-and-explicit-broadcast-receiver

android oreo

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值