AlarmManager
ist eine Klasse, mit der wir Alarme erstellen können. Alarme ermöglichen es unseren Apps, bestimmte Codes zu planen, die zu bestimmten Zeiten in der Zukunft ausgeführt werden sollen.
public class AlarmManager extends Object{}
Es ist besser und effizienter, die Klasse AlarmManager
zu verwenden, um Alarme für die Zeitplanung zu erstellen, als etwas wie einen Timer zu verwenden.
AlarmManager
bietet uns den Zugang zu den Systemalarmdiensten, also ist es nicht so, dass wir unsere eigenen Zeitplanungsalgorithmen erfinden werden.
AlarmManager
wird meistens zusammen mit BroadcastReceiver
verwendet. So funktioniert es:
- Der erste Alarm geht los oder klingelt.
- Das System sendet einen
Intent
. Dies ist derIntent
, der für ihn registriert wurde. - Dadurch wird die Zielanwendung automatisch gestartet, falls sie nicht bereits läuft.
- Wenn das Gerät schläft, werden die bereits registrierten Alarme beibehalten.
- Wenn der Alarm ausgelöst wird, während das Gerät schläft, wird das Gerät aufgeweckt. Dies ist optional.
- Schaltet der Benutzer das Gerät aus oder startet es neu, werden die Alarme gelöscht.
Sie können sicher sein, dass das Telefon nicht schläft, bis Sie die Bearbeitung Ihrer Sendung abgeschlossen haben. Broadcasts werden von der Methode onReceive()
des android.content.BroadcastReceiver
behandelt. Dies ist eine Methode, die man überschreibt, nachdem man diese Klasse abgeleitet hat.
Solange die Methode onReceive()
noch ausgeführt wird, hält der AlarmManager
eine CPU-Wake-Sperre. Also wird das Gerät nicht schlafen.
Dann gibt der AlarmManager
die Aufwach-Sperre frei, wenn onReceive()
die Ausführung beendet und zurückkehrt.
Aber manchmal, wenn die Methode onReceive()
beendet ist, ist es möglich, dass das Telefon sofort schlafen kann. Wenn Sie einen Dienst mit Context.startService()
angefordert haben, wird er nicht gestartet, weil das Gerät schnell geschlafen hat. Das liegt daran, dass das Gerät geschlafen hat, bevor es aufgerufen wurde. Die anfängliche Aufwecksperre ist jedoch nicht mehr vorhanden. Sie wurde in dem Moment freigegeben, als onReceive()
zurückkehrte. Was ist also die Lösung? Nun, man implementiert ein separates Wake Lock für den BroadcastReceiver
und den Service
. Dieses Wake Lock stellt sicher, dass das Gerät läuft, bis der Dienst verfügbar ist.
Wann sollte man also AlarmManager
verwenden und wann nicht? Nun, verwenden Sie AlarmManager
für die Planung von Operationen. Verwenden Sie ihn nicht für Timing- und Ticketing-Operationen. Und verwenden Sie keine Timer für Zeitplanungsoperationen. Geplanter Code, der AlarmManager
verwendet, erfordert nicht, dass die Anwendung die ganze Zeit über läuft. Wenn Sie einen Timer verwenden würden, müsste er die ganze Zeit laufen. Dadurch werden Speicher und Verarbeitungszeit verschwendet.
Das Android-Betriebssystem verschiebt Alarme so, dass die Aufwachzeiten und der Batterieverbrauch minimiert werden. Dies gilt ab Android API 19 (KitKat). Dies bedeutet, dass die Weckzeiten nicht unbedingt genau sind. Wenn Sie streng genau sein müssen, dann können Sie die Methode setExact()
verwenden.
Der AlarmManager
wird nicht direkt instanziiert. Stattdessen verwendet man die statische Methode getSystemService()
der Klasse Context
. Dabei wird das Flag Context.ALARM_SERVICE
übergeben.
Context.getSystemService(Context.ALARM_SERVICE
Beispiel 1: Kotlin Android Build an Alarm Clock
Dies ist ein Beispiel, um die Verwendung von Alarms und Broadcastreceiver zu lernen. Dabei bauen Sie einen einfachen Wecker. Dieses Beispiel ermöglicht es Ihnen, diese Technologien auf praktische Art und Weise zu erlernen.
Schritt 1: Kotlin-Projekt erstellen
Beginnen Sie mit der Erstellung eines leeren Kotlin-Projekts in Android Studio.
Schritt 2: Abhängigkeiten
Es werden keine besonderen Abhängigkeiten benötigt. Da jedoch Coroutines verwendet werden, sollten Sie Kotlin verwenden.
Schritt 3: Berechtigungen
Für dieses Projekt werden keine Berechtigungen benötigt. Allerdings muss in der AndroidManifest.xml
der Empfänger
eingetragen werden, da BroadcastReceiver
in diesem Wecker verwendet wird.
<receiver
android:name=".AlarmReceiver"
android:exported="false" />
Schritt 4: Layout entwerfen
Sie brauchen nur ein Layout, das MainActivity
-Layout. Fügen Sie einfach TextViews und Buttons hinzu und schränken Sie diese mit dem ConstraintLayout
wie folgt ein:
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/background_black"
tools:context=".MainActivity">
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginHorizontal="50dp"
android:background="@drawable/background_white_ring"
app:layout_constraintBottom_toTopOf="@id/onOffButton"
app:layout_constraintDimensionRatio="H,1:1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/timeTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="09:30"
android:textColor="@color/white"
android:textSize="50sp"
app:layout_constraintBottom_toTopOf="@id/ampmTextView"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed" />
<TextView
android:id="@+id/ampmTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="AM"
android:textColor="@color/white"
android:textSize="25sp"
app:layout_constraintBottom_toTopOf="@id/onOffButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/timeTextView" />
<Button
android:id="@+id/onOffButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/on_alarm"
app:layout_constraintBottom_toTopOf="@id/changeAlarmTimeButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
<Button
android:id="@+id/changeAlarmTimeButton"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:text="@string/change_time"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Schritt 5: Modellklasse erstellen
Erstellen Sie eine Modellklasse, eine Kotlin-Datenklasse, die über den constructor
die beiden Ganzzahlen und einen Boolean erhält. Die Ganzzahlen sind die Stunde und die Minute, während der Boolesche Wert ein Ein-Aus-Schalter ist. Diese werden verwendet, um eine Timer-Ansicht zu konstruieren, die im Wecker dargestellt wird:
AlarmDisplayModel.kt
package com.example.alarmclock
data class AlarmDisplayModel(
val hour: Int,
val minute: Int,
var onOff: Boolean
) {
val timeText: String
get() {
val h = "%02d".format(if (hour < 12) hour else hour - 12)
val m = "%02d".format(minute)
return "$h:$m"
}
val ampmText: String
get() {
return if (hour < 12) "AM" else "PM"
}
val onOffText: String
get() {
return if (onOff) "알람 끄기" else "알람 켜기"
}
fun makeDataForDB(): String {
return "$hour:$minute"
}
}
Schritt 5: Erstellen eines Alarm Receivers
Dazu erweitern Sie den Broadcast Receiver
und überschreiben die Methode onReceive()
. Innerhalb der Methode onReceive()
werden Sie einen Benachrichtigungskanal erstellen und eine Benachrichtigung erstellen.
Hier ist der vollständige Code:
AlarmReceiver.kt
package com.example.alarmclock
import android.app.NotificationChannel
import android.app.NotificationManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat
class AlarmReceiver: BroadcastReceiver() {
companion object {
const val NOTIFICATION_ID = 100
const val NOTIFICATION_CHANNEL_ID = "1000"
}
override fun onReceive(context: Context, intent: Intent) {
createNotificationChannel(context)
notifyNotification(context)
}
private fun createNotificationChannel(context: Context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
val notificationChannel = NotificationChannel(
NOTIFICATION_CHANNEL_ID,
"기상 알람",
NotificationManager.IMPORTANCE_HIGH
)
NotificationManagerCompat.from(context).createNotificationChannel(notificationChannel)
}
}
private fun notifyNotification(context: Context) {
with(NotificationManagerCompat.from(context)) {
val build = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID)
.setContentTitle("알람")
.setContentText("일어날 시간입니다.")
.setSmallIcon(R.drawable.ic_launcher_foreground)
.setPriority(NotificationCompat.PRIORITY_HIGH)
notify(NOTIFICATION_ID, build.build())
}
}
}
Schritt 6: Erstellen der Haupttätigkeit
Schließlich erstellen Sie Ihre
MainActivity`` wie unten:
MainActivity.kt
package com.example.alarmclock
import android.app.AlarmManager
import android.app.PendingIntent
import android.app.TimePickerDialog
import android.content.Context
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.TextView
import java.util.*
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initOnOffButton()
initChangeAlarmTimeButton()
val model = fetchDataFromSharedPreferences()
renderView(model)
}
private fun initOnOffButton() {
val onOffButton = findViewById<Button>(R.id.onOffButton)
onOffButton.setOnClickListener {
val model = it.tag as? AlarmDisplayModel ?: return@setOnClickListener
val newModel = saveAlarmModel(model.hour, model.minute, model.onOff.not())
renderView(newModel)
if (newModel.onOff) {
// 켜진 경우 -> 알람을 등록
val calendar = Calendar.getInstance().apply {
set(Calendar.HOUR_OF_DAY, newModel.hour)
set(Calendar.MINUTE, newModel.minute)
if (before(Calendar.getInstance())) {
add(Calendar.DATE, 1)
}
}
val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager
val intent = Intent(this, AlarmReceiver::class.java)
val pendingIntent = PendingIntent.getBroadcast(this, ALARM_REQUEST_CODE,
intent, PendingIntent.FLAG_UPDATE_CURRENT)
alarmManager.setInexactRepeating(
AlarmManager.RTC_WAKEUP,
calendar.timeInMillis,
AlarmManager.INTERVAL_DAY,
pendingIntent
)
} else {
cancelAlarm()
}
}
}
private fun initChangeAlarmTimeButton() {
val changeAlarmButton = findViewById<Button>(R.id.changeAlarmTimeButton)
changeAlarmButton.setOnClickListener {
val calendar = Calendar.getInstance()
TimePickerDialog(this, { picker, hour, minute ->
val model = saveAlarmModel(hour, minute, false)
renderView(model)
cancelAlarm()
}, calendar.get(Calendar.HOUR_OF_DAY), calendar.get(Calendar.MINUTE), false).show()
}
}
private fun saveAlarmModel(
hour: Int,
minute: Int,
onOff: Boolean
): AlarmDisplayModel {
val model = AlarmDisplayModel(
hour = hour,
minute = minute,
onOff = onOff
)
val sharedPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
with(sharedPreferences.edit()) {
putString(ALARM_KEY, model.makeDataForDB())
putBoolean(ONOFF_KEY, model.onOff)
commit()
}
return model
}
private fun fetchDataFromSharedPreferences():AlarmDisplayModel {
val sharedPreferences = getSharedPreferences(SHARED_PREFERENCES_NAME, Context.MODE_PRIVATE)
val timeDBValue = sharedPreferences.getString(ALARM_KEY, "9:30") ?: "9:30"
val onOffDBValue = sharedPreferences.getBoolean(ONOFF_KEY, false)
val alarmData = timeDBValue.split(":")
val alarmModel = AlarmDisplayModel(
hour = alarmData[0].toInt(),
minute = alarmData[1].toInt(),
onOff = onOffDBValue
)
// 보정 보정 예외처리
val pendingIntent = PendingIntent.getBroadcast(this, ALARM_REQUEST_CODE, Intent(this, AlarmReceiver::class.java), PendingIntent.FLAG_NO_CREATE)
if ((pendingIntent == null) and alarmModel.onOff) {
// 알람은 꺼져있는데, 데이터는 켜저있는 경우
alarmModel.onOff = false
} else if ((pendingIntent != null) and alarmModel.onOff.not()){
// 알람은 켜져있는데, 데이터는 꺼져있는 경우
// 알람을 취소함
pendingIntent.cancel()
}
return alarmModel
}
private fun renderView(model: AlarmDisplayModel) {
findViewById<TextView>(R.id.ampmTextView).apply {
text = model.ampmText
}
findViewById<TextView>(R.id.timeTextView).apply {
text = model.timeText
}
findViewById<Button>(R.id.onOffButton).apply {
text = model.onOffText
tag = model
}
}
private fun cancelAlarm() {
val pendingIntent = PendingIntent.getBroadcast(this, ALARM_REQUEST_CODE, Intent(this, AlarmReceiver::class.java), PendingIntent.FLAG_NO_CREATE)
pendingIntent?.cancel()
}
companion object {
private const val SHARED_PREFERENCES_NAME = "time"
private const val ALARM_KEY = "alarm"
private const val ONOFF_KEY = "onOff"
private const val ALARM_REQUEST_CODE = 1000
}
}
Schritt 7: Ausführen
Starten Sie schließlich das Projekt.
Referenz
Hier sind die Code-Referenz-Links:
Nummer | Link |
---|---|
1. | Code herunterladen |
2. | Dem Autor des Codes folgen |
Beispiel 2: Wie man einen Alarm startet
Eine dieser mobilfunkähnlichen Softwareanwendungen ist der Alarm. Oder jede Anwendung, die etwas in der Zukunft planen kann. Dies ist bei mobilen Geräten sogar noch wichtiger als bei Desktop-Anwendungen.
Denn wir verlassen unsere mobilen Geräte nie und schalten sie auch nicht aus. Sie sind unsere persönlichen Assistenten. Wir nutzen sie also auf persönlichere Weise, als wir es bei Desktop-Anwendungen jemals tun würden.
Android bietet uns daher eine umfangreiche Klasse namens AlarmManager
. Eine Klasse, mit der wir auf Systemdienste zugreifen können. Die Klasse ist natürlich öffentlich und leitet sich von java.lang.Object
ab.
Hier ist ihre Definition:
public class AlarmManager extends Object{}
Was bauen wir?
Nun, sehen wir uns ein einfaches android AlarmManager
Beispiel an. Wir sehen, wie man einen Alarm in android startet und abbricht. Wir haben einen einfachen Editiertext. Der Benutzer gibt die Zeit in Millisekunden ein, zu der der Alarm läuten soll. Der Alarm läutet, indem er eine einfache "Toast"-Nachricht anzeigt.
Projektstruktur
Hier ist die Projektstruktur:
Schritt 1 - Android-Projekt erstellen
- Gehen Sie in Ihrem Android Studio auf Datei - Neu - Neues Projekt.
- Geben Sie einen Projektnamen ein.
- Wählen Sie Minimum sdk.
- Wählen Sie aus den Vorlagen eine leere Aktivität oder ein bla.
Schritt 2. - Lassen Sie uns unsere build.gradle
ändern.
Dies ist unser zweiter Schritt. Android-Projekte, die in Android Studio erstellt werden, haben zwei buil.gradle
-Dateien. Wir sind an der App-Ebene build.gradle
interessiert.
Fügen Sie den folgenden Code unter dem Abschnitt dependencies ein:
implementation 'com.android.support:appcompat-v7:24.2.1'
implementation 'com.android.support:design:24.2.1'
Wir haben zwei Abhängigkeiten von der Support-Bibliothek hinzugefügt: AppCompat
und Design
.
Schritt 3. Lassen Sie uns unsere Ressourcen vorbereiten.
Die einzige Ressource, die wir in diesem Fall vorbereiten müssen, sind die Layouts. Ich habe die Basisaktivität als Vorlage gewählt. Ich habe also zwei Layouts:
- activity_main.xm : Vorlagenlayout
- content_main.xml : das müssen wir ändern.
Alles, was ich brauche, ist ein Edit-Text und ein Button. Der Edittext, in den der Benutzer die Zeit in Sekunden einträgt und der Start-Button, um den Alarm zu starten.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_paddingBottom="@dimen/activity_vertical_margin"
android_paddingLeft="@dimen/activity_horizontal_margin"
android_paddingRight="@dimen/activity_horizontal_margin"
android_paddingTop="@dimen/activity_vertical_margin"
app_layout_behavior="@string/appbar_scrolling_view_behavior"
tools_context="com.tutorials.hp.alarmmanagerstarter.MainActivity"
tools_showIn="@layout/activity_main">
<EditText
android_id="@+id/timeTxt"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_alignParentLeft="true"
android_layout_alignParentTop="true"
android_layout_marginTop="28dp"
android_ems="10"
android_hint="Number of seconds"
android_inputType="numberDecimal" />
<Button
android_id="@+id/startBtn"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_alignRight="@+id/timeTxt"
android_layout_below="@+id/timeTxt"
android_layout_marginRight="60dp"
android_layout_marginTop="120dp"
android_text="Start" />
</RelativeLayout>
Schritt 4. Lassen Sie uns unsere BroadcastReceiver
Klasse erstellen.
Ein BroadcastReceiver
ist eine der android Komponenten. Andere sind Activity
, Service
und ContentProvider
.
Ein BroadcastReceiver
hört auf Systemereignisse.
Es ist eigentlich eine abstrakte Klasse, die natürlich öffentlich ist. Sie leitet sich von java.lang.Object
ab:
public abstract class BroadcastReceiver extends Object{}
Intents, die mit sendBroadcast()
gesendet werden, werden von dieser Basisklasse empfangen.
Da es sich um eine abstrakte Klasse handelt, werden wir die Methode onReceive()
außer Kraft setzen.
Erstellen Sie zunächst eine Java-Klasse :
public class MyReceiver{}
Fügen Sie die folgenden Importe hinzu:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
Leiten Sie sie von android.content.BroadcastReceiver
ab:
public class MyReceiver extends BroadcastReceiver {}
Dies wird uns dazu zwingen, die Methode onReceive()
zu übergehen:
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm Ringing...", Toast.LENGTH_SHORT).show();
}
Schritt 5. Kommen wir nun zu unserer MainActivity
Klasse.
Activities sind Android-Komponenten, die eine Benutzeroberfläche darstellen. Wir erstellen Activities, indem wir von einer Activity ableiten. Um mehr Geräte zu unterstützen, verwenden wir AppCompatActivity
.
Also lasst uns eine Activity erstellen:
public class MainActivity extends AppCompatActivity {}
Fügen Sie die folgenden Importe oben auf der Aktivität hinzu:
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
Unsere Aktivität wird drei Methoden und zwei Felder haben:
Zuerst definieren wir unsere zwei Felder: im Grunde eine Schaltfläche und ein Textfeld. Fügen Sie sie innerhalb der Klasse MainActivity
ein:
Button startBtn;
EditText timeTxt;
Dann erstellen wir eine Methode go()
. Diese Methode wird dafür verantwortlich sein, unseren AlarmManager
zu initialisieren und den Alarm zu starten:
private void go()
{
//GET TIME IN SECONDS AND INITIALIZE INTENT
int time=Integer.parseInt(timeTxt.getText().toString());
Intent i=new Intent(this,MyReceiver.class);
//PASS CONTEXT,YOUR PRIVATE REQUEST CODE,INTENT OBJECT AND FLAG
PendingIntent pi=PendingIntent.getBroadcast(this,0,i,0);
//INITIALIZE ALARM MANAGER
AlarmManager alarmManager= (AlarmManager) getSystemService(ALARM_SERVICE);
//SET THE ALARM
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+(time*1000),pi);
Toast.makeText(MainActivity.this, "Alarm set in "+time+" seconds", Toast.LENGTH_SHORT).show();
}
Dann erstellen wir eine weitere Methode, um unseren Button und den Editetext zu initialisieren und den Onclick-Listener des Buttons zu behandeln:
private void initializeViews()
{
timeTxt= (EditText) findViewById(R.id.timeTxt);
startBtn= (Button) findViewById(R.id.startBtn);
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
go();
}
});
}
Schritt 6. Schauen wir uns das AndroidManifest
an
Überprüfen Sie die androidmanifest.xml
. Wir wollen sicherstellen, dass unsere BroadcastReceiver
Klasse in unserem Manifest registriert ist.
Sie können sehen, dass unsere Broadcastreceiver
Klasse registriert ist:
<receiver android_name="MyReceiver" >
</receiver>
Here's what I have:
<?xml version="1.0" encoding="utf-8"?>
<manifest
package="com.tutorials.hp.alarmmanagerstarter">
<application
android_allowBackup="true"
android_icon="@mipmap/ic_launcher"
android_label="@string/app_name"
android_supportsRtl="true"
android_theme="@style/AppTheme">
<activity
android_name=".MainActivity"
android_label="@string/app_name"
android_theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android_name="android.intent.action.MAIN" />
<category android_name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android_name="MyReceiver" >
</receiver>
</application>
</manifest>
Beispiel: Android AlarmManager
- Schedule Showing of Toast
Die Android-Ingenieure fügten die Klasse AlarmManager
in API Level 1 hinzu, also gibt es sie schon seit den Anfängen von Android. Diese Klasse ermöglicht die Planung von Operationen, die irgendwann in der Zukunft durchgeführt werden sollen. Mit AlarmManager
kann man einen Code festlegen, der in der Zukunft ausgeführt werden soll.
Das ist cool, denn es ist nicht notwendig, dass deine App läuft, damit der Code ausgeführt wird. Natürlich wird deine App gestartet, aber nur zum registrierten Zeitpunkt. Alarm Maanager gehört zum android.app Paket und erbt von java.lang.Object.
Auch wenn das Gerät schläft, bleiben die Alarme erhalten, solange sie registriert wurden. Weitere Details zu AlarmManager
finden Sie hier.
Bildschirmfoto
- Hier ist der Screenshot des Projekts.
Allgemeine Fragen, die dieses Beispiel erforscht
- Wie benutzt man android
AlarmManager
. - Was ist
AlarmManager
? - Wie plane ich die Arbeit, die in Zukunft in Android erledigt werden soll?
- Einfaches
AlarmManager
Beispiel mit einemToast
.
Verwendete Tools
Dieses Beispiel wurde mit den folgenden Tools geschrieben:
- Windows 8
- AndroidStudio IDE
- Genymotion-Emulator
Quellcode
Lassen Sie uns direkt zum Quellcode springen.
Build.Gradle
- Normalerweise gibt es in Android-Projekten zwei
build.gradle
-Dateien. Die eine ist die App-Ebenebuild.gradle
, die andere die Projektebenebuild.gradle
. Die App-Ebene gehört in den App-Ordner und ist der Ort, an dem wir normalerweise unsere Abhängigkeiten hinzufügen und die Kompilier- und Ziel-Sdks angeben. - Fügen Sie auch Abhängigkeiten für
AppCompat
und Design Support Bibliotheken hinzu. - Unsere "MainActivity" soll von "AppCompatActivity" abgeleitet werden, während wir auch "FloatingActionButton" aus den Design-Support-Bibliotheken verwenden sollen.
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "25.0.1"
defaultConfig {
applicationId "com.tutorials.hp.alarmmanagerstarter"
minSdkVersion 15
targetSdkVersion 24
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testImplementation 'junit:junit:4.12'
implementation 'com.android.support:appcompat-v7:24.2.1'
implementation 'com.android.support:design:24.2.1'
}
MyReceiver.java"
- Unsere
Broadcast Receiver
Klasse. - Sie soll android.app.content.BroadCastReceiver erweitern.
- Wir überschreiben dann die Methode "OnReceive()". Hier schreiben wir den Code, der ausgeführt werden soll, wenn der Alarm ertönt.
- In diesem Fall zeigen wir einfach eine
Toast
Nachricht an.
package com.tutorials.hp.alarmmanagerstarter;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
/*
RING ALARM WHEN IN WHEN WE RECEIVE OUR BROADCAST
*/
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm Ringing...", Toast.LENGTH_SHORT).show();
}
}
MainActivity
.java
- Launcher-Aktivität.
ActivityMain.xml
wird als Inhaltsansicht für diese Aktivität aufgeblasen.- Wir initialisieren Ansichten und Widgets innerhalb dieser Aktivität.
- Wir initialisieren und starten hier auch unseren Alarm mit dem
AlarmManager
Objekt.
package com.tutorials.hp.alarmmanagerstarter;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
Button startBtn;
EditText timeTxt;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
initializeViews();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
/*
INITIALIZE VIEWS
*/
private void initializeViews()
{
timeTxt= (EditText) findViewById(R.id.timeTxt);
startBtn= (Button) findViewById(R.id.startBtn);
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
go();
}
});
}
/*
INITIALIZE AND START OUR ALARM
*/
private void go()
{
//GET TIME IN SECONDS AND INITIALIZE INTENT
int time=Integer.parseInt(timeTxt.getText().toString());
Intent i=new Intent(this,MyReceiver.class);
//PASS CONTEXT,YOUR PRIVATE REQUEST CODE,INTENT OBJECT AND FLAG
PendingIntent pi=PendingIntent.getBroadcast(this,0,i,0);
//INITIALIZE ALARM MANAGER
AlarmManager alarmManager= (AlarmManager) getSystemService(ALARM_SERVICE);
//SET THE ALARM
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+(time*1000),pi);
Toast.makeText(MainActivity.this, "Alarm set in "+time+" seconds", Toast.LENGTH_SHORT).show();
}
}
ActivityMain.xml
- Template-Layout.
- Enthält unsere ContentMain.xml.
- Definiert auch das Appbarlayout, die Toolbar sowie den Floatingaction Buttton.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_fitsSystemWindows="true"
tools_context="com.tutorials.hp.alarmmanagerstarter.MainActivity">
<android.support.design.widget.AppBarLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android_id="@+id/toolbar"
android_layout_width="match_parent"
android_layout_height="?attr/actionBarSize"
android_background="?attr/colorPrimary"
app_popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton
android_id="@+id/fab"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_gravity="bottom|end"
android_layout_margin="@dimen/fab_margin"
android_src="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
ContentMain.xml
- Content Layout.
- Definiert die Ansichten und Widgets, die innerhalb der
MainActivity
angezeigt werden sollen.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
android_paddingBottom="@dimen/activity_vertical_margin"
android_paddingLeft="@dimen/activity_horizontal_margin"
android_paddingRight="@dimen/activity_horizontal_margin"
android_paddingTop="@dimen/activity_vertical_margin"
app_layout_behavior="@string/appbar_scrolling_view_behavior"
tools_context="com.tutorials.hp.alarmmanagerstarter.MainActivity"
tools_showIn="@layout/activity_main">
<EditText
android_id="@+id/timeTxt"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_alignParentLeft="true"
android_layout_alignParentTop="true"
android_layout_marginTop="28dp"
android_ems="10"
android_hint="Number of seconds"
android_inputType="numberDecimal" />
<Button
android_id="@+id/startBtn"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_alignRight="@+id/timeTxt"
android_layout_below="@+id/timeTxt"
android_layout_marginRight="60dp"
android_layout_marginTop="120dp"
android_text="Start" />
</RelativeLayout>
How To Run
- Laden Sie das obige Projekt herunter.
- Sie erhalten eine gezippte Datei, entpacken Sie sie.
- Öffnen Sie das Android Studio.
- Schließen Sie nun das bereits geöffnete Projekt.
- Klicken Sie in der Menüleiste auf Datei >Neu> Projekt importieren.
- Wählen Sie nun einen Zielordner, aus dem Sie das Projekt importieren möchten.
- Wählen Sie ein Android-Projekt.
- Klicken Sie nun auf "OK".
- Fertig, Sie haben das Projekt importiert und können es nun bearbeiten.
Schlussfolgerung.
Wir haben ein einfaches android AlarmManager
Beispiel gesehen.
Beispiel: Android Zeitplan Wiederholende/Wiederkehrende Alarme
Den AlarmManager
gibt es schon seit den Anfängen von Android. Er ermöglicht es uns, Aufgaben zu planen, die irgendwann in der Zukunft erledigt werden sollen.
Mit AlarmManager
kann man einen Code festlegen, der in der Zukunft ausgeführt werden soll.
AlarmManager gehört zum Paket android.app
und erbt von java.lang.Object
. Auch wenn das Gerät schläft, bleiben die Alarme erhalten, solange sie registriert wurden. In diesem Beispiel werden wir sehen, wie man mit wiederkehrenden Alarmen arbeitet.
Wir werden die Anzeige von "Toast"-Nachrichten nach einer bestimmten Anzahl von Sekunden planen. Zum Beispiel, der Benutzer gibt 5 in den Edittexts
ein und klickt auf den Start-Button, nach jeweils 5 Sekunden wird die Toast
Nachricht angezeigt, bis der Benutzer auf den Cancel-Button klickt, um die Alarme abzubrechen. Wir sehen also, wie man wiederholte Alarme startet und sie abbricht. Sie können mehr Details über AlarmManager
[hier] finden (https://developer.android.com/reference/android/app/AlarmManager
.html).
Allgemeine Fragen, die dieses Beispiel erforscht
- Wie benutzt man android
AlarmManager
. - Wie man wiederkehrende Alarme in android einstellt und abbricht.
- Starten und Abbrechen von Alarmen in android.
- Wie plane ich die Arbeit, die in Zukunft in Android erledigt werden soll?
- Einfaches Beispiel für einen wiederkehrenden
AlarmManager
mit einemToast
.
Verwendete Tools
Dieses Beispiel wurde mit den folgenden Tools geschrieben:
- Windows 8
- AndroidStudio IDE
- Genymotion-Emulator
- Sprache: Java
-
Thema : Android Wiederkehrende Alarme,
AlarmManager
, Start Cancel Repeating alarms - Verwendete Bibliotheken
- Wir verwenden keine Bibliotheken von Drittanbietern.
Quellcode
Lassen Sie uns direkt zum Quellcode springen.
Build.Gradle
Normalerweise gibt es in Android-Projekten zwei build.gradle
-Dateien. Eine ist die App-Ebene build.gradle
, die andere ist die Projektebene build.gradle
. Die App-Ebene gehört in den App-Ordner und ist der Ort, an dem wir normalerweise unsere Abhängigkeiten hinzufügen und die Kompilier- und Ziel-Sdks angeben.
Außerdem fügen wir Abhängigkeiten für die Bibliotheken "AppCompat" und "Design Support" hinzu.
Unsere MainActivity
soll von AppCompatActivity
abgeleitet werden, während wir auch FloatingActionButton
aus den Design-Support-Bibliotheken verwenden sollen.
apply plugin: 'com.android.application'
android {
compileSdkVersion 26
buildToolsVersion "26.0.0"
defaultConfig {
applicationId "com.tutorials.hp.repeatingalarm"
minSdkVersion 15
targetSdkVersion 26
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
androidtestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
implementation 'com.android.support:appcompat-v7:26.+'
implementation 'com.android.support.constraint:constraint-layout:1.0.0-alpha7'
implementation 'com.android.support:design:26.+'
testImplementation 'junit:junit:4.12'
}
MyReceiver.java
- Unsere
MyReceiver
Klasse. - Abgeleitet von
android.content.BroadcastReceiver
. - Wir überschreiben die Methode
onReceive()
und führen hier die Aufgabe aus, die erledigt werden muss, wenn der Alarm klingelt.
package com.tutorials.hp.repeatingalarm;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
/*
RING ALARM WHEN IN WHEN WE RECEIVE OUR BROADCAST
*/
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Alarm Ringing...", Toast.LENGTH_SHORT).show();
}
}
MainActivity
.java
- Unsere
MainActivity
Klasse. - Abgeleitet von
AppCompatActivity
, die eine Basisklasse für Aktivitäten ist, die die Funktionen der Unterstützungsbibliothek Action Bar nutzen. - Methoden:
onCreate()
,initializeViews()
,initializeAlarmManager()
,go()
. - Aufgeblasen aus
activity_main.xml
unter Verwendung dersetContentView()
Methode. - Die Ansichten, die wir verwenden, sind
EditTexts
undButtons
. - Verweisen Sie auf sie in unserer Layout-Spezifikation mit
findViewById()
. - Initialisieren Sie
AlarmManager
. - Starte den Alarm mit
setInExactRepeating()
.
package com.tutorials.hp.repeatingalarm;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
Button startBtn,cancelBtn;
EditText timeTxt;
AlarmManager alarmManager;
PendingIntent pi;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
initializeViews();
initializeAlarmManager();
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
go();
}
});
}
/*
INITIALIZE VIEWS
*/
private void initializeViews()
{
timeTxt= (EditText) findViewById(R.id.timeTxt);
startBtn= (Button) findViewById(R.id.startBtn);
cancelBtn= (Button) findViewById(R.id.cancelBtn);
startBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
go();
}
});
cancelBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(alarmManager != null)
{
alarmManager.cancel(pi);
}
}
});
}
/*
INITIALIZE AND START OUR ALARM
*/
private void initializeAlarmManager()
{
// INITIALIZE INTENT
Intent intent=new Intent(this,MyReceiver.class);
//PASS CONTEXT,YOUR PRIVATE REQUEST CODE,INTENT OBJECT AND FLAG
pi= PendingIntent.getBroadcast(this,0,intent,0);
//INITIALIZE ALARM MANAGER
alarmManager= (AlarmManager) this.getSystemService(ALARM_SERVICE);
}
/*
START OUR ALARM
*/
private void go()
{
//GET TIME IN SECONDS
int time=Integer.parseInt(timeTxt.getText().toString());
//SET THE ALARM
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) {
alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP,System.currentTimeMillis()+(time*1000),time*1000,pi);
Toast.makeText(MainActivity.this, "Alarm set in "+time+" seconds", Toast.LENGTH_SHORT).show();
}else
{
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME,System.currentTimeMillis()+(time*1000),time*1000,pi);
Toast.makeText(MainActivity.this, "Yes Alarm set in "+time+" seconds", Toast.LENGTH_SHORT).show();
}
}
}
ActivityMain.xml
Dies ist ein Vorlagenlayout für unsere "MainActivity". Unser Root-Layout-Tag ist CoordinatorLayout
. KoordinatorLayout" ist eine Ansichtsgruppe, die auf Framelayout aufbaut.
- CoordinatorLayout" ist für zwei Hauptanwendungsfälle gedacht: Als Top-Level-Anwendungsdekor oder Chrom-Layout Als Container für eine spezifische Interaktion mit einer oder mehreren untergeordneten Ansichten
- Innerhalb unseres
CoordinatorLayout
fügen wir hinzu:AppBarLayout
,FloatingActionButton und schließencontent_main.xml
ein. AppBarLayout
ist ein vertikales LinearLayout, das die Scroll-Funktionen des Material Design-Konzepts implementiert.- Es sollte ein direktes Kind von
CoordinatorLayout
sein, sonst werden viele Funktionen nicht funktionieren. - Innerhalb des
AppBarLayout
fügen wir unsereToolbar
hinzu, der wir eine blaue Farbe geben. - Wir werden unsere Widgets in unserer
content_main.xml
hinzufügen, nicht hier, da dies ein Template-Layout ist. - Schließlich haben wir einen
FloatingActionButton
, eine Klasse, die vonandroid.support.design.widget.VisibilityAwareImageButton
abgeleitet ist. Es ist die runde Schaltfläche, die Sie in unserer Benutzeroberfläche sehen.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
tools_context="com.tutorials.hp.repeatingalarm.MainActivity">
<android.support.design.widget.AppBarLayout
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_theme="@style/AppTheme.AppBarOverlay">
<android.support.v7.widget.Toolbar
android_id="@+id/toolbar"
android_layout_width="match_parent"
android_layout_height="?attr/actionBarSize"
android_background="?attr/colorPrimary"
app_popupTheme="@style/AppTheme.PopupOverlay" />
</android.support.design.widget.AppBarLayout>
<include layout="@layout/content_main" />
<android.support.design.widget.FloatingActionButton
android_id="@+id/fab"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_gravity="bottom|end"
android_layout_margin="@dimen/fab_margin"
app_srcCompat="@android:drawable/ic_dialog_email" />
</android.support.design.widget.CoordinatorLayout>
ContentMain.xml
- Unsere
ContentMain.xml
-Datei. - Soll zu
MainActivity
aufgeblasen werden. - Wurzel-Tag ist
ConstraintLayout
. - Enthält
EditTexts
und zwei Schaltflächen. - Der Benutzer gibt die Anzahl der Sekunden, nach denen der Alarm ertönt, in den Edit-Text ein.
- Dann klicken Sie auf die Schaltfläche "Start", um den Alarm zu starten.
- Und Abbrechen-Button, um den Alarm abzubrechen.
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
android_layout_width="match_parent"
android_layout_height="match_parent"
app_layout_behavior="@string/appbar_scrolling_view_behavior"
tools_context="com.tutorials.hp.repeatingalarm.MainActivity"
tools_showIn="@layout/activity_main">
<LinearLayout
android_layout_width="368dp"
android_layout_height="327dp"
android_orientation="vertical"
app_layout_constraintTop_toTopOf="parent"
android_layout_marginTop="8dp">
<EditText
android_id="@+id/timeTxt"
android_layout_width="wrap_content"
android_layout_height="wrap_content"
android_layout_alignParentLeft="true"
android_layout_alignParentTop="true"
android_ems="10"
android_hint="Number of seconds"
android_inputType="numberDecimal"
/>
<Button
android_id="@+id/startBtn"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_layout_alignRight="@+id/timeTxt"
android_layout_below="@+id/timeTxt"
android_text="Start"
/>
<Button
android_id="@+id/cancelBtn"
android_layout_width="match_parent"
android_layout_height="wrap_content"
android_layout_alignRight="@+id/timeTxt"
android_layout_below="@+id/timeTxt"
android_text="Cancel"
/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Video/Vorschau
- Wir haben einen YouTube-Kanal mit fast tausend Tutorials, das folgende ist eines davon.
https://www.youtube.com/watch?v=23Gw-11JFqc
Herunterladen
- Sie können das gesamte Projekt unten herunterladen. Der Quellcode ist gut kommentiert.