6

GcmNetworkManager を使用して、API レベル 17 まで実行されるアプリで定期的なタスクをスケジュールしようとしています。GCM Network Manager ページ ( https://developers.google.com/クラウド メッセージング/ネットワーク マネージャー):

私の AndroidManifest.xml には、次のものがあります。

<service
    android:name=".services.MyService"
    android:exported="true"
    android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE">
    <intent-filter>
        <action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/>
    </intent-filter>
</service>

私のアプリケーションには、次のものがあります。

long periodSecs = 30L; // the task should be executed every 30 seconds
long flexSecs = 15L; // the task can run as early as -15 seconds from the scheduled time

String tag = "myScan|1";

PeriodicTask periodic = new PeriodicTask.Builder()
        .setService(MyService.class)
        .setPeriod(periodSecs)
        .setFlex(flexSecs)
        .setTag(tag)
        .setPersisted(false)
        .setRequiredNetwork(com.google.android.gms.gcm.Task.NETWORK_STATE_ANY)
        .setRequiresCharging(false)
        .setUpdateCurrent(true)
        .build();

GcmNetworkManager.getInstance(this).schedule(periodic);

そして、次のような MyService があります。

public class MyService extends GcmTaskService {
    @Override
    public int onRunTask(TaskParams taskParams) {
        Log.info("onRunTask: " + taskParams.getTag());

        return GcmNetworkManager.RESULT_SUCCESS;
    }

    @Override
    public int onStartCommand (Intent intent, int flags, int startId) {
        Log.info("onStartCommand");

        return GcmTaskService.START_STICKY_COMPATIBILITY;
    }
}

アプリを起動すると、期待どおりにonStartCommandがログに記録されますが、onRunTaskは呼び出されません。何か不足していますか?私は、(開始コマンドの発火によって証明されるように) 開始されると、15 ~ 30 秒ごとに実行されることを期待しています - それは正しい仮定ですか? まったく発射されないのはなぜですか?

ありがとう!

4

2 に答える 2

9

問題は、onStartCommand をオーバーライドしていることです! これは、Google Play Services が GcmTaskService でタスクを実行する方法です。シンプルに動かしたいなら

return super.onStartCommand(intent, flags, startId);

おそらく、onRunTask が提供される理由は、Service のライフサイクルを心配する必要がないようにするためであることに言及する価値があります。

とは言っても、カスタム インテントを使用して GcmTaskService で startService() を実行すると、これが台無しになり、停止すべきときに停止されないサービスになってしまう可能性があります。

GcmTaskService を呼び出す必要がある場合 (推奨されません)、それにバインドする必要があります。そのインターフェイスは、GcmTaskService 内部によって完全に影響を受けません。

于 2015-07-14T17:45:52.723 に答える
1
@Override
public int onRunTask(TaskParams taskParams)
{
    Log.info("onRunTask: " + taskParams.getTag());

    return GcmNetworkManager.RESULT_SUCCESS;
}

@Override
public void onCreate()
{
    Log.i(TAG, "in onCreate");
    super.onCreate();
    GcmNetworkManager.getInstance(this).schedule(createPeriodicSyncTask());
}

private PeriodicTask createPeriodicSyncTask()
{
    return new PeriodicTask.Builder()
            .setService(PeriodicSyncService.class)
            .setPeriod(mSyncIntervalInSec)
            .setFlex(mSyncIntervalInSec - 20)
            .setTag(TAG)
            .setPersisted(true)
            .setRequiredNetwork(NETWORK_STATE_ANY)
            .setUpdateCurrent(true)
            .setRequiresCharging(false)
            .build();
}
于 2015-08-31T17:13:31.640 に答える