Broadcast RecevierレビューおよびカスタムDeviceAdminReceiverテンプレートの完備

13546 ワード

Broadcast Recevierブロードキャスト受信機は、ブロードキャスト通知情報の受信に専念し、対応する処理を行うコンポーネントである.多くのブロードキャストは、タイムゾーンの変更を通知したり、バッテリーの電力が低くなったり、写真を撮ったり、ユーザーが言語オプションを変更したりするシステムコードに由来します.アプリケーションは、他のアプリケーションにデータのダウンロードが完了し、使用可能な状態にあることを通知するなど、ブロードキャストすることもできます.アプリケーションは、興味のあるすべての通知情報に応答するために、任意の数のブロードキャスト受信機を有することができる.すべての受信機はBroadcastReceiverベースクラスから継承されます.ブロードキャスト受信機にはユーザインタフェースがありません.ただし、受信した情報に応答するactivityを起動したり、NotificationManagerでユーザーに通知したりすることができます.通知は、バックライトの点滅、振動、音声の再生など、ユーザーの注意力を引き付けるために多くの方法があります.一般的には、ステータスバーに永続的なアイコンを配置し、ユーザーはそれを開いてメッセージを取得することができます.Android Broadcast Securityから抜粋
一、API解読
BroadcastReceiver
  • 抽象クラス、javaから継承する.lang.Object,クラスの宣言:public abstract class BroadcastReceiver
  • API位置:android.content.BroadcastReceiver
  • 直接サブクラス:AppWidgetProvider,DeviceAdminReceiver,MediaButtonReceiver,RestrictionsReceiver,WakefulBroadcastReceiver
  • これはsendBroadcast()によって送信されるIntentのコードを受け入れるベースクラスである.broadcastが自分のアプリケーション内でのみ受信を送信する場合は、LocalBroadcastManagerクラスを使用することを考慮すべきであり、ブロードキャスト受信機の登録方式は2種類ある
  • クラスに動的に登録する
  • AndroidManifest.xmlにはラベルで登録し、動的登録にはActivity.onResume()で実装された登録イベントはActivity.onPause(). 登録をキャンセルします.

  • 受信可能な放送は2種類ございます
  • 通常放送、Context.sendBroadcastは送信し、Normal broadcastsは完全に非同期であり、すべての受信者に同じ時間に受信することができる.メッセージの伝達効率が高い.しかしながら、受信者が受信メッセージの処理情報を次の受信者に伝えることも、メッセージの伝播を停止することもできないという欠点がある.
  • は秩序ある放送であるContext.sendOrderedBroadcast送信は,設定された優先度に応じてブロードキャスト送信の送信順序を決定する.Ordered broadcastsの受信者は、一定の優先度でメッセージの受信を行う.例えば、A,B,Cの優先度が順次低下すると、メッセージはまずAに伝達され、Bに伝達され、最後にCに伝達される.「優先度宣言」では、[-10001000]の値が大きいほど優先度が高くなります.優先度はfilterでもよい.setPriority(10)方式で設定します.また、Ordered broadcastsの受信者はabortBroadcast()でブロードキャストの伝播をキャンセルしたり、setResultDataとsetResultExtras法で処理の結果をBroadcastに格納して次の受信者に渡したりすることができる.次に、次の受信者は、getResultData()およびgetResultExtras(true)を介して、優先度の高い受信者が格納したデータを受信する.Androidが開発したBroadcastReceiverの詳細
  • から抜粋
    なお、このようなIntent broadcastメカニズムは、ブロードキャストもintentクラスを介して送信受信が、Context.startActivity()Activitiesを起動するintentは異なる概念です
    セキュリティ:
    Context APIsでReceiversを実現することで,その誇示応用の性質が与えられる.他のプログラムがこれらのブロードキャスト受信機を乱用することを考慮する必要があります.
  • intentネーミングスペースはグローバルであり、定義された意図動作名と他の文字列が独自であることを確保し、何気なく他のアプリケーションと衝突することを防止する
  • .
  • ブロードキャストを登録する場合、どの受信機がそれを受け入れることができるかを決定する権限を設定する
  • .
  • はAndroidManifestにあります.xmlにブロードキャストを登録するときに意図フィルタが設定され、他のアプリケーションもこの意図フィルタを介してブロードキャストを送信し、送信を阻止する場合はandroid:exported="false"
  • を設定する.
  • ブロードキャスト受信機の権限を設定することによって、誰が誰のブロードキャストを受け入れることができるかを制限することができるほか、ICE_CREAM_SANDWICH、開始、Intentを呼び出すことができます.setPackageは、単一のパケット受信ブロードキャスト
  • を設定する.
    LocalBroadcastManagementを使用すると、プロセス外で伝達されないことを意図しています.これらの問題はありません.
    レシーバライフサイクル:
    BroadcastReceiverオブジェクトはonReceive(Context,Intent)を呼び出す間のみ有効であり、このメソッドでreturnを行うと、システムは終了すると判断し、実行しない.このメソッドでは、非同期または時間のかかる操作はできません.特に、BroadcastReceiverを使用してダイアログボックスやバインドサービスを表示することはできません.前者では、NotificationManager APIを使用できます.後者の場合、Context.を呼び出すことでstartService()はサービスにコマンドを送信する.
    プロセスライフサイクル:
    BroadcastReceiverを実行しているプロセス(つまりonReceive(Context,Intent)メソッドを実行している)は、フロントプロセスとして扱われ、メモリが不足している場合でも実行を維持します.onReceive()でreturnを実行すると、BroadcastReceiverは実行されなくなり、ホストプロセスの重要度は他のコンポーネントと同じになります.この性質は重要です.ホストプロセスにBroadcastReceiverが1つしか含まれていない場合、onReceive()でreturnを使用すると、BroadcastReceiverは終了します.プロセスは空のプロセスです.システムは他のより重要なプロセスにメモリリソースを提供してこのプロセスを殺します.これは、いくつかの時間のかかる操作では、サービスを使用してBroadcastReceiverを組み合わせる必要があり、操作時間内にプロセスが常に有効であることを保証します.
    LocalBroadcastManager
  • エンティティクラスはjavaから継承する.lang.Object,クラスの宣言:public final class LocalBroadcastManager
  • API位置:android.support.v4.content.LocalBroadcastManager

  • プロセスでローカルオブジェクトに登録してブロードキャストを送信します.これはsendBroadcast(Intent)を使用して送信されるグローバルなブロードキャストよりも利点があります.
  • ブロードキャスト中のデータがアプリケーションから離れないことを知っているので、プライバシーデータの漏洩を心配する必要はありません.
  • 他のアプリケーションでは、これらのブロードキャストをアプリケーションに送信することはできません.そのため、人々が利用できるセキュリティ・ホールが発生する心配はありません.
  • システムで送信されるグローバルブロードキャストよりも効率的である
  • LocalBroadcastManagerはcontext版のBroadcastの縮小版と考えられていますが似たような使い方です
    二、コードの例
    ブロードキャストの発行:
    1,BroadcastReceiverを起動するintent 2を作成し,ブロードキャストを送信する.
  • 通常放送sendBroadcast(Intent intent)、またはsendBroadcast(Intent intent,String receiverPermission)
  • を送信
  • 秩序化ブロードキャストsendOrderedBroadcast(Intent intent,String receiverPermission)、またはsendOrderedBroadcast(Intent intent,String receiverPermission,BroadcastReceiver resultReceiver,Handler scheduler,int initialCode,String initialData,Bundle initialExtras)
  • を送信
  • ローカルブロードキャストsendBroadcast()をローカルブロードキャスト
  • のみをローカルブロードキャストする
    Intent intent=new Intent();//  Intent
    intent.setAction("android.accessibilityservice.AccessibilityService");//                  intent  
    //intent.setClassName(context,"  ");//            
    //intent.setPackage("  ");//           
    //intent.setClass(context,class);//            
    // context.sendBroadcast(intent);//           
    //context.sendUrderedBroadcast(intent,null);//           
    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);//      

    ブロードキャスト受信機の作成:
    BroadcastReceiverの継承:
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    
    public class MyReceiver extends BroadcastReceiver {
        public MyReceiver() {
        }
        @Override
        public void onReceive(Context context, Intent intent) {
        }
    }

    ブロードキャストの登録:
    静的登録:
    ".MyReceiver"
        android:enabled="true"
        android:exported="true"  //  LocalBroadcastManager ,   false
        android:permission="android.permission.   ">
        
            "android.accessibilityservice.AccessibilityService"/> //   
        
    

    動的登録:
    MyReceiver receiver=new MyReceiver();
    IntentFilter filter=new IntentFilter();
    filter.addAction("android.accessibilityservice.AccessibilityService");
    //  receiver
    registerReceiver(receiver, filter);
    //    receiver
    unregisterReceiver(receiver);

    この場合、newでブロードキャストを作成することもできます.
    BroadcastReceiver broadcastReceiver=new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
            }
        };

    秩序化されたブロードキャスト受信機の受信ブロードキャストの優先度の設定
    静的登録時:
    "200">
        "android.accessibilityservice.AccessibilityService"/>
    

    動的登録時:
    filter.setPriority(200);

    三、おすすめ読書
    きそ
    Android開発のBroadcastReceiver詳細
    深く入り込む
    Broadcast内部メカニズム説明Android Broidcast Security
    四、前回のカスタムDeviceAdminReceiverテンプレートを完備する
    DeviceAdminReceiver.java.ftl
    import android.app.admin.DeviceAdminReceiver;
    import android.app.admin.DevicePolicyManager;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.os.Build;
    
    /**
     *   :liuyaowei;  :2016-07-14.
     * QQ:1054185214
     *    :                :  --     --     
     */
    public class ${className} extends DeviceAdminReceiver {
    
    
        public ${className}() {
        }
    
        @Override
        public DevicePolicyManager getManager(Context context) {
            return (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
        }
    
        @Override
        public ComponentName getWho(Context context) {
            return new ComponentName(context, ${className}.class);
        }
    
        /**   
         *              
         * @param context
         * @param intent
         */
        @Override
        public void onReceive(Context context, Intent intent) {
            int flags=intent.getFlags();
            if (!getManager(context).isAdminActive(getWho(context))){
                // Launch the activity to have the user enable our admin.
                Intent a = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
                a.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, getWho(context));
                a.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "555555");//    
                context.startActivity(a);
            }else {
                   switch (flags){
                       case 0:
                           getManager(context).lockNow();
                           break;//  
                       case 1:
                           getManager(context).wipeData(DevicePolicyManager.WIPE_EXTERNAL_STORAGE);
                           break; //      
                       case 2:
                           getManager(context).wipeData(DevicePolicyManager.WIPE_RESET_PROTECTION_DATA);
                           break;  //      
                       case 3:
                           if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                               getManager(context).reboot(getWho(context));
                           }
                           break; //  
                       case 4:
                           getManager(context).resetPassword("",DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED);
                           break; //      
                       case 5:
                           getManager(context).removeActiveAdmin(getWho(context));
                           break;//         
                       default:
                           break; //    
                   }
                }
        }
    
         /**
         *              
         * @param context
         * @param flag
         */
        public static void sendBroadcast(Context context,int flag){
            Intent intent=new Intent();
            intent.setAction("android.app.action.DEVICE_ADMIN_ENABLED");
            intent.addFlags(flag);
            context.sendBroadcast(intent,"android.permission.BIND_DEVICE_ADMIN");
        }
    }

    liuyaowei/DeviceAdminReceiver完