问题描述
我有一次达到特定日期失去其意义和新的日期在DB这些领域应计算,我知道我可以利用AlarmManager类这一点,但是我有一个关于这几个顾虑:
I have certain dates which once attained lose their relevance and new dates for these fields in the DB should be calculated, I know I can leverage the AlarmManager class for this, however I have a few concerns regarding this:
1)注:与API开始19(奇巧)警报传递是不准确的:操作系统将为了尽量减少唤醒和电池使用Shift报警。有新的API,这就需要严格的交付担保支持应用程序;看到setWindow(INT,很长很长,PendingIntent)和setExact(的int,long,PendingIntent)。应用其targetSdkVersion早于19 API将继续看到在其中,当要求所有报警都提供完全previous行为。
1) Note: Beginning with API 19 (KITKAT) alarm delivery is inexact: the OS will shift alarms in order to minimize wakeups and battery use. There are new APIs to support applications which need strict delivery guarantees; see setWindow(int, long, long, PendingIntent) and setExact(int, long, PendingIntent). Applications whose targetSdkVersion is earlier than API 19 will continue to see the previous behavior in which all alarms are delivered exactly when requested.
所以,做我需要分别code这两种情况下,或者如果我的目标奇巧,将是对旧版本太多的工作?另外,作为我的code执行时间性强的,说12AM的一些日午夜后,我的数据失去意义,如何克服报警发生变化。
So do I need to code for both cases separately or if I target kitkat, will that work for older versions too? Also as my code execution is time critical, say after 12AM in the midnight of some date my Data loses relevance, how to overcome shifting of alarms.
2)注册的警报被保留,而在设备处于睡眠状态(并且可任选地唤醒设备,如果他们在这段时间去关闭),但如果它被关闭和重新启动将被清除。
2)Registered alarms are retained while the device is asleep (and can optionally wake the device up if they go off during that time), but will be cleared if it is turned off and rebooted.
2.1)将您的应用程序的清单中RECEIVE_BOOT_COMPLETED权限。这使您的应用程序接收ACTION_BOOT_COMPLETED广播在系统完成引导后的(此方法在应用程序已经被用户推出至少一次)
2.1) Set the RECEIVE_BOOT_COMPLETED permission in your application's manifest. This allows your app to receive the ACTION_BOOT_COMPLETED that is broadcast after the system finishes booting (this only works if the app has already been launched by the user at least once)
2.1.1)。如果我设置闹钟在12,12与此相关的火警服务,现在,当我重新启动设备,当时12已经过去了,报警器会立即再次发射而该服务将被再次叫什么名字?
2.1.1) If I have set an alarm at 12, the service related to this alarm fires at 12, Now when I reboot the device, the time "at 12" has already passed, the alarm will be fired again immediately and the service will be called again?
目前重启的机制是什么,我需要的,为了实现坚持我的code的执行在一定时间内的政策?我如何设置报警,如果用户不启动我的应用程序?
At reboot what mechanism do I need to implement in-order to stick to my code execution policy at certain time? How do I set the alarm if the user does not launch my app?
第三件事是,如果我的应用程序卸载我想清楚了我的code设置所有报警,我怎么听,当应用程序被卸载?
The third thing is that if my app is uninstalled I want to clear all alarms set by my code, how do I listen to when the app is uninstalled?
此外,我想知道,我的应用程序是非常严格时间要求的,在我的数据库中值的每个晚上得到过时12日上午,当我更新的应用程序,如果用户选择使用,在我的应用程序,会是什么结果12当我使用服务来更新它和它在后台运行?
Also I want to know, my app is very time critical, the values in my DB get obsolete by 12 am each night, while I am updating the app, what would be the result if a user chooses to use my app at 12 while I use a service to update it and its running in the background?
编辑:我已经试过到目前为止:
我有一个数据库,其中记录会过时过了午夜,说锋利12:00。我调用报警管理器(在一个测试项目,因为我喜欢找出问题code)消防服务。我还获得一个PARTIAL_WAKE_LOCK的装置上,使我的庞大的数据库操作正确完成。我也实现了一个线程来执行我的耗时的任务。以下是我MainActivity类,我们调用了12来启动报警(随机时间测试的目的):
I have a Database in which records get stale past midnight, say sharp at 12:00. I invoked an Alarm Manager(In a test project as I like to isolate the problem code) to fire a service. I also acquire a PARTIAL_WAKE_LOCK on the device so that my huge database manipulation is done properly. I have also implemented a thread to do my time consuming task. Following is my MainActivity Class which I invoke at 12 to initiate the alarm(Random time for test purpose):
public class MainActivity extends Activity {
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
BroadcastReceiver br;
TextView t;
int sum;
public void setSum(int s){
sum = s;
// t = (TextView)findViewById(R.id.textView1);
// t.setText(sum);
System.out.println("In Set Sum"+s);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setup();
t = (TextView)findViewById(R.id.textView1);
ComponentName receiver = new ComponentName(getApplicationContext(), SampleBootReceiver.class);
PackageManager pm = getApplicationContext().getPackageManager();
pm.setComponentEnabledSetting(receiver,
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 17);
calendar.set(Calendar.MINUTE, 05); // Particular minute
calendar.set(Calendar.SECOND, 0);
alarmMgr = (AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000*60*60*24, alarmIntent);
}
public void setup() {
br = new BroadcastReceiver() {
@Override
public void onReceive(Context c, Intent i) {
Toast.makeText(c, "Rise and Shine!", Toast.LENGTH_LONG).show();
//Invoke the service here Put the wake lock and initiate bind service
t.setText("Hello Alarm set");
startService(new Intent(MainActivity.this, MyService.class));
stopService(new Intent(MainActivity.this, MyService.class));
}
};
registerReceiver(br, new IntentFilter("com.testrtc") );
alarmIntent = PendingIntent.getBroadcast( this, 0, new Intent("com.testrtc"),0 );
alarmMgr = (AlarmManager)(this.getSystemService( Context.ALARM_SERVICE ));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
这是我SampleBootReceiver类序检查重启,重启后重新设置报警,我不知道这是否按预期工作。我找不到任何方法来测试,如果这是工作正常,但我确实收到有关引导完成的吐司消息。
This is my SampleBootReceiver Class inorder to check for reboots and set Alarms again after reboot, I am not sure if it works as intended. I could find no means to test if this is working properly but I do receive the Toast message about completion of boot.
public class SampleBootReceiver extends BroadcastReceiver {
private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
BroadcastReceiver br;
TextView t;
MainActivity main;
@Override
public void onReceive(Context context, Intent intent) {
main= new MainActivity();
if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
Toast.makeText(context, "Hello from Bootloader", 10000).show();
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 15);
calendar.set(Calendar.MINUTE, 50); // Particular minute
calendar.set(Calendar.SECOND, 0);
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
1000*60*60*24, alarmIntent);
context.getApplicationContext().registerReceiver(br, new IntentFilter("com.testrtc") );
alarmIntent = PendingIntent.getBroadcast( context.getApplicationContext(), 0, new Intent("com.testrtc"),
0 );
alarmMgr = (AlarmManager)(context.getApplicationContext().getSystemService( Context.ALARM_SERVICE ));
}
}
}
以下是我的服务类,不确定我在这里做了onStartCommand方法返回的:
The following is my service Class, unsure about the return I am doing here in the onStartCommand method:
public class MyService extends Service {
int a = 2;
int b = 2;
int c = a+b;
public MainActivity main = new MainActivity();
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
Toast.makeText(this, "The new Service was Created", Toast.LENGTH_LONG).show();
}
@Override
public int onStartCommand(Intent i, int flags , int startId){
WakeLock wakeLock = null;
try{
PowerManager mgr = (PowerManager)getApplicationContext().getSystemService(Context.POWER_SERVICE);
wakeLock = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
wakeLock.acquire();
Toast.makeText(this, " Service Started", Toast.LENGTH_LONG).show();
new Thread(new Runnable() {
public void run(){
//Will be substituted with a time consuming long task.
main.setSum(c);
}
}).start();
}catch(Exception e){
System.out.println(e);
}finally{
wakeLock.release();
}
return 1;
}
@Override
public void onDestroy() {
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
此外,在上述,我想知道如果我启动线程将与我是如何获取唤醒锁interfare。另外,如果我可以用一个异步任务,并释放wakelock在onPostExecute?
Also in the above, I want to know if the thread I am starting will interfare with how I am acquiring the wake lock. Also if I can use an async task and release the wakelock in onPostExecute?
最后,这里是我的清单:
Finally here is my Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.testrtc"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.testrtc.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".SampleBootReceiver"
android:enabled="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" >
</action>
</intent-filter>
</receiver>
<service
android:name="com.testrtc.MyService"
android:enabled="true"
android:exported="true" >
</service>
</application>
</manifest>
这是我的重启后的日志猫,有,但是我发现这些相关的应用程序,许多日志消息,它们包含日epackage名称:
THis is my log Cat after reboot, there are many log messages however I find these related to the app, they contain th epackage name:
01-22 15:18:35.652: V/ActivityManager(419): getTasks: max=1, flags=0, receiver=null
01-22 15:18:35.652: V/ActivityManager(419): com.xxx.xxx/.MainActivity: task=TaskRecord{425c58f0 #5 A com.xxx.xxx U 0}
01-22 15:18:35.653: V/ActivityManager(419): We have pending thumbnails: null
更多的问题:我应该在哪里设置报警,如果我这样做,我的闪屏的OnCreate它会在每次应用程序启动时调用,也许覆盖旧的值。
More Questions: Where should I set up the Alarm, if I do it in the onCreate of my Splash screen it will be called each time the app starts, maybe overwriting the older values.
其次,我想收购的时候,我的服务正在运行,如果此时用户试图打开我的应用程序怎么办的数据库的锁? (当数据得到更新我没有什么可以炫耀)。
Second I want to acquire a lock on the DB when my service is running, if in this time the user tries to open my app what do I do? (As data is getting updated I dont have anything to show).
三,在上述code,我仍然发现的问题进行登记重启后报警。
Third in the above code I am still finding problems to register an alarm after reboot.
推荐答案
1)要处理的确切时间报警你有2个选择: a)在18设置最小的SDK水平,而不是19。这将使得在奇巧您的应用程序工作,在准确的时间 B)使用setExact()方法来告诉奇巧保持你的闹钟在指定的确切时间 资料来源: http://developer.android.com/about/versions/android-4.4 html的
1) To handle alarm at exact times you have 2 options: a) Set minimum SDK level at 18 and not 19. This will make your app work on kitkat at the exact time b) Use the setExact() method to tell Kitkat to keep your alarm at the exact time specified Source: http://developer.android.com/about/versions/android-4.4.html
2)引导完成的通知是最好的一段路要走。您可以设置的广播接收器,以获得重新启动的通知。您可以将告警信息数据库和检索重新启动。
2) The boot completed notification is the best way to go. You can set up a Broadcast receiver to get the notification on a reboot. You can store alarms in a Database and retrieve on reboot.
2.1),这是可怕的编程习惯做一些用户不希望你这样做,即设置,即使用户没有打开该应用程序的警报。
2.1) It is horrible programming practice to do something the user did not want you to do, i.e. set an alarm even though user has not opened the app.
3)只要你不创建在SD卡上的文件,所有的应用程序数据在应用程序的卸载删除
3) As long as you don't create files on the SD card, all application data is removed upon uninstall of the app
4)写入或读取来解决你的问题,中午12点时,您应该锁定/解锁数据。如果数据已被锁定,就不会得到受影响,直到用户已经提交该事务。 http://www.sqlite.org/lockingv3:如果您使用SQLite你可以从它的更多信息html的
4) You should lock/unlock data when writing or reading from it to solve your 12AM problem. If the data is locked, it would not get affected until the user has committed the transaction. If you are using SQLite you can get more information on this from: http://www.sqlite.org/lockingv3.html
这篇关于安排一个事件在将来被执行(定时任务的机器人方式)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!