安卓10以上 增加截图专用的前台服务 避免截图异常

This commit is contained in:
TonyJiangWJ 2022-01-16 17:25:08 +08:00
parent e1009c5003
commit f602a2af6f
5 changed files with 100 additions and 5 deletions

View File

@ -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))

View File

@ -53,6 +53,11 @@
<service android:name="com.stardust.enhancedfloaty.FloatyService"
android:exported="false" tools:node="merge"/>
<!-- 截图前台服务 -->
<service android:name="com.stardust.autojs.core.image.capture.CaptureForegroundService"
android:foregroundServiceType="mediaProjection"
android:exported="false"/>
</application>
</manifest>

View File

@ -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();

View File

@ -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);
}
}

View File

@ -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,