Android 如何从其他类(摄影机)获取当前路径

Android 如何从其他类(摄影机)获取当前路径,android,path,android-camera,Android,Path,Android Camera,我正在开发一个应用程序,从我的自定义相机类中拍摄照片,然后获取路径并将其放入活动的imageView中,就像预览图像一样,现在我创建了一个类来处理相机功能,并将预览结果的路径发送给活动。但我的结果并不是我捕捉到的正确图片。示例:第一次拍照时,我的“currentPicpath”为空,但第二次拍照时,它给出了我之前拍摄的第一张图像 因此,在第2类中,我创建了一个方法,该方法获取当前路径,但除非拍摄新图片,否则不会给出null 还有一个问题,为什么图像保存后会出现相反的情况? 我的班级: MainA

我正在开发一个应用程序,从我的自定义相机类中拍摄照片,然后获取路径并将其放入活动的imageView中,就像预览图像一样,现在我创建了一个类来处理相机功能,并将预览结果的路径发送给活动。但我的结果并不是我捕捉到的正确图片。示例:第一次拍照时,我的“currentPicpath”为空,但第二次拍照时,它给出了我之前拍摄的第一张图像

因此,在第2类中,我创建了一个方法,该方法获取当前路径,但除非拍摄新图片,否则不会给出null

还有一个问题,为什么图像保存后会出现相反的情况? 我的班级:

MainActivity:
@Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_additem);

        d_image_pre1 = (ImageView) findViewById(R.id.d_image1);


        d_BTakePicture = (Button) findViewById(R.id.d_bTakePicture);
        bOpenCamera = (Button) findViewById(R.id.bOpenCamera);
        d_BTakePicture.setOnClickListener(this);
        bOpenCamera.setOnClickListener(this);

        take = new TakeApicture(this);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.bOpenCamera:
        take.openCam();
            break;
        case R.id.d_bTakePicture:

            take.makeFolder("myTest");
            take.captureImage();
            String path = take.getCurrentPicPath(); 

            BitmapFactory.Options options = new BitmapFactory.Options();
            options.inSampleSize = 2;
            Bitmap bm = BitmapFactory.decodeFile(path, options);
            d_image_pre1.setImageBitmap(bm); 

            break;

        default:
            break;
        }       
    }
第2类:

public class TakeApicture implements SurfaceHolder.Callback{

    Activity context;

    Camera camera;
    SurfaceView surface;
    SurfaceHolder holder;

    PictureCallback jpegCallback;

    File myGeneralFolder;
    FileOutputStream outStream = null;

    private String fullPathFolder;
    String currentPicPath = "No image path";


    @SuppressWarnings("deprecation")
    public TakeApicture(Activity context) {
        super();
        this.context = context;

        surface  = (SurfaceView)context.findViewById(R.id.surfaceView);
        holder = surface.getHolder();
        holder.addCallback(this);
         holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

           jpegCallBack();


    }


       public void captureImage() {
            camera.takePicture(null, null, jpegCallback);
        }



    public void makeFolder(String itemFolderName) {
        fullPathFolder = Environment.getExternalStorageDirectory()+File.separator+"mySalesImages"+File.separator+itemFolderName;
        myGeneralFolder = new  File(fullPathFolder);
        myGeneralFolder.mkdirs();
    }



    public void jpegCallBack(){
        jpegCallback = new PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                    try {
                        getPicPath(data);

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



    public void getPicPath(byte[] data) throws IOException{
        currentPicPath = String.format(myGeneralFolder+"/%d.jpg",(System.currentTimeMillis()));
        outStream = new FileOutputStream(currentPicPath);
        outStream.write(data); 
        outStream.close();
    }

    public String getCurrentPicPath() {
        return currentPicPath;
    }


    @SuppressWarnings("deprecation")
    public void openCam(){
        try {
        camera = Camera.open();
        Camera.Parameters param;
        param = camera.getParameters();
        //modify parameter
        camera.setDisplayOrientation(90);
        param.setPreviewFrameRate(20);
        param.setPreviewSize(176, 144);
        camera.setParameters(param);

        camera.setPreviewDisplay(holder);
        camera.startPreview();

        } catch (Exception e) {
            // TODO: handle exception
        }

    }


    public void closeCam(){
        camera.stopPreview();
        camera.release();
    }




    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub

    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        // TODO Auto-generated method stub

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        closeCam();
    }


}
这是正确的解决方案???

    take.captureImage();

    new Handler().postDelayed(new Runnable() {
        @Override
        public void run() {
    String path = take.getCurrentPicPath(); 


    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inSampleSize = 2;
    Bitmap bm = BitmapFactory.decodeFile(path, options);
    d_image_pre1.setImageBitmap(bm); 

        }
    }, 1000);

take.captureImage()启动捕获照片的异步过程。一段时间后,Android系统将调用您的
onPictureTaken()
回调,您将计算一个新的图像路径(并相应地写入照片)。但是这条线

String path = take.getCurrentPicPath(); 
已经被执行了

您可以同步计算路径,但即使如此,您的活动也必须等待实际映像写入磁盘。因此,您别无选择,只能提取该片段

String path = take.getCurrentPicPath(); 

BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2;
Bitmap bm = BitmapFactory.decodeFile(path, options);
d_image_pre1.setImageBitmap(bm); 
转换为单独的方法。您可以直接从
onPictureTaken()
调用此新方法,也可以使用
post()
(无需从
onPictureTaken()
调用
postDelayed()
)异步执行它


因此,快速而肮脏的修复(为简洁起见删除了异常处理)如下所示:

MainActivity.java中:

public void onClick(View v) {
  switch (v.getId()) {
    case R.id.bOpenCamera:
      take.openCam();
      break;
    case R.id.d_bTakePicture:
      take.makeFolder("myTest");
      take.captureImage();
      break;
  }       
}

public void setImage(String path) {
  BitmapFactory.Options options = new BitmapFactory.Options();
  options.inSampleSize = 2;
  Bitmap bm = BitmapFactory.decodeFile(path, options);
  d_image_pre1.setImageBitmap(bm); 
}
public void jpegCallBack() {
  jpegCallback = new PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
      getPicPath(data);
      (MainActivity)context.setImage(currentPicPath);
    }
  };
}
在takeapiture.java中

public void onClick(View v) {
  switch (v.getId()) {
    case R.id.bOpenCamera:
      take.openCam();
      break;
    case R.id.d_bTakePicture:
      take.makeFolder("myTest");
      take.captureImage();
      break;
  }       
}

public void setImage(String path) {
  BitmapFactory.Options options = new BitmapFactory.Options();
  options.inSampleSize = 2;
  Bitmap bm = BitmapFactory.decodeFile(path, options);
  d_image_pre1.setImageBitmap(bm); 
}
public void jpegCallBack() {
  jpegCallback = new PictureCallback() {
    public void onPictureTaken(byte[] data, Camera camera) {
      getPicPath(data);
      (MainActivity)context.setImage(currentPicPath);
    }
  };
}

你是说在异步任务中?!不,只需使用一些
处理程序.post()
。AsyncTask在这里是不相关的,因为必须在UI线程上更新ImageView。我编辑了我的问题的某些部分,请查看并告诉我这是否是正确的做法。虽然您所做的更改大部分都能完成任务,但有时会失败(在某些设备上捕获可能需要1秒以上),并在其他情况下引入不必要的延迟(在大多数设备上,捕获比1s快得多)。我在我的第二个解决方案中,我刚刚将位图解码到捕获类中,它工作得很好。但是当我尝试快速点击按钮时,它崩溃了:06-19 13:58:00.046:E/AndroidRuntime(7918):致命异常:main 06-19 13:58:00.046:E/AndroidRuntime(7918):java.lang.RuntimeException:takePicture失败06-19 13:58:00.046:E/AndroidRuntime(7918):在