[Android] Implement all the new Android 34 restrictions

Nicolas Pomepuy git at videolan.org
Thu Oct 3 07:36:48 UTC 2024


vlc-android | branch: 3.5.x | Nicolas Pomepuy <nicolas at videolabs.io> | Mon Aug 28 13:56:51 2023 +0200| [081a7540a9bf088d8010eb7d86e4012039368839] | committer: Nicolas Pomepuy

Implement all the new Android 34 restrictions

(cherry picked from commit 7f74e9a5d5a31c9bc0c3ceb08607613dfed15333)

> https://code.videolan.org/videolan/vlc-android/commit/081a7540a9bf088d8010eb7d86e4012039368839
---

 application/vlc-android/AndroidManifest.xml                 |  8 ++++++--
 .../vlc-android/src/org/videolan/vlc/DebugLogService.kt     |  6 +++++-
 .../vlc-android/src/org/videolan/vlc/MediaParsingService.kt | 11 ++++++++---
 .../vlc-android/src/org/videolan/vlc/PlaybackService.kt     | 13 ++++++++++---
 .../src/org/videolan/vlc/gui/video/PopupManager.kt          | 13 +++++++++++--
 5 files changed, 40 insertions(+), 11 deletions(-)

diff --git a/application/vlc-android/AndroidManifest.xml b/application/vlc-android/AndroidManifest.xml
index de2c54511d..75a3d32067 100644
--- a/application/vlc-android/AndroidManifest.xml
+++ b/application/vlc-android/AndroidManifest.xml
@@ -17,6 +17,9 @@
     <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <!-- Audio search on TV -->
     <uses-permission android:name="android.permission.RECORD_AUDIO"/> <!-- USe foreground services -->
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/> <!-- normal -->
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
+
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
     <uses-permission android:name="android.permission.WAKE_LOCK"/>
     <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
@@ -1047,7 +1050,7 @@
         </service>
         <service
                 android:name=".MediaParsingService"
-                android:foregroundServiceType="mediaProjection" />
+                android:foregroundServiceType="dataSync" />
 
         <receiver
             android:name=".widget.VLCAppWidgetProviderWhite"
@@ -1182,7 +1185,8 @@
                 android:theme="@style/Theme.VLC"
                 android:launchMode="singleTop" />
         <service android:name=".DebugLogService"
-                android:process=":logger" />
+                android:process=":logger"
+                android:foregroundServiceType="dataSync" />
     </application>
 
 </manifest>
diff --git a/application/vlc-android/src/org/videolan/vlc/DebugLogService.kt b/application/vlc-android/src/org/videolan/vlc/DebugLogService.kt
index 5094ee164d..52f5d3375b 100644
--- a/application/vlc-android/src/org/videolan/vlc/DebugLogService.kt
+++ b/application/vlc-android/src/org/videolan/vlc/DebugLogService.kt
@@ -27,6 +27,7 @@ import android.content.ComponentName
 import android.content.Context
 import android.content.Intent
 import android.content.ServiceConnection
+import android.content.pm.ServiceInfo
 import android.os.*
 import android.text.format.DateFormat
 import android.util.Log
@@ -135,7 +136,10 @@ class DebugLogService : Service(), Logcat.Callback, Runnable {
         builder.setSmallIcon(R.drawable.ic_stat_vlc)
         builder.setContentIntent(pi)
         val notification = builder.build()
-        startForeground(3, notification)
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+            startForeground(3, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
+        else
+            startForeground(3, notification)
     }
 
     @Synchronized
diff --git a/application/vlc-android/src/org/videolan/vlc/MediaParsingService.kt b/application/vlc-android/src/org/videolan/vlc/MediaParsingService.kt
index 076b3b3ddc..30f86dbb78 100644
--- a/application/vlc-android/src/org/videolan/vlc/MediaParsingService.kt
+++ b/application/vlc-android/src/org/videolan/vlc/MediaParsingService.kt
@@ -29,6 +29,7 @@ import android.content.BroadcastReceiver
 import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
+import android.content.pm.ServiceInfo
 import android.net.Uri
 import android.os.Binder
 import android.os.Build
@@ -130,7 +131,7 @@ class MediaParsingService : LifecycleService(), DevicesDiscoveryCb {
         val filter = IntentFilter()
         filter.addAction(ACTION_PAUSE_SCAN)
         filter.addAction(ACTION_RESUME_SCAN)
-        registerReceiver(receiver, filter)
+        registerReceiver(receiver, filter, RECEIVER_NOT_EXPORTED)
         val pm = applicationContext.getSystemService<PowerManager>()!!
         wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "VLC:MediaParsingService")
 
@@ -202,7 +203,9 @@ class MediaParsingService : LifecycleService(), DevicesDiscoveryCb {
     private fun forceForeground() {
         val notification = NotificationHelper.createScanNotification(applicationContext, getString(R.string.loading_medialibrary), scanPaused, -1, -1)
         try {
-            startForeground(43, notification)
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+                startForeground(43, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
+            else startForeground(43, notification)
         } catch (e: Exception) {
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e is ForegroundServiceStartNotAllowedException) {
                 Log.w("MediaParsingService", "ForegroundServiceStartNotAllowedException caught!")
@@ -384,7 +387,9 @@ class MediaParsingService : LifecycleService(), DevicesDiscoveryCb {
                 try {
                     val notification = NotificationHelper.createScanNotification(applicationContext, progressText, scanPaused, scheduled, done)
                     try {
-                        startForeground(43, notification)
+                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+                            startForeground(43, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
+                        else startForeground(43, notification)
                     } catch (e: Exception) {
                         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && e is ForegroundServiceStartNotAllowedException) {
                             Log.w("MediaParsingService", "ForegroundServiceStartNotAllowedException caught!")
diff --git a/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt b/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
index 0ae0052522..fa26e23eb6 100644
--- a/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
+++ b/application/vlc-android/src/org/videolan/vlc/PlaybackService.kt
@@ -24,6 +24,7 @@ import android.annotation.TargetApi
 import android.app.*
 import android.appwidget.AppWidgetManager
 import android.content.*
+import android.content.pm.ServiceInfo
 import android.content.res.Configuration
 import android.media.AudioManager
 import android.media.audiofx.AudioEffect
@@ -640,7 +641,7 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner, CoroutineSc
             addAction(ACTION_CAR_MODE_EXIT)
             addAction(CUSTOM_ACTION)
         }
-        registerReceiver(receiver, filter)
+        registerReceiver(receiver, filter, RECEIVER_NOT_EXPORTED)
         if (CarConnectionHandler.preferCarConnectionHandler()) {
             carConnectionHandler = CarConnectionHandler(contentResolver)
             carConnectionHandler.connectionType.observeForever {
@@ -767,7 +768,10 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner, CoroutineSc
                     ctx.resources.getString(R.string.loading), "", "", null, false, true,
                     true, speed, isPodcastMode, false, enabledActions, null, pi)
         }
-        startForeground(3, notification)
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+            startForeground(3, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK)
+        else
+            startForeground(3, notification)
         isForeground = true
         if (stopped) lifecycleScope.launch { hideNotification(true) }
     }
@@ -909,7 +913,10 @@ class PlaybackService : MediaBrowserServiceCompat(), LifecycleOwner, CoroutineSc
                     if (!AndroidUtil.isLolliPopOrLater || playing || audioFocusHelper.lossTransient) {
                         if (!isForeground) {
                             ctx.launchForeground(Intent(ctx, PlaybackService::class.java)) {
-                                ctx.startForeground(3, notification)
+                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+                                    startForeground(3, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK)
+                                else
+                                    startForeground(3, notification)
                                 isForeground = true
                             }
                         } else
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/video/PopupManager.kt b/application/vlc-android/src/org/videolan/vlc/gui/video/PopupManager.kt
index c560e0ffd9..c071d48173 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/video/PopupManager.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/video/PopupManager.kt
@@ -25,11 +25,17 @@
 package org.videolan.vlc.gui.video
 
 import android.content.Intent
+import android.content.pm.ServiceInfo
+import android.os.Build
 import android.os.Handler
 import android.os.Looper
 import android.os.Message
 import android.util.Log
-import android.view.*
+import android.view.GestureDetector
+import android.view.LayoutInflater
+import android.view.MotionEvent
+import android.view.SurfaceView
+import android.view.View
 import android.widget.ImageView
 import androidx.core.app.NotificationCompat
 import androidx.core.view.GestureDetectorCompat
@@ -260,7 +266,10 @@ class PopupManager constructor(private val service: PlaybackService) : PlaybackS
         else
             builder.addAction(R.drawable.ic_popup_play, service.getString(R.string.play), piPlay)
         builder.addAction(R.drawable.ic_popup_fullscreen, service.getString(R.string.popup_expand), piExpand)
-        service.startForeground(42, builder.build())
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+            service.startForeground(42, builder.build(), ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PLAYBACK)
+        else
+            service.startForeground(42, builder.build())
     }
 
     private fun hideNotification() {



More information about the Android mailing list