我正在使用此代码录制前置摄像头的视频,并在表面视图中显示预览:
public class MatchActivity extends Activity implements SurfaceHolder.Callback {
private static final String LOG_TAG = MainActivity.class.getCanonicalName();
View myButton;
MediaRecorder mediaRecorder;
SurfaceHolder surfaceHolder;
boolean recording;
TextView prepareid;
CountDownTimer countDownTimer;
String pathOfVideo;
TextView textmode;
ImageView imagemode;
boolean isRunning = false;
String PIC;
int ID;
operations op = new operations();
final boolean camerastate = op.checkcamera(getBaseContext());
private TextView mTimer;
private Camera mCamera;
private Button.OnClickListener BackToMainL = new Button.OnClickListener() {
@Override
public void onClick(View v) {
op.suoundeffect(v, getBaseContext());
op.buttoneffect(v);
new SweetAlertDialog(MatchActivity.this, SweetAlertDialog.ERROR_TYPE)
.setTitleText("برای خروج مطمئن هستین ؟")
.setConfirmText("بله")
.setCancelText("نه ، ادامه بدیم")
.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
@Override
public void onClick(SweetAlertDialog sDialog) {
if (camerastate)
stopvideo();
countDownTimer.cancel();
Global.audioplay = true;
Global.flaginapp = false;
sDialog.dismissWithAnimation();
finish();
}
})
.show();
}
};
private Button.OnClickListener CorrectAnswer = new Button.OnClickListener() {
@Override
public void onClick(View v) {
op.suoundeffect(v, getBaseContext());
op.buttoneffect(v);
countDownTimer.cancel();
if (camerastate)
stopvideo();
Intent intent = new Intent(MatchActivity.this, ResultPage.class);
Bundle b = new Bundle();
Global.flaginapp = true;
b.putString("PATH", pathOfVideo);
b.putString("PIC", PIC);
b.putInt("Answer", 1);
b.putInt("ID", ID);
b.putString("Word", textmode.getText().toString());
intent.putExtras(b);
startActivity(intent);
Global.audioplay = true;
Global.flaginapp = false;
finish();
}
};
private Button.OnClickListener StartVideo
= new Button.OnClickListener() {
@Override
public void onClick(final View arg0) {
myButton.setVisibility(View.GONE);
prepareid.setVisibility(View.GONE);
countDownTimer = new CountDownTimer(60 * 1000, 1000) {
@Override
public void onTick(long millisUntilFinished) {
mTimer.setText(String.valueOf(millisUntilFinished / 1000) + " ثانیه ");
isRunning = true;
}
@Override
public void onFinish() {
isRunning = false;
if (camerastate)
stopvideo();
Intent intent = new Intent(MatchActivity.this, ResultPage.class);
Bundle b = new Bundle();
b.putString("PIC", PIC);
b.putString("PATH", pathOfVideo);
b.putString("Word", textmode.getText().toString());
b.putInt("Answer", 0);
b.putInt("ID", ID);
intent.putExtras(b);
startActivity(intent);
Global.audioplay = true;
Global.flaginapp = false;
finish();
}
};
startvideo();
}
};
public static Camera openFrontalCamera() {
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
Camera.getCameraInfo(i, cameraInfo);
if (Camera.CameraInfo.CAMERA_FACING_FRONT == cameraInfo.facing) {
return Camera.open(i);
}
}
return Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
new SweetAlertDialog(MatchActivity.this, SweetAlertDialog.ERROR_TYPE)
.setTitleText("برای خروج مطمئن هستین ؟")
.setConfirmText("بله")
.setCancelText("نه ، ادامه بدیم")
.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
@Override
public void onClick(SweetAlertDialog sDialog) {
sDialog.dismissWithAnimation();
if (isRunning) {
if (camerastate) {
stopvideo();
}
countDownTimer.cancel();
}
finish();
}
})
.show();
}
return false;
}
@Override
protected void attachBaseContext(Context newBase) {
super.attachBaseContext(CalligraphyContextWrapper.wrap(newBase));
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.activity_match);
SurfaceView myVideoView = (SurfaceView) findViewById(R.id.surface);
op.Localize();
recording = false;
mCamera = openFrontalCamera();
mediaRecorder = new MediaRecorder();
mediaRecorder.setCamera(mCamera);
pathOfVideo = initMediaRecorder();
surfaceHolder = myVideoView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
if (mCamera != null) {
//continue flow
} else {
Toast.makeText(MatchActivity.this, "Camera Not Availble", Toast.LENGTH_LONG).show();
}
myButton = (View) findViewById(R.id.Prepare);
myButton.setOnClickListener(StartVideo);
ImageView BacktoMain = (ImageView) findViewById(R.id.cancelgame);
BacktoMain.setOnClickListener(BackToMainL);
ImageView CorecctAnswer = (ImageView) findViewById(R.id.correctanswer);
CorecctAnswer.setOnClickListener(CorrectAnswer);
textmode = (TextView) findViewById(R.id.textmode);
imagemode = (ImageView) findViewById(R.id.picturemode);
Intent intent = getIntent();
PIC = intent.getStringExtra("PIC");
ID = intent.getIntExtra("ID", 0);
if (PIC.equals("TRUE")) {
textmode.setVisibility(View.GONE);
} else {
imagemode.setVisibility(View.GONE);
}
final String[] result = new String[1];
API api = RestAdapter.createAPI();
Call<CallBackWord> callbackCall = api.GetWord(ID, PIC);
callbackCall.enqueue(new Callback<CallBackWord>() {
@Override
public void onResponse(Call<CallBackWord> call, Response<CallBackWord> response) {
CallBackWord resp = response.body();
result[0] = resp.name;
if (PIC.equals("TRUE")) {
Picasso.with(getBaseContext()).load(result[0]).into(imagemode);
} else {
textmode.setText(result[0]);
}
}
@Override
public void onFailure(Call<CallBackWord> call, Throwable t) {
Toast.makeText(MatchActivity.this, "لطفا از اتصال اینترنت خود مطمئن شوید." + t, Toast.LENGTH_LONG).show();
Intent intent = new Intent(MatchActivity.this, MainActivity.class);
Global.flaginapp = true;
startActivity(intent);
finish();
}
});
prepareid = (TextView) findViewById(R.id.prepareid);
mTimer = (TextView) findViewById(R.id.timer);
if (ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MatchActivity.this, new String[]{android.Manifest.permission.CAMERA}, 50);
}
}
public void stopvideo() {
recording = false;
try {
mediaRecorder.stop();
mediaRecorder.reset();
finish();
} catch (Exception e) {
Log.e(LOG_TAG, "Failed to stop recorder", e);
}
mediaRecorder.release();
mediaRecorder = null;
if (mCamera != null) {
mCamera.lock();
mCamera.release();
mCamera = null;
}
}
public void startvideo() {
mCamera.unlock();
countDownTimer.start();
mediaRecorder.start();
recording = true;
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (mCamera != null) {
Camera.Parameters params = mCamera.getParameters();
mCamera.setParameters(params);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
}
prepareMediaRecorder();
}
@Override
public void surfaceDestroyed(SurfaceHolder arg0) {
}
private String initMediaRecorder() {
mediaRecorder.setCamera(mCamera);
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.MPEG_4_SP);
CamcorderProfile camcorderProfile = CamcorderProfile.get(Camera.CameraInfo.CAMERA_FACING_FRONT, CamcorderProfile.QUALITY_HIGH); //get your own profile
Camera.Parameters parameters = mCamera.getParameters();
parameters.setPreviewSize(camcorderProfile.videoFrameWidth, camcorderProfile.videoFrameHeight);
mCamera.setParameters(parameters);
File file = new File(getExternalFilesDir(Environment.DIRECTORY_MOVIES), "hadskalme" + System.currentTimeMillis() + ".mp4");
if (file.exists()) {
file.delete();
}
mediaRecorder.setOutputFile(file.getAbsolutePath());
mediaRecorder.setMaxDuration(90000); // Set max duration 90 sec.
mediaRecorder.setMaxFileSize(15000000); // Set max file size 15M
return String.valueOf(file.getAbsolutePath());
}
private void prepareMediaRecorder() {
mediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
try {
mediaRecorder.prepare();
} catch (IllegalStateException | IOException e) {
Log.e(LOG_TAG, " to prepare recorder", e);
}
}
@Override
public void onPause() {
super.onPause();
if (!Global.flaginapp) {
stopAudio();
Global.audioplay = false;
} else {
Global.flaginapp = false;
Global.audioplay = true;
}
}
@Override
public void onResume() {
super.onResume();
Shared.init(getBaseContext());
String background = Shared.read("backgroundmusic", null);
if (Objects.equals(background, "okay") && !Global.audioplay) {
Global.audioplay = true;
playAudio();
}
}
public void playAudio() {
Intent objIntent = new Intent(this, PlayAudio.class);
startService(objIntent);
}
public void stopAudio() {
Intent objIntent = new Intent(this, PlayAudio.class);
stopService(objIntent);
}
}
但在某些设备(+500设备)下面,崩溃报告给我:
lang.java.IllegalStateException
at media.android.MediaRecorder._start(Native Method)
at media.android.MediaRecorder.start(MediaRecorder.java:944)
at hadskalme.hiup.ir.MatchActivity.startvideo(MatchActivity.java:286)
at hadskalme.hiup.ir.MatchActivity$3.onClick(MatchActivity.java:140)
at view.android.View.performClick(View.java:5721)
at view.android.View$PerformClick.run(View.java:22620)
at os.android.Handler.handleCallback(Handler.java:739)
at os.android.Handler.dispatchMessage(Handler.java:95)
at os.android.Looper.loop(Looper.java:148)
at app.android.ActivityThread.main(ActivityThread.java:7409)
at reflect.lang.java.Method.invoke(Native Method)
at os.internal.android.com.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
at os.internal.android.com.ZygoteInit.main(ZygoteInit.java:1120)
**并且此错误:**
lang.java.NullPointerException
at hadskalme.hiup.ir.MatchActivity.stopvideo(MatchActivity.java:274)
at hadskalme.hiup.ir.MatchActivity$4.onClick(MatchActivity.java:168)
at SweetAlert.pedant.cn.SweetAlertDialog.onClick(SweetAlertDialog.java:372)
at view.android.View.performClick(View.java:4463)
at view.android.View$PerformClick.run(View.java:18770)
at os.android.Handler.handleCallback(Handler.java:808)
at os.android.Handler.dispatchMessage(Handler.java:103)
at os.android.Looper.loop(Looper.java:193)
at app.android.ActivityThread.main(ActivityThread.java:5292)
at reflect.lang.java.Method.invokeNative(Native Method)
at reflect.lang.java.Method.invoke(Method.java:515)
at os.internal.android.com.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at os.internal.android.com.ZygoteInit.main(ZygoteInit.java:640)
at system.dalvik.NativeStart.main(Native Method)
此错误超过1000台设备:
UnknownException
at hardware.android.Camera.native_setup(Native Method)
at hardware.android.Camera.<init>(Camera.java:469)
at hardware.android.Camera.open(Camera.java:424)
at hadskalme.hiup.ir.MatchActivity.openFrontalCamera(MatchActivity.java:149)
at hadskalme.hiup.ir.MatchActivity.onCreate(MatchActivity.java:194)
at app.android.Activity.performCreate(Activity.java:5264)
at app.android.Instrumentation.callActivityOnCreate(Instrumentation.java:1088)
at app.android.ActivityThread.performLaunchActivity(ActivityThread.java:2302)
at app.android.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
at app.android.ActivityThread.access$800(ActivityThread.java:151)
at app.android.ActivityThread$H.handleMessage(ActivityThread.java:1321)
at os.android.Handler.dispatchMessage(Handler.java:110)
at os.android.Looper.loop(Looper.java:193)
at app.android.ActivityThread.main(ActivityThread.java:5292)
at reflect.lang.java.Method.invokeNative(Native Method)
at reflect.lang.java.Method.invoke(Method.java:515)
at os.internal.android.com.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at os.internal.android.com.ZygoteInit.main(ZygoteInit.java:640)
at system.dalvik.NativeStart.main(Native Method)
lang.java.RuntimeException: (Unable to start activity ComponentInfo{ir.hiup.hadskalme/ir.hiup.hadskalme.MatchActivity}: java.lang.RuntimeException: Fail to connect to camera service)
at app.android.ActivityThread.performLaunchActivity(ActivityThread.java:2338)
at app.android.ActivityThread.handleLaunchActivity(ActivityThread.java:2390)
at app.android.ActivityThread.access$800(ActivityThread.java:151)
at app.android.ActivityThread$H.handleMessage(ActivityThread.java:1321)
at os.android.Handler.dispatchMessage(Handler.java:110)
at os.android.Looper.loop(Looper.java:193)
at app.android.ActivityThread.main(ActivityThread.java:5292)
at reflect.lang.java.Method.invokeNative(Native Method)
at reflect.lang.java.Method.invoke(Method.java:515)
at os.internal.android.com.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:824)
at os.internal.android.com.ZygoteInit.main(ZygoteInit.java:640)
at system.dalvik.NativeStart.main(Native Method)
我该如何解决这个问题? (此错误出现在不同的设备和不同的Android版本) 谢谢你的时间和回答。