你如何获得一个适用于Android的简单相机程序?

我刚刚开始用Java编程,我需要一个简单的应用程序来显示相机,拍照并在某处发送图片数据。

我一直在网上搜索试图找到一个按预期工作的好的相机教程,但显然它们都需要一些我还没有的内在知识。

在这个页面上,commonsWare指向代码中有一些示例代码用于使用相机。 我已经使用了PictureDemo代码并且运行时没有任何错误。 但是,它只会出现黑屏。 我认为这是因为程序实际上并没有激活主要function中的预览或相机,但每次我尝试添加我认为需要的代码时,我都会遇到exception。

所以我的问题是,我需要在主要function中添加什么才能让相机进入? 或者是否有一个更好的教程,我可以看到简单的基本代码,以获得相机?

package assist.core; import android.app.Activity; import android.graphics.PixelFormat; import android.hardware.Camera; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.util.Log; import android.view.KeyEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.widget.Toast; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; public class MainActivity extends Activity { private SurfaceView preview = null; private SurfaceHolder previewHolder = null; private Camera camera = null; private boolean inPreview = false; /** * */ @Override public void onCreate(Bundle savedInstanceState) { //Call the parent class super.onCreate(savedInstanceState); setContentView(R.layout.main); preview = (SurfaceView) findViewById(R.id.preview); previewHolder = preview.getHolder(); previewHolder.addCallback(surfaceCallback); previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } @Override public void onResume() { super.onResume(); //Get the camera instance camera = CameraFinder.INSTANCE.open(); } @Override public void onPause() { if (inPreview) { camera.stopPreview(); } camera.release(); camera = null; inPreview = false; super.onPause(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_CAMERA || keyCode == KeyEvent.KEYCODE_SEARCH) { if (inPreview) { camera.takePicture(null, null, photoCallback); inPreview = false; } return(true); } return(super.onKeyDown(keyCode, event)); } private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) { Camera.Size result = null; for (Camera.Size size : parameters.getSupportedPreviewSizes()) { if (size.width <= width && size.height  resultArea) { result = size; } } } } return(result); } SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() { public void surfaceCreated(SurfaceHolder holder) { try { camera.setPreviewDisplay(previewHolder); } catch (Throwable t) { Log.e("MainActivity-surfaceCallback", "Exception in setPreviewDisplay()", t); Toast.makeText(MainActivity.this, t.getMessage(), Toast.LENGTH_LONG).show(); } } public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { Camera.Parameters parameters = camera.getParameters(); Camera.Size size = getBestPreviewSize(width, height, parameters); if (size != null) { parameters.setPreviewSize(size.width, size.height); parameters.setPictureFormat(PixelFormat.JPEG); camera.setParameters(parameters); camera.startPreview(); inPreview = true; } } public void surfaceDestroyed(SurfaceHolder holder) { // no-op } }; Camera.PictureCallback photoCallback = new Camera.PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { new SavePhotoTask().execute(data); camera.startPreview(); inPreview = true; } }; class SavePhotoTask extends AsyncTask { @Override protected String doInBackground(byte[]... jpeg) { File photo = new File(Environment.getExternalStorageDirectory(), "photo.jpg"); if(photo.exists()) { photo.delete(); } try { FileOutputStream fos = new FileOutputStream(photo.getPath()); fos.write(jpeg[0]); fos.close(); } catch (java.io.IOException e) { Log.e("MainActivity", "Exception in photoCallback", e); } return(null); } } } 

更新

至于我得到的例外,如果我尝试制作主要function,如下面的代码,

 public void onCreate(Bundle savedInstanceState) { //Call the parent class super.onCreate(savedInstanceState); setContentView(R.layout.main); preview = (SurfaceView) findViewById(R.id.preview); previewHolder = preview.getHolder(); previewHolder.addCallback(surfaceCallback); previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); Camera.Parameters parameters = camera.getParameters(); parameters.setPictureFormat(PixelFormat.JPEG); camera.setParameters(parameters); try { //Start the camera preview display camera.setPreviewDisplay(previewHolder); camera.startPreview(); } catch (IOException ex) { Logger.getLogger(MainActivity.class.getName()).log(Level.SEVERE, null, ex); } } 

我得到“应用程序意外停止。请再试一次。” 我基本上试图遵循android文档指定的步骤。 我还尝试在检索到相机对象后将此代码放入onResume函数,然后调用this.onResume。

如果你需要的只是打开相机,拍照,并获得图像。 然后你可以这样做: 使用Intents启动相机

您的上述代码是集成版本。 这将相机集成到您的应用程序中。 我不确定你是否有真正的Android设备进行测试。 更换真实相机时,模拟器将显示黑色或“android图标”屏幕。

如果不是,请在真实设备上进行测试。

您是否可以更明确地指出您获得的例外情况?

这是一个使用Intents的function齐全的相机(我立即调用相机,你显然会包含一个按钮或菜单项)。 它将图像保存到图库并以Pic.jpg为根,然后显示捕获的图像。

这个答案是Aleksander O的这个EXCELLENT片段的扩展和完整版本。

 import java.io.File; import android.app.Activity; import android.content.ContentResolver; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.Toast; public class CallCameraActivity extends Activity { final int TAKE_PICTURE = 1; private Uri imageUri; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); takePhoto(); } public void takePhoto() { Intent intent = new Intent("android.media.action.IMAGE_CAPTURE"); File photo = new File(Environment.getExternalStorageDirectory(), "Pic.jpg"); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo)); imageUri = Uri.fromFile(photo); startActivityForResult(intent, TAKE_PICTURE); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case TAKE_PICTURE: if (resultCode == Activity.RESULT_OK) { //Uri imageUri; Uri selectedImage = imageUri; getContentResolver().notifyChange(selectedImage, null); ImageView imageView = (ImageView) findViewById(R.id.IMAGE); ContentResolver cr = getContentResolver(); Bitmap bitmap; try { bitmap = android.provider.MediaStore.Images.Media .getBitmap(cr, selectedImage); imageView.setImageBitmap(bitmap); Toast.makeText(this, "This file: "+selectedImage.toString(), Toast.LENGTH_LONG).show(); } catch (Exception e) { Toast.makeText(this, "Failed to load", Toast.LENGTH_SHORT) .show(); Log.e("Camera", e.toString()); } } } } } 

使用它作为main.xml布局

      

strings.xml中

   Hello World, TonyPicturesInc! TGCam  

嘿,你必须看看这个答案它可能会帮助你。

点击这里

或者您也可以使用Intent启动内置摄像头,如下所示

 Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(i, CAMERA_RESULT); 

你必须得到相机活动的结果,如下面的代码

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && requestCode == CAMERA_RESULT) { Bundle extras = data.getExtras(); if(extras.containsKey("data")) { Bitmap bmp = (Bitmap) extras.get("data"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.PNG, 100, baos); byte[] image = baos.toByteArray(); if(image != null) { BitmapFactory.Options options=new BitmapFactory.Options(); options.inSampleSize = 5; Bitmap myImage = BitmapFactory.decodeByteArray(image , 0, image.length, options); imageView.setImageBitmap(myImage); } }else { Toast.makeText(getBaseContext(), "Please capture again", Toast.LENGTH_LONG).show(); } } }