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.getExternalStoragePublicDirectoryEnvironment.getExternalStorageDirectory(适用于 Android 版本 here

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

你需要在AndroidManifest中声明权限:

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

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

【讨论】:

以上是关于Android:在没有用户界面的情况下拍照的主要内容,如果未能解决你的问题,请参考以下文章

android 4.1.1开发时拍照问题:拍完照,保存后没无法返回,一直停在拍照界面,4.0不会出现此种情况

你需要知道的Android拍照适配方案

让用户拍照或从 Android 中的图库中选择图像的单一意图

Android 11.0 修复Camera 启用后置摄像头在拍照界面下,白平衡按钮无法点击

Android:如何在不拍照的情况下从相机捕获文本?

拍照不预览 Android