Android GCMNetworkManager是';重新启动后不运行周期性任务

Android GCMNetworkManager是';重新启动后不运行周期性任务,android,google-cloud-messaging,periodic-task,gcm-network-manager,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:export

如果应用程序在前台、后台或后台运行,则该应用程序将显示预期的行为。但是,一旦重新启动,
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>
在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) 
}
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();
附加所有相关细节:

AndroidManifest.xml

MyTaskService

build.gradle(应用程序模块)

编辑1:经过几天的分析,我得出以下结论:

  • 这是一个特定于设备的问题。例如,nexus设备上不会发生这种情况
  • 这是一个更大问题的一部分。显示此行为的设备在使用
    AlarmManager
    FirebaseJobScheduler
    接收启动完成的广播接收器时也无法正常工作
    
  • 一个解决办法是。但是,此解决方案至少有两个问题。(1) 当您关闭应用程序时,
    AccessibilityService
    权限将重置。这意味着每次在此之后打开应用程序时,都会手动授予权限。(2) 如果应用程序被终止,则在此之后重新启动,不会击中
    接收\u引导\u完成的广播接收器
  • 疯狂发现:在one plus设备中,如果你的应用程序在包结构中有单词
    test
    ,一切都正常
  • 如果您将应用程序列入“设置”>“应用程序”的白名单(在不同的设备中,该应用程序的位置和名称可能不同),则一切正常
  • 您必须手动添加应用的启动应用程序包含WhatsApp、Facebook、Instagram等知名应用程序。当您安装这些应用程序时,它们会自动添加到此列表中!我还没有看到这些制造商为此发布的定制API。这让我觉得,这些应用程序都是从制造商端被列入白名单的
    周期任务配置:

    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) 
    }
    
    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();
    
    更新: 找到可能与主题相关的。 可访问性服务行为似乎在不同设备之间不一致。有些将禁用该服务,有些将恢复,等等。它符合在线发现的用户投诉,也符合您的观察结果

    我能给出的最好建议是在不同的进程上尽可能地减少服务(这样它就不会随着应用程序的终止而终止),并在启动时检查它是否已启用,如果未启用,则使用通知系统允许快速访问安卓可访问性设置屏幕,以便轻松启用


    我不熟悉具体的问题,但我相信这种解决方法会对您有效。我将此代码用于生产中的AlarmManager

    在AndroidManifest.xml中:

        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    
        <receiver android:name=".BootListener">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT"/>
    
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>
    
    我相信

    (2) 如果应用程序被杀死,在那之后重新启动不会击中目标 接收\u引导\u完成的广播接收器


    是错误的,当重新启动时,Android不知道你的应用程序被杀死。这对我的应用程序(+120万用户)来说从来都不是问题。

    这会发生在多台设备上吗?你试过android设备吗?Nexus、Moto、Pixel等?有时,oem执行的操作系统的自定义行为(如MI设备强制关闭应用程序以“杀死”应用程序)可能需要选择一种解决方案,将设备/oem因素排除在外,然后成为比较差异的一种情况可能。。例如,您是否也返回超级for runTask或重写itcheck清单条目和服务类,我现在想不出多少好的,谢谢!检查了所有这些地方;我将把所有这些细节附加在问题中以供参考。希望能有帮助。谢谢你注意到这一点。然而,这不是问题所在。我猜当我复制粘贴时,我复制了错误的文件。问题是特定于设备的。例如,在oneplus和MI设备中,会发生这些问题。这也不一致。事实上,在oneplus(3T)中,如果您在包中有“test”一词,那么boot_completed就是hit!!在密苏里州,什么都不管用。就目前而言,我得到了一个关于无障碍服务的解决方案,正如这里提到的,是的,这是非常具体的设备案例。许多制造商制造了android的风格,并且有自己的安全层,该层阻止应用程序后台服务启动,直到和除非用户去给予独家许可。在我们的开发过程中,我们在Xiomi手机中复制了这种行为。在这种情况下,你必须给用户一些帮助文档。谢谢。我已经试过使用
    android.intent.category.DEFAULT
    filter。不幸的是,它没有';t在三到四台测试设备上工作(一台加上3T、MI、redmi)。应用程序终止后重新启动的问题与
    辅助功能服务有关。我在您发布的代码中没有看到广播接收器。另外,我读到的
    辅助功能服务
    的内容是,当您终止应用程序时,它会重置辅助功能服务权限,即终止辅助功能服务会立即重新启动。也许你的意思是用户禁用服务?不是。我说的是终止您授予可访问性服务权限的应用程序。此外,大多数这些行为都是特定于设备的。
    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'
    }
    
    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();
    
        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
    
        <receiver android:name=".BootListener">
            <intent-filter>
                <category android:name="android.intent.category.DEFAULT"/>
    
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>
    
    public class BootListener extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
          // If your bootstrap is in Application class, then it will be called anyway - nothing to do here.
          // else - call your bootsrap here
        }
    }