我正在学习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;
}
}
}
这样,每次按下onClick
为sendBroadcast(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 为什么会出现这个错误?
最佳答案
ACTION_POWER_CONNECTED
广播是系统广播。LocalBroadcastManager
仅处理以LocalBroadcastManager
发送的广播,因此您注册的 Receiver 实例将不会获得ACTION_POWER_CONNECTED
播送。您需要在Context
上注册您的 Receiver 实例。 ,就像你的Activity
.<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/