我想知道是否可以(以及是否可以)在特定时间启动我的应用程序,例如在特定时间响起的闹钟。假设我希望我的应用程序在早上 8 点启动,这可行吗?
3 回答
您可以使用 AlarmManager 来完成,这是一个简短的示例。首先你需要设置闹钟:
AlarmManager am = (AlarmManager) con.getSystemService(Context.ALARM_SERVICE);
Date futureDate = new Date(new Date().getTime() + 86400000);
futureDate.setHours(8);
futureDate.setMinutes(0);
futureDate.setSeconds(0);
Intent intent = new Intent(con, MyAppReciever.class);
PendingIntent sender = PendingIntent.getBroadcast(con, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
am.set(AlarmManager.RTC_WAKEUP, futureDate.getTimeInMillis(), sender);
接下来,您需要使用一些代码创建一个接收器来执行您的应用程序:(即 - 启动您的应用程序):
public class MyAppReciever extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
startActivity(new Intent(context, MyAppMainActivity.class));
}
}
您可能正在寻找AlarmManager,它可以让您以特定的时间间隔或给定的时间启动服务/活动/发送广播,无论是否重复。这就是您在 android 中编写内存友好型后台服务的方式。AlarmManager
有点像unix中的cron。它允许您的后台服务启动、完成其工作并耗尽内存。
您可能不想启动活动(如果这就是您所说的“应用程序”)。如果您想提醒用户发生了某事,请添加在给定时间启动接收器的警报,并让接收器添加通知。单击通知可以打开应用程序。这比将一些可能不需要的活动带到前台的侵入性要小。
有一个很好的教程:http ://www.javacodegeeks.com/2012/09/android-alarmmanager-tutorial.html
这是c&p:
Android AlarmManager 教程由 Rakesh Cusat 于 2012 年 9 月 20 日 | 归档于:Android 核心
在编写应用程序时,需要安排未来代码的执行。您可能需要 AlarmManager 在指定时间安排您的工作。即使在应用程序没有运行时,AlarmManager 也会访问系统警报并安排代码的执行。项目信息:关于项目的元信息。平台版本:Android API Level 10。IDE:Eclipse Helios Service Release 2 模拟器:Android 4.1
前提条件:初步了解Android应用框架,Intent Broadcast接收器。
警报管理器:
AlarmManager 可以访问系统报警服务。在 AlarmManager 的帮助下,您可以安排将来执行代码。AlarmManager 对象不能直接实例化,但是可以通过调用 Context.getSystemService(Context.ALARM_SERVICE) 来检索它。AlarmManager 总是按意图注册。当警报响起时,系统会自动广播已注册到 AlarmManager 的 Intent。如果目标应用程序未运行,此意图将启动它。当您希望应用程序代码在特定时间运行时,建议使用 AlarmManager,即使您的应用程序当前没有运行。对于其他时序操作应使用处理程序,因为它易于使用。处理程序在其他教程中介绍。
方法 说明 set() 安排一次闹钟。setInexactRepeating() 安排不精确重复的警报。触发时间不受任何严格限制。setRepeating() 安排具有精确重复时间的警报。setTime() 设置系统的挂钟时间。setTimeZone() 设置系统的默认时区。查看 AlarmManager 文档了解更多信息。
在本教程中,让我们学习创建一次性计时器和重复计时器,以及取消重复计时器。这里 timer 和 alarm 可以互换使用,但在本教程上下文中,它们具有相同的含义。
示例代码:
让我们在布局文件中创建三个按钮开始重复计时器、取消重复计时器和一次性计时器。这些按钮分别附有方法,即 startRepeatingTimer、cancelRepeatingTimer 和 onetimeTimer。这些方法将在 Activity 类中定义。布局文件如下所示(activity_alarm_manager.xml)。
<linearlayout android:layout_height='match_parent'
android:layout_width='match_parent' android:orientation='vertical'
xmlns:android='http://schemas.android.com/apk/res/android'
xmlns:tools='http://schemas.android.com/tools'>
<button android:id='@+id/btStart' android:layout_height='wrap_content'
android:layout_width='match_parent' android:onclick='startRepeatingTimer'
android:padding='@dimen/padding_medium' android:text='@string/btStart'
tools:context='.WidgetAlarmManagerActivity'/>
<button android:id='@+id/btCancel' android:layout_height='wrap_content'
android:layout_width='match_parent' android:onclick='cancelRepeatingTimer'
android:padding='@dimen/padding_medium' android:text='@string/btCancel'
tools:context='.WidgetAlarmManagerActivity'/>
<button android:id='@+id/btOneTime' android:layout_height='wrap_content'
android:layout_width='match_parent' android:onclick='onetimeTimer'
android:padding='@dimen/padding_medium' android:text='@string/btOneTime'
tools:context='.WidgetAlarmManagerActivity'/>
</linearlayout>
我们将定义 BroadcastReciever 来处理注册到 AlarmManager 的意图。在给定的类中定义了 onReceive() 方法。一旦收到意图,就会调用此方法。一旦我们收到意图,我们就会尝试获取与此意图关联的额外参数。这个额外的参数是用户定义的,即ONE_TIME,基本上表明这个意图是与一次性定时器相关联还是与重复定时器相关联。一旦提取了 ONE_TIME 参数值,就会相应地显示 Toast 消息。还定义了辅助方法,可以在对象的帮助下从其他地方使用,即 setAlarm()、cancelAlarm() 和 onetimeTimer() 方法。这些方法也可以在其他地方定义以对定时器进行操作,即设置、取消等。为了保持本教程的简单,
setAlarm():此方法通过使用 setRepeating() 方法设置重复警报。setRepeating() 方法需要四个参数:
警报类型,触发时间:将其设置为当前时间间隔(以毫秒为单位):在此示例中,我们将通过 5 秒(1000 * 5 毫秒)待定意图:它将与此警报一起注册。当警报被触发时,pendingIntent 将被广播。cancelAlarm():该方法通过调用cancel()方法取消之前注册的闹钟。cancel() 方法将pendingIntent 作为参数。pendingIntent 应该匹配一个,只有这样 cancel() 方法才能从系统中删除警报。
onetimeTimer():此方法创建一次性警报。这可以通过调用 set() 方法来实现。set() 方法接受三个参数:
警报触发时间类型 待定意图
package com.rakesh.alarmmanagerexample;
import java.text.Format;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.PowerManager;
import android.widget.Toast;
public class AlarmManagerBroadcastReceiver extends BroadcastReceiver {
final public static String ONE_TIME = 'onetime';
@Override
public void onReceive(Context context, Intent intent) {
PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, 'YOUR TAG');
//Acquire the lock
wl.acquire();
//You can do the processing here.
Bundle extras = intent.getExtras();
StringBuilder msgStr = new StringBuilder();
if(extras != null && extras.getBoolean(ONE_TIME, Boolean.FALSE)){
//Make sure this intent has been sent by the one-time timer button.
msgStr.append('One time Timer : ');
}
Format formatter = new SimpleDateFormat('hh:mm:ss a');
msgStr.append(formatter.format(new Date()));
Toast.makeText(context, msgStr, Toast.LENGTH_LONG).show();
//Release the lock
wl.release();
}
public void SetAlarm(Context context)
{
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
intent.putExtra(ONE_TIME, Boolean.FALSE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
//After after 5 seconds
am.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 5 , pi);
}
public void CancelAlarm(Context context)
{
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
public void setOnetimeTimer(Context context){
AlarmManager am=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmManagerBroadcastReceiver.class);
intent.putExtra(ONE_TIME, Boolean.TRUE);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), pi);
}
}
下面给出的是清单文件。在这里,需要 WAKE_LOCK 权限,因为在处理 AlarmManagerBroadcastReceiver 类中的 onReceive() 方法时正在使用唤醒锁。AlarmManagerBroadcastReceiver 已注册为广播接收器。
<manifest android:versioncode='1' android:versionname='1.0'
package='com.rakesh.alarmmanagerexample'
xmlns:android='http://schemas.android.com/apk/res/android'>
<uses-sdk android:minsdkversion='10' android:targetsdkversion='15'/>
<uses-permission android:name='android.permission.WAKE_LOCK'/>
<application android:icon='@drawable/ic_launcher'
android:label='@string/app_name' android:theme='@style/AppTheme'>
<activity android:label='@string/title_activity_alarm_manager'
android:name='com.rakesh.alarmmanagerexample.AlarmManagerActivity'>
<intent-filter>
<action android:name='android.intent.action.MAIN'/>
<category android:name='android.intent.category.LAUNCHER' />
</intent-filter>
</activity>
<receiver android:name='com.rakesh.alarmmanagerexample.AlarmManagerBroadcastReceiver'>
</receiver>
</application>
</manifest>
现在让我们定义定义一些方法的活动类。这些方法将处理按钮点击。在这个类中,我们创建了一个 AlarmManagerBroadcastReciever 的实例,它将帮助我们访问 setAlarm()、cancelAlarm() 和 setOnetime()。其余的代码很容易理解。
package com.rakesh.alarmmanagerexample;
import com.rakesh.alarmmanagerexample.R;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
import android.support.v4.app.NavUtils;
public class AlarmManagerActivity extends Activity {
private AlarmManagerBroadcastReceiver alarm;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_alarm_manager);
alarm = new AlarmManagerBroadcastReceiver();
}
@Override
protected void onStart() {
super.onStart();
}
public void startRepeatingTimer(View view) {
Context context = this.getApplicationContext();
if(alarm != null){
alarm.SetAlarm(context);
}else{
Toast.makeText(context, 'Alarm is null', Toast.LENGTH_SHORT).show();
}
}
public void cancelRepeatingTimer(View view){
Context context = this.getApplicationContext();
if(alarm != null){
alarm.CancelAlarm(context);
}else{
Toast.makeText(context, 'Alarm is null', Toast.LENGTH_SHORT).show();
}
}
public void onetimeTimer(View view){
Context context = this.getApplicationContext();
if(alarm != null){
alarm.setOnetimeTimer(context);
}else{
Toast.makeText(context, 'Alarm is null', Toast.LENGTH_SHORT).show();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_widget_alarm_manager, menu);
return true;
}
}
完成编码后,只需执行项目,您就会发现模拟器中正在运行类似类型的应用程序。
如需参考代码,请下载https://github.com/rakeshcusat/Code4Reference/tree/master/AndroidProjects/AlarmManagerExamplecode 。
参考:我们的 JCG 合作伙伴 Rakesh Cusat 在 Code4Reference 博客上的 Android AlarmManager 教程。
http://code4reference.com/2012/07/tutorial-on-android-alarmmanager/