0

我创建了一个像这样工作的应用程序,它要求用户选择一个视频,他可以通过从图库中选择或仅在当时捕获视频来完成。

为此,我编写了这样的代码:-

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"

,我把我的logcat,

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)

关于如何解决这个问题的任何想法?

4

1 回答 1

0

您需要添加一个 onConfigurationChanged() 方法。这样它会自动保存到应用程序的当前进度并在方向之间切换时保持运行。

此链接可能会对您的问题有所帮助。当我遇到同样的问题时,它对我有用。

http://developer.android.com/guide/topics/manifest/activity-element.html

于 2012-07-05T15:36:17.580 回答