我有一个apk应用程序可以拍照并用按钮拍摄视频。
这是我的活动
package com.example.testcamera;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
public class AndroidCameraTestsActivity extends Activity
{
private static final String TAG = AndroidCameraTestsActivity.class.getSimpleName();
private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
private Uri fileUri;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
/**
* https://developer.android.com/guide/topics/media/camera.html
* **/
public void onCaptureImage(View v)
{
// give the image a name so we can store it in the phone's default location
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "IMG_" + timeStamp + ".jpg");
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image (this doesn't work at all for images)
fileUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); // store content values
intent.putExtra( MediaStore.EXTRA_OUTPUT, fileUri);
// start the image capture Intent
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
}
/**
* https://developer.android.com/guide/topics/media/camera.html
* **/
public void onCaptureVideo(View v)
{
//create new Intent
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
//fileUri = getOutputMediaFileUri(MEDIA_TYPE_VIDEO); // create a file to save the video in specific folder (this works for video only)
//intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // set the video image quality to high
// start the Video Capture Intent
startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Originally I was going to iterate through the list of images and grab last added to the MediaStore.
// But this is not necessary if we store the Uri in the image
/*
String[] projection = {MediaStore.Images.ImageColumns._ID};
String sort = MediaStore.Images.ImageColumns._ID + " DESC";
Cursor cursor = this.managedQuery(MediaStore.Images.Thumbnails.EXTERNAL_CONTENT_URI, projection, null, null, sort);
try{
cursor.moveToFirst();
Long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns._ID));
fileUri = Uri.withAppendedPath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, String.valueOf(id));
} finally{
cursor.close();
}
*/
if(fileUri != null) {
Log.d(TAG, "Image saved to:\n" + fileUri);
Log.d(TAG, "Image path:\n" + fileUri.getPath());
Log.d(TAG, "Image name:\n" + getName(fileUri)); // use uri.getLastPathSegment() if store in folder
}
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the image capture
} else {
// Image capture failed, advise user
}
}
if (requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
// Video captured and saved to fileUri specified in the Intent
fileUri = (Uri) data.getData();
if(fileUri != null) {
Log.d(TAG, "Video saved to:\n" + fileUri);
Log.d(TAG, "Video path:\n" + fileUri.getPath());
Log.d(TAG, "Video name:\n" + getName(fileUri)); // use uri.getLastPathSegment() if store in folder
}
} else if (resultCode == RESULT_CANCELED) {
// User cancelled the video capture
} else {
// Video capture failed, advise user
}
}
}
/** Create a file Uri for saving an image or video to specific folder
* https://developer.android.com/guide/topics/media/camera.html#saving-media
* */
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
if(Environment.getExternalStorageState() != null) {
// this works for Android 2.2 and above
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "AndroidCameraTestsFolder");
// This location 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(TAG, "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;
}
return null;
}
// grab the name of the media from the Uri
protected String getName(Uri uri)
{
String filename = null;
try {
String[] projection = { MediaStore.Images.Media.DISPLAY_NAME };
Cursor cursor = managedQuery(uri, projection, null, null, null);
if(cursor != null && cursor.moveToFirst()){
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
filename = cursor.getString(column_index);
} else {
filename = null;
}
} catch (Exception e) {
Log.e(TAG, "Error getting file name: " + e.getMessage());
}
return filename;
}
}
我有第一台运行该应用的设备,我有2个按钮,take photo
和take video
。
当我在此应用中点击take video
并且效果很好但是当我从按钮点击take picture
时,该应用始终“强行关闭”。
这是我的错误logcat
11-19 14:43:27.085: ERROR/AndroidRuntime(6903): FATAL EXCEPTION: main
11-19 14:43:27.085: ERROR/AndroidRuntime(6903): java.lang.NullPointerException
11-19 14:43:27.085: ERROR/AndroidRuntime(6903): at com.android.camera.Camera.initializeFirstTime(Came ra.java:328)
11-19 14:43:27.085: ERROR/AndroidRuntime(6903): at com.android.camera.Camera.access$1100(Camera.java: 95)
11-19 14:43:27.085: ERROR/AndroidRuntime(6903): at com.android.camera.Camera$MainHandler.handleMessag e(Camera.java:282)
11-19 14:43:27.085: ERROR/AndroidRuntime(6903): at android.os.Handler.dispatchMessage(Handler.java:99 )
11-19 14:43:27.085: ERROR/AndroidRuntime(6903): at android.os.Looper.loop(Looper.java:130)
11-19 14:43:27.085: ERROR/AndroidRuntime(6903): at android.app.ActivityThread.main(ActivityThread.jav a:3683)
11-19 14:43:27.085: ERROR/AndroidRuntime(6903): at java.lang.reflect.Method.invokeNative(Native Method)
11-19 14:43:27.085: ERROR/AndroidRuntime(6903): at java.lang.reflect.Method.invoke(Method.java:507)
11-19 14:43:27.085: ERROR/AndroidRuntime(6903): at com.android.internal.os.ZygoteInit$MethodAndArgsCa ller.run(ZygoteInit.java:839)
11-19 14:43:27.085: ERROR/AndroidRuntime(6903): at com.android.internal.os.ZygoteInit.main(ZygoteInit .java:597)
11-19 14:43:27.085: ERROR/AndroidRuntime(6903): at dalvik.system.NativeStart.main(Native Method)
11-19 14:43:27.093: WARN/ActivityManager(1308): Force finishing activity com.android.camera/.Camera
11-19 14:43:27.109: WARN/ActivityManager(1308): Force finishing activity makemachine.android.examples/.PhotoCaptureExample
编辑:这是我使用单个应用按钮的不同活动
package com.example.maincamera;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
public class OpenCameraDemo extends Activity {
private static final int CAMERA_PIC_REQUEST = 2500;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button b = (Button)findViewById(R.id.Button01);
b.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
}
});
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == CAMERA_PIC_REQUEST) {
Bitmap image = (Bitmap) data.getExtras().get("data");
ImageView imageview = (ImageView) findViewById(R.id.ImageView01);
imageview.setImageBitmap(image);
}
}
}
这个应用程序仍然出错,我尝试了很多应用程序。在google中搜索。错误仍然与我的logcat错误相同
当我尝试在其他设备上运行时,此应用程序运行正常。
如何解决此问题,以便我可以在第一台设备上运行并拍照?
BR。
亚历
答案 0 :(得分:3)
崩溃发生在设备的Camera应用程序内部,而不是您自己的。不幸的是,因为此设备上的Camera应用程序可能是AOSP中实际内容的大量自定义变体,所以失败是什么并不完全清楚,但AOSP 2.3.7源代码树中的here is a link to the source file发生了异常。行号与任何感兴趣的内容都不完全匹配,这就是告诉我您的特定设备上的应用程序至少已经定制了一些。
发生异常的initializeFirstTime()
方法中的任何对象,其中调用方法可能是问题的根源,但这些对象都与请求传递的Intent
参数无关因此,你可以采取哪些措施使其正常运作,这是值得怀疑的。
因此,您可能希望自己在自己的应用程序中实现捕获功能。该设备上的Android API可能比它捆绑的系统应用程序更稳定。 Here is an example如何创建自己的相机预览并捕捉活动。
答案 1 :(得分:0)
我对你的手机很好奇。它们的不同之处
因为 onCaptureImage(View v)确实描述了外部存储。 但 onCaptureVideo(查看v)不
手机无效。它支持外部SD卡吗?如果不是,所有代码都是关于ext.sd
- 醇>
您的手机是否有效,偶尔会移除SD卡?尝试将其连接为相机或mtp
答案 2 :(得分:0)
朋友做一件事。
制作只有一个按钮的简单应用。 onClick
事件照片应该是捕获而不添加其他任务。
它是否正常工作?
答案 3 :(得分:0)
尝试捕获异常并在此处发布消息:
try{
Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(cameraIntent, CAMERA_PIC_REQUEST);
}
catch(ActivityNotFoundException e){
e.printStackTrace();
}
答案 4 :(得分:0)
谢谢@Devunwired,谢谢@chintan并感谢大家的帮助。我使用相机api,它的工作原理。
这是我的活动
package com.exercise.AndroidCamera;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import android.app.Activity;
import android.content.ContentValues;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore.Images.Media;
import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;
public class AndroidCamera extends Activity implements SurfaceHolder.Callback{
Camera camera;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
boolean previewing = false;
LayoutInflater controlInflater = null;
final int RESULT_SAVEIMAGE = 0;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home);
}
public void onCaptureImage(View v)
{
setContentView(R.layout.main);
Toast.makeText(AndroidCamera.this,
"Image dimulai : ",
Toast.LENGTH_LONG).show();
getWindow().setFormat(PixelFormat.UNKNOWN);
surfaceView = (SurfaceView)findViewById(R.id.camerapreview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.control, null);
LayoutParams layoutParamsControl
= new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);
Button buttonTakePicture = (Button)findViewById(R.id.takepicture);
buttonTakePicture.setOnClickListener(new Button.OnClickListener(){
@Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
camera.takePicture(myShutterCallback,
myPictureCallback_RAW, myPictureCallback_JPG);
}});
}
ShutterCallback myShutterCallback = new ShutterCallback(){
@Override
public void onShutter() {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_RAW = new PictureCallback(){
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
}};
PictureCallback myPictureCallback_JPG = new PictureCallback(){
@Override
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
/*Bitmap bitmapPicture
= BitmapFactory.decodeByteArray(arg0, 0, arg0.length); */
Uri uriTarget = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, new ContentValues());
OutputStream imageFileOS;
try {
imageFileOS = getContentResolver().openOutputStream(uriTarget);
imageFileOS.write(arg0);
imageFileOS.flush();
imageFileOS.close();
Toast.makeText(AndroidCamera.this,
"Image Tersimpan: " + uriTarget.toString(),
Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
/*controlInflater = LayoutInflater.from(getBaseContext());
View viewControl = controlInflater.inflate(R.layout.confirm, null);
LayoutParams layoutParamsControl
= new LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT);
this.addContentView(viewControl, layoutParamsControl);*/
}};
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
if(previewing){
camera.stopPreview();
previewing = false;
}
if (camera != null){
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
previewing = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
camera = Camera.open();
//m_camera = Camera.open();
/*Camera.Parameters p = camera.getParameters();
//camera.setDisplayOrientation(90);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT)
{
p.set("orientation", "portrait");
p.set("rotation",90);
}
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE)
{
p.set("orientation", "landscape");
p.set("rotation", 90);
}*/
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
previewing = false;
}
}
我创建home.xml以显示像我的问题
的按钮图像<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button android:text="Capture Image" android:onClick="onCaptureImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
main.xml这是一个相机预览
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<SurfaceView
android:id="@+id/camerapreview"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
并在相机预览中创建control.xml拍照按钮。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="bottom"
>
<Button
android:id="@+id/takepicture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text=" * Ambil Foto "
android:layout_gravity="right"
android:layout_margin="10px"
/>
</LinearLayout>
但我在这个应用程序中有2个问题。