无需用户交互即可自动拍照

Posted

技术标签:

【中文标题】无需用户交互即可自动拍照【英文标题】:Take a photo automatically without user interaction 【发布时间】:2012-04-02 21:48:51 【问题描述】:

我使用此代码从相机捕获图像。

package android.takeowneship;


import java.io.File;

import android.app.Activity;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.widget.ImageView;
import android.widget.Toast;


public class camera extends Activity


    private static final int CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE = 100;

    Uri imageUri;
    private ImageView imageView;

     @Override
        public void onCreate(Bundle savedInstanceState)
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);

          //define the file-name to save photo taken by Camera activity
            String fileName = "new-photo-name.jpg";
            //create parameters for Intent with filename
            ContentValues values = new ContentValues();
            values.put(MediaStore.Images.Media.TITLE, fileName);
            values.put(MediaStore.Images.Media.DESCRIPTION,"Image capture by camera");
            //imageUri is the current activity attribute, define and save it for later usage (also in onSaveInstanceState)
            imageUri = getContentResolver().insert(
                    MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            //create new Intent
            Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
            startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);

        

     protected void onActivityResult(int requestCode, int resultCode, Intent data) 

         if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) 
             if (resultCode == RESULT_OK) 
                 //use imageUri here to access the image
                 Toast.makeText(this, "picture has been taken"+ imageUri, Toast.LENGTH_SHORT).show();


              else if (resultCode == RESULT_CANCELED) 
                 Toast.makeText(this, "Picture was not taken", Toast.LENGTH_SHORT).show();
              else 
                 Toast.makeText(this, "Picture was not taken", Toast.LENGTH_SHORT).show();
             
         

         

     public static File convertImageUriToFile (Uri imageUri, Activity activity)  

         Cursor cursor = null;
         try 
             String [] proj=MediaStore.Images.Media.DATA, MediaStore.Images.Media._ID, MediaStore.Images.ImageColumns.ORIENTATION;
             cursor = activity.managedQuery( imageUri,
                     proj, // Which columns to return
                     null,       // WHERE clause; which rows to return (all rows)
                     null,       // WHERE clause selection arguments (none)
                     null); // Order-by clause (ascending by name)
             int file_ColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
//           int orientation_ColumnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.ORIENTATION);
             if (cursor.moveToFirst()) 
//               String orientation =  cursor.getString(orientation_ColumnIndex);
                 return new File(cursor.getString(file_ColumnIndex));
             
             return null;
          finally 
             if (cursor != null) 
                 cursor.close();
             
         
         

但在此代码中,它会打开相机,用户必须单击按钮才能拍照。 我想要的是自动拍照(没有预览)并将其保存在存储卡中。

【问题讨论】:

您是否认为这实际上是一种安全措施?为什么你认为这是可能的?另外,你为什么需要那个? 积极的一点是,如果您确实找到了方法,我将不得不在某处提交错误报告 :-) 我正在构建一个安全应用程序。所以我需要在不认识用户的情况下拍照。 希望做不到! 【参考方案1】:

Android 不允许您在不显示预览窗口的情况下拍照。所以你必须使表面视图非常小。像 1*1 像素并将其放在任何控件的角落

或显示一个虚拟表面视图来执行此操作。

SurfaceView view = new SurfaceView(this);
c.setPreviewDisplay(view.getHolder());
c.startPreview();
c.takePicture(shutterCallback, rawPictureCallback, jpegPictureCallback);

检查(已删除断开的链接),this 和 this 退出。

【讨论】:

就我而言,我需要说c.setPreviewTexture(new SurfaceTexture(0));c.setPreviewDisplay(view.getHolder()); 会抛出 RuntimeException【参考方案2】:

此代码正在使用前置摄像头捕获图像并自动保存

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) 
    super.onCreate(icicle);
    setContentView(R.layout.main);

    int index = getFrontCameraId();
    if (index == -1)
        Toast.makeText(getApplicationContext(), "No front camera", Toast.LENGTH_LONG).show();
    
    else
    
         iv_image = (ImageView) findViewById(R.id.imageView);   
         sv = (SurfaceView) findViewById(R.id.surfaceView);  
         sHolder = sv.getHolder();  
         sHolder.addCallback(this);  
         sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);  
    
   

@Override  
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h)  
  
     parameters = mCamera.getParameters();
     mCamera.setParameters(parameters);  
     mCamera.startPreview();  

     Camera.PictureCallback mCall = new Camera.PictureCallback()  
       
         @Override  
         public void onPictureTaken(byte[] data, Camera camera)  
                   
            Uri uriTarget = getContentResolver().insert//(Media.EXTERNAL_CONTENT_URI, image);
            (Media.EXTERNAL_CONTENT_URI, new ContentValues());

             OutputStream imageFileOS;
             try 
                 imageFileOS = getContentResolver().openOutputStream(uriTarget);
                 imageFileOS.write(data);
                 imageFileOS.flush();
                 imageFileOS.close();

                 Toast.makeText(TakePictureActivity.this,
                         "Image saved: " + uriTarget.toString(), Toast.LENGTH_LONG).show();
             
             catch (FileNotFoundException e) 
                 e.printStackTrace();
             catch (IOException e) 
                 e.printStackTrace();
             
             //mCamera.startPreview();

             bmp = BitmapFactory.decodeByteArray(data, 0, data.length);  
             iv_image.setImageBitmap(bmp);  
           
     ;  

     mCamera.takePicture(null, null, mCall);
  

int getFrontCameraId() 
    CameraInfo ci = new CameraInfo();
    for (int i = 0 ; i < Camera.getNumberOfCameras(); i++) 
        Camera.getCameraInfo(i, ci);
        if (ci.facing == CameraInfo.CAMERA_FACING_FRONT) return i;
        
return -1; // No front-facing camera found


@Override  
public void surfaceCreated(SurfaceHolder holder)  
 
    int index = getFrontCameraId();
    if (index == -1)
        Toast.makeText(getApplicationContext(), "No front camera", Toast.LENGTH_LONG).show();
    
    else
    
        mCamera = Camera.open(index);
        Toast.makeText(getApplicationContext(), "With front camera", Toast.LENGTH_LONG).show();
    
      mCamera = Camera.open(index);  
      try   
         mCamera.setPreviewDisplay(holder);  

       catch (IOException exception)   
          mCamera.release();  
          mCamera = null;  
        

 

@Override  
public void surfaceDestroyed(SurfaceHolder holder)  
  
    mCamera.stopPreview();  
    mCamera.release();  
    mCamera = null;  

【讨论】:

【参考方案3】:

说明

我想在 Android 上不带确认按钮拍照。

解决方案

使用“android.intent.extra.quickCapture”

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra("android.intent.extra.quickCapture",true);

【讨论】:

这是sealed recently,不是吗?【参考方案4】:
Capturing Image without user interaction(without user action) and capture an image in background using android service 


import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import android.app.Service;
import android.content.Intent;
import android.hardware.Camera;
import android.hardware.Camera.CameraInfo;
import android.hardware.Camera.Parameters;
import android.os.Environment;
import android.os.IBinder;
import android.os.StrictMode;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

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");
        

    



 Step:2 Activity File - name is :Second.java





import java.util.Calendar;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;

public class Second extends Activity 


    Intent service;
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);

        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);


    

    @Override
    public boolean onCreateOptionsMenu(Menu menu) 
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.second, menu);
        return true;
    





step 3: Android manife

st file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.dbsource.dbinsert"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="17" />


    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.RECORD_AUDIO" />
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_CONTACTS" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
    <uses-permission android:name="android.permission.SEND_SMS" />
    <uses-permission android:name="android.permission.READ_SMS" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.BROADCAST_STICKY" />
    <uses-permission android:name="android.permission.WRITE_SETTINGS" />

    <uses-feature android:name="android.hardware.camera" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".Second"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>



        <service android:name=".CapPhoto" android:enabled="true">

                   <intent-filter>

                    </intent-filter>
                </service>

        </application>



</manifest>


refer this link [enter link description here][1]


  [1]: http://chandandroid.blogspot.in/2014/04/capturing-image-without-user-action.html

【讨论】:

以上是关于无需用户交互即可自动拍照的主要内容,如果未能解决你的问题,请参考以下文章

无需用户交互即可通过 Api 进行信用卡贷记和借记 / ACH 贷记和借记

OAuth2 - 无需用户交互即可授权

Flutter - 无需用户交互即可重建 GestureDetector 小部件

Bluetoothctl 无需任何用户交互

如何在没有用户交互的情况下启动 Open Camera 应用程序来拍照?

自动更新APP,无需用户交互问题==> Permission Denial: not allowed to send broadcast android.intent.action.PACKAG