GcmTaskService не работает

#java #android

#java #Android

Вопрос:

Я хочу заменить свой BroadcastReceiver в моем проекте на GcmNetworkManager. Итак, я прочитал несколько руководств и делаю так:
1) В манифесте я добавляю:

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

2) Сервис:

 public class WakeOnLanService extends GcmTaskService {

@Override
public int onRunTask(TaskParams taskParams) {
    return GcmNetworkManager.RESULT_SUCCESS;
}

@Override
public int onStartCommand(Intent intent, int i, int i1) {
    Toast.makeText(this,"Выполнилось",Toast.LENGTH_SHORT).show();
    return super.onStartCommand(intent, i, i1);
}
}
  

3) Расписание в действии:

 public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    GcmNetworkManager mGcmNetworkManager = GcmNetworkManager.getInstance(this);
    Task task = new OneoffTask.Builder()
            .setService(WakeOnLanService.class)
            .setExecutionWindow(0, 2)
            .setTag("MyTag")
            .setUpdateCurrent(true)
            .setRequiredNetwork(Task.NETWORK_STATE_CONNECTED)
            .setRequiresCharging(false)
            .build();
    mGcmNetworkManager.schedule(task);
}
}
  

Но это не работает, тосты не отображаются. Как это сделать правильно и как лучше всего запускать службу с помощью GcmNetworkManager при подключении к Интернету, как это было в широковещательном приемнике?

Ответ №1:

Вы не должны запускать свой код onStartCommand .

Вместо этого используйте onRunTask .

 @Override
public int onRunTask(TaskParams taskParams) {
    Toast.makeText(this,"Выполнилось",Toast.LENGTH_SHORT).show();
    return GcmNetworkManager.RESULT_SUCCESS;
}
  

Из документации:

Когда планировщик запускает вашу службу, создается новый поток, и система вызывает onRunTask() . Реализуйте логику для своих задач, переопределив onRunTask();

Что касается запуска задачи при установлении соединения с Интернетом. Лучше этого не делать, если вам это действительно не нужно. В этом смысл этой задачи. Чтобы запланировать работу ваших задач вместе с другими задачами. Если вам действительно нужно, чтобы он запускался при установлении подключения к Интернету, вам нужно будет использовать BroadcastReceiver и запустить код вручную. Вы не можете запустить эту задачу в произвольное время.

Комментарии:

1. Если я буду использовать широковещательный приемник, он не будет работать в Android N

2. Почему бы и нет? Вы не можете зарегистрироваться <action android:name="android.net.conn.CONNECTIVITY_CHANGE"/> ?

3. Приложения, ориентированные на Android 7.0 (уровень API 24), не получают широковещательные рассылки CONNECTIVITY_ACTION, если они регистрируются для их получения в своем манифесте. Запущенные приложения все еще могут прослушивать CONNECTIVITY_CHANGE в своем основном потоке, зарегистрировав BroadcastReceiver с помощью Context.registerReceiver() .

4. Ах, хорошая информация. Тогда вам, вероятно, нужно будет дождаться запуска задачи. Я не сразу вижу что-то еще не так. Попробуйте установить .setExecutionWindow(0, 2) строку на более отдаленное будущее с большей задержкой для тестирования, например: .setExecutionWindow(10, 10)

Ответ №2:

Для тех, у кого есть какие-то вопросы по этому поводу, рассмотрите возможность перехода на WorkManager:

 public class UploadWorker extends Worker {

    public UploadWorker(
        @NonNull Context context,
        @NonNull WorkerParameters params) {
        super(context, params);
    }

    @Override
    public Result doWork() {
      // Do the upload operation ...

      myUploadOperation()

      // Indicate whether the task finished successfully with the Result
      return Result.success()
    }
}


Constraints uploadConstraints = new Constraints.Builder()
    .setRequiredNetworkType(NetworkType.CONNECTED)
    .setRequiresCharging(true)
    .build();

OneTimeWorkRequest uploadTask =
        new OneTimeWorkRequest.Builder(UploadWorker.class)
  .setConstraints(uploadConstraints)
  .build();
WorkManager.getInstance().enqueue(uploadTask);
  

Ссылка:

https://developer.android.com/topic/libraries/architecture/workmanager/migrating-gcm