屏幕锁定后相机冻结



我正在使用zbar为Android开发条形码扫描仪。一切都很好。但是,当我的应用程序进入睡眠状态或手机锁定时,相机预览会冻结,我无法在简历中重新启动它。

fragment.java

package com.alsafeer.xpressions.fragment;
import android.graphics.Typeface;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.alsafeer.xpressions.AnalyticsSampleApp;
import com.alsafeer.xpressions.CameraPreview;
import com.alsafeer.xpressions.JsonParser;
import com.alsafeer.xpressions.R;
import com.google.android.gms.analytics.GoogleAnalytics;
import com.google.android.gms.analytics.HitBuilders;
import com.google.android.gms.analytics.Tracker;
import net.sourceforge.zbar.Config;
import net.sourceforge.zbar.Image;
import net.sourceforge.zbar.ImageScanner;
import net.sourceforge.zbar.Symbol;
import net.sourceforge.zbar.SymbolSet;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

public class rewards extends Fragment {
private Camera mCamera;
private CameraPreview mPreview;
private Handler autoFocusHandler;
private String Name;
private String Email;
private View view;
private String Mob;
private String Points;
private String result;
private RelativeLayout preview;
TextView scanText;
Button scanButton;
ImageScanner scanner;
private boolean barcodeScanned = false;
private boolean previewing = true;
static {
System.loadLibrary("iconv");
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
setHasOptionsMenu(true);
view = inflater.inflate(R.layout.activity_rewards,
container, false);
view.setFocusableInTouchMode(true);
view.requestFocus();
Tracker t = ((AnalyticsSampleApp) getActivity().getApplication()).getTracker(
AnalyticsSampleApp.TrackerName.APP_TRACKER);
GoogleAnalytics.getInstance(getActivity()).setLocalDispatchPeriod(1);
t.setScreenName("Rewards Barcode Reader");
t.send(new HitBuilders.AppViewBuilder().build());
Typeface font = Typeface.createFromAsset(getActivity().getAssets(), "fonts/font.ttf");
Button next= (Button) view.findViewById(R.id.next);
next.setTypeface(font);
scanText = (EditText)view.findViewById(R.id.editText6);
scanText.setTypeface(font);
mCamera = getCameraInstance();
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE|
WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE);
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!scanText.getText().toString().equals(""))
{
new AsyncTaskParseJson().execute();
}
else
{
Toast.makeText(getActivity(),"Please enter the number or scan the barcode...", Toast.LENGTH_LONG).show();
}
}
});
scanText.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
releaseCamera();
getFragmentManager().beginTransaction().replace(R.id.content_frame, new FirstFragment(), "first").commit();
return true;
}
}
return false;
}
});
view.setOnKeyListener(new View.OnKeyListener() {
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
if ((keyCode == KeyEvent.KEYCODE_BACK)) {
releaseCamera();
getFragmentManager().beginTransaction().replace(R.id.content_frame, new FirstFragment(), "first").commit();
return true;
}
}
return true;
}
});
autoFocusHandler = new Handler();

/* Instance barcode scanner */
scanner = new ImageScanner();
scanner.setConfig(0, Config.X_DENSITY, 3);
scanner.setConfig(0, Config.Y_DENSITY, 3);
mPreview = new CameraPreview(getActivity(), mCamera, previewCb, autoFocusCB);
preview = (RelativeLayout) view.findViewById(R.id.cameraPreview);
preview.addView(mPreview);
scanButton = (Button)view.findViewById(R.id.button6);
scanButton.setTypeface(font);
scanButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (barcodeScanned) {
barcodeScanned = false;
mCamera.setPreviewCallback(previewCb);
mCamera.startPreview();
previewing = true;
mCamera.autoFocus(autoFocusCB);
}
}
});
return view;
}
@Override
public void onResume() {
super.onResume();
if(mCamera==null) {
mCamera=getCameraInstance();
mPreview = new CameraPreview(getActivity(), mCamera, previewCb, autoFocusCB);
preview = (RelativeLayout) view.findViewById(R.id.cameraPreview);
preview.addView(mPreview);
mCamera.setPreviewCallback(previewCb);
mCamera.startPreview();
previewing = true;
mCamera.autoFocus(autoFocusCB);
}
}
@Override
public void onPause() {
super.onPause();
}
@Override
public void onStop() {
super.onStop();
releaseCamera();
}
/** A safe way to get an instance of the Camera object. */
public static Camera getCameraInstance(){
Camera c = null;
try {
c = Camera.open();
} catch (Exception e){
}
return c;
}
public void releaseCamera() {
if (mCamera != null) {
previewing = false;
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
}
private Runnable doAutoFocus = new Runnable() {
public void run() {
if (previewing)
mCamera.autoFocus(autoFocusCB);
}
};
Camera.PreviewCallback previewCb = new Camera.PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
Camera.Parameters parameters = camera.getParameters();
Camera.Size size = parameters.getPreviewSize();
Image barcode = new Image(size.width, size.height, "Y800");
barcode.setData(data);
int result = scanner.scanImage(barcode);
if (result != 0) {
previewing = false;
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
SymbolSet syms = scanner.getResults();
for (Symbol sym : syms) {
scanText.setText(sym.getData());
barcodeScanned = true;
}
}
}
};
// Mimic continuous auto-focusing
Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
autoFocusHandler.postDelayed(doAutoFocus, 1000);
}
};
public class AsyncTaskParseJson extends AsyncTask<String, String, String> {
JSONArray dataJsonArr = null;
@Override
protected void onPreExecute() {}
@Override
protected String doInBackground(String... arg0) {
try {
// instantiate our json parser
JsonParser jParser = new JsonParser();
// get json string from url
JSONObject json = jParser.getJSONFromUrl("http://www.safeerplus.ae/ncno="+scanText.getText().toString());
// get the array of users
dataJsonArr = json.getJSONArray("msg");
// loop through all users
JSONObject c = dataJsonArr.getJSONObject(0);
// Storing each json item in variable
Name = c.getString("name");
Mob = c.getString("mob");
Email = c.getString("email");
Points = c.getString("points");
if(Name.equals("")||Mob.equals("")||Email.equals("")||Points.equals(""))
{
}
else {
Bundle args = new Bundle();
args.putString("code", scanText.getText().toString());
args.putString("name1", Name);
args.putString("mob1", Mob);
args.putString("email1", Email);
args.putString("points1", Points);
releaseCamera();
Fragment fr=new reward_details();
FragmentManager fm = getFragmentManager();
FragmentTransaction ft = fm.beginTransaction();
fr.setArguments(args);
ft.replace(R.id.content_frame, fr);
ft.commit();
}

} catch (JSONException e) {
getActivity().runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getActivity(), "Please use a valid card!", Toast.LENGTH_LONG).show();
}
});
}
return null;
}

@Override
protected void onPostExecute(String strFromDoInBg) {}
}
}

camerapreview.java

package com.alsafeer.xpressions;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PreviewCallback;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder mHolder;
private Camera mCamera;
private PreviewCallback previewCallback;
private AutoFocusCallback autoFocusCallback;
public CameraPreview(Context context, Camera camera,
PreviewCallback previewCb,
AutoFocusCallback autoFocusCb) {
super(context);
mCamera = camera;
previewCallback = previewCb;
autoFocusCallback = autoFocusCb;
/* 
* Set camera to continuous focus if supported, otherwise use
* software auto-focus. Only works for API level >=9.
*/
/*
Camera.Parameters parameters = camera.getParameters();
for (String f : parameters.getSupportedFocusModes()) {
if (f == Parameters.FOCUS_MODE_CONTINUOUS_PICTURE) {
mCamera.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);
autoFocusCallback = null;
break;
}
}
*/
// Install a SurfaceHolder.Callback so we get notified when the
// underlying surface is created and destroyed.
mHolder = getHolder();
mHolder.addCallback(this);
// deprecated setting, but required on Android versions prior to 3.0
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
// open the camera
mCamera = Camera.open();
} catch (RuntimeException e) {
// check for exceptions
System.err.println(e);
return;
}
Camera.Parameters param;
param = mCamera.getParameters();
// modify parameter
param.setPreviewSize(200, 300);
mCamera.setParameters(param);
try {
// The Surface has been created, now tell the camera where to draw
// the preview.
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (Exception e) {
// check for exceptions
System.err.println(e);
return;
}
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
setMeasuredDimension(getMeasuredWidth(), getMeasuredWidth()); //Snap to width
}
public void surfaceDestroyed(SurfaceHolder holder) {
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Camera.Parameters parameters = mCamera.getParameters();
final DisplayMetrics dm = this.getResources().getDisplayMetrics();
//getBestPreviewSize returns the best preview size, don't worry
//but some devices do not return one for all camera matching the aspect ratio
/*
* If your preview can change or rotate, take care of those events here.
* Make sure to stop the preview before resizing or reformatting it.
*/
if (mHolder.getSurface() == null){
// preview surface does not exist
return;
}
// stop preview before making changes
try {
mCamera.stopPreview();
} catch (Exception e){
// ignore: tried to stop a non-existent preview
}
try {
// Hard code camera surface rotation 90 degs to match Activity view in portrait
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewCallback(previewCallback);
mCamera.startPreview();
mCamera.autoFocus(autoFocusCallback);
} catch (Exception e){
Log.d("DBG", "Error starting camera preview: " + e.getMessage());
}
}
}

布局.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp"
android:background="#e7e7e9">
<RelativeLayout
android:id="@+id/cameraPreview"
android:layout_width="300dp"
android:layout_height="300dp"
android:layout_weight="1"
android:gravity="clip_horizontal"
android:layout_below="@+id/editText6"
android:layout_centerHorizontal="true">
</RelativeLayout>
<Button
android:id="@+id/next"
android:text="View points"
android:layout_width="120dp"
android:layout_height="30sp"
android:layout_gravity="center"
android:background="@drawable/loginbutton"
android:textSize="12sp"
android:layout_alignTop="@+id/button6"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:id="@+id/button6"
android:text="Rescan"
android:layout_width="120dp"
android:layout_height="30sp"
android:layout_gravity="center"
android:background="@drawable/loginbutton"
android:textSize="12sp"
android:layout_below="@+id/cameraPreview"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="30dp" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="10"
android:id="@+id/editText6"
android:background="#d1d2d4"
android:textSize="15sp"
android:padding="5dp"
android:textColor="#000000"
android:hint="Enter or Scan the Barcode"
android:textColorHint="#4a4f5a"
android:layout_alignParentTop="true"
android:layout_alignLeft="@+id/cameraPreview"
android:layout_alignStart="@+id/cameraPreview"
android:layout_alignRight="@+id/cameraPreview"
android:layout_alignEnd="@+id/cameraPreview" />
</RelativeLayout>

logcat

04-20 10:40:20.356 7099-7099/com.alsafer.expressions D/Camera JNI﹕setHasPreviewCallback:已安装:1,manualBuffer:004-20 10:40:20.359 7099-7099/com.alsafer.expressions I/CameraFramework﹕相机框架getParameters=afeng最大聚焦步长=0;afeng最小聚焦步长=0;防碰撞=自动;防粘连值=关闭,50赫兹,60赫兹,自动;支持自动曝光锁定=true;支持自动白平衡锁=true;亮度=中等;亮度值=低、中、高;亮度值=39;突发数量=1;cap模式=正常;cap模式值=normal、face_beauty、continuousshot、smileshot、bestshot、evbracketshot、autorama、mav、asd;capfname=/sdcard/DCIM/cap00;对比度=中等;对比度值=低、中、高;edge=中间;边缘值=低、中、高;effect=无;效果值=无、单色、负片、深褐色、浅绿色、白板、黑板;eng闪光占空比最大值=1;eng闪光占空比min=0;eng闪光占空比值=-1;曝光补偿=0;曝光补偿步长=1.0;fbsharp=0;fb sharp max=4;fb锐最小值=-4;fb皮肤颜色=0;fb皮肤颜色最大值=4;fb皮肤颜色最小值=-4;fb平滑级别=0;fb平滑级别max=4;fb平滑水平min=-4;焦距=3.5;焦距=0.95,1.9,无穷大;聚焦模式=无穷大;聚焦模式值=无穷大;水平视角=54;色调=中间;色调值=低、中、高;iso速度=自动;iso速度值=自动,1002004008001600;jpeg质量=100;jpeg缩略图高度=128;jpeg缩略图质量=100;jpeg缩略图大小值=0x0160x128320x240;jpeg缩略图宽度=160;最大曝光补偿=3;检测到的最大人脸数量hw=15;检测到的最大人脸数量sw=0;最大聚焦区域数=0;最大计量区域数=9;最大缩放=10;最小曝光补偿=-3;mtk凸轮模式=0;图片格式=jpeg;图片格式值=jpeg;图片大小=2560x1920;图片大小值=320x240640x4801024x7681280x7201280x7681280x9601600x12002048x15362560x14402560x19202880x1728;视频的首选预览大小=1280x720;预览格式=yuv420sp;预览格式值=yuv420sp、yuv420p、yuv420-yyuvyy-3平面;预览fps范围=500060000;预览fps范围值=(500060000);预览帧速率=30;预览帧速率值=15,24,30;预览大小=640x480;预览大小值=176x144320x240352x288480x320480x368640x480720x480800x480800x600864x480960x5401280x720;旋转=0;饱和度=中等;饱和度值=低、中、高;场景模式=自动;场景模式值=自动,肖像,风景,夜晚,夜间肖像,剧院,海滩,雪,日落,稳定照片,烟花,体育,派对,烛光,hdr;传感器类型=254;支持平滑缩放=true;垂直视角=49;视频帧格式=yuv420p;视频大小=640x480;视频大小值=176x144480x320640x480864x4801280x7201920x1080;支持的视频快照=false;视频稳定=错误;支持视频稳定=true;白平衡=自动;白平衡值=自动、白炽、荧光、暖荧光、日光、阴天、黄昏、阴影;缩放=0;缩放比例=100114132151174200229263303348400;支持缩放=true;zsd模式=关闭;zsd模式值=关闭,打开04-20 10:40:20.390 7099-7112/com.alsafer.expressions D/Camera JNI﹕正在分配回调缓冲区04-20 10:40:20.418 7099-7099/com.alsafer.expressions I/CameraFramework﹕处理消息:1604-20 10:40:20.418 7099-7099/com.alsafer.expressions D/Camera JNI﹕setHasPreviewCallback:已安装:1,manualBuffer:004-20 10:40:20.420 7099-7099/com.alsafer.expressions I/CameraFramework﹕相机框架getParameters=afeng最大聚焦步长=0;afeng最小聚焦步长=0;防碰撞=自动;防粘连值=关闭,50赫兹,60赫兹,自动;支持自动曝光锁定=true;支持自动白平衡锁=true;亮度=中等;亮度值=低、中、高;亮度值=39;突发数量=1;cap模式=正常;cap模式值=normal、face_beauty、continuousshot、smileshot、bestshot、evbracketshot、autorama、mav、asd;capfname=/sdcard/DCIM/cap00;对比度=中等;对比度值=低、中、高;edge=中间;边缘值=低、中、高;effect=无;效果值=无、单色、负片、深褐色、浅绿色、白板、黑板;eng闪光占空比最大值=1;eng闪光占空比min=0;eng闪光占空比值=-1;曝光补偿=0;曝光补偿步长=1.0;fbsharp=0;fb sharp max=4;fb锐最小值=-4;fb皮肤颜色=0;fb皮肤颜色最大值=4;fb皮肤颜色最小值=-4;fb平滑级别=0;fb平滑级别max=4;fb平滑水平min=-4;焦距=3.5;焦距=0.95,1.9,无穷大;聚焦模式=无穷大;聚焦模式值=无穷大;水平视角=54;色调=中间;色调值=低、中、高;iso速度=自动;iso速度值=自动,1002004008001600;jpeg质量=100;jpeg缩略图高度=128;jpeg缩略图质量=100;jpeg缩略图大小值=0x0160x128320x240;jpeg缩略图宽度=160;最大曝光补偿=3;检测到的最大人脸数量hw=15;检测到的最大人脸数量sw=0;最大聚焦区域数=0;最大计量区域数=9;最大缩放=10;最小曝光补偿=-3;mtk凸轮模式=0;图片格式=jpeg;图片格式值=jpeg;图片大小=2560x1920;图片大小值=320x240640x4801024x7681280x7201280x7681280x9601600x12002048x15362560x14402560x19202880x1728;视频的首选预览大小=1280x720;预览格式=yuv420sp;预览格式值=yuv420sp、yuv420p、yuv420-yyuvyy-3平面;预览fps范围=500060000;预览fps范围值=(500060000);预览帧速率=30;预览帧速率值=15,24,30;预览大小=640x480;预览大小值=176x144320x240352x288480x320480x368640x480720x480800x480800x600864x480960x5401280x720;旋转=0;饱和度=中等;饱和度值=低、中、高;场景模式=自动;场景模式值=自动,肖像,风景,夜晚,夜间肖像,剧院,海滩,雪,日落,稳定照片,烟花,体育,派对,烛光,hdr;传感器类型=254;支持平滑缩放=true;垂直视角=49;视频帧格式=yuv420p;视频大小=640x480;视频大小值=176x144480x320640x480864x4801280x7201920x1080;支持的视频快照=false;视频稳定=错误;支持视频稳定=true;白平衡=自动;白平衡值=自动、白炽、荧光、暖荧光、日光、阴天、黄昏、阴影;缩放=0;缩放比例=100114132151174200229263303348400;支持缩放=true;zsd模式=关闭;zsd模式值=关闭,打开04-20 10:40:20.457 7099-7099/com.alsafer.expressions D/Camera JNI﹕setHasPreviewCallback:已安装:0,manualBuffer:004-20 10:40:20.458 7099-7112/com.alsafer.expressions W/摄像头JNI﹕对静态摄影机对象的回调04-20 10:40:20.458 7099-7099/com.alsafer.expressions D/Camera JNI﹕(tid:7099)[本地释放]+上下文=0x66e3fc70相机=0x63f70e3004-20 10:40:20.458 7099-7099/com.alsafer.expressions D/Camera JNI﹕[native_release]context->getStrongCount(2)camera->getStrongeCount(204-20 10:40:21.023 7099-7099/com.alsafer.expressions D/Camera JNI﹕(tid:7099)[本地释放]-上下文=0x66e3fc70相机=0x004-20 10:40:21.023 7099-7099/com.alsafer.expressions D/Camera JNI﹕(tid:7099)[释放相机]-X上下文=0x66e3fc7004-20 10:40:21.024 7099-7111/com.alsafer.expressions D/IPCThreadState﹕[DN#5]BR_CLEAR_DEATH_NOTIFICATION_DONE cookie 0x66e3fba804-20 10:40:21.027 7099-7151/com.alsafer.expressions D/Camera JNI﹕(tid:7151)[~MtkJNICameraContext]this:0x66e3fc7004-20 10:40:21.066 7099-7099/com.alsafer.expressions I/Choreographer﹕跳过了41帧!应用程序可能在其主线程上做了太多的工作。04-20 10:40:21.089 7099-7099/com.alsafer.expressions D/GraphicBuffer﹕创建句柄(0x623e35c0)(w:480,h:790,f:1)04-20 10:40:221.121 7099-7099/com.alsafer.expressions I/SurfaceTextureClient﹕[STC::queueBuffer](此值:0x63159d68)fps:009,dur:10931.96,max:10931.96,min:10931.19604-20 10:40:221.121 7099-7099/com.alsafer.expressions I/SurfaceTextureClient﹕[STC::queueBuffer]this:0x63159d68,api:1,上一次队列运行时间:10931.9604-20 10:40:21.130 7099-7099/com.alsafer.expressions D/OpenGLRenderer﹕刷新缓存(模式0)

似乎每次应用程序恢复(onResume)时,您都在重新创建CameraPreview视图并将其添加到布局中。当你在你的应用程序中,切换到另一个应用程序,然后再回来时,这个问题也会发生吗?如果在这种情况下它也冻结了,我怀疑在添加新的CameraPreview视图实例之前,您需要从布局中删除旧的CameraPreviewView实例。

最新更新