我已经制作了一个应用程序来从相机中捕捉照片。
我创建了两个活动:在 Activity1 中有一个按钮,当它被点击时它会启动相机。捕获图像后,将其传递给 Activity2。
但是,当我运行应用程序并启动 Activity1(使用一个按钮)并单击按钮启动相机时,它会显示一个弹出窗口,显示消息“不幸的是,相机已停止”。log-cat 或控制台上没有错误。
谁能帮我。请。非常感谢。
如果使用 startActiviyForResult(),则只需要一个 Activity:
Bello,一个从相机应用程序拍照的简单源代码,您需要使用 startActiviyForResult() 启动 Activity 并从相机应用程序接收意图。
Java源代码:
package com.example.coursandroid_chp;
import android.os.Bundle;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class MediaActivity extends Activity {
private static final String TAG = "MediaActivity";
private static final int REQUEST_IMAGE_CAPTURE = 1;
private static final int REQUEST_VIDEO_CAPTURE = 2;
private Button mCameraPhotoButton;
private Button mCameraVideoButton;
private ImageView mPhotoImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.screen_media);
mCameraPhotoButton = (Button) this.findViewById(R.id.screen_media_camera_photo_button);
mCameraVideoButton = (Button) this.findViewById(R.id.screen_media_camera_video_button);
mPhotoImageView = (ImageView) this.findViewById(R.id.screen_media_photo_imageview);
mCameraPhotoButton.setOnClickListener(onClickListener);
mCameraVideoButton.setOnClickListener(onClickListener);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.screen_media, menu);
return true;
}
private OnClickListener onClickListener = new OnClickListener() {
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.screen_media_camera_photo_button:
startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE), REQUEST_IMAGE_CAPTURE);
break;
case R.id.screen_media_camera_video_button:
startActivityForResult(new Intent(MediaStore.ACTION_VIDEO_CAPTURE), REQUEST_VIDEO_CAPTURE);
break;
}
}
};
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE) {
switch (resultCode) {
case RESULT_OK:
Log.v(TAG, "Picture taken! :)");
if (data != null) {
Bitmap bitmap = data.getParcelableExtra("data");
mPhotoImageView.setImageBitmap(bitmap);
}
break;
case RESULT_CANCELED:
Log.v(TAG, "Picture canceled! :(");
break;
}
} else if (requestCode == REQUEST_VIDEO_CAPTURE) {
switch (resultCode) {
case RESULT_OK:
Log.v(TAG, "Video taken! :)");
break;
case RESULT_CANCELED:
Log.v(TAG, "Video canceled! :(");
break;
}
}
}
}
Xml layout file
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MediaActivity" >
<Button
android:id="@+id/screen_media_camera_photo_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="32dp"
android:text="Camera photo" />
<Button
android:id="@+id/screen_media_camera_video_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/screen_media_camera_photo_button"
android:layout_centerHorizontal="true"
android:layout_marginTop="28dp"
android:text="Camera video" />
<ImageView
android:id="@+id/screen_media_photo_imageview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/screen_media_camera_video_button"
android:layout_centerHorizontal="true"
android:layout_marginLeft="32dp"
android:layout_marginTop="57dp"
android:src="@drawable/ic_bitmap" />
</RelativeLayout>
试试下面的代码:
package com.example.sample1;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import android.os.Bundle;
import android.os.Environment;
import android.os.StatFs;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class CapturePhotoSample1 extends Activity implements OnClickListener
{
public static final int TAKE_PHOTO=1;
ImageView imageView=null;
private File folder;
String imageFileName=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_capture_photo_sample1);
Button button=(Button)this.findViewById(R.id.capture_button);
button.setOnClickListener(this);
button=null;
imageView=(ImageView)this.findViewById(R.id.image_view1);
folder = new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES)+ "/sample1/");
if (!folder.exists()) {
folder.mkdir();
}
}
private void dispatchTakePictureIntent(int actionCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(takePictureIntent,actionCode);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
int id=v.getId();
if(id==R.id.capture_button)
this.dispatchTakePictureIntent(TAKE_PHOTO);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu1, menu);
return true;
}
public void handleCameraPhoto(Intent intent)
{
Bundle extras=intent.getExtras();
Bitmap bitmap=(Bitmap)extras.get("data");
this.imageView.setImageBitmap(bitmap);
if(this.isExternalStorageAvailable())
{
this.imageFileName="img_"+SDUtil.now(-1)+".png";
/*SDUtil.now() is our own library.It is for creating file name with respect to data and time.IF u copy the hole program means sdutil shows error.For that you write a logic for creating a file name. */
String path=folder+"/"+this.imageFileName;
FileOutputStream fos=null;
BufferedOutputStream bos=null;
try
{
fos=new FileOutputStream(path);
bos=new BufferedOutputStream(fos);
bitmap.compress(Bitmap.CompressFormat.PNG, 40, bos);
}
catch(Exception ex)
{
ex.printStackTrace();
}
if(bos!=null)
{
try
{
bos.flush();
//bos.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
if(bos!=null)
{
try
{
bos.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
if(fos!=null)
{
try
{
fos.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
bos=null;
fos=null;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if(resultCode==Activity.RESULT_OK)
{
if(requestCode==TAKE_PHOTO)
{
handleCameraPhoto(data);
}
}
}
private boolean isExternalStorageAvailable() {
StatFs stat = new StatFs(Environment.getExternalStorageDirectory()
.getPath());
double sdAvailSize = (double) stat.getAvailableBlocks()
* (double) stat.getBlockSize();
// One binary gigabyte equals 1,073,741,824 bytes.
double mbAvailable = sdAvailSize / 1048576;
String state = Environment.getExternalStorageState();
boolean mExternalStorageAvailable = false;
boolean mExternalStorageWriteable = false;
if (Environment.MEDIA_MOUNTED.equals(state)) {
// We can read and write the media
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
// We can only read the media
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
// Something else is wrong. It may be one of many other states, but
// all we need
// to know is we can neither read nor write
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
if (mExternalStorageAvailable == true
&& mExternalStorageWriteable == true && mbAvailable > 10) {
return true;
} else {
return false;
}
}
}
确保添加权限
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
如果那不能解决您的问题,那么您应该向我们展示您的代码
在您的活动中检查以下代码
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
//Check that request code matches ours:
if (requestCode == CAPTURE_IMAGE_THUMBNAIL_ACTIVITY_REQUEST_CODE)
{ //Check if your application folder exists in the external storage, if not create it:
your code should be here.....
//Check if data in not null and extract the Bitmap:
if (data != null)
{
String filename = "image";
String fileNameExtension = ".jpg";
File sdCard = Environment.getExternalStorageDirectory();
String imageStorageFolder = File.separator+"Your application Folder"+File.separator;
File destinationFile = new File(sdCard, imageStorageFolder + filename + fileNameExtension);
Log.d(TAG, "the destination for image file is: " + destinationFile );
if (data.getExtras() != null)
{
Bitmap bitmap = (Bitmap)data.getExtras().get("data");
try
{
FileOutputStream out = new FileOutputStream(destinationFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
}
catch (Exception e)
{
Log.e(TAG, "ERROR:" + e.toString());
}
}}}
看看我就这个主题写的这篇博文:
它可能会帮助您找出问题所在。
步骤是:
1.首先和之前一样,我们需要创建一个静态 int 来作为我们的
public static final int CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE = 1777;
2.接下来我们触发意图启动Activity以获得结果:
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "image.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
startActivityForResult(intent, CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE);
在这里,我们实际上将一个URI作为额外的 Intent 传递,以便在拍摄时将图像保存在此位置。
3.最后我们将收到结果onActivityResult
:
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
//Check that request code matches ours:
if (requestCode == CAPTURE_IMAGE_FULLSIZE_ACTIVITY_REQUEST_CODE)
{
//Get our saved file into a bitmap object:
File file = new File(Environment.getExternalStorageDirectory()+File.separator + "image.jpg");
Bitmap bitmap = decodeSampledBitmapFromFile(file.getAbsolutePath(), 1000, 700);
}
}
当decodeSampledBitmapFromFile
方法是:
public static Bitmap decodeSampledBitmapFromFile(String path, int reqWidth, int reqHeight)
{ // BEST QUALITY MATCH
//First decode with inJustDecodeBounds=true to check dimensions
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(path, options);
// Calculate inSampleSize, Raw height and width of image
final int height = options.outHeight;
final int width = options.outWidth;
options.inPreferredConfig = Bitmap.Config.RGB_565;
int inSampleSize = 1;
if (height > reqHeight)
{
inSampleSize = Math.round((float)height / (float)reqHeight);
}
int expectedWidth = width / inSampleSize;
if (expectedWidth > reqWidth)
{
//if(Math.round((float)width / (float)reqWidth) > inSampleSize) // If bigger SampSize..
inSampleSize = Math.round((float)width / (float)reqWidth);
}
options.inSampleSize = inSampleSize;
// Decode bitmap with inSampleSize set
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(path, options);
}
不要忘记将相关的相机权限添加到清单文件中:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />