diff --git a/app/src/main/java/org/autojs/autojs/external/foreground/ForegroundService.java b/app/src/main/java/org/autojs/autojs/external/foreground/ForegroundService.java index 33f3bcba..9be4c165 100644 --- a/app/src/main/java/org/autojs/autojs/external/foreground/ForegroundService.java +++ b/app/src/main/java/org/autojs/autojs/external/foreground/ForegroundService.java @@ -1,5 +1,7 @@ package org.autojs.autojs.external.foreground; +import static android.app.PendingIntent.FLAG_IMMUTABLE; + import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; @@ -54,7 +56,9 @@ public class ForegroundService extends Service { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { createNotificationChannel(); } - PendingIntent contentIntent = PendingIntent.getActivity(this, 0, MainActivity_.intent(this).get(), 0); + int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? FLAG_IMMUTABLE : 0; + PendingIntent contentIntent = PendingIntent.getActivity(this, 0, MainActivity_.intent(this).get(), flags); + return new NotificationCompat.Builder(this, CHANEL_ID) .setContentTitle(getString(R.string.foreground_notification_title)) .setContentText(getString(R.string.foreground_notification_text)) diff --git a/autojs/src/main/AndroidManifest.xml b/autojs/src/main/AndroidManifest.xml index c268c1d0..6c050d60 100644 --- a/autojs/src/main/AndroidManifest.xml +++ b/autojs/src/main/AndroidManifest.xml @@ -53,6 +53,11 @@ + + + diff --git a/autojs/src/main/java/com/stardust/autojs/AutoJs.java b/autojs/src/main/java/com/stardust/autojs/AutoJs.java index 4e074661..ef789b07 100644 --- a/autojs/src/main/java/com/stardust/autojs/AutoJs.java +++ b/autojs/src/main/java/com/stardust/autojs/AutoJs.java @@ -3,6 +3,7 @@ package com.stardust.autojs; import android.app.Activity; import android.app.Application; import android.content.Context; +import android.content.Intent; import android.os.Build; import android.os.Bundle; import android.util.Log; @@ -13,6 +14,7 @@ import com.stardust.autojs.core.accessibility.AccessibilityBridge; import com.stardust.autojs.core.activity.ActivityInfoProvider; import com.stardust.autojs.core.console.ConsoleImpl; import com.stardust.autojs.core.console.GlobalConsole; +import com.stardust.autojs.core.image.capture.CaptureForegroundService; import com.stardust.autojs.core.image.capture.ScreenCaptureRequestActivity; import com.stardust.autojs.core.image.capture.ScreenCaptureRequester; import com.stardust.autojs.core.record.accessibility.AccessibilityActionRecorder; @@ -98,7 +100,10 @@ public abstract class AutoJs { exception.fillInStackTrace(); return exception; }); - ResourceMonitor.setUnclosedResourceDetectedHandler(detectedException -> mGlobalConsole.error(detectedException)); + ResourceMonitor.setUnclosedResourceDetectedHandler(mGlobalConsole::error); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { + mContext.startForegroundService(new Intent(mContext, CaptureForegroundService.class).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + } } public abstract void ensureAccessibilityServiceEnabled(); diff --git a/autojs/src/main/java/com/stardust/autojs/core/image/capture/CaptureForegroundService.java b/autojs/src/main/java/com/stardust/autojs/core/image/capture/CaptureForegroundService.java new file mode 100644 index 00000000..ae75bd13 --- /dev/null +++ b/autojs/src/main/java/com/stardust/autojs/core/image/capture/CaptureForegroundService.java @@ -0,0 +1,77 @@ +package com.stardust.autojs.core.image.capture; + +import static android.app.PendingIntent.FLAG_IMMUTABLE; + +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.os.Build; +import android.os.IBinder; + +import androidx.annotation.Nullable; +import androidx.annotation.RequiresApi; +import androidx.core.app.NotificationCompat; + +import com.stardust.autojs.R; + +public class CaptureForegroundService extends Service { + + private static final int NOTIFICATION_ID = 2; + private static final String CHANNEL_ID = CaptureForegroundService.class.getName() + ".foreground"; + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + return super.onStartCommand(intent, flags, startId); + } + + @Override + public void onCreate() { + super.onCreate(); + startForeground(NOTIFICATION_ID, buildNotification()); + } + + private Notification buildNotification() { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + createNotificationChannel(); + } + int flags = Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ? FLAG_IMMUTABLE : 0; + PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, ScreenCaptureRequestActivity.class), flags); + + return new NotificationCompat.Builder(this, CHANNEL_ID) + .setContentTitle("Recording") + .setSmallIcon(R.drawable.autojs_material) + .setWhen(System.currentTimeMillis()) + .setContentIntent(contentIntent) + .setChannelId(CHANNEL_ID) + .setVibrate(new long[0]) + .build(); + } + + @RequiresApi(api = Build.VERSION_CODES.O) + private void createNotificationChannel() { + NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + assert manager != null; + CharSequence name = "Recoding"; + String description = "Recoding"; + NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_DEFAULT); + channel.setDescription(description); + channel.enableLights(false); + manager.createNotificationChannel(channel); + } + + @Override + public void onDestroy() { + super.onDestroy(); + stopForeground(true); + } +} diff --git a/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCapturer.java b/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCapturer.java index 2a87fd17..62622964 100644 --- a/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCapturer.java +++ b/autojs/src/main/java/com/stardust/autojs/core/image/capture/ScreenCapturer.java @@ -1,5 +1,6 @@ package com.stardust.autojs.core.image.capture; +import android.annotation.SuppressLint; import android.app.Activity; import android.content.Context; import android.content.Intent; @@ -14,8 +15,10 @@ import android.media.projection.MediaProjectionManager; import android.os.Build; import android.os.Handler; import android.os.Looper; + import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; + import android.util.Log; import android.view.OrientationEventListener; @@ -33,8 +36,8 @@ import java.util.concurrent.atomic.AtomicReference; public class ScreenCapturer { public static final int ORIENTATION_AUTO = Configuration.ORIENTATION_UNDEFINED; - public static final int ORIENTATION_LANDSCAPE = Configuration.ORIENTATION_LANDSCAPE ; - public static final int ORIENTATION_PORTRAIT = Configuration.ORIENTATION_PORTRAIT ; + public static final int ORIENTATION_LANDSCAPE = Configuration.ORIENTATION_LANDSCAPE; + public static final int ORIENTATION_PORTRAIT = Configuration.ORIENTATION_PORTRAIT; private static final String LOG_TAG = "ScreenCapturer"; @@ -75,7 +78,7 @@ public class ScreenCapturer { mDetectedOrientation = orientation; try { refreshVirtualDisplay(orientation); - }catch (Exception e){ + } catch (Exception e) { e.printStackTrace(); mException = e; } @@ -117,6 +120,7 @@ public class ScreenCapturer { startAcquireImageLoop(); } + @SuppressLint("WrongConstant") private void initVirtualDisplay(int width, int height, int screenDensity) { mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 3); mVirtualDisplay = mMediaProjection.createVirtualDisplay(LOG_TAG,