当前位置: 首页 > 知识库问答 >
问题:

GCMNetworkManager在重新启动后未运行PeriodicTask

巫马修为
2023-03-14
<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>

定期任务配置:

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

        mGcmNetworkManager.schedule(task);

在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) 
}

附加所有相关细节:

<?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>
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;
        }
    }
}
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;
    }


}
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'
}

编辑一:经过几天的分析,我想出了以下几点:

  1. 这是特定于设备的问题。例如,在nexus设备上不会发生。
  2. 这是一个更大问题的一部分。显示此行为的设备在使用AlarmManagerFireBaseJobSchedulerReceive_Boot_Completed broadcast Receiver时也不能正常工作。
  3. 一个解决方案是此解决方案。但是,这个解决方案至少存在2个问题。(1)当您终止应用程序时,accessibilityservice权限将被重置。这意味着每次你打开应用程序后,手动权限是给予。(2)如果应用程序被杀死,在此之后重新启动将不会命中receive_boot_completed广播接收器
  4. 疯狂发现:在一加设备中,如果您的应用程序在包结构中有测试一词,则一切正常!!
  5. 如果您将应用程序白名单到“设置”>“应用程序”(其位置和名称在不同设备中可能不同),则所有操作都将按预期进行。
  6. 你必须手动添加应用程序的启动应用程序包含知名的应用程序,如WhatsApp、Facebook、Instagram和许多其他应用程序。当你安装这些应用程序,他们会自动添加到这个列表!我还没有看到这些制造商发布的定制API来实现这一点。这让我觉得这些应用是从厂商端白列出来的。

共有1个答案

孔彭祖
2023-03-14

更新:发现一个无法修复(不可行)的错误,可能与主题相关。似乎可访问性服务行为在设备之间并不一致。有的会禁用服务,有的会恢复服务,等等。它符合用户在网上发现的抱怨,也符合你的观察结果。

我能给出的最好建议是,在另一个进程中尽可能地使服务最小化(这样它就不会随着应用程序被杀死而被杀死),并且在启动时检查它是否被启用,如果不启用--使用通知系统允许快速访问Android辅助功能设置屏幕,以便于启用。

我不熟悉具体的问题,但我相信这个变通办法对你有用。我将此代码用于生产中的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>

并创建类

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
    }
}

我相信

 类似资料:
  • *更新:我已经通过删除空指针解决了这些问题。我不知道有任何错误,因为我没有检查,也不知道如何打开日志错误,这就是为什么我不知道这种类型的问题曾经问过。顺便说一下,我是一个新的android开发者。

  • 我在minikube上运行kubernetes,我在一个代理后面,所以我设置了env变量(HTTP_代理) pod从未启动,我得到了错误 运行良好

  • 我有一个Spring Boot(1.5.17)Web应用程序,其Tomcat JDBC连接池(8.5.34)配置如下: 现在,如果我重新启动数据库服务器(SQL server),我会得到exception,连接池未恢复。 那么我做错了什么?

  • 问题内容: 在一定数量的行之后,如何重新启动我的Row_Number。 例如 我该怎么转 进入 请注意,实际上没有办法根据ID进行分区。 我尝试使用递归CTE并非常接近。 这: 返回值: 与第一个ID距离很近。 任何帮助将是巨大的。 谢谢, 将要 问题答案: 使用模运算符: 如果不是列,则还可以使用以下功能:

  • 我们在Android8.1及以上版本中偶然发现了一个我们以前从未见过的问题,不幸的是,这使得我们的应用程序对我们的用户来说不太方便。在Android 8.1及以上版本中,当用户刷屏杀死应用程序时,后台粘性服务不会重新启动。

  • 我用Inno Setup做了一个安装程序,在一些文件运行后我需要重启电脑,所以我用了这篇文章中的解决方案。 inno安装示例“CodePrepareToInstall”。iss运行良好,所以我使用了代码进行测试安装,但计算机重新启动后安装程序无法启动。 两个安装程序(inno demo和我的测试)都在“HKLM\Software\Microsoft\Windows\CurrentVersion\R