我一直在研究这款相机应用程序一段时间了。基本上我想做的是拍照(并在内部存储),然后在下一个Activity中显示该图像。预览工作完美,但是当我点击MainActivity上的Capture按钮时,错误“不幸的是,myApplication已停止”显示并且应用程序崩溃。 AndroidStudio没有给我任何事件日志信息......
这是主要的活动(SendInfo出了什么问题?):
public class MainActivity extends ActionBarActivity {
public final static String EXTRA_MESSAGE = "File_name";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create an instance of Camera
Camera mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
CameraPreview mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
// Add a listener to the Capture button
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Camera mCamera = getCameraInstance();
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);
}
//////////////////////
public void sendInfo(View view)
{
Intent intent = new Intent(this,show_image.class);
Uri fileUri = getOutputMediaFileUri(1);
intent.putExtra(EXTRA_MESSAGE, fileUri.toString());
startActivity(intent);
}
/////////////////
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d("Logtag:", "Error creating media file, check storage permissions: "
);
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
Log.d("Logtag:", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("Logtag:", "Error accessing file: " + e.getMessage());
}
}
};
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/** A safe way to get an instance of the Camera object. */
public Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
}
catch (Exception e){
// Camera is not available (in use or does not exist)
Toast.makeText(getApplicationContext(), "Camera is not available (in use or does not exist)",
Toast.LENGTH_LONG).show();
}
return c; // returns null if camera is unavailable
}
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This locat ion works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("Logtag", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
}
这是第二个应该显示图像的活动......
public class show_image extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent intent = getIntent();
String stringURI = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
// Uri uri = Uri.parse(stringURI);
Bitmap bitmap = BitmapFactory.decodeFile(stringURI);
ImageView imageView = new ImageView(this);
imageView.setImageBitmap(bitmap);
setContentView(imageView);
}
public static Bitmap decodeFile(File f, final int maxSize) {
Bitmap b = null;
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
fis.close();
int scale = 1;
if (o.outHeight > maxSize || o.outWidth > maxSize) {
scale = (int) Math.pow(2, (int) Math.round(Math.log(maxSize / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
} catch (Exception e) {
Log.e("Logtag", "Error processing bitmap", e);
} finally {
//FileUtil.closeQuietly(fis);
}
return b;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
Log Cat的输出:
02-25 00:53:11.907 13191-13191/edu.ramapo.camer I/System.out﹕ debugger has settled (1480)
02-25 00:53:12.177 13191-13191/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.view.ViewGroup.onNestedScrollAccepted, referenced from method android.support.v7.internal.widget.ActionBarOverlayLayout.onNestedScrollAccepted
02-25 00:53:12.177 13191-13191/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 11357: Landroid/view/ViewGroup;.onNestedScrollAccepted (Landroid/view/View;Landroid/view/View;I)V
02-25 00:53:12.177 13191-13191/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6f at 0x0000
02-25 00:53:12.177 13191-13191/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.view.ViewGroup.onStopNestedScroll, referenced from method android.support.v7.internal.widget.ActionBarOverlayLayout.onStopNestedScroll
02-25 00:53:12.177 13191-13191/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 11363: Landroid/view/ViewGroup;.onStopNestedScroll (Landroid/view/View;)V
02-25 00:53:12.177 13191-13191/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6f at 0x0000
02-25 00:53:12.177 13191-13191/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.support.v7.internal.widget.ActionBarOverlayLayout.stopNestedScroll, referenced from method android.support.v7.internal.widget.ActionBarOverlayLayout.setHideOnContentScrollEnabled
02-25 00:53:12.177 13191-13191/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 9047: Landroid/support/v7/internal/widget/ActionBarOverlayLayout;.stopNestedScroll ()V
02-25 00:53:12.177 13191-13191/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x000e
02-25 00:53:12.207 13191-13191/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.content.res.TypedArray.getChangingConfigurations, referenced from method android.support.v7.internal.widget.TintTypedArray.getChangingConfigurations
02-25 00:53:12.207 13191-13191/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 365: Landroid/content/res/TypedArray;.getChangingConfigurations ()I
02-25 00:53:12.207 13191-13191/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002
02-25 00:53:12.207 13191-13191/edu.ramapo.camer I/dalvikvm﹕ Could not find method android.content.res.TypedArray.getType, referenced from method android.support.v7.internal.widget.TintTypedArray.getType
02-25 00:53:12.207 13191-13191/edu.ramapo.camer W/dalvikvm﹕ VFY: unable to resolve virtual method 387: Landroid/content/res/TypedArray;.getType (I)I
02-25 00:53:12.207 13191-13191/edu.ramapo.camer D/dalvikvm﹕ VFY: replacing opcode 0x6e at 0x0002
02-25 00:53:13.068 13191-13191/edu.ramapo.camer D/libEGL﹕ loaded /system/lib/egl/libEGL_adreno200.so
02-25 00:53:13.068 13191-13191/edu.ramapo.camer D/libEGL﹕ loaded /system/lib/egl/libGLESv1_CM_adreno200.so
02-25 00:53:13.078 13191-13191/edu.ramapo.camer D/libEGL﹕ loaded /system/lib/egl/libGLESv2_adreno200.so
02-25 00:53:13.078 13191-13191/edu.ramapo.camer I/Adreno200-EGL﹕ <qeglDrvAPI_eglInitialize:265>: EGL 1.4 QUALCOMM build: HAREESHG_Nondeterministic_AU+PATCH[ES]_msm8960_JB_1.9.6_MR2_CL3219408_release_ENGG (CL3219408)
Build Date: 09/28/13 Sat
Local Branch: hhh
Remote Branch: quic/jb_1.9.6_1
Local Patches: 8d50ec23e42ef52b570aa6ff1650afac0b503d78 CL3219408: Fix in the Glreadpixels for negative offsets and larger dimensions.
801859126f6ca69482b39a34ca61447e3f7cded8 rb: fix panel settings to clear undrawn/undefined buffers
Reconstruct Branch: LOCAL_PATCH[ES]
02-25 00:53:13.118 13191-13191/edu.ramapo.camer D/OpenGLRenderer﹕ Enabling debug mode 0
02-25 00:53:27.353 13191-13191/edu.ramapo.camer D/Logtag﹕ failed to create directory
02-25 00:53:27.353 13191-13191/edu.ramapo.camer D/Logtag:﹕ Error creating media file, check storage permissions:
答案 0 :(得分:1)
我认为崩溃的原因是因为您试图让相机实例两次:创建活动时以及按下按钮captureButton
。当您第二次尝试获取时,它会返回null
,因为它已被您的活动使用。
您应该在按下captureButton
按钮之前获取一次相机实例并处理之后拍摄的照片。
public class MainActivity extends ActionBarActivity {
public final static String EXTRA_MESSAGE = "File_name";
private Camera mCamera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Create an instance of Camera
mCamera = getCameraInstance();
// Create our Preview view and set it as the content of our activity.
CameraPreview mPreview = new CameraPreview(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(mPreview);
// Add a listener to the Capture button
Button captureButton = (Button) findViewById(R.id.button_capture);
captureButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// get an image from the camera
mCamera.takePicture(null, null, mPicture);
}
}
);
}
...
修改强>
要在拍摄照片时转到下一个活动,您可以在startActivity
后拨打Camera.PictureCallback
已将byte
数组保存到文件中。
private Camera.PictureCallback mPicture = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null){
Log.d("Logtag:", "Error creating media file, check storage permissions: "
);
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
Intent intent = new Intent(this,show_image.class);
Uri fileUri = Uri.fromFile(pictureFile);
intent.putExtra(EXTRA_MESSAGE, fileUri.toString());
startActivity(intent);
} catch (FileNotFoundException e) {
Log.d("Logtag:", "File not found: " + e.getMessage());
} catch (IOException e) {
Log.d("Logtag:", "Error accessing file: " + e.getMessage());
}
}
};
...
修改2
您需要将此权限添加到清单中才能将照片存储在设备上:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
我希望这会有所帮助。