Android authoritative Programming Guide-notes (27th broadcast Intent)

Source: Internet
Author: User
Tags eventbus

Requirements for this chapter: first, let the app poll for new results and notify the user when something is discovered, even if the app hasn't been opened since the user restarted the device. Second, ensure that users do not notice new results when they use the app.

1. General intent and broadcast intent

Many system components need to know about the occurrence of certain events (WiFi signal is sometimes not, call incoming, etc.), in order to meet such requirements, Andorid provides broadcast intent components.

Broadcast intent works similar to the intent previously learned, but the difference is that broadcast intent can be received by multiple components called broadcast receiver,

2. Accept system broadcast: Wake up after reboot

2.1 Standalone Receiver

Standalone receiver is a broadcast receiver declared in the manifest configuration file. Standalone receiver can be activated even if the application process has been eliminated. (There is also a dynamic receiver that can be bound to the life cycle of the fragemt or activity)

Broadcast receiver must be registered in the system to play a role, if not registered, the system will not know where to send Intent,broadcast receiver Onreceiver () method will not be able to get the scheduled call.

To register broad receiver, you first create it:

 public   Class  Startupreceiver extends   broadcastreceiver { private  static  final     String TAG = "Startupreceiver" ; @Override  public  void   OnReceive (context context, Intent Intent) {//onreceiver is executed in the main thread         log.i (TAG,  "Received Broadcast intent:" + intent.getaction ());  boolean  isOn = Querypreferences.isalarmon        (context);    Pollservice.setservicealarm (context, isOn); }}

Broadcast receiver is a component that accepts intent, and when intent is sent to Startupreceiver, its onreceive () method is called.

Then declare it in the Androidmanifest.xml file:

  

<Usespermissionandroid:name= "Android.permission.RECEIVE_BOOT_COMPLETED" /><receiverAndroid:name=". Startupreceiver "><Intent-filter><ActionAndroid:name= "Android.intent.action.BOOT_COMPLETED"/></Intent-filter></receiver>

Upon completion of the declaration, even if the app is not running, broadcast receiver will wake up to receive the onreceive of Intent,broadcast receiver as long as there is a matching broadcast intent. Intent) method begins execution and is then destroyed.

3. Filter the foreground notification message

Another flaw in the photogallery application is that notification messages, while useful, should not be notified when the app is open.

How to resolve:

First, we send (or receive) a fixed-plate broadcast intent (which eventually locks it, allowing only the Photogallery app to receive it). Second, instead of using the manifest file, use code to dynamically register receiver broadcast intent. (The dynamically registered receiver is bound to the fragment, which is stated in the app when the broadcast is received) Finally, an ordered broadcast is sent to pass the data in a group of receiver to ensure that a receiver is finally run ( The last receiver decides not to display the notification, the receiver is statically registered).

  3.1 Send broadcast intent

To send broadcast intent, you need to create a intent and pass in the Sendbroadcast (intent) method.

 Public Static Final String action_show_notification = "Com.bignerdranch.android.photogallery.SHOW_NOTIFICATION"; Sendbroadcast (  New Intent (action_show_notification));

  3.2 Dynamic broadcast receiver

Dynamic broadcast receiver is the completion of the registration declaration in the Code, not in the configuration file. To enlist in code, you call the Registerreceiver (Broadcastreceiver, Intentfliter) method, and when you cancel the enlistment, the Unregiseterreceiver

(Broadcastreceiver) method. Receiver itself is usually defined as an internal class instance, like a button-click Listener. The Broadcastreceiver in the Registerreceiver () and Unregisterreceiver () methods require the same instance,

We want to only accept the broadcast filter when the app is open, we can't declare a filter in the manifest, but create a broadcast receiver dynamically. Here we create a generic fragment subclass for hiding foreground notifications:

    

 Public Abstract classVisiblefragmentextendsFragment {Private Static FinalString TAG = "Visiblefragment"; @Override Public voidOnStart () {Super. OnStart (); Intentfilter Filter=NewIntentfilter (pollservice.action_show_notification); Getactivity (). Registerreceiver (monshownotification, filter, Pollservice.perm_private,NULL); } @Override Public voidOnStop () {Super. OnStop ();    Getactivity (). Unregisterreceiver (monshownotification); }    PrivateBroadcastreceiver monshownotification =NewBroadcastreceiver () {@Override Public voidOnReceive (Context context, Intent Intent) {//If you receive a broadcast, it means the app is in the foreground, so get rid of ResultCodeLOG.I (TAG, "canceling notification");        Setresultcode (activity.result_canceled); }    };}

  3.3 Using private permissions

There is a problem with dynamic broadcast receiver that any application in the system can listen and trigger our receiver.

There are two ways to stop an app from breaking into our private domain, one way is to add a android:exported= "false" attribute to the receiver tag in the Mainfest configuration file, declaring that it is only used internally by the app.

    

Alternatively, you can create your own permission to do so by adding a permission tag to the Androidmanifest.xml:

<android:name= "Com.bignerdranch.android.photogallery.PRIVATE"android: ProtectionLevel= "signature"/><android:name= " Com.bignerdranch.android.photogallery.PRIVATE "/>

To use a permission, pass it as a parameter to Sendbroadcast (), with this permission, all apps must use the same permissions to accept the intent we send.

How do you protect our broad receiver? Other apps can trigger it by creating their own broadcast intent. Similarly, passing in a custom permission in the Registerreceiver (...) method resolves the problem:

Public  abstractclassextends  Fragment {    ...    @Override    publicvoid  OnStart () {        super. OnStart ();        = Newintentfilter (pollservice.action_show_notification);        Getactivity (). Registerreceiver (monshownotification, filter,        null);    }    ...}   

   

3.3.1 deep learning about security levels          

Custom permissions must specify the Android:protectionlevel property value. Android determines how custom permissions are used based on the value of the ProtectionLevel property. In photogallery applications, the ProtectionLevel we use is signature. The signature security level indicates that if other applications need to use our custom permissions, they must be signed with the same key as the current application. For app-only use-only permissions, choosing the signature security level is appropriate. Since other developers do not have the same key, it is natural that they will not be able to access rights-protected items. In addition, with its own key, it can be used in other applications we develop in the future.

   3.4 Using ordered broadcast

    If you want the program to open without sending a notification, you can no longer let the service be notified because it cannot know the status of the foreground. So we let Pollservice send an orderly broadcast.

     

 Public Static FinalString Request_code = "Request_code"; Public Static FinalString NOTIFICATION = "NOTIFICATION";Private voidShowbackgroundnotification (intRequestcode, Notification Notification) {Intent I=NewIntent (action_show_notification);    I.putextra (Request_code, Requestcode);    I.putextra (NOTIFICATION, NOTIFICATION); Sendorderedbroadcast (i, Perm_private,NULL,NULL, ACTIVITY.RESULT_OK,NULL,NULL);} 

Ordered broadcasts are sent in priority order, first sent to the receiver with high priority, and then to the receiver with low priority. Since it is also necessary to notify after the end of the application, it is clear that the broadcast receiver we are notifying is required to be declared in the manifest file.

The internal implementation is as follows:

    

 Public classNotificationreceiverextendsBroadcastreceiver {Private Static FinalString TAG = "Notificaitonreceiver"; @Override Public voidOnReceive (Context context, Intent Intent) {log.i (TAG,"Received result:" +Getresultcode ()); if(Getresultcode ()! =ACTIVITY.RESULT_OK) {            //The result code of the intent band issued by Pollservice is RESULT_OK//if not, the description is applied to the foreground and the result code is modified.            return; }            //If there is no return, the application is not in the foreground and you can send a notification.         intRequestcode = Intent.getintextra (pollservice.request_code, 0); Notification Notification=(Notification) Intent.getparcelableextra (pollservice.notification); Notificationmanagercompat Notificationmanager=Notificationmanagercompat.from (context);    Notificationmanager.notify (requestcode, notification); }}

  

<receiverAndroid:name=". Notificationreceiver "android:exported= "false">    <!--set the priority here to the lowest, i.e. -999 -    <Intent-filterandroid:priority= " -999">        <ActionAndroid:name= "Com.kniost.photogallery.SHOW_NOTIFICATION" />    </Intent-filter></receiver>

3.5 Receiver with long running tasks

    If you do not want to be constrained and the main thread time limit, want to broadcast intent trigger a long-running task, how to do it?

    • Hand over the task to the service and start the service via broadcast receiver.
    • Use the Broadcastreceiver.getasync () method. the method returns a Broadcastreceiver.pendingresult object that can then be used to provide the result. Therefore, the pendingresult can be handed to Asynctask to run the task, and then call Pendingresult's method to respond to broadcast.
    • The disadvantage of the Goasync () method is that it is not flexible enough. We still need to respond quickly to broadcast (within 10 seconds), and there is no architectural mode option compared to using the service. Of course, the Goasync () method also has obvious advantages: You can call this method to set the result of an ordered broadcast.

3.6 using Eventbus

Broadcast intent enables global messaging within the system. If only the message event broadcast within the app is required, how
What do you do? The answer is to use the event bus.

The idea of event bus is to provide a shared bus or data stream that a part within an app can subscribe to. Event once
Posted to the bus, each subscription part is activated and the corresponding callback code is executed.

The Eventbus, produced by Greenrobot, is a widely known third-party event bus library.

To implement in-app send broadcast intent,android itself also provides a call as localbroadcast-
Manager's broadcast management class, but these third-party libraries are more flexible and convenient to use.

    

Android authoritative Programming Guide-notes (27th broadcast Intent)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.