为什么我的 BroadCast 接收器不工作?

Why is my BroadCast Receiver not working?

我正在学习广播接收器。我试图通过以下代码实现的是,当我切换到飞行模式时,无论应用程序是否打开,我都希望看到祝酒词。我没有做什么/做错了什么?请帮忙。谢谢

ConnectivityChangedReceiver.java class

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.widget.Toast;

public class ConnectivityChangedReceiver extends BroadcastReceiver {

@Override
public void onReceive( Context context, Intent intent )
{
    Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show();

}
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.READ_PHONE_STATE"></uses-permission>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<uses-permission android:name="android.permission.SEND_SMS"/>
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

    <receiver android:name=".ConnectivityChangedReceiver">
        <intent-filter>
            <action android:name="android.intent.action.AIRPLANE_MODE">
            </action>
        </intent-filter>

    </receiver>

</application>

MainActivity.java`

 import android.support.v7.app.AppCompatActivity;
 import android.os.Bundle;
 import android.content.Intent;


 import java.util.ArrayList;

 public class MainActivity extends AppCompatActivity {

private TextView switchStatus;
private Switch mySwitch;


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

您必须在 manifest.xml 文件中启用广播:

<receiver android:enabled="true" android:name=". ConnectivityChangedReceiver">
    <intent-filter>
        <action android:name="android.intent.action.AIRPLANE_MODE"/>
    </intent-filter>
</receiver>

像这样尝试,尝试添加,android:exported="true":

//也添加这个权限

<uses-permission android:name="android.permission.WRITE_SETTINGS" />


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

The Real state is determined like this:

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

        boolean isAirplaneModeOn = intent.getBooleanExtra("state", false);
        if(isAirplaneModeOn){

           // handle Airplane Mode on
        } else {
           // handle Airplane Mode off
        }
    }

Broadcast Receivers官方文档说:

android:exported

广播接收器是否可以从其应用程序之外的来源接收消息 - "true" 如果可以,"false" 如果不能。如果"false",广播接收器只能接收由同一应用程序的组件或具有相同用户 ID 的应用程序发送的消息。

所以我刚刚找到了上面问题的解决方案。 我变了

<receiver android:name=".ConnectivityChangedReceiver">

<receiver android:name="ConnectivityChangedReceiver">

(去掉名字开头的'.' 希望对迷路的有帮助!

您需要将接收器放入捆绑包中:

package my.bundles.id;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.widget.Toast;

public class ConnectivityChangedReceiver extends BroadcastReceiver {

@Override
public void onReceive( Context context, Intent intent )
{
    Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show();

}
}

你应该把它放在一个与 bundleId 相同的包中,这样才能让上面的工作正常进行。名称字段中的第一个点表示 Class 是 bundles 命名空间的成员。所以,因为它不在包裹中,所以点让它看起来在错误的地方。

来自 android 文档:

https://developer.android.com/guide/components/broadcast-exceptions

As part of the Android 8.0 (API level 26) Background Execution Limits, apps that target the API level 26 or higher can no longer register broadcast receivers for implicit broadcasts in their manifest. However, several broadcasts are currently exempted from these limitations. Apps can continue to register listeners for the following broadcasts, no matter what API level the apps target.

https://developer.android.com/distribute/best-practices/develop/target-sdk

Google Play will require that new apps target at least Android 8.0 (API level 26) from August 1, 2018, and that app updates target Android 8.0 from November 1, 2018.

"android.intent.action.AIRPLANE_MODE" 不再在豁免广播列表中。因此,在 activity 而不是 AndroidManifest 中注册您的广播接收器。

如果您 API 级别高于 26,您应该像这样向您的代码添加权限:

super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
   
val _receiver = cSmsListener() //<--you BroadCastreciever class 
val intentFilter = IntentFilter()

intentFilter.addAction(Telephony.Sms.Intents.SMS_RECEIVED_ACTION)
getApplicationContext().registerReceiver(_receiver, intentFilter);

var myPermission: Array<String> = arrayOf(Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS)
ActivityCompat.requestPermissions(this, myPermission,1)