今天樓主在寫一個廣播的demo,功能非常的簡單,就是一個應用發送一個自定義的廣播,同時在這個應用里面定義了一個廣播接受者,並且在AndroidManifest文件中進行靜態的注冊。Demo看上去非常的簡單,但是在Android 8.0的設備運行這個應用,始終不能接收到這個發送出去的廣播,感覺非常的蒙蔽。關鍵是,在Android 7.0的設備是能夠接收到的!
1. 原因
看到這個情況,我就覺得不是我的代碼問題,應該是Android 8.0相較於Android 8.0之前的設備有所變換,於是Google了一把,果然被我找到了問題所在。在Google爸爸的Android官網找到了Android 8.0行為變更的介紹,其中有一句說的是:

這句話的意思就是說,在Android 8.0的平台上,應用不能對大部分的廣播進行靜態注冊,也就是說,不能在AndroidManifest文件對有些廣播進行靜態注冊,這里必須強調是有些廣播,因為有些廣播還是能夠注冊的。比如,經過樓主測試,對接收Android 開機的廣播通過靜態注冊還是能夠正常接收的。
Android 8.0行為變更的介紹鏈接: https://developer.android.com/about/versions/oreo/android-8.0-changes.html?hl=zh-cn,前面那個鏈接必須通過FQ,當然我們提倡科學上網,所以國內鏡像網站鏈接: https://developer.android.google.cn/about/versions/oreo/android-8.0.html。
2. 解決辦法
前面我們知道了是什么原因導致的,只要知道了原因,解決辦法就非常容易的想出來的。
我們知道廣播的注冊方式分為兩種:
1. 靜態注冊,也就是說在AndroidManifest文件中對BroadcastReceiver進行注冊,通常還會加上action用來過濾。
2. 動態注冊,調用Context中的registerReceiver對廣播進行動態注冊,使用unRegisterReceiver方法對廣播進行取消注冊的操作。
3. 代碼
MainActivity文件的代碼
public class MainActivity extends AppCompatActivity { private Button mButton = null; private IntentFilter mIntentFilter = null; private MyBroadcastReceiver mMyBroadcastRecvier = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //過濾器 mIntentFilter = new IntentFilter("pby"); //創建廣播接收者的對象 mMyBroadcastRecvier = new MyBroadcastReceiver(); //注冊廣播接收者的對象 registerReceiver(mMyBroadcastRecvier, mIntentFilter); mButton = (Button) findViewById(R.id.id_button); mButton.setOnClickListener(new View.OnClickListener(){ @Override public void onClick(View v) { Intent intent = new Intent("pby"); //發送一個廣播 sendBroadcast(intent); } }); } @Override protected void onDestroy() { super.onDestroy(); //取消廣播接收者的注冊 unregisterReceiver(mMyBroadcastRecvier); } }
MyBroadcastReceiver文件的代碼
public class MyBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { Toast.makeText(context, "收到了自定義的廣播", Toast.LENGTH_LONG).show(); } }
只有上面的簡單配置,沒有修改AndroidManifest文件中任何的代碼
效果圖:
