Android:在没有用户界面的情况下拍照
Posted
技术标签:
【中文标题】Android:在没有用户界面的情况下拍照【英文标题】:Android: Take Photo Without User Interface 【发布时间】:2013-12-08 23:01:34 【问题描述】:我有兴趣为 android 编写一个应用程序,在应用程序中的某个事件之后,使用 android 上的相机自动拍摄一张照片。
我需要的东西:
没有照片预览
没有按钮供用户按下拍照
只需运行该操作即可拍摄照片并将其存储到相册中。
这是我从在线教程中尝试的一些代码:
public void snap()
mCamera = Camera.open();
SurfaceView sv = new SurfaceView(getApplicationContext());
try
mCamera.setPreviewDisplay(sv.getHolder());
parameters = mCamera.getParameters();
//set camera parameters
mCamera.setParameters(parameters);
mCamera.startPreview();
mCamera.takePicture(null, null, mCall);
catch (IOException e)
// TODO Auto-generated catch block
e.printStackTrace();
//Get a surface
sHolder = sv.getHolder();
Camera.PictureCallback mCall = new Camera.PictureCallback()
public void onPictureTaken(byte[] data, Camera camera)
//decode the data obtained by the camera into a Bitmap
FileOutputStream outStream = null;
try
outStream = new FileOutputStream("/sdcard/Image.jpg");
outStream.write(data);
outStream.close();
catch (FileNotFoundException e)
Log.d("CAMERA", e.getMessage());
catch (IOException e)
Log.d("CAMERA", e.getMessage());
;
public IBinder onBind(Intent intent)
// TODO Auto-generated method stub
return null;
以及它所做的事情的日志
11-24 01:54:37.738: E/AndroidRuntime(6971): FATAL EXCEPTION: main
11-24 01:54:37.738: E/AndroidRuntime(6971): java.lang.RuntimeException: Unable to start activity ComponentInfocom.example.udptest/com.example.udptest.Main: java.lang.RuntimeException: takePicture failed
11-24 01:54:37.738: E/AndroidRuntime(6971): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2308)
11-24 01:54:37.738: E/AndroidRuntime(6971): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2358)
11-24 01:54:37.738: E/AndroidRuntime(6971): at android.app.ActivityThread.access$600(ActivityThread.java:153)
11-24 01:54:37.738: E/AndroidRuntime(6971): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1247)
11-24 01:54:37.738: E/AndroidRuntime(6971): at android.os.Handler.dispatchMessage(Handler.java:99)
11-24 01:54:37.738: E/AndroidRuntime(6971): at android.os.Looper.loop(Looper.java:137)
11-24 01:54:37.738: E/AndroidRuntime(6971): at android.app.ActivityThread.main(ActivityThread.java:5227)
11-24 01:54:37.738: E/AndroidRuntime(6971): at java.lang.reflect.Method.invokeNative(Native Method)
11-24 01:54:37.738: E/AndroidRuntime(6971): at java.lang.reflect.Method.invoke(Method.java:511)
11-24 01:54:37.738: E/AndroidRuntime(6971): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795)
11-24 01:54:37.738: E/AndroidRuntime(6971): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562)
11-24 01:54:37.738: E/AndroidRuntime(6971): at dalvik.system.NativeStart.main(Native Method)
11-24 01:54:37.738: E/AndroidRuntime(6971): Caused by: java.lang.RuntimeException: takePicture failed
11-24 01:54:37.738: E/AndroidRuntime(6971): at android.hardware.Camera.native_takePicture(Native Method)
11-24 01:54:37.738: E/AndroidRuntime(6971): at android.hardware.Camera.takePicture(Camera.java:1101)
11-24 01:54:37.738: E/AndroidRuntime(6971): at android.hardware.Camera.takePicture(Camera.java:1046)
11-24 01:54:37.738: E/AndroidRuntime(6971): at com.example.udptest.Main.snap(Main.java:129)
11-24 01:54:37.738: E/AndroidRuntime(6971): at com.example.udptest.Main.onCreate(Main.java:84)
11-24 01:54:37.738: E/AndroidRuntime(6971): at android.app.Activity.performCreate(Activity.java:5104)
11-24 01:54:37.738: E/AndroidRuntime(6971): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
11-24 01:54:37.738: E/AndroidRuntime(6971): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2262)
11-24 01:54:37.738: E/AndroidRuntime(6971): ... 11 more
您有什么想法,或者有更好的方法来完成这项任务吗?
【问题讨论】:
可以分享一下基础教程吗? 【参考方案1】:这是在后台拍摄照片的服务,希望对您有所帮助。:
public class CapPhoto extends Service
private SurfaceHolder sHolder;
private Camera mCamera;
private Parameters parameters;
@Override
public void onCreate()
super.onCreate();
Log.d("CAM", "start");
if (android.os.Build.VERSION.SDK_INT > 9)
StrictMode.ThreadPolicy policy =
new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
Thread myThread = null;
@Override
public void onStart(Intent intent, int startId)
super.onStart(intent, startId);
if (Camera.getNumberOfCameras() >= 2)
mCamera = Camera.open(CameraInfo.CAMERA_FACING_FRONT);
if (Camera.getNumberOfCameras() < 2)
mCamera = Camera.open();
SurfaceView sv = new SurfaceView(getApplicationContext());
try
mCamera.setPreviewDisplay(sv.getHolder());
parameters = mCamera.getParameters();
mCamera.setParameters(parameters);
mCamera.startPreview();
mCamera.takePicture(null, null, mCall);
catch (IOException e) e.printStackTrace();
sHolder = sv.getHolder();
sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
Camera.PictureCallback mCall = new Camera.PictureCallback()
public void onPictureTaken(final byte[] data, Camera camera)
FileOutputStream outStream = null;
try
File sd = new File(Environment.getExternalStorageDirectory(), "A");
if(!sd.exists())
sd.mkdirs();
Log.i("FO", "folder" + Environment.getExternalStorageDirectory());
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHmmss");
String tar = (sdf.format(cal.getTime()));
outStream = new FileOutputStream(sd+tar+".jpg");
outStream.write(data); outStream.close();
Log.i("CAM", data.length + " byte written to:"+sd+tar+".jpg");
camkapa(sHolder);
catch (FileNotFoundException e)
Log.d("CAM", e.getMessage());
catch (IOException e)
Log.d("CAM", e.getMessage());
;
@Override
public IBinder onBind(Intent intent)
return null;
public void camkapa(SurfaceHolder sHolder)
if (null == mCamera)
return;
mCamera.stopPreview();
mCamera.release();
mCamera = null;
Log.i("CAM", " closed");
AndroidManifest.xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-feature android:name="android.hardware.camera" />
<service android:name=".CapPhoto" android:enabled="true">
<intent-filter>
</intent-filter>
</service>
在你的 MainActivity 中调用它来调用服务:
Intent service;
....
Calendar cal = Calendar.getInstance();
service = new Intent(getBaseContext(), CapPhoto.class);
cal.add(Calendar.SECOND, 15);
//TAKE PHOTO EVERY 15 SECONDS
PendingIntent pintent = PendingIntent.getService(this, 0, service, 0);
AlarmManager alarm = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
60*60*1000, pintent);
startService(service);
【讨论】:
我检查了这段代码,需要的最低SDK是24,有没有可能使用SDK 21。 @ZG-RG 我创建了一个 CapPhoto 类并在服务线程中执行它没有任何解决方案【参考方案2】:小贴士:
首先,不要对文件路径进行硬编码。您的 /sdcard 可能根本不存在,因此您的 outStream 将为空,并且当您从 outStream 调用任何方法时它会崩溃。请改为使用 Environment.getExternalStoragePublicDirectory 或 Environment.getExternalStorageDirectory(适用于 Android 版本 here
无照片预览 - 您可以将预览尺寸设为 1 像素 x 1 像素,因此几乎不可见
你需要在AndroidManifest中声明权限:
“android.permission.CAMERA”和“android.permission.WRITE_EXTERNAL_STORAGE”(如果要保存图片)
我建议您查看 example 表单并进行实验。
【讨论】:
以上是关于Android:在没有用户界面的情况下拍照的主要内容,如果未能解决你的问题,请参考以下文章
android 4.1.1开发时拍照问题:拍完照,保存后没无法返回,一直停在拍照界面,4.0不会出现此种情况
让用户拍照或从 Android 中的图库中选择图像的单一意图