11

Mam aplikację dla systemu Android, który wykorzystuje API Awareness do ustawiania ogrodzenia, gdy zestaw słuchawkowy jest podłączonyAwareness API & Android O użyciu BroadcastReceiver

ja wdrożyły AwarenessFence przy użyciu kodu podobnie jak w przykładach na stronie:. https://developers.google.com/awareness/android-api/fence-register .

mam PendingIntent zdefiniowany jako:

PendingIntent.getBroadcast(context, 0, new Intent("my.application.packageFENCE_RECEIVER_ACTION"), 0) 

Wtedy w moim pliku AndroidManifest.xml mam

<receiver android:name=".fence.FenceDetector$MyFenceReceiver"> 
<intent-filter> 
    <action android:name="my.application.packageFENCE_RECEIVER_ACTION" /> 
</intent-filter> 

te zostały zgłoszone w manifeście z uwagi na fakt, że Chcę odbierać audycje, nawet gdy moja aplikacja jest w tle.

To wszystko działało dobrze na Androidzie 7.0 i poniżej, ale gdy uruchomię to na Androidzie 8.0 pojawia się błąd:

BroadcastQueue: Background execution not allowed: receiving Intent { act=my.application.packageFENCE_RECEIVER_ACTION 

Zakładam, to ze względu na nowe ograniczenia dla realizacji tła Android O .

czy ktoś może mi powiedzieć jak zarejestrować odbiornik emisji, która może wysłuchać świadomości ogrodzenia wyzwala gdy w tle na urządzenia z systemem Android API 26.

Daj mi znać, jeśli istnieje coś, co jest jasne, czy Muszę to rozwinąć meting.

Z góry dziękuję

Odpowiedz

4

Nie mogę przetestować tego na urządzeniu, ale z tego, co przeczytałem, ograniczenie dotyczy tylko niejawnych transmisji. Oznacza to, że jeśli tworzysz jawną transmisję, to wszystko, czego potrzebujesz, aby działało.

Oznacza to, że zamiast tego:

// implicit intent matching action 
PendingIntent.getBroadcast(context, 0, 
    new Intent("my.application.packageFENCE_RECEIVER_ACTION"), 0) 

to zrobić:

// explicit intent directly targeting your class 
PendingIntent.getBroadcast(context, 0, 
    new Intent(context, FenceDetector.MyFenceReceiver.class), 0) 
+1

Przetestowany i sprawdzony. To powinno być zaakceptowaną odpowiedzią, – Simon

+1

Masz rację Simon. Właśnie to przetestowałem i mogę potwierdzić, że działa. Jest to teraz zaakceptowana odpowiedź. –

+0

Pamiętaj, że musisz jeszcze zarejestrować odbiornik w manifeście, na przykład:

1

Twoje zrozumienie jest bardzo poprawne.

Apps that target Android 8.0 or higher can no longer register broadcast receivers for implicit broadcasts in their manifest. An implicit broadcast is a broadcast that does not target that app specifically.

Apps can continue to register for explicit broadcasts in their manifests.

Source

Jeśli jesteś zainteresowany tylko w instalacji ogrodzenia, gdy zestaw słuchawkowy jest podłączony. Można użyć

Note: A number of implicit broadcasts are currently exempted from this limitation. Apps can continue to register receivers for these broadcasts in their manifests, no matter what API level the apps are targeting. For a list of the exempted broadcasts, see Implicit Broadcast Exceptions .

można Resister dla ACTION_HEADSET_PLUG w Android Manifest. W wersji onReceive można:

  • Uruchomić NotificationManager.startServiceInForeground(), dzięki czemu można dalej wykonywać pracę w tle.
  • Znajdź sposób duplikowania funkcji usługi z zaplanowanym zadaniem. Jeśli usługa nie robi czegoś natychmiast zauważalnego dla użytkownika, powinieneś zasadniczo móc użyć zaplanowanego zadania. Odwoływanie pracy w tle, dopóki aplikacja nie znajdzie się naturalnie na pierwszym planie.

Proponuję użyć kombinacji Job Scheduler z ACTION_HEADSET_PLUG jeśli długa praca bieg musi być zrobione.

Inne mądre, jeśli krótki czas potrzebuje do zrobienia co w onReceive z was może przyjąć pomoc z następujących opcji:

A BroadcastReceiver that uses goAsync() to flag that it needs more time to finish after onReceive() is complete. This is especially useful if the work you want to complete in your onReceive() is long enough to cause the UI thread to miss a frame (>16ms), making it better suited for a background thread.

you should not start long running background threads from a broadcast receiver. After onReceive(), the system can kill the process at any time to reclaim memory, and in doing so, it terminates the spawned thread running in the process. To avoid this, you should either call goAsync() (if you want a little more time to process the broadcast in a background thread) or schedule a JobService from the receiver using the JobScheduler, so the system knows that the process continues to perform active work.

Source

+0

Dzięki za odpowiedź Anuraga. Jednak muszę używać interfejsu API Awareness, ponieważ moje ogrodzenie nie tylko obejmuje HeadsetFence, ale także wykorzystuje DetectedActivityFence, a więc łączę dwa ogrodzenia za pomocą AwarenessFence.and (DetectedActivityFence.during (DetectedActivityFence.IN_VEHICLE), HeadphoneFence.during (HeadphoneState.PLUGGED_IN)) W przeciwnym razie ACTION_HEADSET_PLUG byłby idealny. –

6

Zrobiłem trochę kopanie wokół i natknął this blog post przez CommonsWare. Określa on sam problem, przed którym stoisz.

Z powyższego posta: -

One of the more controversial changes in Android O — for apps with a sufficiently-high targetSdkVersion — is the effective ban on implicit broadcasts.

więc, zgodnie z tym, nie sądzę, problemu nie ma nic wspólnego z API świadomości. Zamiast tego, jest to spowodowane nowym zachowaniem wprowadzonym w systemie Android 8.

Niestety, wydaje się, że obecnie nie ma na to realnego rozwiązania. Znów frazowanie z tego samego postu: -

If you are receiving system-sent implicit broadcasts (e.g., ACTION_PACKAGE_ADDED), keep your targetSdkVersion at 25 or lower, until we figure out better workarounds that (hopefully) do not involve polling.

Miejmy nadzieję, że w najbliższej przyszłości będzie lepsze rozwiązanie dla 8 osób. Tymczasem można rozważyć inne opcje lub rozważyć obniżenie docelowego pliku SDK.

+0

Zrobiłem to, gdy rozwijałem swoją aplikację, jednak zaakceptowana odpowiedź jest lepszym rozwiązaniem, więc sprawdź to. –