Search code examples
mauimaui-android

How can i use UsageStatsManager in .NET MAUI


I try to use UsageStatsManager in .NET MAUI.

I asked for permission but I can't get it. It's always denied and of course the stats does not return any values.

private async Task<bool> CheckPermissions()
{
    PermissionStatus status = PermissionStatus.Unknown;

    if (DeviceInfo.Platform == DevicePlatform.Android)
    {
        status = await Permissions.CheckStatusAsync<PackagePermission.PackageUsageStatsPermission>();

        if (status == PermissionStatus.Granted)
            return true;

        if(Permissions.ShouldShowRationale<PackagePermission.PackageUsageStatsPermission>())
        {
            await Shell.Current.DisplayAlert("Needs permissions", "You must activate manualy", "OK");
        }

        status = await Permissions.RequestAsync<PackagePermission.PackageUsageStatsPermission>();
    }

    return status == PermissionStatus.Granted;
}

And this is my BasePlatformPermission


using static Microsoft.Maui.ApplicationModel.Permissions;

namespace MauiStats.PackagePermission;

internal class PackageUsageStatsPermission : BasePlatformPermission
{
#if ANDROID
    public override (string androidPermission, bool isRuntime)[] RequiredPermissions => 
        new List<(string permission, bool isRuntime)>
        {
            ("android.permission.PACKAGE_USAGE_STATS", true)
        }.ToArray();
#endif
}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application android:allowBackup="true" android:icon="@mipmap/appicon" android:supportsRtl="true"></application>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"/>
  <uses-sdk android:minSdkVersion="21" />
</manifest>

I would like to get an application like this


Solution

  • The official document about the UsageStatsManager said:

    NOTE: Most methods on this API require the permission android.permission.PACKAGE_USAGE_STATS. However, declaring the permission implies intention to use the API and the user of the device still needs to grant permission through the Settings application. See Settings.ACTION_USAGE_ACCESS_SETTINGS. Methods which only return the information for the calling package do not require this permission

    So you also need to let the user grant the permission in the Settings.ACTION_USAGE_ACCESS_SETTINGS activity:

    Microsoft.Maui.ApplicationModel.Platform.CurrentActivity.StartActivity(new Android.Content.Intent(Android.Provider.Settings.ActionUsageAccessSettings));
    

    The will go to the Settings.ACTION_USAGE_ACCESS_SETTINGS activity and then the user needs to find the app in the list and grant it the permission.

    And then you can use the following code to retrieve applications statistics:

    var usm = Android.App.Application.Context.GetSystemService(Android.Content.Context.UsageStatsService) as Android.App.Usage.UsageStatsManager;
    var list = usm.QueryUsageStats(Android.App.Usage.UsageStatsInterval.Daily, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() - 1000*3600*24, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds());
    

    You can check if the permission is granted by checking the count of the list is 0 or the value of the list is null or not.