Почему я не могу получить действие POWER_CONNECTED? - PullRequest
0 голосов
/ 12 мая 2018

Я изучаю Android. Я динамически регистрирую свой пользовательский приемник вещания CustomBroadcastreceiver в MainActivity.java с кодами ниже:

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;
        }
    }
}

Таким образом, я могу получать трансляцию ACTION_MY_BRODACAST каждый раз, когда нажимаю кнопку, чья onClick равна sendBroadcast(View view). Но когда я подключаю или отключаю 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>

На этот раз я не знаю, что происходит: каждый раз, когда я подключаю зарядную линию, приложение просто сразу падает и возвращается. Я даже не вижу logcat в Android Studio. Чтобы узнать, что на самом деле происходит, я добавляю 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 покажет Custombroadcast Received! после 5-секундного перерыва. При подключении линии зарядки через 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)

Это показывает, что mTextView равно нулю, когда я получаю действие POWER_CONNECTED. Зачем? Я создал экземпляр customReceiver с customReceiver = new CustomBroadcastreceiver(textView); , поэтому mTextView не должен быть нулевым, и на самом деле действие ACTION_MY_BRODACAST заставит mTextView отображать правильный текст без каких-либо ошибок. Наконец, два моих вопроса:

1 мы можем получить только действие POWER_CONNECTED со статической регистрацией на широковещательном приемнике?

2 Почему произошла ошибка?

1 Ответ

0 голосов
/ 12 мая 2018
  1. Трансляция ACTION_POWER_CONNECTED является системной трансляцией. LocalBroadcastManager обрабатывает только широковещательные сообщения, отправленные с LocalBroadcastManager, поэтому ваш зарегистрированный экземпляр Receiver не получит ACTION_POWER_CONNECTED трансляцию. Вам необходимо зарегистрировать свой экземпляр Receiver на Context, например, на Activity.

  2. Элемент <receiver> в манифесте статически регистрирует получатель класс , а не какой-либо существующий экземпляр . Затем этот класс создается системой по мере необходимости, и ни в одном из этих экземпляров не будет установлено поле TextView. Если вы хотите обновить Activity из статически зарегистрированного класса Receiver, вам нужно будет использовать какой-то другой механизм; например, Intent с, LocalBroadcastManager, некоторая другая шина событий и т. д.


Я бы также упомянул, что ACTION_POWER_CONNECTED трансляция не включена в список исключений неявной трансляции для Android 8.0 и выше , поэтому, если ваш targetSdkVersion равен 26+, вы не сможете получать эту трансляцию с Статически зарегистрированный приемник, начиная с Oreo.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...