Android中的廣播(BroadcastReceiver)
阿新 • • 發佈:2018-11-17
廣播的傳送是通過意圖(intent)實現的,那麼廣播的接收呢,使用過Broadcast Receiver來實現的。
廣播分為兩種,一種是標準廣播,另一種是有序廣播。
接收廣播,我們可以動態的註冊也可以靜態的註冊。
下面我們舉一個動態註冊的例子:
package com.example.sunshunli.broadcasttest; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private NetworkChangeReceiver networkChangeReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); IntentFilter intentFilter = new IntentFilter(); //給intentfilter添加個action,因為當網路的緩急變化時就會發注這樣的廣播。 intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE"); networkChangeReceiver = new NetworkChangeReceiver(); //註冊監聽 registerReceiver(networkChangeReceiver,intentFilter); } protected void onDestory(){ super.onDestroy(); unregisterReceiver(networkChangeReceiver); } class NetworkChangeReceiver extends BroadcastReceiver{ @Override public void onReceive(Context context, Intent intent) { //ConnectivityManager是一個系統服務類,專用於網路管理的。 ConnectivityManager connectivityManager =(ConnectivityManager) getSystemService(context.CONNECTIVITY_SERVICE); NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo(); if (networkInfo !=null && networkInfo.isAvailable()){ Toast.makeText(context, "network is avaliable", Toast.LENGTH_SHORT).show(); }else { Toast.makeText(context, "network is not avaliable", Toast.LENGTH_SHORT).show(); } } } }
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
上面的例子是我們動態註冊監聽網路的變化。
我要要監聽它的變化,那麼我們是不是應該有一個監聽器呢,所以我們洗了一個監聽器的類繼承BroadcastReceiver,然後重寫父類onReceive方法。當有廣播到來時onReceive方法搜不會呼叫執行。
我們可以在模擬器的setting中找到datausage,然後每個模擬器還不一樣,你看著哪裡有按鈕可以控制開關就行。
我的是
接下里是靜態註冊開機啟動的例子:
package com.example.sunshunli.broadcasttest; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class BootCompleteReceived extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // TODO: This method is called when the BroadcastReceiver is receiving // an Intent broadcast. Toast.makeText(context, "Boot Complete", Toast.LENGTH_SHORT).show(); throw new UnsupportedOperationException("Not yet implemented"); } }
<receiver
android:name=".BootCompleteReceived"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
</intent-filter>
</receiver>
還是要加上許可權
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
這樣我們的靜態註冊就完成了。
對比一下動態註冊和今天註冊。
1.動態註冊沒有在mainifest檔案中進行接收器的註冊,而靜態的需要註冊。
2.動態註冊我們的action屬性是通過IntentFilter類來實現的,而靜態的是我們手動新增的。
上面我們做的都是系統的一些廣播,接下來我們來發送自定義的廣播。
這是一個標準廣播
package com.example.sunshunli.broadcasttest;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.sunshunli.broadcasttest.my_broadcast");
sendBroadcast(intent);
}
});
}
}
package com.example.sunshunli.broadcasttest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();
}
}
自己需要在mainifest檔案中進行註冊我們的監聽器。
我們在建立一個專案,就是另一個應用程式。試試能不能接受這個廣播。
package com.example.sunshunli.broadcasttest2;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class AnotherBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Toast.makeText(context, "receiver anotherbroadcastreceiver", Toast.LENGTH_SHORT).show();
throw new UnsupportedOperationException("Not yet implemented");
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sunshunli.broadcasttest2">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
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=".AnotherBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.sunshunli.broadcasttest.my_broadcast"/>
</intent-filter>
</receiver>
</application>
</manifest>
答案是肯定的,當我們點選了send按鈕我們的連個專案都會有提示。
下面是我們的有序廣播:
第一個專案:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sunshunli.broadcasttest">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
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=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.example.sunshunli.broadcasttest.my_broadcast"/>
</intent-filter>
</receiver>
</application>
</manifest>
package com.example.sunshunli.broadcasttest;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent("com.example.sunshunli.broadcasttest.my_broadcast");
sendOrderedBroadcast(intent,null);
}
});
}
}
sendOrderedBroadcast(intent,null);傳送有序廣播,第二個引數是與許可權相關的字串。填null就可以。
package com.example.sunshunli.broadcasttest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyBroadcastReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();
abortBroadcast();
}
}
abortBroadcast();是截斷廣播的。
第二個專案:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sunshunli.broadcasttest2">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
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=".AnotherBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="100">
<action android:name="com.example.sunshunli.broadcasttest.my_broadcast"/>
</intent-filter>
</receiver>
</application>
</manifest>
<intent-filter android:priority="100">
是設定優先順序的。
package com.example.sunshunli.broadcasttest2;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
package com.example.sunshunli.broadcasttest2;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class AnotherBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO: This method is called when the BroadcastReceiver is receiving
// an Intent broadcast.
Toast.makeText(context, "receiver anotherbroadcastreceiver", Toast.LENGTH_SHORT).show();
throw new UnsupportedOperationException("Not yet implemented");
}
}
這樣的,話但是接收到後截斷了,第二個就收不到了。