重新启动后GCMNetworkManager未运行PeriodicTask

ran*_*ose 12 android google-cloud-messaging periodic-task gcm-network-manager

如果应用程序在前台,后台运行或被杀死,该应用程序会显示预期的行为.但是,一旦重新启动,PeriodicTask停止运行

以下是相关的代码:

AndroidManifest:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<service android:name=".tracking.MyTaskService"
            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>
Run Code Online (Sandbox Code Playgroud)

PeriodicTask配置:

PeriodicTask task = new PeriodicTask.Builder()
                .setService(MyTaskService.class)
                .setTag(TASK_TAG_PERIODIC)
                .setPeriod(30L)
                .setFlex(10L)
                .setExtras(bundle)
                .setPersisted(true)
                .build();

        mGcmNetworkManager.schedule(task);
Run Code Online (Sandbox Code Playgroud)

在Logcat中,我得到以下内容:

E/NetworkScheduler.TED: Couldn't start service: Intent 
{ act=com.google.android.gms.gcm.ACTION_TASK_READY
  cmp=xxx.xxxxxx.xxx/.tracking.MyTaskService (has extras) 
}
Run Code Online (Sandbox Code Playgroud)

附加所有相关细节:

AndroidManifest.xml中

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.google.example.gcmnetworkmanagerquickstart">

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <!-- [START manifest_service] -->
        <service
            android:name=".MyTaskService"
            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>
        <!-- [END manifest_service] -->

    </application>

</manifest>
Run Code Online (Sandbox Code Playgroud)

主要活动

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";
    private static final int RC_PLAY_SERVICES = 123;
    public static final String TASK_TAG_PERIODIC = "periodic_task";

    private GcmNetworkManager mGcmNetworkManager;

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

        mGcmNetworkManager = GcmNetworkManager.getInstance(this);

        if(checkPlayServicesAvailable()){
            startPeriodicTask();
        }

    }



    public void startPeriodicTask() {
        Log.d(TAG, "startPeriodicTask");

        PeriodicTask task = new PeriodicTask.Builder()
                .setService(MyTaskService.class)
                .setTag(TASK_TAG_PERIODIC)
                .setPeriod(5)
                .setPersisted(true)
                .build();

        mGcmNetworkManager.schedule(task);
    }

    private boolean checkPlayServicesAvailable() {
        GoogleApiAvailability availability = GoogleApiAvailability.getInstance();
        int resultCode = availability.isGooglePlayServicesAvailable(this);

        if (resultCode != ConnectionResult.SUCCESS) {
            if (availability.isUserResolvableError(resultCode)) {
                // Show dialog to resolve the error.
                availability.getErrorDialog(this, resultCode, RC_PLAY_SERVICES).show();
            } else {
                // Unresolvable error
                Toast.makeText(this, "Google Play Services error", Toast.LENGTH_SHORT).show();
            }

            Log.d(TAG, "Play Services NOT Available");
            return false;
        } else {
            Log.d(TAG, "Play Services Available");
            return true;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

MyTaskService

public class MyTaskService extends GcmTaskService {

    private static final String TAG = "MyTaskService";

    @Override
    public void onInitializeTasks() {
    }

    @Override
    public int onRunTask(TaskParams taskParams) {
        Log.d(TAG, "onRunTask: " + taskParams.getTag());

        return doPeriodicTask();
    }

    private int doPeriodicTask() {
        Log.d(TAG, "doPeriodicTask Called");
        return GcmNetworkManager.RESULT_SUCCESS;
    }


}
Run Code Online (Sandbox Code Playgroud)

build.gradle(App Module)

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.0"

    defaultConfig {
        applicationId "com.google.example.gcmnetworkmanagerquickstart"
        minSdkVersion 14
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

allprojects {
    repositories {
        jcenter()
        google()
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    testCompile 'junit:junit:4.12'
    implementation 'com.android.support:appcompat-v7:26.0.0-beta2'

    compile 'com.squareup.okhttp:okhttp:2.7.0'

    compile 'com.google.android.gms:play-services-gcm:11.0.2'
}
Run Code Online (Sandbox Code Playgroud)

编辑1:经过几天的分析,我发现了以下几点:

  1. 这是特定于设备的问题.例如,在nexus设备上不会发生这种情况.
  2. 这是一个更大问题的一部分.显示此行为的设备也无法正常工作AlarmManager,FirebaseJobSchedulerRECEIVE_BOOT_COMPLETED broadcast receiver.
  3. 一种解决方法是此解决方案.但是,此解决方案至少有2个问题.(1)当您终止应用程序时,AccessibilityService权限将被重置.这意味着每次在此之后打开应用程序时,都会给出手动权限.(2)如果应用程序被杀死,那么重新启动后就不会命中了RECEIVE_BOOT_COMPLETED broadcast receiver
  4. 疯狂的发现:在一加设备中,如果您的应用程序test在包结构中有单词,一切正常!
  5. 如果您将应用程序列入白名单设置>应用程序(不同设备的位置和名称可能不同),一切都按预期工作.
  6. 您必须手动添加应用程序的启动应用程序包含众所周知的应用程序,如WhatsApp,Facebook,Instagram和许多其他应用程序.当您安装这些应用程序时,它们会自动添加到此列表中!我还没有看到任何这些制造商发布的自定义API来执行此操作.这让我觉得这些应用程序是从制造商的最终列出的白名单.

Udd*_*tam 1

周期性任务配置:

PeriodicTask task = new PeriodicTask.Builder()
                .setService(MyTaskService.class)
                .setTag(TASK_TAG_PERIODIC)
                .setPeriod(30L)
                .setFlex(10L)
                .setExtras(bundle) **/* you put this line here */**
                .setPersisted(true)
                .build();


    PeriodicTask task = new PeriodicTask.Builder()
                    .setService(MyTaskService.class)
                    .setTag(TASK_TAG_PERIODIC)
/* you don't have ".setExtras(bundle)" line here */ 
/* try adding this line from above, as logcat is showing this */
                    .setPeriod(5)
                    .setPersisted(true)
                    .build();
Run Code Online (Sandbox Code Playgroud)