gpt4 book ai didi

java - 如何使用 MediaProjection API 从后台服务类截取屏幕截图?

转载 作者:行者123 更新时间:2023-12-05 00:16:01 27 4
gpt4 key购买 nike

在对这个主题进行了大量研究之后,虽然我找到了一些答案,但我无法理解 MediaProjection API 的工作原理。

我想从后台服务类中获取设备的屏幕截图。有没有可能做到。我有一个 MainActivity.java,它启动一个 serviceIntent 到另一个类,它是一个服务(不是 Activity )。所以我想在这个服务类中实现这个API。请帮助我

最佳答案

这是实现这一目标的棘手方法。

首先你需要创建透明背景主题。

    <style name="transparentTheme" parent="Theme.AppCompat.NoActionBar">
<item name="android:background">#00000000</item> <!-- Or any transparency or color you need -->
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@android:style/Animation</item>
<item name="android:navigationBarColor" tools:ignore="NewApi">#00000000</item>
<item name="android:statusBarColor" tools:ignore="NewApi">#00000000</item>
</style>

现在您需要在 Manifest 文件中的 ScreenShotActivity 上添加应用此主题。

  <activity
android:name=".Activities.ScreenShotActivity"
android:theme="@style/transparentTheme" />
<activity

您的 ScreenShotActivity 类。

public class ScreenShotActivity extends Activity {

private static final int videoTime = 5000;
private static final int REQUEST_CODE = 1000;
private static final int REQUEST_PERMISSION = 1000;
private static final SparseIntArray ORIENTATION = new SparseIntArray();
private MediaProjectionManager mediaProjectionManager;
private MediaProjection mediaProjection;
private VirtualDisplay virtualDisplay;
private ScreenShotActivity.MediaProjectionCallback mediaProjectionCallback;
private MediaRecorder mediaRecorder;
PostWebAPIData postWebAPIData;
private int mScreenDensity;
private static int DISPLAY_WIDTH = 720;
private static int DISPLAY_HEIGHT = 1280;

static {
ORIENTATION.append(Surface.ROTATION_0, 90);
ORIENTATION.append(Surface.ROTATION_90, 0);
ORIENTATION.append(Surface.ROTATION_180, 270);
ORIENTATION.append(Surface.ROTATION_270, 180);
}

private String screenShotUri = "";

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_screen_shot);
init();
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void init() {
//Screen tracking Code Started here..............................
DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);
mScreenDensity = metrics.densityDpi;
postWebAPIData = new PostWebAPIData();
DISPLAY_HEIGHT = metrics.heightPixels;
DISPLAY_WIDTH = metrics.widthPixels;

mediaRecorder = new MediaRecorder();
mediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
if (ContextCompat.checkSelfPermission(ScreenShotActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
+ ContextCompat.checkSelfPermission(ScreenShotActivity.this, Manifest.permission.RECORD_AUDIO)
!= PackageManager.PERMISSION_GRANTED) {
if (ActivityCompat.shouldShowRequestPermissionRationale(ScreenShotActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) ||
ActivityCompat.shouldShowRequestPermissionRationale(ScreenShotActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
} else {
ActivityCompat.requestPermissions(ScreenShotActivity.this, new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.RECORD_AUDIO
}, REQUEST_PERMISSION);
}
} else {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
toogleScreenShare();
}
}, 500);
}
}


@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void toogleScreenShare() {
initRecorder();
recordScreen();
}


public void getPathScreenShot(String filePath) {
FFmpegMediaMetadataRetriever med = new FFmpegMediaMetadataRetriever();

med.setDataSource(filePath);
Bitmap bmp = med.getFrameAtTime(2 * 1000000, FFmpegMediaMetadataRetriever.OPTION_CLOSEST);
String myPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + new StringBuilder("/screenshot").append(".bmp").toString();

File myDir = new File(myPath);
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-" + n + ".jpg";
File file = new File(myDir, fname);
Log.i(TAG, "" + myDir);
if (myDir.exists())
myDir.delete();
try {
FileOutputStream out = new FileOutputStream(myDir);
bmp.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
postScreenShot(myPath);
}


@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void recordScreen() {
if (mediaProjection == null) {
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);
} else {
virtualDisplay = createVirtualDisplay();
mediaRecorder.start();
onBackPressed();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mediaRecorder.stop();
mediaRecorder.reset();
stopRecordScreen();
destroyMediaProjection();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
getPathScreenShot(screenShotUri);
}
}, 2000);
}
}, videoTime);
}
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private VirtualDisplay createVirtualDisplay() {
return mediaProjection.createVirtualDisplay("MainActivity", DISPLAY_WIDTH, DISPLAY_HEIGHT, mScreenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
mediaRecorder.getSurface(), null, null);
}

private void initRecorder() {
try {
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);

screenShotUri = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + new StringBuilder("/screenshot").append(".mp4").toString();

mediaRecorder.setOutputFile(screenShotUri);
mediaRecorder.setVideoSize(DISPLAY_WIDTH, DISPLAY_HEIGHT);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setVideoEncodingBitRate(512 * 1000);
mediaRecorder.setVideoFrameRate(5);

int rotation = getWindowManager().getDefaultDisplay().getRotation();
int orientation = ORIENTATION.get(rotation + 90);
mediaRecorder.setOrientationHint(orientation);
mediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
Log.d("ExceptionOccured", "" + e.getMessage());
}
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode != REQUEST_CODE) {
stopService(new Intent(this, BackgroundService.class));
startService(new Intent(this, BackgroundService.class));
Toast.makeText(ScreenShotActivity.this, "Unknown Error", Toast.LENGTH_SHORT).show();
Log.d("Livetracking", "ScreenShot" + requestCode + " " + resultCode + " " + data);
return;
}
if (resultCode != RESULT_OK) {
stopService(new Intent(this, BackgroundService.class));
startService(new Intent(this, BackgroundService.class));
Toast.makeText(ScreenShotActivity.this, "Permission denied" + requestCode, Toast.LENGTH_SHORT).show();
Log.d("Livetracking", "Screenshot" + requestCode + " " + resultCode + " " + data);
return;
}
Log.d("Livetracking", "Screenshot" + requestCode + " " + resultCode + " " + data);

mediaProjectionCallback = new ScreenShotActivity.MediaProjectionCallback();
mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);
mediaProjection.registerCallback(mediaProjectionCallback, null);
virtualDisplay = createVirtualDisplay();
mediaRecorder.start();
onBackPressed();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
mediaRecorder.stop();
mediaRecorder.reset();
stopRecordScreen();
destroyMediaProjection();
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
getPathScreenShot(screenShotUri);
}
}, 2000);
}
}, videoTime);
ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
if (am != null) {
List<ActivityManager.AppTask> tasks = am.getAppTasks();
if (tasks != null && tasks.size() > 0) {
Log.d("RemovingApp", "recent");
tasks.get(0).setExcludeFromRecents(true);
}
}
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private class MediaProjectionCallback extends MediaProjection.Callback {
@Override
public void onStop() {
mediaRecorder.stop();
mediaRecorder.reset();
mediaProjection = null;
stopRecordScreen();
destroyMediaProjection();
if (mediaProjection != null) {
destroyMediaProjection();
}
super.onStop();
}
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void stopRecordScreen() {
if (virtualDisplay == null) {
virtualDisplay.release();
if (mediaProjection != null) {
destroyMediaProjection();
}
return;

}
}

@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
private void destroyMediaProjection() {
if (mediaProjection != null) {
mediaProjection.unregisterCallback(mediaProjectionCallback);
mediaProjection.stop();
mediaProjection = null;
}
}
}

在您的 list 文件中添加这些权限。

   <uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

现在魔术从这里开始,您需要像这样从您的服务中调用 ScreenShotActivity。

      Intent dialogIntent = new Intent(BackgroundService.this, ScreenShotActivity.class);
dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(dialogIntent);

关于java - 如何使用 MediaProjection API 从后台服务类截取屏幕截图?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62938965/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com