11

我有一個Android應用,它使用的意識API設置一個圍欄當耳機在插入意識API和Android o使用廣播接收器

我已經在實施了使用AwarenessFence代碼很像在實施例中:https://developers.google.com/awareness/android-api/fence-register

我有一個的PendingIntent定義爲:由於

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

然後在我的AndroidManifest.xml文件我有

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

這是在清單中聲明,我即使當我的應用程序在後臺時也希望收到廣播。

這一切都工作正常在Android 7.0及以下,但是當我上的是Android 8.0運行此我得到的錯誤:

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

我認爲這是由於在Android O背景執行新的限制。

誰能告訴我如何註冊廣播接收器可以聽意識圍欄時觸發在Android設備上運行API的後臺26

讓我知道,如果有一些東西,不清晰,或者我需要詳細說明mething。

在此先感謝

回答

4

我現在無法在設備上測試它,但是從我讀過的所有內容來看,限制僅限於隱式廣播。這意味着,如果您創建一個明確的廣播,那就只需要讓它工作。

這意味着不是這樣的:

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

你做到這一點:

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

經過測試和工作。這應該是被接受的答案, – Simon

+1

你是對的西蒙。我只是測試了這一點,並可以確認它正在工作。這是現在被接受的答案。 –

+0

請注意,您仍然需要在清單中註冊接收者,如:

1

您的理解是非常正確的。

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

如果你只對設置當耳機在插上籬笆感興趣。您可以使用

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 .

可以在Android Manifest電阻爲ACTION_HEADSET_PLUG。在onReceive你可以:

  • 啓動NotificationManager.startServiceInForeground(),這樣你就可以繼續在後臺工作。
  • 找到一種方法來使用計劃作業複製服務的功能。如果服務沒有對​​用戶立即引起注意,您通常應該可以使用預定作業。請參閱Job Scheduler
  • 推遲後臺工作,直到應用程序自然處於前臺。

如果需要長時間運行的工作,我會建議使用Job SchedulerACTION_HEADSET_PLUG的組合。

其他明智的,如果持續時間短的工作需要做哪些在你onReceive 可以幫助從以下方面:

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

謝謝您的回答阿努拉格。但是我需要使用Awareness API,因爲我的圍欄不僅包含HeadsetFence,而且還使用DetectedActivityFence,因此我使用AwarenessFence.and(DetectedActivityFence.during(DetectedActivityFence.IN_VEHICLE),HeadphoneFence.during(HeadphoneState.PLUGGED_IN))組合了兩個柵欄。否則ACTION_HEADSET_PLUG本來是完美的。 –

6

我做了一個小挖周圍,偶然發現this blog post通過CommonsWare。它陳述了你正面臨的問題。

從上述職位: -

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

因此,根據這一點,我不認爲你的問題有什麼關係意識API。相反,這是因爲Android 8引入了新行爲。

不幸的是,目前似乎還沒有可行的解決方案。同樣,從相同的文章措辭: -

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.

所以,希望在不久的將來會有更好的解決方案8。同時,你可以考慮其他選擇,或者可以考慮降低你的targetSDK。

+0

當我開發我的應用程序時,這樣做的竅門,但接受的答案是更好的解決方案,所以請檢查這一點。 –