2

我的服务器上有一个 Web 服务,需要每小时 ping 一次。为此,我使用 Android 应用程序每小时 ping 它一次。我曾尝试使用警报管理器,但它会在几个小时后停止工作,如果我滑动退出它。我曾尝试使用服务,但由于某种原因,这似乎不起作用,我的应用程序不断崩溃。我正在考虑使用 Firebase Job 调度程序。我的要求是应用程序需要每小时 ping 我服务器上的 Web 服务。这种情况至少会持续 3-4 个月。有没有办法做到这一点?提前致谢!

编辑:我已经尝试使用警报管理器进行广播接收器,但无法维持发射超过 4 小时。

4

4 回答 4

2

Jhon 你可以使用firebase jobdispatcher。因为它将支持 api 级别 9。您可以在下面看到如何创建作业调度程序以及如何调用它。

  public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    scheduleJob(this);
}

public static void scheduleJob(Context context) {
    //creating new firebase job dispatcher
    FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
    //creating new job and adding it with dispatcher
    Job job = createJob(dispatcher);
    dispatcher.mustSchedule(job);
}

public static Job createJob(FirebaseJobDispatcher dispatcher){

    Job job = dispatcher.newJobBuilder()
            //persist the task across boots
            .setLifetime(Lifetime.FOREVER)
            //.setLifetime(Lifetime.UNTIL_NEXT_BOOT)
            //call this service when the criteria are met.
            .setService(ScheduledJobService.class)
            //unique id of the task
            .setTag("UniqueTagForYourJob")
            //don't overwrite an existing job with the same tag
            .setReplaceCurrent(false)
            // We are mentioning that the job is periodic.
            .setRecurring(true)
            // Run between 30 - 60 seconds from now.
            .setTrigger(Trigger.executionWindow(30, 60))
            // retry with exponential backoff
            .setRetryStrategy(RetryStrategy.DEFAULT_LINEAR)
            //.setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
            //Run this job only when the network is available.
            .setConstraints(Constraint.ON_ANY_NETWORK, Constraint.DEVICE_CHARGING)
            .build();
    return job;
}

public static Job updateJob(FirebaseJobDispatcher dispatcher) {
    Job newJob = dispatcher.newJobBuilder()
            //update if any task with the given tag exists.
            .setReplaceCurrent(true)
            //Integrate the job you want to start.
            .setService(ScheduledJobService.class)
            .setTag("UniqueTagForYourJob")
            // Run between 30 - 60 seconds from now.
            .setTrigger(Trigger.executionWindow(30, 60))
            .build();
    return newJob;
}

public void cancelJob(Context context){

    FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(context));
    //Cancel all the jobs for this package
    dispatcher.cancelAll();
    // Cancel the job for this tag
    dispatcher.cancel("UniqueTagForYourJob");

}}

ScheduledJobService.java

public class ScheduledJobService extends JobService {

private static final String TAG = ScheduledJobService.class.getSimpleName();

@Override
public boolean onStartJob(final JobParameters params) {
    //Offloading work to a new thread.
    new Thread(new Runnable() {
        @Override
        public void run() {
            codeYouWantToRun(params);
        }
    }).start();

    return true;
}

@Override
public boolean onStopJob(JobParameters params) {
    return false;
}

public void codeYouWantToRun(final JobParameters parameters) {
    try {

        Log.d(TAG, "completeJob: " + "jobStarted");
        //This task takes 2 seconds to complete.
        Thread.sleep(2000);

        Log.d(TAG, "completeJob: " + "jobFinished");
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        //Tell the framework that the job has completed and doesnot needs to be reschedule
        jobFinished(parameters, true);
    }
}}
于 2018-02-13T09:01:50.600 回答
2

我支持Anantha 的回答,但似乎工作参数对您的需求来说几乎没有。

您可以阅读本文以了解各种作业调度程序之间的细微差别。

事实上,如果应用程序由于各种原因需要进行网络通信,即使谷歌也建议使用Firebase Job Schedular 。请观看 Github 页面上的附加视频以获取更多信息。这也为您提供了启动应用程序的基本代码。您可以更改作业参数以满足您的需求

希望下面的代码可以满足您每隔一小时触发一次的要求,容差为 15 分钟

 FirebaseJobDispatcher dispatcher = new FirebaseJobDispatcher(new GooglePlayDriver(getContext()));
    final int periodicity = (int)TimeUnit.HOURS.toSeconds(1); // Every 1 hour periodicity expressed as seconds
    final int toleranceInterval = (int)TimeUnit.MINUTES.toSeconds(15); // a small(ish) window of time when triggering is OK

    Job myJob = dispatcher.newJobBuilder()
            // the JobService that will be called
            .setService(yourJobService.class)
            // uniquely identifies the job
            .setTag("my-unique-tag")
            // recurring job
            .setRecurring(true)
            // persist past a device reboot
            .setLifetime(Lifetime.FOREVER)
            // start between 0 and 60 seconds from now
            .setTrigger(Trigger.executionWindow(periodicity, toleranceInterval))
            // overwrite an existing job with the same tag
            .setReplaceCurrent(true)
            // retry with exponential backoff
            .setRetryStrategy(RetryStrategy.DEFAULT_EXPONENTIAL)
            // constraints that need to be satisfied for the job to run
            .setConstraints(
                    // only run on an unmetered network
                    Constraint.ON_ANY_NETWORK
            )
            .setExtras(schedulerextras)
            .build();

    dispatcher.mustSchedule(myJob);
于 2018-02-25T00:27:10.753 回答
1

您将需要使用JobScheduler(api >21 ) 和GcmNetworkManager(api<21) ,具体取决于 android 的 api 级别。从 evernote 中查看这个库,它负责处理它。

于 2018-02-13T07:41:46.440 回答
1

你试试广播接收器吗?我使用带有警报管理器的广播接收器每分钟振动一次,它工作正常。唯一的问题是,当设备关闭或重新启动时,它不会振动,直到我进入我的应用程序。

我的测试代码。

 public void setAlarm() {
    alarmMgr =(AlarmManager)getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(AlarmManagerActivity.this, AlarmManagerBroadcastReceiver.class);
    intent.setAction("a.b.c.d");
    PendingIntent pi = PendingIntent.getBroadcast( getApplicationContext(), 0, intent, 0);
    //After after 5 seconds
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.HOUR_OF_DAY, 13);
    calendar.set(Calendar.MINUTE, 40);
    alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis()
            , (1000) * (60)
            , pi);
}

我的接收器

@Override
public void onReceive(Context context, Intent intent) {
    Log.d(getClass().getSimpleName(), Intent.ACTION_BOOT_COMPLETED);
if ( intent.getAction().equals("a.b.c.d")) {
        Log.d(getClass().getSimpleName(), "Custom Broadcast01");
    Vibrator  vibrator = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
    vibrator.vibrate(10000);
    }
    else
        Log.d(getClass().getSimpleName(), "no this action for intent!");
}

广播接收器在设备重启时启动警报

<receiver
            android:name=".OnBootBroadcastReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
</receiver>

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class OnBootBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

        setAlarm();
    }
}
于 2018-02-13T07:37:44.300 回答