AppGatekeeper updated for latest Android

This new version 1.6.0 has targetSdkVersion of 26 (Android Oreo). Partly, this is due to Google sending developers a reminder that after November 1, 2018, the Play Console will prevent you from submitting new APKs with a targetSdkVersion less than 26.

Below is the list of changes group by:

UI or behavior changes:

In prior versions, the app uses Theme.Holo . Now, it will use Theme.Material for Android 5 & above, otherwise it use back Theme.Holo . There are some minor adjustments due to using the material theme.

The app now checks for runtime permission for read/write external storage for Android 6 & above. Basically, just before the app needs to read or write to external storage, it checks with the Android system whether user has granted the required permission. If permission has already been granted, it proceeds as usual; otherwise it asks Android to prompt the user to either approve or deny the requested permission. If user approves, the read/write will proceed; otherwise the operation is aborted.

The free app does not perform any read/write. The upgraded app performs read only for Restore, read/write for Backup, write only for Export All Usage and Export Usage, and it will request for read/write permissions when user taps on the Export to directory path setting in Settings screen. Regardless, the Android system request permission dialog will only ask the user to approve storage permission. (Currently, both read and write external storage are grouped by Android system into storage permission)

On restoring the app from Android system recents, if Android system creates a new app process, then instead of allowing Android system to launch the last recently used activity, the app will always launch the main activity. This change fix dependencies issue for some of the activities that rely on the main activity.

Slightly related to above, if user leaves the app such that it is not visible, the app will now close or cancel any alert message dialog.

There is a particular issue when using material theme for Android 5 system. The maximum date of DatePickerDialog although shown visually to be selectable, cannot be selected. Thus, to solve this, the app checks if it is Android 5.X , and it explicitly creates the DatePickerDialog with Theme.Holo . It compensates this by making a slight change to the dialog title and the buttons color via using material theme colors. The DatePickerDialog in material theme will set the dialog title to the selected date, but this is not done if using holo theme. The new code implements showing the selected date in the title as well for holo theme.

The app uses a default Export to directory path, which is now not created, until the first write operation is executed or when user first taps on the Export to directory path setting in Settings screen and has approved the Android storage permission. This default Export path is not displayed in the Settings until user changes it.

Code only changes:

Certain broadcast receiver in the manifest is now handled/registered via the activity or service.

  • main activity register CONNECTIVITY_ACTION system broadcast
  • service register shutdown, time and timezone change system broadcasts

On receiving boot completed broadcast (or others that require restarting service), the receiver starts the service via startForegroundService method on Android 8 & above. The reason is that in that instance, the app is in the background, and Android 8 system doesn't allow a background app to create a background service.

Code changes to cater for notification channels. Starting in Android 8 (API level 26), all notifications must be assigned to a channel or it will not appear. A channel of default importance is created for the foreground service notification.

Simplify certain codes related to the service execution when it is started from the receiver. (only apply to Android 8 & above)

Adjustment of codes related to UsageStatsManager.queryUsageStats. On testing the service in Android 9 emulator, this method can return UsageStats from the previous day, and also can have multiple UsageStats per app. The new code handles this possibility.

The app will query billing service within the Application.onCreate method, which is too early. For example, the after boot receiver will also query billing service, which is unintentional. This querying is shifted until the first app activity is created.

Various changes to make the actionBar work like before, due to the use of material theme.

Internal code changes to cancel any modification in "Allowed Access" screen by rotating the device.

The app now uses ACRA 4.8.5 , a slight change is made to make it not send any crash reports when the app starts.

The app internal crash logger previously log stack trace to the default Export path. (It is enabled only if the Application Crash Report setting is enabled) Given that this default Export path may not exist, it now logs to the path provided by getExternalFilesDir(null)

Bug fix:

Android 7.1 makes a change in the internal system interface used by Toast. This causes the service's warning toast to crash the service. The fix handles the new interface and comply with its expected behavior.

When the app draws the labels used in the apps usage graph, an exception may be thrown possibly when the labels are very close. This bug is fixed.

In some cases of Android system/device, when the app draws Chinese chars for the category icon, an exception may be thrown. The fix catches the exception, and draws only the first character instead.

Android 9 dark greylist non SDK changes:

Android 9 (API level 28) introduces new restrictions on the use of non-SDK interfaces, whether directly, via reflection, or via JNI.

The app target SDK is below API level 28, so the use of dark greylist interface is permitted. But, considering Google is requiring developers to update to the latest API. The dark greylist interface usage may eventually be denied.

The app access Spinner.SavedState field showDropdown. In case if an exception is caught, it checks if API level >= 28, and access the whitelist hidden method Spinner.isPopupShowing .

The app "Restrict days to" spinner access superclass non-SDK interface. In case of exception, it is using a work-around solution. Certain codes are simplified as well.

The app service toast access non-SDK light greylist interface. It is not in immediate danger. Just in case the use of light greylist interface is disallowed in future, the service code is modified to disable the display of warning toast message if the interface is inaccessible. However, the "app has been stopped" message toast will still be displayed.

Testing is done on the Android emulator with Android 9 image.

To disallow usage of dark grey and black listed APIs, change the below settings to 2.

    adb shell settings put global hidden_api_policy_pre_p_apps 2
adb shell settings put global hidden_api_policy_p_apps 2

This is the first release built using gradle, all previous versions are built using ant.

Testing is done on alps A9, Amazon Fire 7 & 8, LG Q6 (Android 7.1 & after upgrade 8.1), Android emulator with Android 6, 8, 9.

Thanks to Google and especially stackoverflow!

Google is introducing digital wellbeing features for Android 9, including a new Dashboard that helps you understand how you’re spending time on your device; an App Timer that lets you set time limits on apps and grays out the icon on your home screen when the time is up; the new Do Not Disturb, which silences all the visual interruptions that pop up on your screen; and Wind Down, which switches on Night Light and Do Not Disturb and fades the screen to grayscale before bedtime.

Given Google may request developers to update their apps targetSdkVersion in the future, and it is possible that I do now want to do so if it causes too much trouble, and I may still want to update the app to fix bugs; I will provide the app binary release on my website. Download AppGatekeeper-release.v1.6.0.apk

App Gatekeeper (version 1.6.0) is released.

Past release:


blog comments powered by Disqus