android - 为什么我无法收到 POWER CONNECTED 操作?

标签 android nullpointerexception broadcastreceiver

我正在学习Android。我使用以下代码在 MainActivity.java 中动态注册我的自定义广播接收器 CustomBroadcastreceiver:

package com.example.bob.broadcastcounterback;

import android.content.ComponentName;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private PackageManager packageManager;
    private ComponentName componentName;
    private CustomBroadcastreceiver customReceiver;
    private TextView textView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        packageManager = getPackageManager();
        componentName = new ComponentName(this,CustomBroadcastreceiver.class);

        textView = findViewById(R.id.countText);

        customReceiver = new CustomBroadcastreceiver(textView);

        IntentFilter mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(Intent.ACTION_POWER_CONNECTED);
        mIntentFilter.addAction("com.example.bob.broadcastcounter");

        LocalBroadcastManager.getInstance(this).
                registerReceiver(customReceiver,mIntentFilter);

//        LocalBroadcastManager.getInstance(this).registerReceiver(customReceiver,new IntentFilter(Intent.ACTION_POWER_CONNECTED));

    }

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

//        packageManager.setComponentEnabledSetting(
//                componentName,
//                PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
//                PackageManager.DONT_KILL_APP);
    }

    @Override
    protected void onStop() {
        super.onStop();
//        packageManager.setComponentEnabledSetting(
//                componentName,
//                PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
//                PackageManager.DONT_KILL_APP);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.d("DESTORY CALLED:","destroy");
        LocalBroadcastManager.getInstance(this).unregisterReceiver(customReceiver);
    }

    public void sendBroadcast(View view) {
        Intent intent = new Intent("com.example.bob.broadcastcounter");

        LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
    }
}

CustomBroadcastreceiver.java:

package com.example.bob.broadcastcounterback;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.TextView;

public class CustomBroadcastreceiver extends BroadcastReceiver {

    private TextView mTextView;
    private int count = 0;

    private static final String ACTION_MY_BRODACAST = "com.example.bob.broadcastcounter";

    public CustomBroadcastreceiver(){
        super();
    }

    public CustomBroadcastreceiver(TextView mTextView){
        this();
        this.mTextView = mTextView;
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        String intentString = intent.getAction();


        switch (intentString){
            case Intent.ACTION_POWER_CONNECTED:
                Log.d("BroadcastReceiver:",mTextView.toString());
                mTextView.setText("power connected!");
//                mTextView.setText(++count);
                break;
            case ACTION_MY_BRODACAST :
                mTextView.setText("Custombroadcast Received!");
                break;
        }
    }
}

这样,每次按下onClicksendBroadcast(View view)的按钮时,我都可以收到ACTION_MY_BRODACAST广播。但是当我插入或拔出 USB 电缆时,什么也不会发生。然后我选择在 AndroidManinfest.xml 中注册广播接收器:

<receiver
        android:name=".CustomBroadcastreceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
        </intent-filter>
    </receiver>

这次我不知道会发生什么:每次我插入充电线时,应用程序都会立即崩溃并返回。我什至在 Android Studio 中看不到 logcat。要了解到底发生了什么,我将 Thread.sleep(5000) 添加到 onReceive() 方法中:

@Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        String intentString = intent.getAction();

        try {
            Thread.sleep(5000);
        }catch (InterruptedException e){
            Log.e("Broadcastcounterback:",e.toString());
        }



        switch (intentString){
            case Intent.ACTION_POWER_CONNECTED:
                Log.d("BroadcastReceiver:",mTextView.toString());
                mTextView.setText("power connected!");
//                mTextView.setText(++count);
                break;
            case ACTION_MY_BRODACAST :
                mTextView.setText("Custombroadcast Received!");
                break;
        }
    }

这一次,当我点击发送自定义广播的按钮时,mTextView 将在 5 秒休息后显示 Custombroadcast Received!。当我插入充电线时,5 秒后出现错误:

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.view.View.toString()' on a null object reference
                                                                                    at com.example.bob.broadcastcounterback.CustomBroadcastreceiver.onReceive(CustomBroadcastreceiver.java:41)

这表明当我收到 POWER_CONNECTED 操作时,mTextView 为空。为什么?我用 customReceiver = new CustomBroadcastreceiver(textView); 实例化了 customReceiver ,因此 mTextView 不应该为 null,实际上 ACTION_MY_BRODACAST 操作将触发 mTextView 显示正确的文本,没有任何错误。 最后,我的两个问题:

1 我们只能通过广播接收器静态注册来接收 POWER_CONNECTED 操作?

2 为什么会出现这个错误?

最佳答案

  1. ACTION_POWER_CONNECTED广播是系统广播。 LocalBroadcastManager仅处理以 LocalBroadcastManager 发送的广播,因此您注册的 Receiver 实例将不会获得 ACTION_POWER_CONNECTED播送。您需要在 Context 上注册您的 Receiver 实例。 ,就像你的 Activity .

  2. <receiver> list 中的元素静态注册接收器,而不是任何现有实例。然后系统根据需要实例化该类,并且这些实例都不会具有 TextView字段集。如果您想更新Activity从静态注册的 Receiver 类中,您需要使用其他一些机制;例如,Intent s,LocalBroadcastManager ,一些其他事件总线等。


我还要提到 ACTION_POWER_CONNECTED广播未开启the list of implicit broadcast exemptions for Android 8.0 and above ,所以如果你的targetSdkVersion 26 岁以上,您无法使用静态注册的接收器接收该广播,从 Oreo 开始。

关于android - 为什么我无法收到 POWER CONNECTED 操作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50302022/

相关文章:

java - 实现 AnimationListener 抽象方法

java - 遇到java.lang.NullPointerException

json - 使用 Groovy 的 HTTPBuilder 发布 JSON 数据

Android 关闭上一个 Activity

android - 如何快速检查 xml 值所需的 API 级别?

android - 两行约束布局

Android 广播接收器不接收 ACTION_SCREEN_ON

android - 监听android中的硬件按钮点击事件

android - 更新 SDK 后,构建 Android 包失败并显示 'apply' 消息 - 如何修复?

java - 启动 Web 启动应用程序时出现 NullPointerException