androidservice定时
⑴ Android开发,在service里遍历所有的定时,service启动瞬间,所有闹钟都响了,怎么
使用AlramManager设置闹钟的时候,需要设置PendingIntent,构造的时候如下:
java">PendingIntent.getBroadcast(context,id*100+pos,
intent,PendingIntent.FLAG_UPDATE_CURRENT);
看下你PendingIntent的ID是不是相同的,如果相同的话,会认为是同一个事件。
⑵ android 怎么实现后台注册一个service,定时定位的功能
public class ServiceLocationGPS extends Service implements AMapLocationListener {
private GlobalApp app;
private LocationManagerProxy aMapLocManager = null;
private AMapLocation aMapLocation;// 用于判断定位超时
public Timer timer;
TimerTask task;
public Integer period = 10;
public Integer count = 0;
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
app = (GlobalApp) getApplication();
start();
super.onCreate();
}
@Override
public void onDestroy() {
stoptime();
super.onDestroy();
}
@Override
@Deprecated
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onLocationChanged(Location arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
public void startLocation() {
if (aMapLocManager == null) {
aMapLocManager = LocationManagerProxy
.getInstance(ServiceLocationGPS.this);
System.out.println("startLocation");
aMapLocManager.requestLocationUpdates(
LocationProviderProxy.AMapNetwork, -1, 10, this);
} else {
aMapLocManager.requestLocationUpdates(
LocationProviderProxy.AMapNetwork, -1, 10, this);
}
public void start() {
initSchele();
// 10秒以后启动任务;
startSchele(10);
}
@Override
public void onLocationChanged(AMapLocation location) {
if (location != null) {
this.aMapLocation = location;// 判断超时机制
Double geoLat = location.getLatitude();
Double geoLng = location.getLongitude();
String cityCode = "";
String desc = "";
Bundle locBundle = location.getExtras();
if (locBundle != null) {
cityCode = locBundle.getString("citycode");
desc = locBundle.getString("desc");
}
System.out.println("onLocationChanged," + geoLat + "," + geoLng);
// aMapLocManager.removeUpdates(this);
//stopLocation();
}
}
/**
* 销毁定位
*/
public void stopLocation() {
if (aMapLocManager != null) {
aMapLocManager.removeUpdates(this);
aMapLocManager.destory();
}
aMapLocManager = null;
}
/**
* 开启定时任务;
*/
public void startSchele(int delay) {
if (timer != null && task != null)
// 10秒以后执行任务;
timer.schele(task, delay * 1000, period * 1000);
}
public void initSchele() {
if (timer == null)
timer = new Timer();
if (task == null)
task = new TimerTask() {
@Override
public void run() {
startLocation();
}
};
}
private void stoptime() {
if (timer != null) {
timer.cancel();
timer = null;
}
if (task != null) {
task.cancel();
task = null;
}
}
}
⑶ android 后台运行 并定时触发任务
Android中的定时任务一般有两种实现方式,一种是使用Java
API里的Timer类,另一种是使用Android的Alarm机制。
这两种方式在多数情况下都能实现类似的效果,但Timer有一个明显的短板,它并不太适用与那些需要长期在后台运行的定时任务。As we
know,为了能让电池更加耐用,每种手机都会有自己的休眠策略:比如手机不用的时候智能的断开wifi连接,根据光线强弱自动调节屏幕亮度,根据手机长时间无操作时自动的让CPU进入到休眠状态等,当进入休眠状态时,这就有可能导致Timer中的定时任务无法正常运行。而Alarn机制则不存在这种情况,它具有唤醒CPU的功能,即可以保证每次需要执行定时任务的时候CPU都能正常工作。需要注意的是,这里的唤醒CPU和唤醒屏幕不是同一个概念,不能混淆。
这里我们只说Alarm机制的方式,代码如下:
public class AutoUpdateService extends Service {
@Override
public IBinder onBind(Intent intent) {
return null;
}
// 每次服务启动的时候调用
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
new Thread(new Runnable() {
@Override
public void run() {
doSomething();//这是定时所执行的任务
}
}).start();
AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
int anHour =8 * 60 * 60 * 1000;// 这是8小时的毫秒数 为了少消耗流量和电量,8小时自动更新一次
long triggerAtTime = SystemClock.elapsedRealtime() + anHour;
Intent intent2 = new Intent(this, AutoUpdateReceiver.class);
PendingIntent pi = PendingIntent.getBroadcast(this, 0, intent2, 0);
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime, pi);</span>
return super.onStartCommand(intent, flags, startId);
}
注意这里的AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);此处实现了定时任务。
首先我们通过调用Context的getSystemService()方法来获取AlarmManager的实例,这里需要传入的参数是ALARM_SERVICE.
接下来调用AlarmManager的set()方法就可以设置一个定时任务了,比如设定一个任务在5秒钟后执行,就可以写成 long
triggerAtTime = SystemClock.elapsedRealtime() + 5*1000;
manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, triggerAtTime,
pi);
其中第一个参数是一个整形参数,用于指定AlarmManager的工作类型,有四种值可以选,分别是
ELAPSED_REALTIME、ELAPSED_REALTIME_WAKEUP、RTC和RTC_WAKEUP。其中ELAPSED_REALTIME表示让定时任务的触发时间从系统开机开始算起,但不会唤醒CPU。ELAPSED_REALTIME_WAKEUP同样表示让定时任务的触发时间从系统开机开始算起,但会唤醒CPU。RTC表示让定时任务的触发时间从1970年1月1日0点开始算起,但不会唤醒CPU。RTC_WAKEUP同样表示让定时任务的触发时间从1970年1月1日0点开始算起,但会唤醒CPU。使用SystemClock.elapsedRealtime()方法可以获取到系统开机至今所经历时间的毫秒数,使用System.currentTimeMillis()方法可以获取到1970年1月1日0点至今所经历时间的毫秒数。
然后看一下第二个参数,这个参数就好理解多了,就是定时任务触发的时间,以毫秒为单位。如果第一个参数使用的是ELAPSED_REALTIME或ELAPSED_REALTIME_WAKEUP,则这里传入开机至今的时间再加上延迟执行的时间。如果第一个参数使用的是RTC或RTC_WAKEUP,则这里传入1970年1月1日0点至今的时间再加上延迟执行的时间。
第三个参数是一个PendingIntent,这里我们一般会调用getBroadcast()方法来获取一个能够执行广播的PendingIntent。这样当定时任务被触发的时候,广播接收器的onReceive()方法就可以得到执行。
当然设定一个任务在10秒钟后执行还可以写成:
longtriggerAtTime =
System.currentTimeMillis() + 10 * 1000;
manager.set(AlarmManager.RTC_WAKEUP,triggerAtTime,
pendingIntent);
然后创建PendingIntent指定处理定时任务的广播接收器AutoUpdateReceiver。
import service.AutoUpdateService;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class AutoUpdateReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, AutoUpdateService.class);
context.startService(i);
}
}
当启动AutoUpdateService后,就会在onStartCommand()方法里设定一个定时任务,这样每8个小时AutoUpdateReceiver的onReceive()方法就会得到执行,这样就又会启动AutoUpdateService服务,形成了永久的循环,保证服务每隔一段时间就会启动一次,这样就完成了一个长期在后台运行的服务。
我们在哪里启动服务呢,这要看具体的情况了,一般的话,当我们打开程序的时候启动一次就好了
比如写在Activity的onCrete()方法里
Intent
intent =new Intent(this,AutoUpdateService.class);
startService(intent);
最后,既然我们用到了服务和广播接收器,那么就得在AndroidManifest.xml中注册才行。
<service android:name="service.AutoUpdateService" ></service>
<receiver android:name="receiver.AutoUpdateReceiver"
></receiver>
本文参考资料:《第一行代码》
⑷ android 关于定时执行问题
Handler.postDelayed的Integer参数代表是毫秒,你给的1000意思是一秒钟,如果你是重复执行某一任务,延迟时间是上一次任务执行完毕,再等待十秒,你虽然延迟的是一秒,但可能gps(),代码执行需要9秒。
⑸ android service 做个定时器 时间到了无论在那个程序都会显示对话框
只需要在service里弹出一个全局对话框即可,以下是示例代码:
1.创建对象框
AlertDialog.Builder builder = new Builder(context);
builder.setTitle("请输入"); //设置对话框标题
builder.setIcon(android.R.drawable.btn_star); //设置对话框标题前的图标
2.创建EditText输入框
final EditText edit = new EditText(context);
3.将输入框赋值给Dialog,并增加确定取消按键
builder.setView(edit);
builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(context, "你输入的是: " + edit.getText().toString(), Toast.LENGTH_SHORT).show();
}
});
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Toast.makeText(context, "你点了取消", Toast.LENGTH_SHORT).show();
}
});
4.设置常用api,并show弹出
builder.setCancelable(true); //设置按钮是否可以按返回键取消,false则不可以取消
AlertDialog dialog = builder.create(); //创建对话框
dialog.setCanceledOnTouchOutside(true); //设置弹出框失去焦点是否隐藏,即点击屏蔽其它地方是否隐藏
dialog.show();
⑹ android中如何实现定时提醒
android中可以使用闹钟进行提醒,你只需要告知系统你想在什么时候被提醒,然后需要一个闹钟的广播接收器,当到你设置的时间时,系统会给你发送一条广播,当你接收到广播后你就可以做一些操作,比如启动你的app,或者跳转到你app中的任何一个界面。代码如下:
//发送闹钟请求
Intent intent = new Intent(mContext, AlarmReceiver.class);
intent.setAction("something");
intent.setType("something");
intent.setData(Uri.EMPTY);
intent.addCategory(“something”);
intent.setClass(context, AlarmReceiver.class);
// 以上给intent设置的四个属性是用来区分你发给系统的闹钟请求的,当你想取消掉之前发的闹钟请求,这四个属性,必须严格相等,所以你需要一些比较独特的属性,比如服务器返回给你的json中某些特定字段。
//当然intent中也可以放一些你要传递的消息。
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, alarmCount, intent, 0);
//alarmCount是你需要记录的闹钟数量,必须保证你所发的alarmCount不能相同,最后一个参数填0就可以。
AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);
//这样闹钟的请求就发送出去了。time是你要被提醒的时间,单位毫秒,注意不是时间差。第一个参数提醒的需求用我给出的就可以,感兴趣的朋友,可以去google一下,这方面的资料非常多,一共有种,看一下就知道区别了。
//取消闹钟请求
Intent intent = new Intent(mContext, AlarmReceiver.class);
intent.setAction("something");
intent.setType(something);
intent.setData(Uri.EMPTY);
intent.addCategory(something);
intent.setClass(context, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(mContext, alarmCount, intent, 0);
//alarmCount对应到你设定时的alarmCount,
AlarmManager am = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
am.cancel(pendingIntent);
//接着,你需要一个广播接收的类:
public class AlarmReceiver extends BroadcastReceiver{
private NotificationManager manager;
@Override
public void onReceive(Context context, Intent intent) {
manager = (NotificationManager)context.getSystemService(android.content.Context.NOTIFICATION_SERVICE);
//例如这个id就是你传过来的
String id = intent.getStringExtra("id");
//MainActivity是你点击通知时想要跳转的Activity
Intent playIntent = new Intent(context, MainActivity.class);
playIntent.putExtra("id", id);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, playIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setContentTitle("title").setContentText("提醒内容").setSmallIcon(R.drawable.app_icon).setDefaults(Notification.DEFAULT_ALL).setContentIntent(pendingIntent).setAutoCancel(true).setSubText("二级text");
manager.notify(1, builder.build());
}
}
⑺ Android 实现定时任务的五种方式
1、普通线程sleep的方式,可用于一般的轮询Polling
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
//todo
try {
Thread.sleep(iDelay);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
优点:非常简单的实现,逻辑清晰明了,也是最常见的写法
缺点:在sleep结束后,并不能保证竞争到cpu资源,这也就导致了下次执行时间必定>=iDelay,存在时间精度问题
2、Timer定时器
//Timer + TimerTask结合的方法
private final Timer timer = new Timer();
private TimerTask timerTask = new TimerTask() {
@Override
public void run() {
//todo
}
};
启动定时器方法:
timer.schele(TimerTask task, long delay, long period)
立即执行
timer.schele(timerTask, 0, 1000); //立刻执行,间隔1秒循环执行
延时执行
timer.schele(timerTask, 2000, 1000); //等待2秒后再执行,间隔1秒循环执行
关闭定时器方法:timer.cancel();
优点:纯正的定时任务,纯java SDK,单独线程执行,比较安全,而且还可以在运行过程中取消执行
缺点:基于单线程执行,多个任务之间会相互影响,多个任务的执行是串行的,性能较低,而且timer也无法保证时间精确度,是因为手机休眠的时候,无法唤醒cpu,不适合后台任务的定时
3、ScheledExecutorService
private Runnable runnable2 = new Runnable() {
@Override
public void run() {
//todo
}
};
ScheledExecutorService executor = Executors.newScheledThreadPool(1);
executor.scheleAtFixedRate(runnable2, 0, 1, TimeUnit.SECONDS);
关于scheleAtFixedRate(Runnable command, long initialDelay, long period, TimeUnit unit) 方法说明:
command:需要执行的线程
initialDelay:第一次执行需要延时的时间,如若立即执行,则initialDelay = 0
period:固定频率,周期性执行的时间
unit:时间单位,常用的有MILLISECONDS、SECONDS和MINUTES等,需要注意的是,这个单位会影响initialDelay和period,如果unit = MILLISECONDS,则initialDelay和period传入的是毫秒,如果unit = SECONDS,则initialDelay和period传入的是秒
补充一下: 还有一个方法跟上面的很相似:scheleWithFixedDelay(Runnable command, long initialDelay, long delay, TimeUnit unit),这个也是带延迟时间的调度,并且也是循环执行,唯一的不同就是固定延迟时间循环执行,上面的是固定频率的循环执行。那这两者的区别?
举例子:
使用scheleAtFixedRate,任务初始延迟3秒,任务执行3秒,任务执行间隔为5秒:
ScheledExecutorService executor = Executors.newScheledThreadPool(1);
Log.e(TAG, "schele just start! time =" + simpleDateFormat.format(System.currentTimeMillis()));
executor.scheleAtFixedRate(new Runnable() {
@Override
public void run() {
SystemClock.sleep(3000L);
Log.e(TAG, "runnable just do it! time =" + simpleDateFormat.format(System.currentTimeMillis()));
}
}, 3, 5, TimeUnit.SECONDS);
执行结果截图:
使用scheleWithFixedDelay,任务初始延迟3秒,任务执行3秒,任务执行延迟为5秒:
ScheledExecutorService executor = Executors.newScheledThreadPool(1);
Log.e(TAG, "schele just start! time =" + simpleDateFormat.format(System.currentTimeMillis()));
executor.scheleWithFixedDelay(new Runnable() {
@Override
public void run() {
SystemClock.sleep(3000L);
Log.e(TAG, "runnable just do it! time =" + simpleDateFormat.format(System.currentTimeMillis()));
}
}, 3, 5, TimeUnit.SECONDS);
执行结果截图:
从这两者的运行结果就可以看到区别了:scheleAtFixedRate是相对于任务执行的开始时间,而scheleWithFixedDelay是相对于任务执行的结束时间。
优点:ScheledExecutorService是一个线程池,其内部使用的延迟队列,本身就是基于等待/唤醒机制实现的,所以CPU并不会一直繁忙。解决了Timer&TimerTask存在的问题,多任务处理时效率高
缺点:取消时需要打断线程池的运行,而且和外界的通信不太好处理
4、使用Handler中的postDelayed方法
private Handler mHandler = new Handler();
private Runnable runnable = new Runnable() {
@Override
public void run() {
//todo
mHandler.postDelayed(this, iDelay);
}
};
mHandler.post(runnable); //立即执行
mHandler.postDelayed(runnable, iDelay); //延时执行
mHandler.removeCallbacks(runnable); //取消执行
优点:比较简单的android实现,适用UI线程
缺点:没想到,手动捂脸。。。。我估计是使用不当会造成内存泄露吧
5、Service + AlarmManger + BroadcastReceiver
⑻ android 怎么实现后台注册一个service,定时定位的功能
public class ServiceLocationGPS extends Service implements AMapLocationListener {
private GlobalApp app;
private LocationManagerProxy aMapLocManager = null;
private AMapLocation aMapLocation;// 用于判断定位超时
public Timer timer;
TimerTask task;
public Integer period = 10;
public Integer count = 0;
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
app = (GlobalApp) getApplication();
start();
super.onCreate();
}
@Override
public void onDestroy() {
stoptime();
super.onDestroy();
}
@Override
@Deprecated
public void onStart(Intent intent, int startId) {
// TODO Auto-generated method stub
super.onStart(intent, startId);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onLocationChanged(Location arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProviderDisabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onProviderEnabled(String arg0) {
// TODO Auto-generated method stub
}
@Override
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
// TODO Auto-generated method stub
}
public void startLocation() {
if (aMapLocManager == null) {
aMapLocManager = LocationManagerProxy
.getInstance(ServiceLocationGPS.this);
System.out.println("startLocation");
aMapLocManager.requestLocationUpdates(
LocationProviderProxy.AMapNetwork, -1, 10, this);
} else {
aMapLocManager.requestLocationUpdates(
LocationProviderProxy.AMapNetwork, -1, 10, this);
}
public void start() {
initSchele();
// 10秒以后启动任务;
startSchele(10);
}
@Override
public void onLocationChanged(AMapLocation location) {
if (location != null) {
this.aMapLocation = location;// 判断超时机制
Double geoLat = location.getLatitude();
Double geoLng = location.getLongitude();
String cityCode = "";
String desc = "";
Bundle locBundle = location.getExtras();
if (locBundle != null) {
cityCode = locBundle.getString("citycode");
desc = locBundle.getString("desc");
}
System.out.println("onLocationChanged," + geoLat + "," + geoLng);
// aMapLocManager.removeUpdates(this);
//stopLocation();
}
}
/**
* 销毁定位
*/
public void stopLocation() {
if (aMapLocManager != null) {
aMapLocManager.removeUpdates(this);
aMapLocManager.destory();
}
aMapLocManager = null;
}
/**
* 开启定时任务;
*/
public void startSchele(int delay) {
if (timer != null && task != null)
// 10秒以后执行任务;
timer.schele(task, delay * 1000, period * 1000);
}
public void initSchele() {
if (timer == null)
timer = new Timer();
if (task == null)
task = new TimerTask() {
@Override
public void run() {
startLocation();
}
};
}
private void stoptime() {
if (timer != null) {
timer.cancel();
timer = null;
}
if (task != null) {
task.cancel();
task = null;
}
}
}
⑼ android 当关闭程序时,service 每天定时更新数据
这种需求可以用AlarmManager实现,在AlarmManager里设置初次执行时间和循环间隔,到设置时间了触发Service更新数据