我正在开发一个Android应用程序,允许用户检查QR码内容并根据读取结果执行某些操作。
为了提高性能,我想实现两种方法:
我已经做了一些挖掘,并发现对于管理相机和闪光灯我需要能够将Camera
作为对象本身进行管理。
这就是噩梦开始的地方。
我使用以下代码显示相机结果并跟踪QR码。
import android.app.FragmentTransaction;
import android.content.Context;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.util.SparseArray;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.TextView;
import com.google.android.gms.vision.Detector;
import com.google.android.gms.vision.barcode.Barcode;
import com.google.android.gms.vision.barcode.BarcodeDetector;
import java.io.IOException;
public class MainReadActivity extends AppCompatActivity {
public SurfaceView cameraView;
private TextView barcodeInfo;
public BarcodeDetector barcodeDetector;
public CameraSource cameraSource;
public Vibrator v;
public String textInfo;
public DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_read);
v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout_main);
getSupportFragmentManager().findFragmentById(R.id.drawer_layout_main);
cameraView = (SurfaceView) findViewById(R.id.camera_view);
//barcodeInfo = (TextView) findViewById(R.id.code_info);
barcodeDetector = new BarcodeDetector.Builder(this)
.setBarcodeFormats(Barcode.QR_CODE)
.build();
cameraSource = new CameraSource.Builder(this, barcodeDetector).build();
cameraView.getHolder().addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
cameraSource.start(cameraView.getHolder());
} catch (IOException ie) {
Log.e("CAMERA SOURCE", ie.getMessage());
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
cameraSource.stop();
}
});
barcodeDetector.setProcessor(new Detector.Processor<Barcode>() {
@Override
public void release() {
}
@Override
public void receiveDetections(Detector.Detections<Barcode> detections) {
final SparseArray<Barcode> barcodes = detections.getDetectedItems();
if (barcodes.size() != 0) {
new Runnable() { // Use the post method of the TextView
public void run() {
v.vibrate(500);
// textInfo = barcodes.valueAt(0).displayValue;
MyFragmentDialog newf = new MyFragmentDialog();
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.fragment_container, newf);
transaction.addToBackStack("tag");
transaction.commit();
}
};
}
}
});
}
public void onBackPressed() {
// do nothing
}
}
所以,我需要从CameraSource访问Camera(我是对的吗?!) 一旦无法实现,我就会尝试使用GoogleSamples git中的这个CameraSource类,它允许使用setFocusMode方法......但不幸的是我没有成功。
我也尝试使用API 21,因为API 22 no longer supports Camera和CameraPreferences。
我很确定这不仅是我的问题,还无法找到解决问题的方法。
任何人都可以提供帮助吗?
FIXED:
只需使用此CameraSource(github.com/googlesamples/android-vision/blob/master/visionSamples/barcode-reader/app/src/main/java/com/google/android/gms/samples/vision/barcodereader/ ui / camera / CameraSource.java)。是的,我知道,我已经建议了......但这次我解决了我的问题!所以,如果您要使用它,请确保您的编译如下所示:
compile 'com.google.android.gms:play-services:8.1.0'
答案 0 :(得分:2)
初始化这些并在OnCreate
Camera.Parameters params;
Camera camera;
CameraSource cameraSource;
SurfaceView cameraView;
boolean isFlash = false;
调用changeFlashStatus()
方法打开闪光灯并再次调用它以关闭闪光灯
public void changeFlashStatus() {
Field[] declaredFields = CameraSource.class.getDeclaredFields();
for (Field field : declaredFields) {
if (field.getType() == Camera.class) {
field.setAccessible(true);
try {
camera = (Camera) field.get(cameraSource);
if (camera != null) {
params = camera.getParameters();
if (!isFlash) {
params.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
flashImage.setColorFilter(getResources().getColor(R.color.yellow));
isFlash = true;
} else {
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
flashImage.setColorFilter(getResources().getColor(R.color.greyLight));
isFlash = false;
}
camera.setParameters(params);
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
break;
}
}
}
要使相机对焦,您需要一个特定区域(Rect
)将其传递给相机以对焦于该区域。因此,我们必须为onTouchListener()
实施surfaceView
,因此当我们触摸surfaceView
时,我们会创建MotionEvent
,这决定了您在何处触及surfaceView
然后我们就可以提取来自Rect
的{{1}}。
在OnCreate中调用MotionEvent
。在相机启动后安全地调用它
initCameraFocusListener()
答案 1 :(得分:0)
我使用这个库,它工作得很好,而且易于实现
答案 2 :(得分:0)
在这里回答:Google Vision API Samples: Get the CameraSource to Focus
使用自动对焦
.setAutoFocusEnabled(true)
CameraSource.Builder()