【问题标题】:Android: Take Photo Without User InterfaceAndroid:在没有用户界面的情况下拍照
【发布时间】: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   ComponentInfo{com.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

您有什么想法,或者有更好的方法来完成这项任务吗?

【问题讨论】:

  • 可以分享一下基础教程吗?

标签: java android android-camera


【解决方案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.getExternalStoragePublicDirectoryEnvironment.getExternalStorageDirectory(适用于 Android 版本 here

  • 无照片预览 - 您可以将预览尺寸设为 1 像素 x 1 像素,因此几乎不可见

  • 你需要在AndroidManifest中声明权限:

    “android.permission.CAMERA”和“android.permission.WRITE_EXTERNAL_STORAGE”(如果要保存图片)

我建议您查看 example 表单并进行实验。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 2020-04-22
    • 2011-12-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多