我面临的问题是: 1)我严格要从android后台服务(和NOT FROM ACTIVITY)捕获图像和视频。 2)现在的问题是: a)在三星galaxy s6边缘等设备中,图像首次正确拍摄,几乎在拍摄后立即拍摄。但第二次它起飞了。即使在尝试了很多之后,从控制台跟踪异常也变得非常困难。 b)在像Nexus 6这样的设备中,在服务解雇后,开始捕获图像的过程需要花费大量时间,有时根本不会捕获。
c)现在最糟糕的是,即使它在延迟后捕获图像,它也会完全冻结手机而不仅仅是屏幕。如果只有屏幕被冻结,可以理解,因为绘制了1 X 1的表面视图(否则android不允许拍摄图像)。无论如何,我在这里发布代码。任何帮助将不胜感激:主要服务(CamerService.java): 公共类CamerService扩展了Service实现 SurfaceHolder.Callback {
private Camera mCamera;
private Camera.Parameters parameters;
private Bitmap bmp;
FileOutputStream fo;
private String FLASH_MODE;
private int QUALITY_MODE = 0;
private boolean isFrontCamRequest = false;
private Camera.Size pictureSize;
SurfaceView sv;
private SurfaceHolder sHolder;
private WindowManager windowManager;
WindowManager.LayoutParams params;
public Intent cameraIntent;
SharedPreferences pref;
SharedPreferences.Editor editor;
int width = 0, height = 0;
@Override
public void onCreate() {
super.onCreate();
}
Handler handler = new Handler();
Image capture asynctask :
private class TakeImage extends AsyncTask<Intent, Void, Void> {
.
.
.
.
private synchronized void takeImage(Intent intent) {
handler.postDelayed(new Runnable() {
@Override
public void run() {
try {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
if (sv != null)
windowManager.removeView(sv);
}
catch(Exception e)
{
e.printStackTrace();
}
}
},2000);
if (checkCameraHardware(getApplicationContext())) {
Bundle extras = intent.getExtras();
if (extras != null) {
String flash_mode = extras.getString("FLASH");
FLASH_MODE = flash_mode;
boolean front_cam_req = extras.getBoolean("Front_Request");
isFrontCamRequest = front_cam_req;
int quality_mode = extras.getInt("Quality_Mode");
QUALITY_MODE = quality_mode;
}
if (FLASH_MODE==null)
FLASH_MODE = "off";
if (isFrontCamRequest) {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD) {
mCamera = openFrontFacingCameraGingerbread();
if (mCamera != null) {
try {
mCamera.setPreviewDisplay(sv.getHolder());
} catch (IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),
"API dosen't support front camera",
Toast.LENGTH_LONG).show();
}
});
stopSelf();
}
Camera.Parameters parameters = mCamera.getParameters();
pictureSize = getBiggesttPictureSize(parameters);
if (pictureSize != null)
parameters
.setPictureSize(pictureSize.width, pictureSize.height);
// set camera parameters
mCamera.setParameters(parameters);
try
{
Thread.sleep(20);
}
catch (Exception e)
{
e.printStackTrace();
}
mCamera.startPreview();
mCamera.takePicture(mShutter, null, mCall);
mCamera.stopPreview();
mCamera.startPreview();
// return 4;
} else {
mCamera = null;
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(
getApplicationContext(),
"Your Device dosen't have Front Camera !",
Toast.LENGTH_LONG).show();
}
});
stopSelf();
}
} else {
if (checkFrontCamera(getApplicationContext())) {
mCamera = openFrontFacingCameraGingerbread();
if (mCamera != null) {
try {
mCamera.setPreviewDisplay(sv.getHolder());
} catch (IOException e) {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(
getApplicationContext(),
"API dosen't support front camera",
Toast.LENGTH_LONG).show();
}
});
stopSelf();
}
Camera.Parameters parameters = mCamera.getParameters();
pictureSize = getBiggesttPictureSize(parameters);
if (pictureSize != null)
parameters
.setPictureSize(pictureSize.width, pictureSize.height);
// set camera parameters
mCamera.setParameters(parameters);
try
{
Thread.sleep(20);
}
catch (Exception e)
{
e.printStackTrace();
}
mCamera.startPreview();
///.setPreviewCallback(null);
mCamera.takePicture(mShutter, null, mCall);
mCamera.stopPreview();
mCamera.startPreview();
// return 4;
} else {
mCamera = null;
handler.post(new Runnable() {
@Override
public void run() {
}
});
stopSelf();
}
}
}
}
else // backcam
{
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = Camera.open();
} else
mCamera = getCameraInstance();
try {
if (mCamera != null) {
mCamera.setPreviewDisplay(sv.getHolder());
parameters = mCamera.getParameters();
if (FLASH_MODE == null || FLASH_MODE.isEmpty()) {
FLASH_MODE = "auto";
}
parameters.setFlashMode(FLASH_MODE);
// set biggest picture
setBesttPictureResolution();
// log quality and image format
Log.d("Qaulity", parameters.getJpegQuality() + "");
Log.d("Format", parameters.getPictureFormat() + "");
// set camera parameters
mCamera.setParameters(parameters);
try
{
Thread.sleep(20);
}
catch (Exception e)
{
e.printStackTrace();
}
mCamera.startPreview();
Log.d("ImageTakin", "OnTake()");
//mCamera.setPreviewCallback(null);
mCamera.takePicture(mShutter, null, mCall);
mCamera.stopPreview();
mCamera.startPreview();
} else {
handler.post(new Runnable() {
@Override
public void run() {
try {
Toast.makeText(getApplicationContext(),
"Camera is unavailable !",
Toast.LENGTH_LONG).show();
}
catch (Exception e) {
// TODO Auto-generated catch block
Log.e("TAG", "CmaraHeadService()::takePicture", e);
NotiUtils.sendNot3(getApplicationContext(),"err1001",""+e,4);
stopSelf();
}
}
});
stopSelf();
}
// return 4;
} catch (Exception e) {
// TODO Auto-generated catch block
Log.e("TAG", "CmaraHeadService()::takePicture", e);
NotiUtils.sendNot3(getApplicationContext(),"err",""+e,4);
stopSelf();
}
}
} else {
// display in long period of time
try {
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getApplicationContext(),
"Your Device dosen't have a Camera !",
Toast.LENGTH_LONG).show();
}
});
}
catch (Exception e)
{
NotiUtils.sendNot3(getApplicationContext(),"err2002",""+e,4);
stopSelf();
}
stopSelf();
}
// return super.onStartCommand(intent, flags, startId);
}
@SuppressWarnings("deprecation")
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
cameraIntent = intent;
Log.d("ImageTakin", "StartCommand()");
pref = getApplicationContext().getSharedPreferences("MyPref", 0);
editor = pref.edit();
try {
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_TOAST,
WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
PixelFormat.TRANSLUCENT
);
params.gravity = Gravity.TOP | Gravity.LEFT;
params.width = 1;
params.height = 1;
params.x = 0;
params.y = 0;
sv = new SurfaceView(getApplicationContext());
windowManager.addView(sv, params);
sHolder = sv.getHolder();
sHolder.addCallback(this);
if (Build.VERSION.SDK_INT < 11)
sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
catch (Exception e)
{
e.printStackTrace();
}
return START_NOT_STICKY;
}
String file;
Camera.ShutterCallback mShutter ;
Camera.PictureCallback mCall = new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// decode the data obtained by the camera into a Bitmap
Log.d("ImageTakin", "Done");
try {
if (bmp != null)
bmp.recycle();
System.gc();
bmp = decodeBitmap(data);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
if (bmp != null && QUALITY_MODE == 0)
bmp.compress(Bitmap.CompressFormat.JPEG, 70, bytes);
else if (bmp != null && QUALITY_MODE != 0)
bmp.compress(Bitmap.CompressFormat.JPEG, QUALITY_MODE, bytes);
//
try {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
if (sv != null)
windowManager.removeView(sv);
}
catch(Exception e)
{
e.printStackTrace();
}
File imagesFolder = new File(
Constants.CAMERSERV_STOR);
if (!imagesFolder.exists())
imagesFolder.mkdirs(); // <----
File image = new File(imagesFolder, System.currentTimeMillis()
+ ".jpg");
file=image.getAbsolutePath();
try {
fo = new FileOutputStream(image);
} catch (Exception e) {
Log.e("TAG", "FileNotFoundException", e);
stopSelf();
}
try {
fo.write(bytes.toByteArray());
} catch (Exception e) {
stopSelf();
}
try {
fo.close();
if (Build.VERSION.SDK_INT < 19)
sendBroadcast(new Intent(
Intent.ACTION_MEDIA_MOUNTED,
Uri.parse("file://"
+ Environment.getExternalStorageDirectory())));
else {
MediaScannerConnection
.scanFile(
getApplicationContext(),
new String[]{image.toString()},
null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(
String path, Uri uri) {
}
});
}
} catch (Exception e) {
e.printStackTrace();
NotiUtils.sendNot3(getApplicationContext(),"err303",""+e,4);
stopSelf();
}
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
Log.d("Camera", "Image Taken !");
if (bmp != null) {
bmp.recycle();
bmp = null;
System.gc();
}
mCamera = null;
handler.post(new Runnable() {
@Override
public void run() {
try {
Toast.makeText(getApplicationContext(),
"Your Picture has been taken !", Toast.LENGTH_SHORT)
.show();
}
catch(Exception e)
{
e.printStackTrace();
NotiUtils.sendNot3(getApplicationContext(),"err5051",""+e,4);
stopSelf();
}
}
});
count++;
Log.e("excecamrServ",":count:"+count);
Intent ii=new Intent(getApplicationContext(),UploadMedia.class);
ii.putExtra("file",""+file);
ii.setAction("foo");
if (isFrontCamRequest)
ii.putExtra("type","frontCam");
else
ii.putExtra("type","backCam");
ii.putExtra("type2","img1");
if (Helper.isMyServiceRunning(getApplicationContext(),UploadMedia.class))
stopService(ii);
stopSelf();
} catch (Exception e) {
e.printStackTrace();
stopSelf();
}
}
};
int count=0;
@Override
public IBinder onBind(Intent intent) {
return null;
}
public Camera getCameraInstance() {
Camera c = null;
try {
c = Camera.open(); // attempt to get a Camera instance
} catch (Exception e) {
e.printStackTrace();
stopSelf(); } 返回c; //如果相机不可用,则返回null }
@Override
public void onDestroy() {
try {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
if (sv != null)
windowManager.removeView(sv);
Intent intent = new Intent("custom-event-name");
intent.putExtra("message", "This is my message!");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
catch(Exception e)
{
e.printStackTrace();
}
super.onDestroy();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if (cameraIntent != null)
new TakeImage().execute(cameraIntent);
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
try {
if (mCamera != null) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
}
catch (Exception e)
{
stopSelf();
}
}
现在,这就是服务的启动方式:
Intent front_translucent = new Intent(getApplicationContext(), CamerService.class);
front_translucent.putExtra("Quality_Mode", 30);
//Camera.CameraInfo info = new Camera.CameraInfo();
front_translucent.putExtra("Front_Request", false);
front_translucent.putExtra("FLASH", "on");
//Log.e("info",";"+info.canDisableShutterSound);
startService(front_translucent);
请帮助找出延迟或失败或冻结屏幕的原因