Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TIMOB-26260] Android: Updated "Ti.Android.Service" to handle Android P "FOREGROUND_SERVICE" permission #10314

Merged
merged 5 commits into from
Oct 4, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.ServiceConnection;
import android.Manifest;
import android.os.Build;
import android.os.IBinder;

Expand Down Expand Up @@ -298,12 +302,67 @@ public void run()
throw new RuntimeException(ex);
}

// Determine if service is configured for the foreground or background.
boolean isForeground = (notificationId != 0) && (notificationObject != null);

// For foreground services, check if "AndroidManifest.xml" has "FOREGROUND_SERVICE" permission,
// but only if the app is "targeting" API Level 28 (android 9.0) or higher.
boolean hasPermission = true;
final String permissionName = "android.permission.FOREGROUND_SERVICE";
try {
if (isForeground) {
String packageName = service.getPackageName();
PackageManager packageManager = service.getPackageManager();
PackageInfo packageInfo =
packageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS);
ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0);
if (appInfo.targetSdkVersion >= 28) {
// Fetch array of manifest permissions and find the one required.
// Note: We can't use Context.checkCallingOrSelfPermission() on older OS versions
// since it'll always fail for newer OS permission constants, but we want
// to check anyways in case app developer doesn't test on newest OS.
boolean wasFound = false;
if (packageInfo.requestedPermissions != null) {
for (String nextPermissionName : packageInfo.requestedPermissions) {
if (permissionName.equals(nextPermissionName)) {
wasFound = true;
break;
}
}
}
hasPermission = wasFound;
}
}
} catch (Exception ex) {
// Something else went wrong. Assume we have permission and proceed.
Log.w(TAG, ex.getMessage(), ex);
}
if (!hasPermission) {
// We don't have permission. Log an error.
String message =
"[Developer Error] Ti.Android.Service.foregroundNotify() requires manifest permission: "
+ permissionName;
Log.e(TAG, message);

// Throw an exception, but only if in developer mode.
// This allows Titanium to display an exception dialog to the developer stating what's wrong.
boolean isProduction =
TiApplication.getInstance().getDeployType().equals(TiApplication.DEPLOY_TYPE_PRODUCTION);
if (!isProduction) {
throw new RuntimeException(message);
}
}

// Enable/Disable the service's foreground state.
// Note: A notification will be shown in the status bar while enabled.
if ((notificationId != 0) && (notificationObject != null)) {
service.startForeground(notificationId, notificationObject);
} else {
service.stopForeground(true);
try {
if (isForeground) {
service.startForeground(notificationId, notificationObject);
} else {
service.stopForeground(true);
}
} catch (Exception ex) {
Log.e(TAG, ex.getMessage(), ex);
}
}
});
Expand Down
12 changes: 12 additions & 0 deletions apidoc/Titanium/Android/Service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,18 @@ methods:
The notification will be automatically removed from the status bar when the service has
been stopped or if you call the [foregroundCancel()](Titanium.Android.Service.foregroundCancel)
method.

This method will fail on Android 9.0 and above unless you set the following Android manifest
permission in your "tiapp.xml" file.

<ti:app>
<android xmlns:android="http://schemas.android.com/apk/res/android">
<manifest>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
</manifest>
</android>
</ti:app>

parameters:
- name: id
summary: Unique integer ID to be assigned to the notification. Cannot be zero.
Expand Down