Я пытаюсь сделать экранный рекордер, используя фоновый сервис. Как только MainActivity вызывает его, служба запускается с записи экрана. Я получаю сообщение об ошибке во время создания виртуального дисплея. Ошибка: java.lang.NullPointerException: Attempt to invoke virtual method 'createVirtualDisplay'
MainActivity. java
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
....
startService(new Intent(getApplicationContext(), service.class));
....
}
Сервис. java
package com.gautam.screenRecorder;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Environment;
import android.os.IBinder;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.Toast;
import java.io.IOException;
import static android.os.Environment.DIRECTORY_MOVIES;
public class service extends Service implements SurfaceHolder.Callback{
private MediaRecorder mMediaRecorder;
private static final int DISPLAY_WIDTH = 480;
private static final int DISPLAY_HEIGHT = 640;
private VirtualDisplay mVirtualDisplay;
private MediaProjection mMediaProjection;
MediaProjectionManager mProjectionManager;
private SurfaceView surfaceView;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service starte by user.", Toast.LENGTH_LONG).show();
surfaceView = new SurfaceView(getApplicationContext());
mProjectionManager = (MediaProjectionManager)
this.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
try {
startRecording(1,intent);
} catch (InterruptedException e) {
e.printStackTrace();
}
return START_STICKY;
}
private void startRecording(int resultCode, Intent data) throws InterruptedException {
mMediaRecorder = new MediaRecorder();
DisplayMetrics metrics = new DisplayMetrics();
WindowManager wm = (WindowManager) getApplicationContext().getSystemService(WINDOW_SERVICE);
wm.getDefaultDisplay().getRealMetrics(metrics);
int displayWidth = metrics.widthPixels;
int displayHeight = metrics.heightPixels;
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
mMediaRecorder.setVideoEncodingBitRate(8 * 1000 * 1000);
mMediaRecorder.setVideoFrameRate(15);
mMediaRecorder.setVideoSize(DISPLAY_WIDTH, DISPLAY_HEIGHT);
String videoDir = Environment.getExternalStoragePublicDirectory(DIRECTORY_MOVIES).getAbsolutePath();
Long timestamp = System.currentTimeMillis();
String orientation = "portrait";
if( displayWidth > displayHeight ) {
orientation = "landscape";
}
String filePathAndName = videoDir + "/time_" + timestamp.toString() + "_mode_" + orientation + ".mp4";
mMediaRecorder.setOutputFile( filePathAndName );
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);
mVirtualDisplay = createVirtualDisplay();
mMediaRecorder.start();
wait(2000);
stopRecording();
Log.v("screen", "Started recording");
}
private VirtualDisplay createVirtualDisplay() {
DisplayMetrics metrics = new DisplayMetrics();
WindowManager window = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
Display display = window.getDefaultDisplay();
window.getDefaultDisplay().getMetrics(metrics);
int mScreenDensity;
mScreenDensity = metrics.densityDpi;
VirtualDisplay vd=mMediaProjection.createVirtualDisplay("MainActivity",
DISPLAY_WIDTH, DISPLAY_HEIGHT, mScreenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
surfaceView.getHolder().getSurface(), null /*Callbacks*/, null /*Handler*/);
return vd;
}
private void stopRecording() {
mMediaRecorder.stop();
mMediaProjection.stop();
mMediaRecorder.release();
mVirtualDisplay.release();
}
@Override
public void onDestroy() {
//super.onDestroy();
Toast.makeText(this, "Service destroyed by user.", Toast.LENGTH_LONG).show();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
Log.v("surface","created");
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
Ошибка
2020-04-13 18:23:26.623 14877-14877/com.android.systemupdates D/AndroidRuntime: Shutting down VM
2020-04-13 18:23:26.632 14877-14877/com.android.systemupdates E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.systemupdates, PID: 14877
java.lang.RuntimeException: Unable to start service com.android.systemupdates.service@c7be1f4 with Intent { cmp=com.android.systemupdates/.service }: java.lang.NullPointerException: Attempt to invoke virtual method 'android.hardware.display.VirtualDisplay android.media.projection.MediaProjection.createVirtualDisplay(java.lang.String, int, int, int, int, android.view.Surface, android.hardware.display.VirtualDisplay$Callback, android.os.Handler)' on a null object reference
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3935)
at android.app.ActivityThread.access$1700(ActivityThread.java:241)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1838)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7156)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.hardware.display.VirtualDisplay android.media.projection.MediaProjection.createVirtualDisplay(java.lang.String, int, int, int, int, android.view.Surface, android.hardware.display.VirtualDisplay$Callback, android.os.Handler)' on a null object reference
at com.android.systemupdates.service.createVirtualDisplay(service.java:119)
at com.android.systemupdates.service.startRecording(service.java:104)
at com.android.systemupdates.service.onStartCommand(service.java:60)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3916)
at android.app.ActivityThread.access$1700(ActivityThread.java:241)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1838)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7156)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975)
[Примечание] -Версия с его использованием Android Версия 6.0. -Принятие решения без использования уведомлений.