Google's time fence using Awareness API is not reliable - android

I am building an SDK that is using Google Awareness API.
I have some actions that need to be executed based on different schedules for each day, also when the app is backgrounded - a perfect match for Google's FenceClient or so I thought.
The problem is that the notifications I'm getting are not really related to times I configured in the fence - sometimes the notifications are minutes/hours late and sometimes I'm not getting those notifications at all.
What's weirder is that all Google's examples are still using the deprecatedGoogleApiClient.
Technical issues:
I defined these two permissions in the manifest:
uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
uses-permission
android:name="android.permission.ACCESS_COARSE_LOCATION"
Awareness is activated in the Google console and I have the API keys defined in the manifest.
I tried to use both (one of them in each time) BroadcastReceiver and JobIntentService using PendingIntent.getBroadcast and PendingIntent.getService. Both of them also defied in the manifest.
I'm building the AwarenessFence like this: TimeFence.inIntervalOfDay(dayOfWeek, TimeZone.getDefault(), startTimeOfDayMillis, stopTimeOfDayMillis); start and stop times are in milliseconds since the start of the day.
fenceClient.updateFences is completed successfully.

Related

Android 12: Using SCHEDULE_EXACT_ALARM permission to get/show data at specific time are safe in Google Play Policy?

I have an Android app on Play store for 8 years. Recently Google release Android S or 12 introduce some limit with Foreground service launch restrictions
https://developer.android.com/about/versions/12/behavior-changes-12#foreground-service-launch-restrictions
and
Exact alarm permission
https://developer.android.com/about/versions/12/behavior-changes-12#exact-alarm-permission
In the app I use foreground service and alarm clock to schedule update weather data from the cloud and device sensor and send notification to user, update the widget.
But they said: Exact alarms should only be used for user-facing features so if I continue use those API, it is safe (with Google Play policy)?
I ask this because other solution like sticky notification with foreground service and workmanager not work as my requirements.
if you are testing android 12 then don't forget to add this line to Manifest
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
Yes, the android.permission.SCHEDULE_EXACT_ALARM it's safe to use, on Android 12 this permission is automatically granted by the Android system but on Android 13 you need to check if the user has granted this permission.
So you need to add the permission to the manifest
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>
And then you need to check if the permission was granted, if not granted then you need to redirect the user to the Alarms & Reminders page
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val alarmManager = ContextCompat.getSystemService(context, AlarmManager::class.java)
if (alarmManager?.canScheduleExactAlarms() == false) {
Intent().also { intent ->
intent.action = Settings.ACTION_REQUEST_SCHEDULE_EXACT_ALARM
context.startActivity(intent)
}
}
}
Google also suggests that you need to check any changes on this permission by registering a Broadcast Receiver and check the changes on ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED
Google states: "(when your app) requires precisely-timed actions". Your use case is "to schedule update weather data (…) send notification to user". While this might be user-facing, it doesn't seem to require to be precisely on a certain time. I would guess your app doesn't qualify.
The methods requiring the additional permission are currently: setExact(), setExactAndAllowWhileIdle() and setAlarmClock(). Repeating alarms will always be inexact. Seems like getting processing weather data and device sensors is something repetitive anyway.
From what you've mentioned, you're talking about user-facing features.
A hypothetical example of the opposite would be Facebook forcing synchronization of user data at some specific time. That would be bad because it's preferable not to force a schedule on those types of things as it doesn't matter whether it happens at a specific time or a minute later when system resources are not used by some other service.
Also, "should" means it's a recommendation. Facebook can do the above, but it would be a less optimal solution. It's best to leave control over those kinds of services to Android as it would likely do a better job at distributing resources and preventing lag. So in other words, you not listening to their recommendation won't get your app removed from the app store or something like that.
Also, the paragraph you quoted from the second link, has a link to examples of acceptable use cases, and it mentions alarm apps. This is likely why your question was downvoted.
effective solution
you need to add the permission to the manifest before <application

What are the requirements to comply with the background location rules from the Play Store?

I have a similar issue to this post How to make my Android app comply with the "Background Location Policy" but that post doesn't have an answer.
I have a web browser app, which on occasion will ask for location permissions if the user visits a website that requests that. App targets API 29. The app manifest has <uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" /> which is API 23 and higher because I didn't want to force location permission on older phones.
Today I got an email saying I have until March to fix this, but I don't understand what I have to do, I'm not requesting background location anywhere.
Anyone have any idea what I have to do?
Edit: I have read the help center, and I'm wondering if that my issue is the ACCESS_FINE_LOCATION, maybe something is accessing it on the background. I don't know how I would prevent ad networks from that if they do it. I already pause the WebViews the app is not on the foreground so websites should not be using it.
Edit2: Is there maybe a way I can log background location access so that I can monitor my app a few days to see if it happens?
I would like to answer my own question in case someone else is searching for this. I can't say that I know for certain this is correct but it has worked for me so far.
First, on this answer https://stackoverflow.com/a/65894488/704836 I was told to use AppOpsManager to log background location requests. After doing that I found a few places where that takes places. I will discuss those below:
Ad networks. I have ad network initialization on my Application.onCreate() and a lot of those accessed location. So when triggering a BroadcastReceiver, they would check location.
WifiManager.getConnectionInfo() - this will trigger a location request. Same deal as above, I had one of those on Application.onCreate().
After removing those calls the Play store stopped complaining.

How to start app when phone starts with smartface.io

I am using Notifications.local.scheduleNotification to schedule a notification. However, if the phone is rebooted before the fire event, the notification does not fire.
I would like to have the app start when the phone boots up so that I can add the notification to the alarm manager again. In the android manifest I would be asking for the following permission.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
How can this be implemented in smartface?
Today, this is not supported by Smartface, but there will be plugin support soon, you can write your own plugin and use it.
Also for licenced users, there is an option to ask for new implementations. If they need some new features, they can report them to Smartface team, and these features will be added to road map.

Missing Google Services permissions in logcat

We have a weather app for Android that also provides a widget.
The widget displays the current time and weather for the current user location.
We update the widget clock every minute (via AlarmManager) if the display is active, the weather data at longer intervals. Sometimes the widget "freezes". We were able to track that down to the alarm for the next check not being set but don't have a clue why, yet.
Now we noticed the following warning in the device logs of an affected device:
03-12 10:15:44.803 771 4958 W ActivityManager: Permission Denial: opening provider com.google.android.gsf.gservices.GservicesProvider from ProcessRecord{41a4d028 25012:com.my.app/u0a88} (pid=25012, uid=10088) requires com.google.android.providers.gsf.permission.READ_GSERVICES or com.google.android.providers.gsf.permission.WRITE_GSERVICES
This starts to appear exactly at the time where the clock should have been updated. The message is then repeated several times until the ActivityManager terminates the process.
We use the Google Play Location Services to get the current (or last known) location of the user. I found references to a bug in version 4.2 of the services (here and https://stackoverflow.com/questions/22682538/when-to-use-read-gservices-permission) that could cause this error, but the device has version 6.7.76 installed.
One more thing to consider is that the device is running Cyanogenmod, though the stuck widget problem also happens on devices with "regular" Android.
Any hints what could cause this permission error are very much appreciated. Thanks!
Edit: The widget and app work fine on that and many other devices until the warning appears. Also the Google documentation is not mentioning that you need to get those permissions. In fact the only mention of those is here in this document according to the on site search, but no mention of READ_GSERVICES on the page itself.
The two permissions it is asking for:
<uses-permission android:name="com.google.android.providers.gsf.permisson.READ_GSERVICES"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.WRITE_GSERVICES"/>
Something to remember just because this issue was reported in Google Play Location Services in 4.2 does not mean it has been fixed. It may be worth looking through the Google bug reported to see if anyone has any issues. I found a few issues raised running much newer Google Play Services.
Upon doing a quick Google search myself it seems like the major problem phones are the Moto X and the Nexus 5. Which is rather interesting as they are both Android Open Source Project bugs (i.e phones running stock Android with no skin!)
Just a few questions:
Can you confirm what phone you have and which version of Android you
are running please?
Also what is your target SDK?
What version of play services are included in your APK?

PhoneStateListener onMessageWaitingIndicatorChanged() not being called reliably

I have some code that detects when there is new voicemail. It's based on a PhoneStateListener.onMessageWaitingIndicatorChanged() implementation (so technically it fires only when the MWI indicator changes, not necessarily for every new voicemail).
It has been working perfectly for many months until 4.x.x updates to the devices.
Now, this works when the device is rebooted, otherwise its very unreliable. I can see the voicemail icon appear in the notification bar, but the debug logs in onMWIChanged stay silent.
I know that with 4.x.x there is a voicemail provider API. Thinking that this may have a connection, I added the android.intent.action.NEW_VOICEMAIL and android.intent.action.PROVIDER_CHANGED intents to my receiver, but they don't fire (in my BroadcastReceiver onReceive) either (my app's minSdkVersion is 8).
This is a post from Android Developers about the Android 4.0 APIs.
http://developer.android.com/about/versions/android-4.0.html
If you scroll down there is a section about Voicemail Providers where it explains:
Because the APIs currently do not allow third-party apps to read all the voicemails from the system, the only third-party apps that should use the voicemail APIs are those that have voicemail to deliver to the user.
However, I assume if you are trying to receive voicemails from a third party and not from your service then this still may be possible. Check out this link about VoicemailContracts where I believe it says you need the permission ADD_VOICEMAIL in your manifest to use the actions you are using above.
http://developer.android.com/reference/android/provider/VoicemailContract.html
There are also samples that I did not get a chance to look at called Voicemail Provider Demo in your SDK. I hope this helps.
It does require the READ_PHONE_STATE permission. Although, if it worked before you must of had it set.
See LISTEN_MESSAGE_WAITING_INDICATOR.

Categories

Resources