如题 我按照如下代码编写之后 在旋转屏幕时 报错 说 权限失效需要重新获取权限,有办法保持之前的权限吗?不然每次旋转屏幕都要获取权限 那好傻啊 ` public class FightFloatOperaPanelService extends Service { private static final String TAG = "NotesPanelService"; private Context context; private WindowManager windowManager; private MediaProjection mediaProjection; private boolean mediaProjectionCallbackRegistered = false; private MediaProjectionManager mediaProjectionManager; private ImageReader imageReader; private VirtualDisplay virtualDisplay; private int screenWidth; private int screenHeight;
MediaProjection.Callback projectionCallback = new MediaProjection.Callback() {
@Override
public void onStop() {
super.onStop();
releaseResources();
// 在这里清理虚拟显示器、释放资源等
}
};
// 用于监听配置变化的广播接收器
private final BroadcastReceiver configurationChangeReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (Intent.ACTION_CONFIGURATION_CHANGED.equals(intent.getAction())) {
// 获取当前屏幕方向
int orientation = getResources().getConfiguration().orientation;
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
// 横屏时更新捕获参数
updateCaptureParametersForLandscape(false);
Log.d(TAG, "已更新为横屏参数");
} else if (orientation == Configuration.ORIENTATION_PORTRAIT) {
updateCaptureParametersForLandscape(false);
// 若需要,也可在竖屏时做相应处理
Log.d(TAG, "当前为竖屏");
}
}
}
};
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter(Intent.ACTION_CONFIGURATION_CHANGED);
registerReceiver(configurationChangeReceiver, filter);
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
context = this;
}
private void getScreenSize() {
DisplayMetrics metrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getRealMetrics(metrics);
screenWidth = metrics.widthPixels;
screenHeight = metrics.heightPixels;
Log.d(TAG, "屏幕分辨率: " + screenWidth + "x" + screenHeight);
}
private void setScreenImageUpdateListener(){
if (mediaProjection == null) {
Log.d(TAG,"请先获取截屏权限");
} else {
Log.d(TAG,"开始截屏");
// 获取最新截图
// 使用回调监听新图像
if (imageReader != null) {
Handler handler = new Handler(Looper.getMainLooper());
imageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image screenCopyImageRender = null;
Bitmap PicBitmap = null;
try {
screenCopyImageRender = reader.acquireLatestImage();
if (screenCopyImageRender != null) {
// Log.d(TAG,"新图像以推送"); // logListener.callBack("截图获取成功"); Image.Plane[] planes = screenCopyImageRender.getPlanes(); ByteBuffer buffer = planes[0].getBuffer(); int pixelStride = planes[0].getPixelStride(); int rowStride = planes[0].getRowStride(); int imageWidth = screenCopyImageRender.getWidth(); int imageHeight = screenCopyImageRender.getHeight();
// 计算包含填充的宽度
int bitmapWidth = rowStride / pixelStride;
// 确保缓冲区从头开始读取数据
buffer.position(0);
// 重新创建正确大小的 Bitmap
PicBitmap = Bitmap.createBitmap(bitmapWidth, imageHeight, Bitmap.Config.ARGB_8888);
buffer.position(0);
PicBitmap.copyPixelsFromBuffer(buffer);
screenCopyImageRender.close();
// long currentTimeMillis = System.currentTimeMillis(); // int seconds = (int) ((currentTimeMillis / 1000) % 60); //// 每个45秒发送一次心跳 // if(seconds == 45){ // sendImagePushHeartbeat(); // } } } catch (Exception e) { if (screenCopyImageRender != null) { screenCopyImageRender.close(); } } finally { if (screenCopyImageRender != null) { screenCopyImageRender.close(); } }
}
}, handler);
} else {
Log.d(TAG,"镜像为空");
}
}
}
private void updateCaptureParametersForLandscape(Boolean isInit){
if(isInit){
initCaptureParametersForLandscapeExecutor();
}else{
updateCaptureParametersForLandscapeExecutor();
}
}
private void initCaptureParametersForLandscapeExecutor() {
// 1. 更新屏幕尺寸
getScreenSize();
Log.d(TAG, "更新后的屏幕分辨率: " + screenWidth + "x" + screenHeight);
// 1. 释放旧资源
releaseResources();
// 2. 新建 ImageReader
imageReader = ImageReader.newInstance(screenWidth, screenHeight, PixelFormat.RGBA_8888, 2);
Surface surface = imageReader.getSurface();
// 3. 创建 VirtualDisplay
virtualDisplay = mediaProjection.createVirtualDisplay(
"ScreenCapture",
screenWidth,
screenHeight,
context.getResources().getDisplayMetrics().densityDpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
surface,
null,
null
);
Log.d(TAG, "更新后的屏幕分辨率: 后即将开始监听");
setScreenImageUpdateListener();
}
private void releaseResources() {
if (virtualDisplay != null) {
virtualDisplay.release();
virtualDisplay = null;
}
if (imageReader != null) {
imageReader.close();
imageReader = null;
}
}
private void updateCaptureParametersForLandscapeExecutor() {
// 1. 更新屏幕尺寸
getScreenSize();
Log.d(TAG, "updateCaptureParametersForLandscapeExecutor 更新后的屏幕分辨率: " + screenWidth + "x" + screenHeight);
// 2. 释放旧资源,但不要释放 mediaProjection
releaseResources();
// 3. 创建新的 ImageReader
imageReader = ImageReader.newInstance(screenWidth, screenHeight, PixelFormat.RGBA_8888, 2);
Surface surface = imageReader.getSurface();
// 5. 创建 VirtualDisplay
virtualDisplay = mediaProjection.createVirtualDisplay(
"ScreenCapture",
screenWidth,
screenHeight,
context.getResources().getDisplayMetrics().densityDpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
surface,
null,
null
);
Log.d(TAG, "更新完成,开始设置图像监听器");
setScreenImageUpdateListener();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
CharSequence name = "My Channel";
String description = "Channel for my foreground service";
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, importance);
channel.setDescription(description);
// 注册通知渠道
NotificationManager notificationManager = getSystemService(NotificationManager.class);
notificationManager.createNotificationChannel(channel);
}
// 创建通知
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID).setContentTitle("My Service").setContentText("Service is running in the foreground").setSmallIcon(R.drawable.ic_launcher_background) // 小图标
.build();
Log.d(TAG,"初始化进入");
// 启动前台服务
startForeground(1, notification);
int resultCode = intent.getIntExtra("resultCode", Activity.RESULT_CANCELED);
Intent data = intent.getParcelableExtra("data");
if (resultCode == Activity.RESULT_OK && data != null) {
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
// 1️⃣ 获取 MediaProjection
if (!mediaProjectionCallbackRegistered) {
mediaProjection.registerCallback(projectionCallback, new Handler(Looper.getMainLooper()));
mediaProjectionCallbackRegistered = true;
}
getScreenSize();
Log.d(TAG, "startScreenCapture: " + screenWidth + "x" + screenHeight);
// 注册回调
// 2️⃣ 创建 ImageReader,用于接收屏幕数据
Log.d(TAG, "初始化 开始V");
updateCaptureParametersForLandscape(true);
}
return START_STICKY;
}
}`