diff options
author | Thomas Guillem <thomas@gllm.fr> | 2020-03-25 22:08:17 +0100 |
---|---|---|
committer | Max Kellermann <max@musicpd.org> | 2020-03-26 17:30:55 +0100 |
commit | 9c15760c4d932b1a9fde83661d0a58dd8e2efece (patch) | |
tree | 427a5671025152d0a84070ae23ce90a59ebce629 /android | |
parent | e1c43ec65f237b60e4cdbd7f6e0e24900419d710 (diff) |
android/Main: handle API26 NotificationChannel
This seems to be required on recent Android versions (tested with Android 10).
This is also required for android TV services (cf. next commit).
This is done using Java reflection so that the project doesn't depend on
android compat libs.
Diffstat (limited to 'android')
-rw-r--r-- | android/AndroidManifest.xml | 1 | ||||
-rw-r--r-- | android/src/Main.java | 49 |
2 files changed, 46 insertions, 4 deletions
diff --git a/android/AndroidManifest.xml b/android/AndroidManifest.xml index 6de3d89eb..01ff051c4 100644 --- a/android/AndroidManifest.xml +++ b/android/AndroidManifest.xml @@ -11,6 +11,7 @@ <uses-permission android:name="android.permission.WAKE_LOCK"/> <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> + <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <application android:allowBackup="true" android:icon="@drawable/icon" diff --git a/android/src/Main.java b/android/src/Main.java index 840168565..399d945f0 100644 --- a/android/src/Main.java +++ b/android/src/Main.java @@ -21,6 +21,7 @@ package org.musicpd; import android.annotation.TargetApi; import android.app.Notification; +import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.ComponentName; @@ -35,6 +36,9 @@ import android.os.RemoteException; import android.util.Log; import android.widget.RemoteViews; +import java.lang.reflect.Constructor; +import java.lang.reflect.Method; + public class Main extends Service implements Runnable { private static final String TAG = "Main"; private static final String REMOTE_ERROR = "MPD process was killed"; @@ -156,11 +160,36 @@ public class Main extends Service implements Runnable { sendMessage(MSG_SEND_STATUS, mStatus, 0, mError); } + private Notification.Builder createNotificationBuilderWithChannel() { + final NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE); + if (notificationManager == null) + return null; + + final String id = "org.musicpd"; + final String name = "MPD service"; + final int importance = 3; /* NotificationManager.IMPORTANCE_DEFAULT */ + + try { + Class<?> ncClass = Class.forName("android.app.NotificationChannel"); + Constructor<?> ncCtor = ncClass.getConstructor(String.class, CharSequence.class, int.class); + Object nc = ncCtor.newInstance(id, name, importance); + + Method nmCreateNotificationChannelMethod = + NotificationManager.class.getMethod("createNotificationChannel", ncClass); + nmCreateNotificationChannelMethod.invoke(notificationManager, nc); + + Constructor nbCtor = Notification.Builder.class.getConstructor(Context.class, String.class); + return (Notification.Builder) nbCtor.newInstance(this, id); + } catch (Exception e) + { + Log.e(TAG, "error creating the NotificationChannel", e); + return null; + } + } + private void start() { if (mThread != null) return; - mThread = new Thread(this); - mThread.start(); final Intent mainIntent = new Intent(this, Settings.class); mainIntent.setAction("android.intent.action.MAIN"); @@ -168,13 +197,25 @@ public class Main extends Service implements Runnable { final PendingIntent contentIntent = PendingIntent.getActivity(this, 0, mainIntent, PendingIntent.FLAG_CANCEL_CURRENT); - Notification notification = new Notification.Builder(this) - .setContentTitle(getText(R.string.notification_title_mpd_running)) + Notification.Builder nBuilder; + if (Build.VERSION.SDK_INT >= 26 /* Build.VERSION_CODES.O */) + { + nBuilder = createNotificationBuilderWithChannel(); + if (nBuilder == null) + return; + } + else + nBuilder = new Notification.Builder(this); + + Notification notification = nBuilder.setContentTitle(getText(R.string.notification_title_mpd_running)) .setContentText(getText(R.string.notification_text_mpd_running)) .setSmallIcon(R.drawable.notification_icon) .setContentIntent(contentIntent) .build(); + mThread = new Thread(this); + mThread.start(); + startForeground(R.string.notification_title_mpd_running, notification); startService(new Intent(this, Main.class)); } |