jjzjj

当我在 jellybean 上的 archos 平板电脑上按下后退按钮时,Android Camera 表面 View 相机重新创建

coder 2023-12-23 原文

在我的代码中,我在单击按钮时进行了摄像头预览和视频录制,因此我的代码可以很好地进行录制和预览。

但是当我按下后退按钮时,在调用 surfaceview destroy 方法之后调用 surfaceview 创建和 surface view change 方法,所以我必须再次按下 back 按钮,此时它直接调用 surface destroy(第二次 surface create 和 surface change不被调用)

这是我的代码,任何人都可以帮助我吗?

public class VideoCapture extends Activity implements  SurfaceHolder.Callback {

public static final String LOGTAG = "VIDEOCAPTURE";
private static final int SELECT_PHOTO = 100;
private MediaRecorder recorder;
private SurfaceHolder holder;
private CamcorderProfile camcorderProfile;
private Camera camera;        

boolean recording = false;
boolean usecamera = true;
boolean previewRunning = false;
Button recorderButton,selectVideo;
long init,now,time;
Handler handler;
Runnable updater;
SimpleDateFormat df;
Camera.Parameters parameters;
String timeString, timeStamp,selectedVideoPath;


@Override
public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                        WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        setContentView(R.layout.main);
         handler = new Handler();
       df = new SimpleDateFormat("mm:ss");

        camcorderProfile = CamcorderProfile.get(CamcorderProfile.QUALITY_HIGH);
        recorderButton = (Button)findViewById(R.id.button);
        selectVideo = (Button)findViewById(R.id.videoselect);

        final TextView timerText = (TextView)findViewById(R.id.time);
        File dir = new File(Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_DCIM), "/Filme");
        if (!dir.exists()) {
            dir.mkdirs();
        }

        // Animation for blinking red dot while recording
        SurfaceView cameraView = (SurfaceView) findViewById(R.id.CameraView);

        holder = cameraView.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);      

        cameraView.setClickable(true);


        cameraView.setOnClickListener(new OnClickListener(){
            @Override
            public void onClick(View v) {
                camera.autoFocus(new AutoFocusCallback(){
                    @Override
                    public void onAutoFocus(boolean arg0, Camera arg1) {
                        //camera.takePicture(shutterCallback, rawCallback, jpegCallback);
                    }
                });
            }
        });  

        selectVideo.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub

                  Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
                  photoPickerIntent.setType("video/*");

                  startActivityForResult(photoPickerIntent, SELECT_PHOTO);  
            }
        });

        recorderButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                 if (recording) {
                     recorderButton.setBackgroundResource(R.drawable.recordbutton_background_selector);
                        recorder.stop();
                        handler.removeCallbacks(updater); // stop handler


                     // to refresh media scan on storage 
                        sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse
                                ("file://" + Environment.getExternalStorageDirectory())));

                        String filepath =Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)+File.separator+"Filme"+File.separator+"Filme_"+timeStamp+".mp4";
                        Intent i = new Intent(getBaseContext(),VideoCutActivity.class);
                          i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

                          i.putExtra("path", filepath);
                          getBaseContext().startActivity(i);
                          finish();
                         /*
                        if (usecamera) {
                                try {
                                        camera.reconnect();
                                } catch (IOException e) {
                                        e.printStackTrace();

                                }
                        }                        
                      */
                        recording = false;
                        Log.v(LOGTAG, "Recording Stopped");
                        // Let's prepareRecorder so we can record again
                       // prepareRecorder();
                } else {
                    recorderButton.setBackgroundResource(R.drawable.stopbutton_background_selector);



                        recording = true;
                        prepareRecorder();
                     //   recorder.start();
                        Log.v(LOGTAG, "Recording Started");
                }
            }
        });

        // Recording timmer 
         updater = new Runnable() {
            @Override
            public void run() {

                    now=System.currentTimeMillis();
                    time=now-init;
                    timeString  = df.format(new Date(time));
                    timerText.setText(timeString);
                    handler.postDelayed(this, 30);

            }
        };

}
   @Override
  protected void onResume() {
       super.onResume();
  Log.e("onresume", "on resume");
    // Open the default i.e. the first rear facing camera. 
}



@Override
protected void onPause() {
    super.onPause();

    // Because the Camera object is a shared resource, it's very
    // important to release it when the activity is paused.
    if (recording) {
     recorder.stop();
        recording = false;
        recorder.release();
        camera.stopPreview();
        camera.setPreviewCallback(null);
        camera.release();
        camera = null;
}
else
{
    if (camera != null) {      
        previewRunning = false;
        camera.release();
        camera = null;
    }
}}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { 
    super.onActivityResult(requestCode, resultCode, imageReturnedIntent); 

    switch(requestCode) { 
    case SELECT_PHOTO:
        if(resultCode == RESULT_OK){  
            Uri selectedImage = imageReturnedIntent.getData();
            selectedVideoPath  = getPath(selectedImage);

          Intent i = new Intent(getBaseContext(),VideoCutActivity.class);
          i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

          i.putExtra("path", selectedVideoPath);
          VideoCapture.this.startActivity(i);
          finish();

        }
    }
}

public String getPath(Uri uri) {
     String[] proj = { MediaStore.Images.Media.DATA };
        CursorLoader loader = new CursorLoader(getBaseContext(), uri, proj, null, null, null);
        Cursor cursor = loader.loadInBackground();
        int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
        cursor.moveToFirst();
        return cursor.getString(column_index);
    }


private void prepareRecorder() {
recorder = new MediaRecorder();
        recorder.setPreviewDisplay(holder.getSurface());

        if (usecamera) {
                camera.unlock();
                recorder.setCamera(camera);
        }

        recorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
        recorder.setVideoSource(MediaRecorder.VideoSource.DEFAULT);
        recorder.setProfile(camcorderProfile);


        timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        recorder.setOutputFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)+File.separator+"Filme"+File.separator+"Filme_"+timeStamp+".mp4");
        Log.v(LOGTAG, "camcorderProfile");


        try {
                recorder.prepare();
                recorder.start();
                init = System.currentTimeMillis();
                handler.post(updater);

        } catch (IllegalStateException e) {
                e.printStackTrace();
                finish();
        } catch (IOException e) {
                e.printStackTrace();
                finish();
        }
}



public void surfaceCreated(SurfaceHolder holder) {
        Log.v(LOGTAG, "surfaceCreated");

        if (usecamera) {
                camera = Camera.open();
                parameters = camera.getParameters();
                try {
                    Log.i("Capture","surface created");
                     parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                     camera.setParameters(parameters);
                        camera.setPreviewDisplay(holder);
                        camera.startPreview();
                        previewRunning = true;
                }
                catch (IOException e) {
                        Log.e(LOGTAG,e.getMessage());
                        e.printStackTrace();
                }        
        }                

}


public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        Log.v(LOGTAG, "surfaceChanged");

        if (!recording && usecamera) {

                if (previewRunning){
                    Log.e("Capture","preview is running");
                        camera.stopPreview();
                }

                try {
                    Log.e("Capture","inside try of surface changed");
                    parameters = camera.getParameters();
                    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                    parameters.setPreviewSize(camcorderProfile.videoFrameWidth, camcorderProfile.videoFrameHeight);
                    parameters.setPreviewFrameRate(camcorderProfile.videoFrameRate);

                        camera.setParameters(parameters);
                        camera.setPreviewDisplay(holder);
                        camera.startPreview();
                        previewRunning = true;
                }
                catch (IOException e) {

                        Log.e(LOGTAG,e.getMessage());
                        e.printStackTrace();
                }        

               // prepareRecorder();        
        }
}


public void surfaceDestroyed(SurfaceHolder holder) {
        Log.v(LOGTAG, "surfaceDestroyed");

        if (camera != null) {
            camera.stopPreview();
        }

        if (recording) {
            try{
            Log.e("Capture","inside recording  of surface destory");
                recorder.stop();
                recording = false;
                recorder.release();
                camera.stopPreview();
                camera.setPreviewCallback(null);
                camera.release();
                camera = null;
            }
            catch (RuntimeException e) {
                Log.d("surface destroyed", "Problem in surfaceDestroyed"); 
                e.printStackTrace();
            } 
        }

最佳答案

基于调试/聊天讨论:

  • 第一次返回时,现有的 Camera Activity 被销毁并创建了另一个。使用以下内容跟踪返回堆栈中的更改:

    adb shell dumpsys Activity | grep -i 运行

  • 不需要新的任务,所以这是无用的: i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

    显然,使用 i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP) 有帮助!

但我不确定为什么这会有所帮助。 (特别是,因为 IIUC,使用 *CLEAR_TOP,将使用堆栈上 Activity 的现有实例(使用 onNewIntent),但在这里(根据 dumpsys 的输出,创建了一个新 Activity :|)。但它适用于爱可视。

关于当我在 jellybean 上的 archos 平板电脑上按下后退按钮时,Android Camera 表面 View 相机重新创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19629591/

有关当我在 jellybean 上的 archos 平板电脑上按下后退按钮时,Android Camera 表面 View 相机重新创建的更多相关文章

  1. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  2. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  3. ruby - 如何在续集中重新加载表模式? - 2

    鉴于我有以下迁移:Sequel.migrationdoupdoalter_table:usersdoadd_column:is_admin,:default=>falseend#SequelrunsaDESCRIBEtablestatement,whenthemodelisloaded.#Atthispoint,itdoesnotknowthatusershaveais_adminflag.#Soitfails.@user=User.find(:email=>"admin@fancy-startup.example")@user.is_admin=true@user.save!ende

  4. ruby-on-rails - active_admin 目录中的常量警告重新声明 - 2

    我正在使用active_admin,我在Rails3应用程序的应用程序中有一个目录管理,其中包含模型和页面的声明。时不时地我也有一个类,当那个类有一个常量时,就像这样:classFooBAR="bar"end然后,我在每个必须在我的Rails应用程序中重新加载一些代码的请求中收到此警告:/Users/pupeno/helloworld/app/admin/billing.rb:12:warning:alreadyinitializedconstantBAR知道发生了什么以及如何避免这些警告吗? 最佳答案 在纯Ruby中:classA

  5. ruby-on-rails - date_field_tag,如何设置默认日期? [ rails 上的 ruby ] - 2

    我想设置一个默认日期,例如实际日期,我该如何设置?还有如何在组合框中设置默认值顺便问一下,date_field_tag和date_field之间有什么区别? 最佳答案 试试这个:将默认日期作为第二个参数传递。youcorrectlysetthedefaultvalueofcomboboxasshowninyourquestion. 关于ruby-on-rails-date_field_tag,如何设置默认日期?[rails上的ruby],我们在StackOverflow上找到一个类似的问

  6. ruby-on-rails - 如何在我的 Rails 应用程序 View 中打印 ruby​​ 变量的内容? - 2

    我是一个Rails初学者,但我想从我的RailsView(html.haml文件)中查看Ruby变量的内容。我试图在ruby​​中打印出变量(认为它会在终端中出现),但没有得到任何结果。有什么建议吗?我知道Rails调试器,但更喜欢使用inspect来打印我的变量。 最佳答案 您可以在View中使用puts方法将信息输出到服务器控制台。您应该能够在View中的任何位置使用Haml执行以下操作:-puts@my_variable.inspect 关于ruby-on-rails-如何在我的R

  7. ruby-on-rails - openshift 上的 rails 控制台 - 2

    我将我的Rails应用程序部署到OpenShift,它运行良好,但我无法在生产服务器上运行“Rails控制台”。它给了我这个错误。我该如何解决这个问题?我尝试更新ruby​​gems,但它也给出了权限被拒绝的错误,我也无法做到。railsc错误:Warning:You'reusingRubygems1.8.24withSpring.UpgradetoatleastRubygems2.1.0andrun`gempristine--all`forbetterstartupperformance./opt/rh/ruby193/root/usr/share/rubygems/rubygems

  8. ruby-on-rails - 相关表上的范围为 "WHERE ... LIKE" - 2

    我正在尝试从Postgresql表(table1)中获取数据,该表由另一个相关表(property)的字段(table2)过滤。在纯SQL中,我会这样编写查询:SELECT*FROMtable1JOINtable2USING(table2_id)WHEREtable2.propertyLIKE'query%'这工作正常:scope:my_scope,->(query){includes(:table2).where("table2.property":query)}但我真正需要的是使用LIKE运算符进行过滤,而不是严格相等。然而,这是行不通的:scope:my_scope,->(que

  9. ruby-on-rails - 如何在 Rails View 上显示错误消息? - 2

    我是rails的新手,想在form字段上应用验证。myviewsnew.html.erb.....模拟.rbclassSimulation{:in=>1..25,:message=>'Therowmustbebetween1and25'}end模拟Controller.rbclassSimulationsController我想检查模型类中row字段的整数范围,如果不在范围内则返回错误信息。我可以检查上面代码的范围,但无法返回错误消息提前致谢 最佳答案 关键是您使用的是模型表单,一种显示ActiveRecord模型实例属性的表单。c

  10. ruby - 在 Ruby 中重新分配常量时抛出异常? - 2

    我早就知道Ruby中的“常量”(即大写的变量名)不是真正常量。与其他编程语言一样,对对象的引用是唯一存储在变量/常量中的东西。(侧边栏:Ruby确实具有“卡住”引用对象不被修改的功能,据我所知,许多其他语言都没有提供这种功能。)所以这是我的问题:当您将一个值重新分配给常量时,您会收到如下警告:>>FOO='bar'=>"bar">>FOO='baz'(irb):2:warning:alreadyinitializedconstantFOO=>"baz"有没有办法强制Ruby抛出异常而不是打印警告?很难弄清楚为什么有时会发生重新分配。 最佳答案

随机推荐