Android
BroadcastReceiver
Sök…
Introduktion
BroadcastReceiver (mottagare) är en Android-komponent som låter dig registrera dig för system- eller applikationshändelser. Alla registrerade mottagare för en händelse meddelas av Android-runtime när denna händelse inträffar.
till exempel en sändning som meddelar att skärmen har stängts av, att batteriet är svagt eller att en bild togs.
Program kan också initiera sändningar - till exempel för att låta andra program veta att en del data har laddats ner till enheten och är tillgängliga för dem att använda.
Introduktion till Broadcast-mottagare
En Broadcast-mottagare är en Android-komponent som låter dig registrera dig för system- eller applikationshändelser.
En mottagare kan registreras via AndroidManifest.xml
filen eller dynamiskt via Context.registerReceiver()
.
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Your implementation goes here.
}
}
Här har jag tagit ett exempel på ACTION_BOOT_COMPLETED
som avfyras av systemet när Android har slutfört startprocessen.
Du kan registrera en mottagare i manifestfil som denna:
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<receiver android:name="MyReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED">
</action>
</intent-filter>
</receiver>
</application>
Nu startas enheten, onReceive()
-metoden kommer att onReceive()
och sedan kan du göra ditt arbete (t.ex. starta en tjänst, starta ett larm).
BroadcastReceiver Basics
BroadcastReceivers används för att ta emot sändnings avsikter som skickas av Android OS, andra program, eller inom samma app.
Varje Intent skapas med en Intent Filter, som kräver en sträng åtgärd. Ytterligare information kan konfigureras i avsikt.
På samma sätt registrerar BroadcastReceivers att ta emot avsikter med ett visst avsiktsfilter. De kan registreras programmatiskt:
mContext.registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//Your implementation goes here.
}
}, new IntentFilter("Some Action"));
eller i filen AndroidManifest.xml
:
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="Some Action"/>
</intent-filter>
</receiver>
För att få avsikten, ställ in åtgärden till något som är dokumenterat av Android OS, av en annan app eller API eller i din egen applikation med hjälp av sendBroadcast
:
mContext.sendBroadcast(new Intent("Some Action"));
Dessutom kan avsikten innehålla information, till exempel strängar, primitiv och paket , som kan ses i onReceive
.
Använda LocalBroadcastManager
LocalBroadcastManager används för att skicka Broadcast Intents inom en applikation utan att utsätta dem för oönskade lyssnare.
Att använda LocalBroadcastManager är mer effektivt och säkrare än att använda context.sendBroadcast()
direkt, eftersom du inte behöver oroa dig för några sändningar som förfalskats av andra applikationer, vilket kan utgöra en säkerhetsrisk.
Här är ett enkelt exempel på att skicka och ta emot lokala sändningar:
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("Some Action")) {
//Do something
}
}
});
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(mContext);
manager.registerReceiver(receiver, new IntentFilter("Some Action"));
// onReceive() will be called as a result of this call:
manager.sendBroadcast(new Intent("Some Action"));//See also sendBroadcastSync
//Remember to unregister the receiver when you are done with it:
manager.unregisterReceiver(receiver);
Bluetooth Broadcast-mottagare
lägg tillåtelse i din manifestfil
<uses-permission android:name="android.permission.BLUETOOTH" />
I ditt fragment (eller aktivitet)
- Lägg till mottagarmetoden
private BroadcastReceiver mBluetoothStatusChangedReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final Bundle extras = intent.getExtras();
final int bluetoothState = extras.getInt(Constants.BUNDLE_BLUETOOTH_STATE);
switch(bluetoothState) {
case BluetoothAdapter.STATE_OFF:
// Bluetooth OFF
break;
case BluetoothAdapter.STATE_TURNING_OFF:
// Turning OFF
break;
case BluetoothAdapter.STATE_ON:
// Bluetooth ON
break;
case BluetoothAdapter.STATE_TURNING_ON:
// Turning ON
break;
}
};
Registrera sändning
- Ring den här metoden på onResume ()
private void registerBroadcastManager(){
final LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());
manager.registerReceiver(mBluetoothStatusChangedReceiver, new IntentFilter(Constants.BROADCAST_BLUETOOTH_STATE));
}
Avregistrera sändningen
- Ring den här metoden på OnPause ()
private void unregisterBroadcastManager(){
final LocalBroadcastManager manager = LocalBroadcastManager.getInstance(getActivity());
// Beacon機能用
manager.unregisterReceiver(mBluetoothStatusChangedReceiver);
}
Aktivera och inaktivera en Broadcast-mottagare programmatiskt
För att aktivera eller inaktivera en BroadcastReceiver
, måste vi få en referens till PackageManager
och vi behöver ett ComponentName
objekt som innehåller klassen för mottagaren vi vill aktivera / inaktivera:
ComponentName componentName = new ComponentName(context, MyBroadcastReceiver.class);
PackageManager packageManager = context.getPackageManager();
Nu kan vi anropa följande metod för att aktivera BroadcastReceiver
:
packageManager.setComponentEnabledSetting(
componentName,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
Eller så kan vi istället använda COMPONENT_ENABLED_STATE_DISABLED
att inaktivera mottagaren:
packageManager.setComponentEnabledSetting(
componentName,
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
BroadcastReceiver för att hantera BOOT_COMPLETED-händelser
Exempel nedan visar hur man skapar en BroadcastReceiver
som kan ta emot BOOT_COMPLETED
händelser. På det här sättet kan du starta en Service
eller starta en Activity
så snart enheten startades.
Du kan också använda BOOT_COMPLETED
händelser för att återställa dina larm eftersom de förstörs när enheten är avstängd.
OBS! Användaren måste ha startat applikationen minst en gång innan du kan få åtgärden BOOT_COMPLETED
.
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.example" >
...
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
...
<application>
...
<receiver android:name="com.test.example.MyCustomBroadcastReceiver">
<intent-filter>
<!-- REGISTER TO RECEIVE BOOT_COMPLETED EVENTS -->
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
MyCustomBroadcastReceiver.java
public class MyCustomBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action != null) {
if (action.equals(Intent.ACTION_BOOT_COMPLETED) ) {
// TO-DO: Code to handle BOOT COMPLETED EVENT
// TO-DO: I can start an service.. display a notification... start an activity
}
}
}
}
Exempel på en LocalBroadcastManager
En BroadcastReceiver är i princip en mekanism för att vidarebefordra avsikter genom operativsystemet för att utföra specifika åtgärder. En klassisk definition är
"En Broadcast-mottagare är en Android-komponent som låter dig registrera dig för system- eller applikationshändelser."
LocalBroadcastManager är ett sätt att skicka eller ta emot sändningar inom en ansökningsprocess. Denna mekanism har många fördelar
- eftersom uppgifterna förblir inuti applikationsprocessen kan data inte läckas ut.
- LocalBroadcasts lösas snabbare, eftersom upplösningen av en normal sändning sker under körning i hela OS.
Ett enkelt exempel på en LocalBroastManager är:
SenderActivity
Intent intent = new Intent("anEvent");
intent.putExtra("key", "This is an event");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
ReceiverActivity
- Registrera en mottagare
LocalBroadcastManager.getInstance(this).registerReceiver(aLBReceiver, new IntentFilter("anEvent"));
- Ett konkret objekt för att utföra åtgärder när mottagaren anropas
private BroadcastReceiver aLBReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { // perform action here. } };
- avregistrera när vyn inte syns längre.
@Override protected void onPause() { // Unregister since the activity is about to be closed. LocalBroadcastManager.getInstance(this).unregisterReceiver(aLBReceiver); super.onDestroy(); }
Kommunicera två aktiviteter genom anpassad Broadcast-mottagare
Du kan kommunicera två aktiviteter så att aktivitet A kan meddelas om en händelse som händer i aktivitet B.
Aktivitet A
final String eventName = "your.package.goes.here.EVENT";
@Override
protected void onCreate(Bundle savedInstanceState) {
registerEventReceiver();
super.onCreate(savedInstanceState);
}
@Override
protected void onDestroy() {
unregisterEventReceiver(eventReceiver);
super.onDestroy();
}
private void registerEventReceiver() {
IntentFilter eventFilter = new IntentFilter();
eventFilter.addAction(eventName);
registerReceiver(eventReceiver, eventFilter);
}
private BroadcastReceiver eventReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//This code will be executed when the broadcast in activity B is launched
}
};
Aktivitet B
final String eventName = "your.package.goes.here.EVENT";
private void launchEvent() {
Intent eventIntent = new Intent(eventName);
this.sendBroadcast(eventIntent);
}
Naturligtvis kan du lägga till mer information i sändningen och lägga till extra till avsikt som ges mellan aktiviteterna. Inte läggs till för att hålla exemplet så enkelt som möjligt.
Klibbig sändning
Om vi använder metoden sendStickyBroadcast (avsikt) är motsvarande avsikt klibbig, vilket innebär att avsikten du skickar kvarstår efter att sändningen är klar. En StickyBroadcast som namnet antyder är en mekanism för att läsa data från en sändning, efter att sändningen är klar. Detta kan användas i ett scenario där du kanske vill kontrollera säga i en Activity's onCreate()
värdet på en nyckel i avsikten innan den aktiviteten startades.
Intent intent = new Intent("com.org.action");
intent.putExtra("anIntegerKey", 0);
sendStickyBroadcast(intent);
Med hjälp av beställda sändningar
Beställda sändningar används när du behöver ange en prioritet för sändningslyssnare.
I det här exemplet kommer firstReceiver
att ta emot sändning alltid innan än en secondReceiver
:
final int highPriority = 2;
final int lowPriority = 1;
final String action = "action";
// intent filter for first receiver with high priority
final IntentFilter firstFilter = new IntentFilter(action);
first Filter.setPriority(highPriority);
final BroadcastReceiver firstReceiver = new MyReceiver();
// intent filter for second receiver with low priority
final IntentFilter secondFilter = new IntentFilter(action);
secondFilter.setPriority(lowPriority);
final BroadcastReceiver secondReceiver = new MyReceiver();
// register our receivers
context.registerReceiver(firstReceiver, firstFilter);
context.registerReceiver(secondReceiver, secondFilter);
// send ordered broadcast
context.sendOrderedBroadcast(new Intent(action), null);
Vidare kan sändningsmottagare avbryta beställd sändning:
@Override
public void onReceive(final Context context, final Intent intent) {
abortBroadcast();
}
i detta fall får inte alla mottagare med lägre prioritet ett sändningsmeddelande.
Android stoppat tillstånd
Från och med Android 3.1 placeras alla applikationer i stoppläge vid installationen. Medan det är i stoppat tillstånd, kommer inte applikationen att köras av någon anledning, förutom genom en manuell lansering av en aktivitet eller en uttrycklig avsikt som adresserar en aktivitet, tjänst eller sändning.
När du skriver systemapp som installerar APKs direkt ska du ta hänsyn till att den nyinstallerade APP inte kommer att få några sändningar förrän den har flyttats till ett icke stoppat tillstånd.
Ett enkelt sätt att aktivera en app är att skicka en uttrycklig sändning till den här appen. eftersom de flesta appar implementerar INSTALL_REFERRER
, kan vi använda det som en kopplingspunkt
Skanna manifestet för den installerade appen och skicka en uttrycklig sändning till varje mottagare:
Intent intent = new Intent();
intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
intent.setComponent(new ComponentName(packageName, fullClassName));
sendBroadcast(intent);