このように機能するアプリを作成しました。ユーザーは、ギャラリーから選択するか、その時点でのみビデオをキャプチャして、ビデオを選択するように求められます。
このために、私は次のようにコードを書きました:-
public class VideoQuestionActivity extends Activity implements View.OnClickListener, Callback
{
/ Here I have declared my object like Button etc so omitting this from code /
private Dialog myDialog;
private Dialog videoDialog;
private File videoFolder;
private String videoFileName;
private String selectedVideoPath;
private Uri selectedVideoURI;
private Bitmap bMap;
private SurfaceView surfaceView;
private SurfaceHolder surfaceHolder;
private MediaPlayer mediaPlayer;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.question);
mCurrentSurvey =(Survey)getIntent().getSerializableExtra("CurrentSurvey");
mCurrentQuestion =(Question)getIntent().getSerializableExtra("CurrentQuestion");
Initialize();
}
public void Initialize()
{
// This function initializes the objects like buttons, surface view media player so also omitting this just to keep the code simple
}
@Override
public void onClick(View v)
{
// TODO Auto-generated method stub
switch(v.getId())
{
case R.id.btnQuestionTypeAction:
getVideo();
break;
case R.id.btn_live:
Intent liveIntent= new Intent( android.provider.MediaStore.ACTION_VIDEO_CAPTURE);
startActivityForResult(liveIntent,RESULT_CAPTURE_VIDEO);
myDialog.dismiss();
break;
case R.id.btn_gallery:
Intent galIntent = new Intent(Intent.ACTION_GET_CONTENT);
galIntent.setType("video/*");
startActivityForResult(galIntent,RESULT_LOAD_VIDEO);
myDialog.dismiss();
break;
case R.id.btnCancel:
videoDialog.dismiss();
break;
case R.id.btnOk:
videoDialog.dismiss();
boolean sdcardAvailable = sdcardState();
if(sdcardAvailable)
{
videoFolder =new File(userFolderPath+"/Videos");
if(!videoFolder.exists())
{
videoFolder.mkdir();
}
CopyFile(selectedVideoPath,videoFolder.toString());
try {
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
mediaPlayer.setDisplay(surfaceHolder);
mediaPlayer.setDataSource(getApplicationContext(), selectedVideoURI);
mediaPlayer.prepare();
mediaPlayer.start();
}
catch (IllegalArgumentException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (SecurityException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IllegalStateException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
Toast.makeText(getApplicationContext(),selectedVideoPath , Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(),"SD Card not available", Toast.LENGTH_LONG).show();
}
break;
}
}
public void startIntentForController()
{
// this function calls another activity so omitting this from code.
}
@Override
public void onBackPressed() {
}
private void getVideo()
{
boolean sdcardAvailable = sdcardState();
if(sdcardAvailable)
{
extStorageDirectory= Environment.getExternalStorageDirectory().getAbsolutePath().toString();
userFolderPath=extStorageDirectory+"/User";
File userFolder=new File(userFolderPath);
if(!(userFolder.exists()))
userFolder.mkdir();
dialogShow();
}
else
{
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("SD Card unavailable.....")
.setCancelable(false)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
public boolean sdcardState()
{
sdcardState = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(sdcardState))
{
// We can read and write the media
return true;
}
else
{
// We can't read and write the media
return false;
}
}
public void dialogShow()
{
myDialog = new Dialog(VideoQuestionActivity.this);
myDialog.setContentView(R.layout.picturecustomdialog);
//Initializing the UI component of custom dialog
TextView title = (TextView) myDialog.findViewById(R.id.lbl_photo);
TextView subTitle = (TextView) myDialog.findViewById(R.id.lbl_source);
Button gallery=(Button) myDialog.findViewById(R.id.btn_gallery);
Button live=(Button) myDialog.findViewById(R.id.btn_live);
//Setting the value to each UI component of custom dialog
title.setText("Attach a Video");
subTitle.setText("Choose a source");
gallery.setText("Gallery");
live.setText("Capture");
myDialog.show();
gallery.setOnClickListener(this);
live.setOnClickListener(this);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RESULT_LOAD_VIDEO && resultCode == RESULT_OK && data != null)
{
myDialog.dismiss();
Uri myVideo;
myVideo= data.getData();
selectedVideoURI=myVideo;
selectedVideoPath= getRealPathFromURI(myVideo);
videoDialogshow();
}
if (requestCode == RESULT_LOAD_VIDEO && resultCode == RESULT_CANCELED && data!= null)
{
finish();
}
if (requestCode == RESULT_CAPTURE_VIDEO && resultCode == RESULT_OK)
{
myDialog.dismiss();
Uri myVideo;
myVideo= data.getData();
selectedVideoURI=myVideo;
selectedVideoPath= (getRealPathFromURI(myVideo));
videoDialogshow();
}
if (requestCode == RESULT_CAPTURE_VIDEO && resultCode == RESULT_CANCELED )
{
finish();
}
if(resultCode==RESULT_CANCELED)
{
mCurrentSurvey.setSurveyQuestionIndex(mCurrentSurvey.getSurveyQuestionIndex());
startIntentForController();
}
}
public String getRealPathFromURI(Uri contentUri)
{
String imgAbsolutePath;
String[] proj = { MediaStore.Video.Media.DATA };
Cursor cursor = managedQuery(contentUri, proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Video.Media.DATA);
cursor.moveToFirst();
imgAbsolutePath=cursor.getString(column_index);
return imgAbsolutePath;
}
public void videoDialogshow()
{
videoDialog = new Dialog(VideoQuestionActivity.this);
videoDialog.setContentView(R.layout.mediacontaincustomdialog);
//Initializing the UI component of custom dialog
Button btnVideoCancel = (Button) videoDialog.findViewById(R.id.btnCancel);
Button btnVideoOk = (Button) videoDialog.findViewById(R.id.btnOk);
btnVideoCancel.setBackgroundResource(R.drawable.img_wrong);
btnVideoOk.setBackgroundResource(R.drawable.img_right);
//Setting the value to each UI component of custom dialog
LinearLayout llMediaView =(LinearLayout) videoDialog.findViewById(R.id.llMediaView);
final VideoView mediaVideoView=new VideoView(this);
mediaVideoView.setVideoURI(selectedVideoURI);
mediaVideoView.setMediaController(new MediaController(this));
mediaVideoView.requestFocus();
llMediaView.addView(mediaVideoView);
videoDialog.show();
bMap = ThumbnailUtils.createVideoThumbnail(selectedVideoPath, MediaStore.Video.Thumbnails.MICRO_KIND);
mediaVideoView.setBackgroundDrawable(new BitmapDrawable(getResources(), bMap));
mediaVideoView.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
mediaVideoView.start();
}
});
btnVideoCancel.setOnClickListener(this);
btnVideoOk.setOnClickListener(this);
}
public boolean CopyFile(String srcPath,String destPath)
{
//this function copies the file to a custom location in my sd card so also omitting this
}
@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
mediaPlayer.reset();
}
@Override
protected void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
mediaPlayer.release();
}
}
現在、このコードは私の電話では正常に動作しますが、向きを変更するとアプリケーションがクラッシュします。
また、私のマニフェストでは、構成変更属性を追加しました:-
android:configChanges="keyboardHidden|orientation"
、私は私のログキャットを入れています、
07-05 20:26:09.203: E/AndroidRuntime(1907): FATAL EXCEPTION: main
07-05 20:26:09.203: E/AndroidRuntime(1907): java.lang.IllegalStateException
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.media.MediaPlayer._reset(Native Method)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.media.MediaPlayer.reset(MediaPlayer.java:1066)
07-05 20:26:09.203: E/AndroidRuntime(1907): at com.optimus.mobile.question.VideoQuestionActivity.surfaceDestroyed(VideoQuestionActivity.java:475)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.SurfaceView.reportSurfaceDestroyed(SurfaceView.java:568)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.SurfaceView.updateWindow(SurfaceView.java:472)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.SurfaceView.onWindowVisibilityChanged(SurfaceView.java:206)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.View.dispatchDetachedFromWindow(View.java:6173)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1156)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1156)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1156)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1156)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1156)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.ViewGroup.dispatchDetachedFromWindow(ViewGroup.java:1156)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.ViewRoot.dispatchDetachedFromWindow(ViewRoot.java:1630)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.ViewRoot.doDie(ViewRoot.java:2671)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.ViewRoot.die(ViewRoot.java:2641)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:218)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.view.Window$LocalWindowManager.removeViewImmediate(Window.java:436)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3684)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.app.ActivityThread.handleRelaunchActivity(ActivityThread.java:3789)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.app.ActivityThread.access$2400(ActivityThread.java:125)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2037)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.os.Handler.dispatchMessage(Handler.java:99)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.os.Looper.loop(Looper.java:123)
07-05 20:26:09.203: E/AndroidRuntime(1907): at android.app.ActivityThread.main(ActivityThread.java:4627)
07-05 20:26:09.203: E/AndroidRuntime(1907): at java.lang.reflect.Method.invokeNative(Native Method)
07-05 20:26:09.203: E/AndroidRuntime(1907): at java.lang.reflect.Method.invoke(Method.java:521)
07-05 20:26:09.203: E/AndroidRuntime(1907): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
07-05 20:26:09.203: E/AndroidRuntime(1907): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
07-05 20:26:09.203: E/AndroidRuntime(1907): at dalvik.system.NativeStart.main(Native Method)
どうすればこれを解決できますか?