AlarmManager (目覚まし時計サービス)


このセクションの紹介:

このセクションでは、Android の AlarmManager (目覚まし時計サービス) を紹介します。その名前から、それを通じてモバイル目覚まし時計アプリを開発できることがわかります。 ドキュメントの説明は次のとおりです。 簡単に言うと、特定の瞬間に指定されたインテントをブロードキャストします。 次に、時間切れになると、AlarmManager は設定したインテントをブロードキャストします。たとえば、時間切れになると、特定のインテントを指定できます。 アクティビティまたはサービス!さらに、公式ドキュメントには注意すべき点がいくつかあります:

1.png
もう 1 つ注意すべきことは、AlarmManager は主に、特定の時点でアプリが実行されている場合でも、コードを実行するために使用されることです。 時間は流れていない!また、API 19 以降では、アラーム メカニズムが正確に渡されず、オペレーティング システムがアラーム クロックを変換します。 、ウェイクアップとバッテリーの使用量を最小限に抑えます。一部の新しい API は厳密に正確な配信をサポートします。を参照してください。 setWindow(int,long,long,PendingIntent) および setExact(int,long,PendingIntent)。 API 19 より前の TargetSdkVersion アプリケーションは引き続き以前の動作を使用し、すべてのアラームは必要なときに正確に配信されます。 次回からはきちんとお届けいたします。詳細については、公式 API ドキュメントを参照してください: AlarmManager

1 Timer クラスと AlarmManager クラスの違い:

J2SE を学習したことがある場合は、Timer に精通しているはずです。タイマーは通常、スケジュールされたタスクを書き込むときに使用されます。 それは間違いなく彼と切り離せないものですが、Android には欠点があり、バックグラウンドで長時間実行する必要があるものには適していません。 スケジュールされたタスク。Android デバイスには独自のスリープ ポリシーがあるため、長時間操作がない場合、デバイスは自動的に CPU を起動します。 スリープ状態。これにより、タイマーでスケジュールされたタスクが適切に実行されなくなる可能性があります。そしてAlarmManagerは存在しません この場合、CPU をウェイクアップする機能があるため、特定のタスクを実行する必要があるたびに CPU が正常に動作できるようになります。 つまり、CPU がスリープしているときに登録された目覚まし時計は保持されます (CPU をウェイクアップできます)。ただし、デバイスの電源がオフになったり再起動されたりすると、 アクティブにするとアラームは解除されます。 (Androidスマホの電源が切れていると目覚まし時計は鳴りません…)


2. AlarmManager インスタンスオブジェクトを取得します:

AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

3. 関連メソッドの説明:

  • set(int type, long startTime, PendingIntent pi): ワンタイムアラームクロック
  • setRepeating(int)タイプ、長い startTime、長い intervalTime、PendingIntent pi): 繰り返し目覚まし時計は 3 とは異なります。 3 目覚まし時計の間隔時間は固定されていません
  • setInexactRepeating (int 型、long startTime、long intervalTime、PendingIntent pi): 定期的な目覚まし時計、時間は固定されていません
  • cancel(PendingIntent pi): AlarmManager のスケジュールされたサービスをキャンセルします
  • getNextAlarmClock(): 次の目覚まし時計を取得、戻り値 AlarmManager.AlarmClockInfo
  • setAndAllowwhileIdle(int)タイプ、長いtriggerAtMillis、PendingIntentオペレーション) set メソッドと同様に、この目覚まし時計は、システムが低電力モードの場合に有効です
  • setExact(int 型、longtriggerAtMillis、PendingIntent 操作): 指定した時刻に目覚まし時計を正確に実行します。これは、set メソッドよりも正確です。デフォルトのタイムゾーン
  • setWindow(int型、long windowStartMillis、long windowLengthMillis、PendingIntent操作): 指定された時間枠内でアラームが鳴るように設定します。 set と同様に、この方法を使用すると、アプリケーションはオペレーティング システムの調整を正確に制御できます。 アラームのトリガー時間全体の範囲。
  • 主要パラメータの説明
  • :
    • タイプ(目覚まし時計タイプ): オプションの値は 5 つあります。 アラームマネージャー.ELAPSED_REALTIME: 電話機がスリープ状態の場合、目覚まし時計は使用できません。この状態では、目覚まし時計は相対時間を使用し(システムの起動開始を基準にして)、状態値は 3 です。 AlarmManager.ELAPSED_REALTIME_WAKEUP目覚まし時計はシステムをウェイクアップし、スリープ状態でプロンプト機能を実行します。この状態では、目覚まし時計も相対時間を使用し、ステータス値は 2 です。 AlarmManager.RTC スリープ状態では目覚まし時計は使用できません。この状態では、目覚まし時計は現在のシステム時間である絶対時間を使用し、ステータス値は 1 です。 AlarmManager.RTC_WAKEUP は、目覚まし時計がシステムをウェイクアップし、スリープ状態でプロンプト機能を実行することを意味します。この状態では、目覚まし時計は絶対時間を使用し、ステータス値は 0 です。 AlarmManager.POWER_OFF_WAKEUP は、電話機の電源がオフのときに目覚まし時計もプロンプト機能を正常に実行できることを意味するため、5 つの状態の中で最もよく使用される状態の 1 つです。この状態では、目覚まし時計も絶対時間を使用します。 、状態値は 4 ですが、この状態は SDK バージョンの影響を受けるようで、一部のバージョンはそれをサポートしていません
    • startTime: 目覚まし時計の最初の実行時間 (ミリ秒単位)。カスタマイズできますが、通常は現在の時刻が使用されます。 最初のパラメータに対応する目覚まし時計が相対時間を使用する場合、この属性は最初の属性 (タイプ) と密接に関連していることに注意してください。 (ELAPSED_REALTIME および ELAPSED_REALTIME_WAKEUP) の場合、この属性は相対時間を使用する必要があります (システム起動時間に相対)、たとえば、現在時間は次のように表されます。 SystemClock.elapsedRealtime(); 最初のパラメータに対応する目覚まし時計が絶対時間を使用する場合 (RTC、RTC_WAKEUP、POWER_OFF_WAKEUP)、 この場合、この属性は絶対時間を使用する必要があります。たとえば、現在時刻は System.currentTimeMillis() のように表現されます。
    • intervalTime: 2 つの目覚まし時計の実行間隔をミリ秒単位で示します。
    • PendingIntent: ブロードキャストの送信、プロンプトの表示など、目覚まし時計の実行アクションをバインドします。 PendingIntent は、Intent のカプセル化クラスです。アラーム プロンプトがサービスの開始によって実装されている場合は、Pending.getService を使用して PendingIntent オブジェクトを取得する必要があることに注意してください。 (Context c, int i, Intent 意図, int j) メソッド。目覚まし時計がブロードキャストを通じて実装される場合。 PendingIntent オブジェクトを取得するには、PendingIntent.getBroadcast を使用する必要があることに注意してください。 (Context c, int i, Intenttent, int j) メソッド (アクティビティを使用して実装されている場合)。 目覚まし時計のプロンプトが表示される場合は、次を使用して PendingIntent オブジェクトを取得する必要があります。 PendingIntent.getActivity(Context c,int i,Intenttent,int j) メソッド。 これら 3 つの方法が誤って使用された場合、エラーは報告されませんが、アラーム プロンプトの効果は表示されません。

    4. 使用例: 単純なスケジュールされたタスク

    私が言いたいのは、この例は Android 4.4 より前のシステムでのみ実行可能であり、将来 5.0 以降になる場合には実行可能ではないということです。 上記の AlarmManager ソリューションは、やがて追加される予定です。さらに、ここで set メソッドを使用することは、必要に応じて少し不正確になる可能性があります。 より正確には、setExtra() メソッドを使用して AlarmManager を設定できます。

    レンダリングの実行:

    2.png3.png

    実装コード:

    最初に単純なレイアウト ファイル: activity_main.xml 、さらに res は raw フォルダーを作成し、その中に音声ファイルを置きます。 さらに、目覚まし時計が鳴ったときのActivityのレイアウトとして、外側のレイアウトのみでactivity_track.xmlを作成します!何もなければ投稿しません

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/LinearLayout1"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">
    
        <Button
            android:id="@+id/btn_set"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="设置闹钟" />
    
        <Button
            android:id="@+id/btn_cancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="关闭闹钟"
            android:visibility="gone" /></LinearLayout>

    次に、MainActivity.javaがあります。これも非常に簡単です:

    public class MainActivity extends AppCompatActivity implements View.OnClickListener{
    
        private Button btn_set;
        private Button btn_cancel;
        private AlarmManager alarmManager;
        private PendingIntent pi;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            bindViews();
        }
    
        private void bindViews() {
            btn_set = (Button) findViewById(R.id.btn_set);
            btn_cancel = (Button) findViewById(R.id.btn_cancel);
            alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
    
            Intent intent = new Intent(MainActivity.this, ClockActivity.class);
            pi = PendingIntent.getActivity(MainActivity.this, 0, intent, 0);
    
            btn_set.setOnClickListener(this);
            btn_cancel.setOnClickListener(this);
    
        }
    
    
        @Override
        public void onClick(View v) {
            switch (v.getId()){
                case R.id.btn_set:
                    Calendar currentTime = Calendar.getInstance();
                    new TimePickerDialog(MainActivity.this, 0,
                            new TimePickerDialog.OnTimeSetListener() {
                                @Override
                                public void onTimeSet(TimePicker view,
                                                      int hourOfDay, int minute) {
                                    //设置当前时间
                                    Calendar c = Calendar.getInstance();
                                    c.setTimeInMillis(System.currentTimeMillis());
                                    // 根据用户选择的时间来设置Calendar对象
                                    c.set(Calendar.HOUR, hourOfDay);
                                    c.set(Calendar.MINUTE, minute);
                                    // ②设置AlarmManager在Calendar对应的时间启动Activity
                                    alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pi);
                                    Log.e("HEHE",c.getTimeInMillis()+"");   //这里的时间是一个unix时间戳
                                    // 提示闹钟设置完毕:
                                    Toast.makeText(MainActivity.this, "闹钟设置完毕~"+ c.getTimeInMillis(),
                                            Toast.LENGTH_SHORT).show();
                                }
                            }, currentTime.get(Calendar.HOUR_OF_DAY), currentTime
                            .get(Calendar.MINUTE), false).show();
                    btn_cancel.setVisibility(View.VISIBLE);
                    break;
                case R.id.btn_cancel:
                    alarmManager.cancel(pi);
                    btn_cancel.setVisibility(View.GONE);
                    Toast.makeText(MainActivity.this, "闹钟已取消", Toast.LENGTH_SHORT)
                            .show();
                    break;
            }
        }
    }

    次に、アラームページ用のClockActivity.javaがあります:

    /**
     * Created by Jay on 2015/10/25 0025.
     */
    public class ClockActivity extends AppCompatActivity {
    
        private MediaPlayer mediaPlayer;
    
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_clock);
            mediaPlayer = mediaPlayer.create(this,R.raw.pig);
            mediaPlayer.start();
            //创建一个闹钟提醒的对话框,点击确定关闭铃声与页面
            new AlertDialog.Builder(ClockActivity.this).setTitle("闹钟").setMessage("小猪小猪快起床~")
                    .setPositiveButton("关闭闹铃", new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            mediaPlayer.stop();
                            ClockActivity.this.finish();
                        }
                    }).show();
        }
    }

    コードは非常にシンプルで、コアプロセスは次のとおりです:

    • AlarmManageralarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); システムによって提供される AlarmManager サービスのオブジェクトを取得します
    • インテントは開始されるコンポーネントを設定します: インテントtent = new Intent(MainActivity.this, ClockActivity.class);
    • PendingIntent オブジェクトは、アクティビティ、サービス、ブロードキャストのいずれであっても、アクションを設定します!PendingIntent pi = PendingIntent.getActivity(MainActivity.this, 0,tent , 0);
    • AlarmManager の set() メソッドを呼び出して、単一アラームのアラーム タイプ、開始時刻、PendingIntent オブジェクトを設定します!alarmManager.set(AlarmManager.RTC_WAKEUP,c.getTimeInMillis(), pi);

    さらに、アラームが機能しない場合は、次の側面から始めることができます:

    1. システムバージョンまたは携帯電話、5.0以上では基本的に役に立たない、Xiaomi、自分でBaiduに行ってください~ 2. ClockActivityは登録されていますか? 3.alarmManager を使用してブロードキャストを送信し、ブロードキャスト後にアクティビティをアクティブ化する場合は、インテントのフラグを設定する必要があります。 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    2. 4.

    3. 4.png

    4. これらの場所はgetServiceなどと書いてはいけませんか?~


    また、スケジュールされたバックグラウンド タスクを実装するための後のサービスと組み合わせた AlarmManager の例については、4.2.2 Service Advanced


    5 を参照してください。 コード サンプルのダウンロード:

    AlarmManagerDemo.zip


    このセクションの概要:

    さて、このセクションでは、例のようにカスタマイズできることに加えて、Android での AlarmManager (目覚まし時計サービス) の使用方法について説明します。 独自の目覚まし時計を Service や Thread と組み合わせてポーリングなどを行うこともできます。使い方はたくさんありますが、やはり自分で探索する必要がありますね。 このセクションはここまでです、ありがとうございました~5.gif