我想将zbar扫描仪的相机预览放到我现有的布局中,但是我试图把它放在一起的地方总是保持黑色并且不能启动相机读取qrs。如果我不使用自定义布局,但示例中的那个(它在所有新活动中启动扫描仪并且它占用了所有屏幕大小)一切都很好。这意味着我没有权限或类似的问题。 这是我现在使用的代码:
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 com.dm.zbar.android.scanner.CameraPreview;
import com.dm.zbar.android.scanner.ZBarConstants;
import com.dm.zbar.android.scanner.ZBarScannerActivity;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.text.TextUtils;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.widget.TextView;
import android.widget.Toast;
public class PointGivingActivity extends Activity implements Camera.PreviewCallback, ZBarConstants{
private static final int ZBAR_SCANNER_REQUEST = 0;
private static final int ZBAR_QR_SCANNER_REQUEST = 1;
private static final String TAG = "ZBarScannerActivity";
private CameraPreview mPreview;
private Camera mCamera;
private ImageScanner mScanner;
private Handler mAutoFocusHandler;
private boolean mPreviewing = true;
static {
System.loadLibrary("iconv");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!isCameraAvailable()) {
cancelRequest();
return;
}
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_point_giving2);
mAutoFocusHandler = new Handler();
setupScanner();
LinearLayout zbarLayout = (LinearLayout) findViewById(R.id.zbar_layout_area);
mPreview = new CameraPreview(zbarLayout.getContext(), this, autoFocusCB);
mPreview.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
zbarLayout.addView(mPreview);
}
public void launchScanner(View v) {
if (isCameraAvailable()) {
Intent intent = new Intent(this, ZBarScannerActivity.class);
startActivityForResult(intent, ZBAR_SCANNER_REQUEST);
} else {
Toast.makeText(this, "Rear Facing Camera Unavailable",
Toast.LENGTH_SHORT).show();
}
}
public void launchScanner() {
if (isCameraAvailable()) {
Intent intent = new Intent(this, ZBarScannerActivity.class);
startActivityForResult(intent, ZBAR_SCANNER_REQUEST);
} else {
Toast.makeText(this, "Rear Facing Camera Unavailable",
Toast.LENGTH_SHORT).show();
}
}
public void launchQRScanner(View v) {
if (isCameraAvailable()) {
Intent intent = new Intent(this, ZBarScannerActivity.class);
intent.putExtra(ZBarConstants.SCAN_MODES,
new int[] { Symbol.QRCODE });
startActivityForResult(intent, ZBAR_SCANNER_REQUEST);
} else {
Toast.makeText(this, "Rear Facing Camera Unavailable",
Toast.LENGTH_SHORT).show();
}
}
public void MyMethod(View v) {
Intent intent = new Intent(this, ZBarScannerActivity.class);
startActivityForResult(intent, ZBAR_SCANNER_REQUEST);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
TextView someText = (TextView) findViewById(R.id.givePointtv1);
someText.setText(data.getStringExtra(ZBarConstants.SCAN_RESULT));
// Toast.makeText(this, "Scan Result = " +
// data.getStringExtra(ZBarConstants.SCAN_RESULT),
// Toast.LENGTH_SHORT).show();
// Toast.makeText(this, "Scan Result Type = " +
// data.getStringExtra(ZBarConstants.SCAN_RESULT_TYPE),
// Toast.LENGTH_SHORT).show();
} else if (resultCode == RESULT_CANCELED) {
// Toast.makeText(this, "Camera unavailable",
// Toast.LENGTH_SHORT).show();
}
}
public boolean isCameraAvailable() {
PackageManager pm = getPackageManager();
return pm.hasSystemFeature(PackageManager.FEATURE_CAMERA);
}
public void cancelRequest() {
Intent dataIntent = new Intent();
dataIntent.putExtra(ERROR_INFO, "Camera unavailable");
setResult(Activity.RESULT_CANCELED, dataIntent);
finish();
}
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 = mScanner.scanImage(barcode);
if (result != 0) {
mCamera.cancelAutoFocus();
mCamera.setPreviewCallback(null);
mCamera.stopPreview();
mPreviewing = false;
SymbolSet syms = mScanner.getResults();
for (Symbol sym : syms) {
String symData = sym.getData();
if (!TextUtils.isEmpty(symData)) {
Intent dataIntent = new Intent();
dataIntent.putExtra(SCAN_RESULT, symData);
dataIntent.putExtra(SCAN_RESULT_TYPE, sym.getType());
setResult(Activity.RESULT_OK, dataIntent);
finish();
break;
}
}
}
}
private Runnable doAutoFocus = new Runnable() {
public void run() {
if(mCamera != null && mPreviewing) {
mCamera.autoFocus(autoFocusCB);
}
}
};
// Mimic continuous auto-focusing
Camera.AutoFocusCallback autoFocusCB = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
mAutoFocusHandler.postDelayed(doAutoFocus, 1000);
}
};
public void setupScanner() {
mScanner = new ImageScanner();
mScanner.setConfig(0, Config.X_DENSITY, 3);
mScanner.setConfig(0, Config.Y_DENSITY, 3);
int[] symbols = getIntent().getIntArrayExtra(SCAN_MODES);
if (symbols != null) {
mScanner.setConfig(Symbol.NONE, Config.ENABLE, 0);
for (int symbol : symbols) {
mScanner.setConfig(symbol, Config.ENABLE, 1);
}
}
}
}
我很确定问题就在这里:
LinearLayout zbarLayout = (LinearLayout) findViewById(R.id.zbar_layout_area);
mPreview = new CameraPreview(zbarLayout.getContext(), this, autoFocusCB);
mPreview.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
zbarLayout.addView(mPreview);
但是无法弄清楚如何让它按照我想要的方式运作。
这是我的xml文件,如果需要的话
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/pointgivingll1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#f1f1f1"
android:orientation="vertical"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:weightSum="10" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
android:weightSum="8" >
<Button
android:id="@+id/givePointMenuBut"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:visibility="invisible" />
<TextView
android:id="@+id/givePointtv1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="6"
android:gravity="center"
android:text="@string/pointGiving"
android:textColor="@android:color/black"
android:textSize="22sp" />
<Button
android:id="@+id/givePointMenuBut"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
android:layout_marginTop="10dp"
android:layout_weight="1"
android:gravity="center"
android:text="@string/ruchno"
android:textSize="10sp" />
</LinearLayout>
<LinearLayout
android:gravity="center"
android:layout_weight="9"
android:id="@+id/zbar_layout_area"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="vertical" >
</LinearLayout>
</LinearLayout>
答案 0 :(得分:0)
我遇到了同样的问题,并通过以编程方式向FrameLayout添加/删除视图来做一些技巧。我在这里找到了这个解决方案:
Customize Camera View for Android using zbar
这是我的activity_qr_code_reader.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@android:color/black" >
<FrameLayout
android:id="@+id/flytCamera"
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1" >
<ImageView
android:id="@+id/ivScanner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/im_qr_scan"/>
</FrameLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:padding="10dp"
android:textColor="@android:color/white"
android:textSize="16sp"
android:background="@color/transparent_black"
android:text="@string/qr_code_reading"/>
</LinearLayout>
到目前为止,我在底部有一个信息文本视图和一个QR码阅读框图像(只有4个白角)。我想将相机预览放在整个FrameLayout中,但最终只将它放在中心位置。这是代码。它并不完美,但至少更加用户友好。
public class QRCodeReaderActivity extends ZBarScannerActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_qr_code_reader);
FrameLayout flytCamera = (FrameLayout) findViewById(R.id.flytCamera);
ImageView ivScanner = (ImageView) findViewById(R.id.ivScanner);
flytCamera.addView(mPreview);
flytCamera.removeView(ivScanner);
flytCamera.addView(ivScanner);
}
}
是的,我希望我的ZBarScanner是肖像,所以我也强迫相机旋转90度。
http://developer.android.com/reference/android/hardware/Camera.html#setDisplayOrientation(int)
@Override
protected void onResume() {
super.onResume();
setCameraDisplayOrientation(this, Camera.CameraInfo.CAMERA_FACING_BACK, mCamera);
}
public static void setCameraDisplayOrientation(Activity activity,
int cameraId, android.hardware.Camera camera) {
android.hardware.Camera.CameraInfo info =
new android.hardware.Camera.CameraInfo();
android.hardware.Camera.getCameraInfo(cameraId, info);
int rotation = activity.getWindowManager().getDefaultDisplay()
.getRotation();
int degrees = 0;
switch (rotation) {
case Surface.ROTATION_0: degrees = 0; break;
case Surface.ROTATION_90: degrees = 90; break;
case Surface.ROTATION_180: degrees = 180; break;
case Surface.ROTATION_270: degrees = 270; break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // compensate the mirror
} else { // back-facing
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
}