13

アプリケーションがフォアグラウンド、バックグラウンド、または強制終了している場合、アプリケーションは予期される動作を示します。 AndroidManifestリブート後にGCMNetworkManagerがPeriodicTaskを実行していません

<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の設定:

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で、それが再起動された後しかし、後

を実行しているPeriodicTaskストップは、コードの関連するビットです私は次のようになる:

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

追加は、すべての関連する詳細情報:

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

MainActivity

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

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


} 

build.gradle(アプリケーションモジュール)

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

EDIT1:分析の数日後、私は次のことを考え出した:

  1. これは、デバイス固有の問題です。たとえば、ネクサスデバイスでは発生しません。
  2. これは大きな問題の一部です。この動作を示すデバイスも、AlarmManager,FirebaseJobSchedulerRECEIVE_BOOT_COMPLETED broadcast receiverと期待どおりに動作しません。
  3. 回避策の1つはthis solutionです。ただし、このソリューションには少なくとも2つの問題があります。 (1)アプリを終了すると、AccessibilityServiceの権限がリセットされます。つまり、この後にアプリを開くたびに、手動による許可が与えられます。 (2)アプリが殺された場合、再起動するとそれ以降は再起動されません。RECEIVE_BOOT_COMPLETED broadcast receiver
  4. 奇妙な発見:1つのデバイスで、パッケージ構造にtestという単語があるとすべて動作します!
  5. アプリケーションを設定>アプリケーション(この場所と名前はデバイスによって異なる可能性があります)にホワイトリストすると、すべて正常に動作します。
  6. アプリを手動で追加する必要がある起動アプリには、WhatsApp、Facebook、Instagramなどのよく知られているアプリが含まれています。これらのアプリをインストールすると、自動的にこのリストに追加されます。私はこれを行うためにこれらのメーカーのいずれかによって発行されたカスタムAPIをまだ見ていません。これは、私がこれらのアプリがメーカー側からホワイトリストに載っていると思うようにする。
+0

Googleの独自のYoutube for Kidsアプリも同じ問題を抱えているという事実に気づいた。** E/NetworkScheduler.TED:サービスを開始できませんでした:Intent {act = com.google.android。 gms.gcm.ACTION_TASK_READY cmp = com.google.android.apps.youtube.kids/com.google.android.libraries.youtube.common.gcore.gcoreclient.gcm.impl.GcmTaskServiceDelegator(追加情報あり)} ** – ranjjose

+1

複数のデバイスで発生しますか? – user2450263

+0

はい、複数のデバイスで発生します。私はこれを1つのプラスのMIデバイスで経験しました。 – ranjjose

答えて

0

PeriodicTaskの設定:

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(); 
+0

それに気づいてくれてありがとう。しかし、それは問題ではありません。私は貼り付けたときに間違ったファイルをコピーしたと思います。問題はデバイス固有です。例えば、1つのプラットフォームとMIデバイスでは、これらの問題が発生します。それも矛盾しています。実際にoneplus(3T)の中にboot_completedというパッケージに "test"という単語があると、ヒットします!! MIでは何も動かない。当分の間、ここで触れたようにアクセシビリティサービスで対処しています。https://stackoverflow.com/a/41627296/1349159 – ranjjose

+1

はい、非常に特殊な場合です。多くのメーカーがアンドロイドの味を作り、ユーザーが行って独占的な許可を与えない限り、アプリのバックグラウンドサービスが開始されるのを止めるセキュリティレイヤーを所有しています。私たちは、Xiomiのモバイルでこの動作を再現しました。その場合は、何らかのヘルプ文書をユーザーに与える必要があります。 – Devesh

2

更新: トピックに関連している可能性がありWon't Fix (Infeasible) bugを発見しました。 アクセシビリティサービスの動作がデバイス間で一貫していないようです。サービスを無効にするものもあれば、再開するものもあれば、オンラインで見つかったユーザーの苦情や、あなたの観察結果に合ったものもあります。

私が与えることができる最良のアドバイスは、別のプロセスで可能な限り最小限に抑えることです(アプリケーションが強制終了されても殺されることはありません)。 not - 通知システムを使用して、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> 

そして、それ

アプリが殺された場合(2)、リブートしているウォンの後に」私は信じて

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

クラスを作成しますtヒント RECEIVE_BOOT_COMPLETEDブロードキャストレシーバー

再起動すると、あなたのアプリが死亡したという知らせがなくなります。それは私のアプリ(+ 1.2Mのユーザー)にとっては決して問題ではありませんでした。

+0

ありがとうauval。私はすでに 'android.intent.category.DEFAULT'フィルタで試していました。残念ながら、それは3つから4つのテストデバイス(1つに3T、MI、redmiを加えたもの)で動作しませんでした。' App kill問題の後のリブートは、「アクセシビリティサービス」に関するものです – ranjjose

+0

投稿したコードにBroadcastReceiverが表示されませんでした。 – auval

+0

また、「アクセシビリティサービス」について読んだことは、アプリケーションを終了するとアクセシビリティサービスのアクセス許可がリセットされるということです。 – ranjjose

関連する問題