AlarmManager (service de réveil)


Introduction à cette section :

Cette section présente AlarmManager (service de réveil) dans Android. D'après son nom, nous savons que nous pouvons l'utiliser pour développer des applications de réveil mobiles. . L'explication dans le document est la suivante : diffusez une intention spécifiée pour nous à un moment précis. En termes simples, nous fixons nous-mêmes une heure. Ensuite, lorsque le temps est écoulé, AlarmManager diffusera une intention que nous avons définie pour nous. Par exemple, lorsque le temps est écoulé, il peut pointer vers un certain. Activité ou service ! De plus, il y a certaines choses auxquelles il faut faire attention dans les documents officiels :

1.png
Une autre chose à noter est qu'AlarmManager sert principalement à exécuter votre code à un certain moment, même si votre L'APP est si spécifique Le temps ne passe pas ! De plus, à partir de l'API 19, le mécanisme d'alarme n'est pas transmis avec précision et le système d'exploitation convertira le réveil , pour minimiser les réveils et l'utilisation de la batterie ! Certaines nouvelles API prendront en charge une livraison strictement précise, voir setWindow(int, long, long, PendingIntent) et setExact(int, long, PendingIntent). Les applications TargetSdkVersion antérieures à l'API 19 continueront à utiliser le comportement précédent et toutes les alarmes seront émises avec précision lorsque cela est nécessaire. Il sera livré avec précision la prochaine fois. Plus de détails peuvent être trouvés dans la documentation officielle de l'API : AlarmManager

1. La différence entre la classe Timer et la classe AlarmManager :

Si vous avez étudié J2SE, vous serez certainement familier avec Timer. Les minuteries sont généralement utilisées lors de l'écriture de tâches planifiées. Il en est définitivement indissociable, mais sous Android, il a un défaut et ne convient pas à ceux qui ont besoin de fonctionner en arrière-plan pendant longtemps. Tâches planifiées, car les appareils Android ont leurs propres politiques de veille. Lorsqu'il n'y a aucune opération pendant une longue période, l'appareil laisse automatiquement le processeur entrer. État de veille, ce qui peut empêcher les tâches planifiées dans Timer de s'exécuter correctement ! Et AlarmManager n'existe pas Dans ce cas, parce qu'il a pour fonction de réveiller le CPU, il peut garantir que le CPU peut fonctionner normalement à chaque fois qu'il a besoin d'effectuer une tâche spécifique. En d'autres termes, le réveil enregistré lorsque le CPU est en veille sera conservé (peut réveiller le CPU), mais si l'appareil est éteint ou redémarré, Si elle est activée, l'alarme sera effacée ! (Le réveil ne sonne pas lorsque le téléphone Android est éteint...)


2. Obtenez l'objet d'instance AlarmManager :

AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);

3. Explication des méthodes associées :

  • set. (type int, long startTime, PendingIntent pi) : alarme unique
  • setRepeating(int type, long startTime, long intervalTime, PendingIntent pi) : Réveil à répétition, qui est différent de 3, l'intervalle de 3 réveils n'est pas fixe
  • setInexactRepeating (type int, long startTime, long intervalTime, PendingIntent pi) : Réveil répétitif, l'heure n'est pas fixe
  • cancel(PendingIntent pi) : Annuler le service programmé d'AlarmManager
  • getNextAlarmClock() : Obtenez le prochain réveil, valeur de retour AlarmManager.AlarmClockInfo
  • setAndAllowWhileIdle(type int, long triggerAtMillis, opération PendingIntent) Semblable à la méthode définie, ce réveil est valide lorsque le système est en mode faible consommation
  • setExact(type int, long triggerAtMillis, opération PendingIntent) : Exécutez le réveil avec précision à l'heure spécifiée, ce qui est plus précis que la méthode définie
  • setTime(long millis) : Réglez l'heure sur le mur du système
  • . setTimeZone(String timeZone) : définit le fuseau horaire par défaut persistant du système
  • setWindow(type int, long windowStartMillis, long windowLengthMillis, opération PendingIntent) : Définissez une alarme pour qu’elle se déclenche dans une fenêtre de temps donnée. Semblable au set, cette méthode permet aux applications de contrôler avec précision les ajustements du système d’exploitation. L'étendue de la durée totale de déclenchement de l'alarme.

Explication des paramètres clés :

  • Type(type réveil) : Il existe cinq valeurs facultatives : AlarmManager.ELAPSED_REALTIME : Le réveil n'est pas disponible lorsque le téléphone est en état de veille. Dans cet état, le réveil utilise l'heure relative (par rapport au début du démarrage du système) et la valeur de l'état est 3 ; AlarmManager.ELAPSED_REALTIME_WAKEUPLe réveil réveillera le système et exécutera des fonctions d'invite en état de veille. Dans cet état, le réveil utilise également l'heure relative et la valeur d'état est 2 ; AlarmManager.RTCLe réveil n'est pas disponible en état de veille. Dans cet état, le réveil utilise l'heure absolue, qui est l'heure actuelle du système, et la valeur d'état est 1 ; AlarmManager.RTC_WAKEUP indique que le réveil réveillera le système et exécutera des fonctions d'invite en état de veille. Dans cet état, le réveil utilise l'heure absolue et la valeur d'état est 0 ; AlarmManager.POWER_OFF_WAKEUP signifie que le réveil peut également exécuter la fonction d'invite normalement lorsque le téléphone est éteint, c'est donc l'un des états les plus couramment utilisés parmi les 5 états Dans cet état, le réveil. utilise également le temps absolu, et la valeur de l'état est 4 ; Cependant, cet état semble être affecté par la version du SDK, et certaines versions ne le prennent pas en charge
  • startTime : La première exécution ; heure du réveil, en millisecondes, l'heure peut être personnalisée, mais utilisez généralement l'heure actuelle. Il est à noter que cet attribut est étroitement lié au premier attribut (type). Si le réveil correspondant au premier paramètre utilise l'heure relative. (ELAPSED_REALTIME et ELAPSED_REALTIME_WAKEUP), alors cet attribut doit utiliser le temps relatif (par rapport à l'heure de démarrage du système), par exemple, l'heure actuelle est exprimée comme suit : SystemClock.elapsedRealtime(); Si le réveil correspondant au premier paramètre utilise le temps absolu (RTC, RTC_WAKEUP, POWER_OFF_WAKEUP), Ensuite, cet attribut doit utiliser l'heure absolue. Par exemple, l'heure actuelle est exprimée comme suit : System.currentTimeMillis().
  • intervalTime : Indique l'intervalle entre l'exécution de deux réveils, également en millisecondes
  • PendingIntent : Lie l'action d'exécution de l'alarme. horloge, comme envoyer une diffusion, donner des invites, etc. PendingIntent est la classe d'encapsulation d'Intent. Il convient de noter que si l'invite d'alarme est implémentée lors du démarrage d'un service, l'objet PendingIntent doit être obtenu à l'aide de Pending.getService. (Contexte c, int i, Intent intent, int j) méthode si le réveil est mis en œuvre via la diffusion ; Pour rappel, PendingIntent.getBroadcast doit être utilisé pour obtenir l'objet PendingIntent. (Contexte c, int i, Intent intent, int j) si elle est implémentée à l'aide de l'activité ; Si le réveil vous le demande, l'objet PendingIntent doit être obtenu en utilisant Méthode PendingIntent.getActivity(Context c,int i,Intent intent,int j). Si ces trois méthodes ne sont pas utilisées correctement, même si aucune erreur ne sera signalée, l'effet d'invite d'alarme ne sera pas visible.

4. Exemple d'utilisation : une simple tâche planifiée

Ce que je veux dire, c'est que cet exemple n'est réalisable que dans les systèmes inférieurs à Android 4.4. . Au-dessus de 5,0 n'est pas réalisable, s'il y a 5,0 dans le futur. La solution AlarmManager ci-dessus sera ajoutée en temps voulu ! De plus, utiliser la méthode définie ici peut être un peu inexact si vous le souhaitez. Pour être plus précis, vous pouvez utiliser la méthode setExtra() pour définir AlarmManager !

Exécuter le rendu  :

2.png3.png

Code d'implémentation :

D'abord un fichier de mise en page simple : activity_main.xml De plus, créez un dossier brut en res et lancez le fichier audio. dedans ! De plus, créez un activity_clock.xml avec uniquement une disposition externe comme disposition de l'activité lorsque le réveil sonne ! S'il n'y a rien, je ne le publierai pas

<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>

suivi de MainActivity.java, qui est aussi très simple :

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;
        }
    }
}

puis ClockActivity. java< de la page d'alarme 🎜> :

/**
 * 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();
    }
}

Le code est très simple, le processus de base est le suivant :

    AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE );
  • Obtenir le service AlarmManager fourni par le système L'objet
  • Intent définit le composant à lancer : Intent intent = new Intent(MainActivity.this, ClockActivity.class);
  • L'objet PendingIntent définit l'action, qu'il s'agisse de démarrer une activité, un service ou une diffusion !PendingIntent pi = PendingIntent.getActivity ( MainActivity.this, 0, intent, 0);
  • Appelez la méthode set() de AlarmManager pour définir le type d'alarme, l'heure de démarrage et l'objet PendingIntent d'une seule alarme !alarmManager.set (AlarmManager .RTC_WAKEUP,c.getTimeInMillis(), pi);
De plus, si l'alarme n'est pas valide, vous pouvez partir de ces aspects :

  1. Version du système ou téléphone mobile, au-dessus de 5.0 est fondamentalement inutile, Xiaomi, va sur Baidu par toi-même~ 2. ClockActivity est-il enregistré ? 3. Si vous utilisez alarmManager pour envoyer des diffusions, puis activez l'activité après la diffusion, vous devez définir un indicateur pour l'intention : i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

  2. 4.

  3. 4.png

  4. Ces endroits sont-ils corrects ? N'écrivez pas getActivity comme getService, etc.~


De plus, concernant AlarmManager combiné avec Service ultérieur Pour des exemples de mise en œuvre de tâches en arrière-plan planifiées, voir :

4.2.2 Service avancé


5. Téléchargement d'un exemple de code :

AlarmManagerDemo.zip.


Résumé de cette section :

Bon, cette section vous explique l'utilisation d'AlarmManager (service de réveil) sous Android en plus de pouvoir le personnaliser comme l'exemple. Votre propre réveil peut également être combiné avec Service et Thread pour effectuer des sondages, etc. Il existe de nombreuses façons de l'utiliser, et vous devez toujours l'explorer par vous-même, hein C'est tout pour cette rubrique, merci~5.gif