【发布时间】:2012-05-02 19:28:03
【问题描述】:
我正在开发一个应用程序,它将有关其位置的信息中继到远程服务器。我打算通过向网络服务器发送一个简单的 HTTP 帖子来做到这一点,一切都很简单。
但根据规范,应用程序需要不时执行自身,假设每 30 分钟执行一次。独立于界面,这意味着即使应用程序关闭,它也需要运行。
我环顾四周,发现需要使用 Android Services。我可以用什么来实现这样的系统。手机重启时服务(或其他机制)会重启吗?
提前致谢。
【问题讨论】:
我正在开发一个应用程序,它将有关其位置的信息中继到远程服务器。我打算通过向网络服务器发送一个简单的 HTTP 帖子来做到这一点,一切都很简单。
但根据规范,应用程序需要不时执行自身,假设每 30 分钟执行一次。独立于界面,这意味着即使应用程序关闭,它也需要运行。
我环顾四周,发现需要使用 Android Services。我可以用什么来实现这样的系统。手机重启时服务(或其他机制)会重启吗?
提前致谢。
【问题讨论】:
创建Service 将您的信息发送到您的服务器。大概,你已经控制住了。
您的Service 应该由AlarmManager 触发的警报启动,您可以在其中指定时间间隔。除非您必须每 30 分钟准确报告一次数据,否则您可能需要不准确的警报,以便节省一些电池寿命。
最后,您可以通过设置BroadcastReceiver 来注册您的应用以获取启动广播,如下所示:
public class BootReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
// Register your reporting alarms here.
}
}
}
您需要将以下权限添加到您的 AndroidManifest.xml 才能使其正常工作。正常运行应用时不要忘记注册闹钟,否则只有在设备启动时才会注册。
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
【讨论】:
这是一种使服务永久运行的半不同方式。如果你愿意,有办法在代码中杀死它
后台服务:
package com.ex.ample;
import android.app.Service;
import android.content.*;
import android.os.*;
import android.widget.Toast;
public class BackgroundService extends Service {
public Context context = this;
public Handler handler = null;
public static Runnable runnable = null;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
Toast.makeText(this, "Service created!", Toast.LENGTH_LONG).show();
handler = new Handler();
runnable = new Runnable() {
public void run() {
Toast.makeText(context, "Service is still running", Toast.LENGTH_LONG).show();
handler.postDelayed(runnable, 10000);
}
};
handler.postDelayed(runnable, 15000);
}
@Override
public void onDestroy() {
/* IF YOU WANT THIS SERVICE KILLED WITH THE APP THEN UNCOMMENT THE FOLLOWING LINE */
//handler.removeCallbacks(runnable);
Toast.makeText(this, "Service stopped", Toast.LENGTH_LONG).show();
}
@Override
public void onStart(Intent intent, int startid) {
Toast.makeText(this, "Service started by user.", Toast.LENGTH_LONG).show();
}
}
这是您从主要活动或您希望的任何地方开始的方式:
startService(new Intent(this, BackgroundService.class));
onDestroy() 将在应用程序关闭或终止时被调用,但可运行对象只是重新启动它。
我希望这对某人有所帮助。
有些人这样做的原因是因为企业应用程序在某些情况下用户/员工不能停止某些事情:)
http://i.imgur.com/1vCnYJW.png
从 Android O (8.0) 开始,您必须使用 JobManager 来执行计划任务。有一个名为 Android-Job by Evernote 的库,它可以让所有 Android 版本的定期后台工作变得轻而易举。我还为这个库做了一个Xamarin Binding。
那么你需要做的就是:
在您的应用程序类中:
public class MyApp extends Application {
@Override
public void onCreate() {
super.onCreate();
JobManager.create(this).addJobCreator(new MyJobCreator());
}
}
创建以下两个类YourJobCreator 和YourSyncJob(所有工作都将在其中完成。Android 为要运行的所有后台作业分配时间。对于
public class MyJobCreator implements JobCreator {
@Override
@Nullable
public Job create(@NonNull String tag) {
switch (tag) {
case MySyncJob.TAG:
return new MySyncJob();
default:
return null;
}
}
}
public class MySyncJob extends Job {
public static final String TAG = "my_job_tag";
@Override
@NonNull
protected Result onRunJob(Params params) {
//
// run your job here
//
//
return Result.SUCCESS;
}
public static void scheduleJob() {
new JobRequest.Builder(MySyncJob.TAG)
.setExecutionWindow(30_000L, 40_000L) //Every 30 seconds for 40 seconds
.build()
.schedule();
}
}
【讨论】:
AndroidManifest.xml:<service android:name=".services.MyService" android:label="MyService" ></service>。
您应该使用警报管理器安排您的服务,首先创建待处理的服务意图:
Intent ii = new Intent(getApplicationContext(), MyService.class);
PendingIntent pii = PendingIntent.getService(getApplicationContext(), 2222, ii,
PendingIntent.FLAG_CANCEL_CURRENT);
然后使用警报管理器安排它:
//getting current time and add 5 seconds to it
Calendar cal = Calendar.getInstance();
cal.add(Calendar.SECOND, 5);
//registering our pending intent with alarmmanager
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), pi);
这将在当前时间 5 秒后启动您的服务。你可以让你的闹钟重复。
【讨论】:
System.currentTimeMillis() + TIMEOUT_MS 之类的事情可能比处理Calendar 更容易,以获得您的初始延迟。
public static final long INTERVAL_DAYpublic static final long INTERVAL_FIFTEEN_MINUTESpublic static final long INTERVAL_HALF_DAYpublic static final long INTERVAL_HALF_HOURpublic static final long INTERVAL_HOUR
您可以使用Alarm Manager在指定时间启动服务,然后在指定时间间隔重复报警。当警报响起时,您可以启动服务并连接到服务器并制作您想要的东西
【讨论】: