在服务中捕获图像,无需预览android
问题陈述: 当有人试图用错误的模式/PIN打开设备时,我的应用程序会触发警报,向注册的手机号码发送警报短信。它应该捕获试图解锁设备的人的图像,并将该图像发送到注册的电子邮件ID 我所取得的成就:在服务中捕获图像,无需预览android,android,camera,Android,Camera,问题陈述: 当有人试图用错误的模式/PIN打开设备时,我的应用程序会触发警报,向注册的手机号码发送警报短信。它应该捕获试图解锁设备的人的图像,并将该图像发送到注册的电子邮件ID 我所取得的成就: 我在我的DeviceAdmin类中收到错误模式/PIN的通知 我为后台任务启动服务。此服务成功播放警报 我向注册的手机号码发送提醒短信。 我成功地向注册的电子邮件ID发送了一封提醒电子邮件。(但没有图像。) 当设备被锁定时,我不知道如何在后台IntentService拍摄图像,而且在没有预览的情况下
- 我在我的
类中收到错误模式/PIN的通知DeviceAdmin
- 我为后台任务启动服务。此服务成功播放警报
- 我向注册的手机号码发送提醒短信。
我成功地向注册的
发送了一封提醒电子邮件。(但没有图像。)电子邮件ID
IntentService
拍摄图像,而且在没有预览的情况下也是如此
显然,我无法使用摄像机意图。因为无法从服务调用startActivityForResult
。另外,我不希望用户在打开相机应用程序后捕捉图像
我的研究已经让我找到了这些帖子
问题是:
不推荐使用照相机API`。Camera2 API至少需要sdk版本21
但我客户的要求是MinsdkVersion15,我不能更改。我不知道现在该怎么办。有任何参考资料或帮助吗?我在的帮助下解决了我的问题
因此,我使用以下代码在后台服务中捕获图像:
@Override
public void onStart(Intent intent, int startId) {
mCamera = getAvailableFrontCamera(); // globally declared instance of camera
if (mCamera == null){
mCamera = Camera.open(); //Take rear facing camera only if no front camera available
}
SurfaceView sv = new SurfaceView(getApplicationContext());
SurfaceTexture surfaceTexture = new SurfaceTexture(10);
try {
mCamera.setPreviewTexture(surfaceTexture);
//mCamera.setPreviewDisplay(sv.getHolder());
parameters = mCamera.getParameters();
//set camera parameters
mCamera.setParameters(parameters);
//This boolean is used as app crashes while writing images to file if simultaneous calls are made to takePicture
if(safeToCapture) {
mCamera.startPreview();
mCamera.takePicture(null, null, mCall);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Get a surface
sHolder = sv.getHolder();
//tells Android that this surface will have its data constantly replaced
sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
Camera.PictureCallback mCall = new Camera.PictureCallback()
{
public void onPictureTaken(byte[] data, Camera camera)
{
safeToCapture = false;
//decode the data obtained by the camera into a Bitmap
FileOutputStream outStream = null;
try{
// create a File object for the parent directory
File myDirectory = new File(Environment.getExternalStorageDirectory()+"/Test");
// have the object build the directory structure, if needed.
myDirectory.mkdirs();
//SDF for getting current time for unique image name
SimpleDateFormat curTimeFormat = new SimpleDateFormat("ddMMyyyyhhmmss");
String curTime = curTimeFormat.format(new java.util.Date());
// create a File object for the output file
outStream = new FileOutputStream(myDirectory+"/user"+curTime+".jpg");
outStream.write(data);
outStream.close();
mCamera.release();
mCamera = null;
String strImagePath = Environment.getExternalStorageDirectory()+"/"+myDirectory.getName()+"/user"+curTime+".jpg";
sendEmailWithImage(strImagePath);
Log.d("CAMERA", "picture clicked - "+strImagePath);
} catch (FileNotFoundException e){
Log.d("CAMERA", e.getMessage());
} catch (IOException e){
Log.d("CAMERA", e.getMessage());
}
safeToCapture = true; //Set a boolean to true again after saving file.
}
};
private Camera getAvailableFrontCamera (){
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
try {
cam = Camera.open(camIdx);
} catch (RuntimeException e) {
Log.e("CAMERA", "Camera failed to open: " + e.getLocalizedMessage());
}
}
}
return cam;
}
//Send Email using javamail API as user will not be allowed to choose available
// application using a Chooser dialog for intent.
public void sendEmailWithImage(String imageFile){
.
.
.
}
@覆盖
公共无效启动(Intent Intent,int startId){
mCamera=getAvailableFrontCamera();//全局声明的camera实例
if(mCamera==null){
mCamera=Camera.open();//只有在没有前置摄像头的情况下才能使用后置摄像头
}
SurfaceView sv=新的SurfaceView(getApplicationContext());
表面结构表面结构=新表面结构(10);
试一试{
mCamera.setPreviewTexture(表面纹理);
//setPreviewDisplay(sv.getHolder());
parameters=mCamera.getParameters();
//设置相机参数
mCamera.setParameters(参数);
//如果同时调用takePicture,则将此布尔值用作将图像写入文件时应用程序崩溃
如果(安全捕获){
mCamera.startPreview();
takePicture(null,null,mCall);
}
}捕获(IOE异常){
//TODO自动生成的捕捉块
e、 printStackTrace();
}
//浮出水面
sHolder=sv.getHolder();
//告诉安卓,这个表面将不断更换其数据
sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_缓冲器);
}
Camera.PictureCallback mCall=新建Camera.PictureCallback()
{
公共void onPictureTaken(字节[]数据,摄像头)
{
安全捕获=假;
//将摄像头获取的数据解码为位图
FileOutputStream扩展流=null;
试一试{
//为父目录创建文件对象
File myDirectory=新文件(Environment.getExternalStorageDirectory()+“/Test”);
//如果需要,让对象构建目录结构。
myDirectory.mkdirs();
//用于获取唯一图像名称的当前时间的SDF
SimpleDataFormat curTimeFormat=新的SimpleDataFormat(“DDMMYYYYHMMSS”);
字符串curTime=curTimeFormat.format(新java.util.Date());
//为输出文件创建文件对象
outStream=新文件OutputStream(myDirectory+“/user”+curTime+“.jpg”);
外扩。写入(数据);
exptream.close();
mCamera.release();
mCamera=null;
String strImagePath=Environment.getExternalStorageDirectory()+“/”+myDirectory.getName()+“/user”+curTime+“.jpg”;
sendEmailWithImage(strImagePath);
Log.d(“相机”、“点击图片-”+条纹路径);
}catch(filenotfounde异常){
Log.d(“摄影机”,e.getMessage());
}捕获(IOE异常){
Log.d(“摄影机”,e.getMessage());
}
safeToCapture=true;//保存文件后再次将布尔值设置为true。
}
};
私人摄像机getAvailableFrontCamera(){
int cameraCount=0;
摄像机摄像机=null;
Camera.CameraInfo CameraInfo=新的Camera.CameraInfo();
cameraCount=Camera.getNumberOfCameras();
对于(int-camIdx=0;camIdx
此清单文件需要以下使用功能和权限:
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.front"
android:required="false" />
<uses-permission android:name="android.permission.SEND_MAIL" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
我已将属性required
设置为false,这样用户即使没有任何可用的摄像头也可以安装我的应用程序。也许这对将来的人会有帮助。我在他的帮助下解决了我的问题
因此,我使用以下代码在后台服务中捕获图像:
@Override
public void onStart(Intent intent, int startId) {
mCamera = getAvailableFrontCamera(); // globally declared instance of camera
if (mCamera == null){
mCamera = Camera.open(); //Take rear facing camera only if no front camera available
}
SurfaceView sv = new SurfaceView(getApplicationContext());
SurfaceTexture surfaceTexture = new SurfaceTexture(10);
try {
mCamera.setPreviewTexture(surfaceTexture);
//mCamera.setPreviewDisplay(sv.getHolder());
parameters = mCamera.getParameters();
//set camera parameters
mCamera.setParameters(parameters);
//This boolean is used as app crashes while writing images to file if simultaneous calls are made to takePicture
if(safeToCapture) {
mCamera.startPreview();
mCamera.takePicture(null, null, mCall);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//Get a surface
sHolder = sv.getHolder();
//tells Android that this surface will have its data constantly replaced
sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
Camera.PictureCallback mCall = new Camera.PictureCallback()
{
public void onPictureTaken(byte[] data, Camera camera)
{
safeToCapture = false;
//decode the data obtained by the camera into a Bitmap
FileOutputStream outStream = null;
try{
// create a File object for the parent directory
File myDirectory = new File(Environment.getExternalStorageDirectory()+"/Test");
// have the object build the directory structure, if needed.
myDirectory.mkdirs();
//SDF for getting current time for unique image name
SimpleDateFormat curTimeFormat = new SimpleDateFormat("ddMMyyyyhhmmss");
String curTime = curTimeFormat.format(new java.util.Date());
// create a File object for the output file
outStream = new FileOutputStream(myDirectory+"/user"+curTime+".jpg");
outStream.write(data);
outStream.close();
mCamera.release();
mCamera = null;
String strImagePath = Environment.getExternalStorageDirectory()+"/"+myDirectory.getName()+"/user"+curTime+".jpg";
sendEmailWithImage(strImagePath);
Log.d("CAMERA", "picture clicked - "+strImagePath);
} catch (FileNotFoundException e){
Log.d("CAMERA", e.getMessage());
} catch (IOException e){
Log.d("CAMERA", e.getMessage());
}
safeToCapture = true; //Set a boolean to true again after saving file.
}
};
private Camera getAvailableFrontCamera (){
int cameraCount = 0;
Camera cam = null;
Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
cameraCount = Camera.getNumberOfCameras();
for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
Camera.getCameraInfo(camIdx, cameraInfo);
if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
try {
cam = Camera.open(camIdx);
} catch (RuntimeException e) {
Log.e("CAMERA", "Camera failed to open: " + e.getLocalizedMessage());
}
}
}
return cam;
}
//Send Email using javamail API as user will not be allowed to choose available
// application using a Chooser dialog for intent.
public void sendEmailWithImage(String imageFile){
.
.
.
}
@覆盖
公共无效启动(Intent Intent,int startId){
mCamera=getAvailableFrontCamera();//全局声明的camera实例
if(mCamera==null){
mCamera=Camera.open();//只有在没有前置摄像头的情况下才能使用后置摄像头
}
SurfaceView sv=新的SurfaceView(getApplicationContext());
表面结构表面结构=新表面结构(10);
试一试{
mCamera.setPreviewTexture(表面纹理);
//mCamera.setPreviewDispl