Android - 定期背景服务 - 建议

Ziy*_*een 29 service android

我正在开发一个应用程序,它将有关其位置的信息转发到远程服务器.我打算通过向Web服务器执行一个简单的HTTP发布来完成它,一切都很简单.

但根据规范,应用程序需要不时执行,每30分钟就说一次.独立于界面,即使应用程序关闭也需要运行.

我环顾四周,发现Android服务是需要使用的.我可以用什么来实现这样一个系统.手机重启时服务(或其他机制)会重启吗?

提前致谢.

Arg*_*yle 31

创建一个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.            
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

您需要添加以下权限才能AndroidManifest.xml使其正常工作.不要忘记在正常运行应用程序时注册警报,或者只在设备启动时注册它们.

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
Run Code Online (Sandbox Code Playgroud)


Pie*_*rre 17

这是一种半不同的方式来保持服务永远.如果你愿意,有办法在代码中杀死它

后台服务:

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

以下是您从主要活动或您希望的任何地方开始的方式:

startService(new Intent(this, BackgroundService.class));
Run Code Online (Sandbox Code Playgroud)

onDestroy() 当应用程序关闭或被杀死时会被调用,但是runnable会立即启动它.

我希望这可以帮助别人.

有些人这样做的原因是因为企业应用程序在某些情况下用户/员工必须无法阻止某些事情:)

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

创建以下两个类YourJobCreatorYourSyncJob(其中所有工作都将完成.Android为所有后台作业分配时间.对于Android版本<8.0,它仍将按照正常情况运行警报管理器和后台服务)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 不要忘记将服务添加到您的`AndroidManifest.xml`中:`&lt;service android:name =“。services.MyService” android:label =“ MyService”&gt; &lt;/ service&gt;`。 (2认同)

Soh*_*ziz 8

您应该使用警报管理器安排服务,首先创建待处理的服务意图:

Intent ii = new Intent(getApplicationContext(), MyService.class);
PendingIntent pii = PendingIntent.getService(getApplicationContext(), 2222, ii,
PendingIntent.FLAG_CANCEL_CURRENT);
Run Code Online (Sandbox Code Playgroud)

然后使用警报管理器安排它:

//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);
Run Code Online (Sandbox Code Playgroud)

这将在5秒的当前时间后启动您的服务.你可以重复闹钟.

  • 你们知道你在AlarmManager中有1天,12小时,1小时,半小时和15分钟的静态值吗?`public static final long INTERVAL_DAY`` public static final long INTERVAL_FIFTEEN_MINUTES`` public static final long INTERVAL_HALF_DAY`` public static final long INTERVAL_HALF_HOUR`` public static final long INTERVAL_HOUR` (5认同)