13

Uygulama, ön planda, arka planda çalışırken veya öldürülmüşse uygulama beklenen davranışı gösterir. LogCat yılındaGCMNetworkManager, yeniden başlatıldıktan sonra PeriodicTask çalıştırmıyor

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

     mGcmNetworkManager.schedule(task); 

:

AndroidManifest yılında:

<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 yapılandırmasına o takiben

çalışan PeriodicTask durur yeniden başlatıldıktan sonra ancak ilgili kod parçalarıdır Aşağıdakileri alıyorum:

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

ekleme ilgili tüm ayrıntıları:

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 (Uygulama Modülü)

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. Bu cihaz belirli bir konudur: analizinin birkaç gün sonra ben aşağıdaki anladım. Örneğin, nexus cihazlarda gerçekleşmez.
  2. Bu daha büyük bir sorunun bir parçasıdır. Bu davranışı gösteren aygıtlar ayrıca AlarmManager, FirebaseJobScheduler ve RECEIVE_BOOT_COMPLETED broadcast receiver ile beklendiği gibi çalışmaz. Bir geçici çözüm this solution'dir. Ancak, bu çözümün en az 2 sorunu var. (1) Uygulamayı öldürdüğünüzde, AccessibilityService izni sıfırlanır. Bundan sonra uygulamayı açtığınız her seferinde, manuel izin verilecektir. (2) Uygulama öldürülürse, bu yeniden başlatmadan sonra yeniden başlatır RECEIVE_BOOT_COMPLETED broadcast receiver
  3. Çılgın bulma: Uygulamanın paket yapısında test kelimesi varsa tekli cihazlarda, her şey çalışır!
  4. Uygulamanızı beyaz listeye eklerseniz, ayarlar> Uygulamalar'a gidersiniz (Konum ve adı farklı cihazlarda farklı olabilir), her şey beklendiği gibi çalışır.
  5. Uygulamanızı manuel olarak eklemeniz gereken başlangıç ​​uygulamaları, WhatsApp, Facebook, Instagram ve diğerleri gibi iyi bilinen uygulamaları içerir. Bu uygulamaları yüklediğinizde, bu listeye otomatik olarak eklenirler! Bunu yapmak için bu üreticilerin herhangi biri tarafından yayınlanan özel bir API göremiyorum. Bu, bu uygulamaların üreticilerin sonundan beyaz listelendiğini düşünmemi sağlıyor.
+0

Günlükleri incelerken Google'ın kendi Çocuklar İçin Youtube uygulamasının da aynı sorunu yaşadığına inandım: ** E/NetworkScheduler.TED: Hizmet başlatılamadı: 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 (sahip ekstralar var)} ** – ranjjose

+1

bunu yapıyor Birden fazla cihazda ne olur? – user2450263

+0

Evet .. Birden fazla cihazda gerçekleşir. Bunu bir artı, MI cihazlarda yaşadım. – ranjjose

cevap

0

PeriodicTask yapılandırma:

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

Bunu bildirdiğiniz için teşekkür ederiz. Ancak sorun bu değil. Sanırım yapıştırdığımda yanlış dosyayı kopyaladım. Sorun, cihaza özgüdür. Örneğin, oneplus ve MI cihazlarında, bu sorunlar meydana gelir. Bu da tutarsız. Aslında oneplus (3T) paketinde "test" kelimesi varsa boot_completed isabet edilir! MI'da hiçbir şey işe yaramıyor. Şu an için burada belirtildiği gibi erişilebilirlik hizmetleri ile ilgili bir işim var. Https://stackoverflow.com/a/41627296/1349159 – ranjjose

+1

Evet, cihazların çok özel durumları var. Birçok üretici, androidin tadını çıkarır ve kullanıcı gitmeden ve özel izin vermedikçe, uygulamayı başlatmak için yer hizmetini durduran kendi güvenlik katmanına sahiptir. Bu davranışı, gelişmemizde Xiomi ceplerinde çoğaltdık. Bu durumda kullanıcıya bir çeşit yardım belgesi vermelisiniz. – Devesh

2

Güncelleme: konuyla ilgili olabilecek bir Won't Fix (Infeasible) bug buldum. Erişilebilirlik Hizmeti davranışı aygıtlar arasında tutarlı değil gibi görünüyor. Bazıları hizmeti devre dışı bırakacak, bazıları da devam edecek, vb. Çevrimiçi olarak bulunan kullanıcı şikayetlerine ve gözlemlerinize iyi uyuyor.

Verebileceğim en iyi tavsiye, hizmeti farklı bir süreçte olabildiğince minimal hale getirmektir (böylece, uygulama ile öldürülmeyecek) ve ayrıca etkin olup olmadığını ve önyükleme kontrolü etkinse, değil - kolay erişim için Android Erişilebilirlik ayarları ekranına hızlı erişim sağlamak için bildirim sistemini kullanın.


Belirli sorun aşina değilim, ama bu geçici çözüm sizin için çalışacaktır inanıyoruz. Bu kodu, üretimde AlarmManager için kullanıyorum.

AndroidManifest.xml yılında

:

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

Ve bu

uygulama ölürse (2), yeniden doğmuş o won sonra' İnanıyorum

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

bir sınıf oluşturmak t RECEIVE_BOOT_COMPLETED yayın alıcısına

Yanlış, Android yeniden başlatıldığında uygulamanızın öldürüldüğü konusunda hiçbir bilgiye sahip değil. Uygulamam için hiçbir zaman sorun değildi (+ 1.2M kullanıcıları).

+0

Teşekkürler auval. Ben zaten android.intent.category.DEFAULT 'filtre ile denedim. Ne yazık ki, üç ila dört test cihazında (bir artı 3T, MI, redmi) çalıştığı ' t. Uygulama öldürme sorunundan sonra yeniden başlayanlar, "Erişilebilirlik hizmeti" – ranjjose

+0

ile ilgili olarak yayınladığınız kodda bir BroadcastReceiver görmedim. – auval

+0

Ayrıca 'erişilebilirlik servisi' hakkında okuduğum şey, uygulamayı öldürdüğünüzde, erişilebilirlik hizmet iznini – ranjjose

İlgili konular