アプリを Google Play にアップロードしましたが、他のデバイスではビデオ録画が機能しないことに気付きました。私のデバイスでは問題なく動作します。それでデバッグを行ったところ、「ディレクトリの作成に失敗しました」というエラーメッセージが表示されることがわかりました。これは、デバイスにSDカードが含まれていないためであることに気付きました。SD カードを別のデバイスに移動したところ、カメラが録画を開始したように見えますが、[停止] をクリックするとアプリがクラッシュします。
私のデバイス android 4.0.3 LG OPTIMUS (仕事)
HTC 4.0.3 で (動作しません)
主な活動 :
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.media.CamcorderProfile;
import android.media.MediaRecorder;
import android.net.Uri;
import android.os.Bundle;
import android.os.Debug;
import android.os.Environment;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.util.Log;
import android.view.Menu;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.MediaController;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;
public class MainActivity extends Activity {
private Button initBtn = null ;
private Button startBtn = null ;
private Button stopBtn = null ;
private Button playBtn = null ;
private Button stopPlayBtn = null ;
private TextView recordingMSG = null ;
private VideoView videoView = null ;
static String TAG = "MainActivity" ;
private String outputFileName ;
private Camera mCamera;
private SurfaceView mPreview;
private MediaRecorder mMediaRecorder;
public static final int MEDIA_TYPE_VIDEO = 2;
public static final int MEDIA_TYPE_IMAGE = 1;
private boolean isRecording = false;
private FrameLayout preview = null ;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initBtn = (Button) findViewById(R.id.initBtn) ;
startBtn = (Button) findViewById(R.id.startBtn) ;
stopBtn = (Button) findViewById(R.id.stopBtn) ;
playBtn = (Button) findViewById(R.id.playBtn) ;
stopPlayBtn = (Button) findViewById(R.id.stopPlayBtn) ;
recordingMSG = (TextView) findViewById(R.id.recordingMSG) ;
if ( !checkCameraHardware(this)){
Toast.makeText(MainActivity.this, "not recognize device camera", Toast.LENGTH_SHORT).show(); //chack syntax
}
//play button can not play in the begin
playBtn.setEnabled(false);
Log.d(TAG,"end creat");
}
//if clicked on one of the button
public void ButtonTapped(View view){
int id = view.getId();
if (id == R.id.initBtn) {
Log.d(TAG, "idan initialize button") ;
initRecorder();
} else if (id == R.id.startBtn) {
beginRecording();
} else if (id == R.id.stopBtn) {
stopRecording();
} else if (id == R.id.playBtn) {
playRecording();
} else if (id == R.id.stopPlayBtn) {
stopPlayback();
}}
private void stopPlayback() {
}
private void playRecording() {
PuseAndRelease(); //try
Intent intent = new Intent(this, StartPlay.class);
intent.putExtra("outputFileName",outputFileName);
startActivity(intent);
finish();
StartAndContinuCamera(); //try
}
private void stopRecording() {
// TODO Auto-generated method stub
}
private void beginRecording() {
if (isRecording) {
// stop recording and release camera
mMediaRecorder.stop(); // stop the recording
releaseMediaRecorder(); // release the MediaRecorder object
mCamera.lock(); // take camera access back from MediaRecorder
// inform the user that recording has stopped
//setCaptureButtonText("Capture");
startBtn.setText("start");
isRecording = false;
playBtn.setEnabled(true);
} else {
// initialize video camera
if (prepareVideoRecorder()) {
// Camera is available and unlocked, MediaRecorder is prepared,
// now you can start recording
mMediaRecorder.start();
Log.d(TAG,"MEDIA RECORDER START");
// inform the user that recording has started
//setCaptureButtonText("Stop");
startBtn.setText("stop");
isRecording = true;
} else {
// prepare didn't work, release the camera
releaseMediaRecorder();
// inform user
}
}
}
private void initRecorder() {
}
private boolean prepareVideoRecorder(){
//mCamera = getCameraInstance();
mMediaRecorder = new MediaRecorder();
// Step 1: Unlock and set camera to MediaRecorder
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
// Step 2: Set sources
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
// Step 3: Set a CamcorderProfile (requires API Level 8 or higher)
mMediaRecorder.setProfile(CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH));
// Step 4: Set output file
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO).toString());
outputFileName = getOutputMediaFile(MEDIA_TYPE_VIDEO).toString() ;
// Step 5: Set the preview output
mMediaRecorder.setPreviewDisplay(mPreview.getHolder().getSurface());
// Step 6: Prepare configured MediaRecorder
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d(TAG, "IllegalStateException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
} catch (IOException e) {
Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
return true;
}
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
@Override
protected void onPause() {
super.onPause();
PuseAndRelease();
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
StartAndContinuCamera();
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
public void StartAndContinuCamera(){
// Create an instance of Camera
mCamera = getCameraInstance();
Log.d(TAG,"camera on resume"+ " " + mCamera );
// Create our Preview view and set it as the content of our activity.
mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
Log.d(TAG,"camera on resume"+ " " + mCamera );
}
public void PuseAndRelease (){
releaseMediaRecorder(); // if you are using MediaRecorder, release it first
releaseCamera(); // release the camera immediately on pause event
Log.d(TAG,"camera onpause" + mCamera );
}
private void releaseMediaRecorder(){
if (mMediaRecorder != null) {
mMediaRecorder.reset(); // clear recorder configuration
mMediaRecorder.release(); // release the recorder object
Log.d(TAG,"release the recorder") ;
mMediaRecorder = null;
mCamera.lock(); // lock camera for later use
Log.d(TAG," CAMERA lock") ;
}
}
private void releaseCamera(){
if (mCamera != null){
mCamera.setPreviewCallback(null);
mPreview.getHolder().removeCallback((Callback) mPreview);//try
mCamera.release(); // release the camera for other applications
Log.d(TAG,"camera release");
mCamera = null;
}
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
}
return c; // returns null if camera is unavailable
}
private boolean checkCameraHardware(Context context) {
Log.d(TAG,"test") ;
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
} else {
// no camera on this device
return false;
}
}
}
logcat :
05-31 13:34:04.449: V/MediaRecorderJNI(19487): stop
05-31 13:34:04.449: V/MediaRecorderJNI(19487): getMediaRecorder E
05-31 13:34:04.499: V/MediaRecorderJNI(19487): JNIMediaRecorderListener::notify
05-31 13:34:04.499: V/MediaRecorderJNI(19487): notify msgType 0x65, ext1 0x100003E8
05-31 13:34:04.659: E/MediaRecorder(19487): stop failed: -1007
05-31 13:34:04.659: V/MediaRecorderJNI(19487): process_media_recorder_call
05-31 13:34:04.659: D/AndroidRuntime(19487): Shutting down VM
05-31 13:34:04.659: W/dalvikvm(19487): threadid=1: thread exiting with uncaught exception (group=0x40af7228)
05-31 13:34:04.669: E/AndroidRuntime(19487): FATAL EXCEPTION: main
05-31 13:34:04.669: E/AndroidRuntime(19487): java.lang.IllegalStateException: Could not execute method of the activity
05-31 13:34:04.669: E/AndroidRuntime(19487): at android.view.View$1.onClick(View.java:3071)
05-31 13:34:04.669: E/AndroidRuntime(19487): at android.view.View.performClick(View.java:3538)
05-31 13:34:04.669: E/AndroidRuntime(19487): at android.view.View$PerformClick.run(View.java:14330)
05-31 13:34:04.669: E/AndroidRuntime(19487): at android.os.Handler.handleCallback(Handler.java:608)
05-31 13:34:04.669: E/AndroidRuntime(19487): at android.os.Handler.dispatchMessage(Handler.java:92)
05-31 13:34:04.669: E/AndroidRuntime(19487): at android.os.Looper.loop(Looper.java:156)
05-31 13:34:04.669: E/AndroidRuntime(19487): at android.app.ActivityThread.main(ActivityThread.java:4987)
05-31 13:34:04.669: E/AndroidRuntime(19487): at java.lang.reflect.Method.invokeNative(Native Method)
05-31 13:34:04.669: E/AndroidRuntime(19487): at java.lang.reflect.Method.invoke(Method.java:511)
05-31 13:34:04.669: E/AndroidRuntime(19487): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
05-31 13:34:04.669: E/AndroidRuntime(19487): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
05-31 13:34:04.669: E/AndroidRuntime(19487): at dalvik.system.NativeStart.main(Native Method)
05-31 13:34:04.669: E/AndroidRuntime(19487): Caused by: java.lang.reflect.InvocationTargetException
05-31 13:34:04.669: E/AndroidRuntime(19487): at java.lang.reflect.Method.invokeNative(Native Method)
05-31 13:34:04.669: E/AndroidRuntime(19487): at java.lang.reflect.Method.invoke(Method.java:511)
05-31 13:34:04.669: E/AndroidRuntime(19487): at android.view.View$1.onClick(View.java:3066)
05-31 13:34:04.669: E/AndroidRuntime(19487): ... 11 more
05-31 13:34:04.669: E/AndroidRuntime(19487): Caused by: java.lang.RuntimeException: stop failed.
05-31 13:34:04.669: E/AndroidRuntime(19487): at android.media.MediaRecorder.stop(Native Method)
05-31 13:34:04.669: E/AndroidRuntime(19487): at com.example.your_voice.MainActivity.beginRecording(MainActivity.java:141)
05-31 13:34:04.669: E/AndroidRuntime(19487): at com.example.your_voice.MainActivity.ButtonTapped(MainActivity.java:93)
05-31 13:34:04.669: E/AndroidRuntime(19487): ... 14 more