Problem mit Zxing Scanner

  • 1 Antworten
  • Letztes Antwortdatum
S

SpecialFighter108

App-Anbieter (In-App)
4
Guten Morgen alle zusammen,

ich habe in meiner Android app den Barcode Scanner von Zxing eingebunden.
Dieser funktioniert auch ganz gut, bis auf eine winzige, aber wichtige Sache.
Meine App wird ausschließlich im Portait Mode verwendet.

Scannen ich einen Barcode, der horizontal verläuft (genau so wie die rote Linie), wird dieser Barcode erfolgreich erkannt und gescannt:
Screenshot_2016-01-15-07-50-49.png

Wenn ich aber einen Barcode scanne, welcher nicht horizontal, sondern vertikal verläuft, wird der Barcode nicht erkannt und nicht gescannt:
Screenshot_2016-01-15-07-51-40.png


Das ist die komplette Class des Barcode Scanners.
Habt ihr ne Idee wie ich das Problem lösen kann?

Code:
package me.dm7.barcodescanner.zxing.sample;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.zxing.Result;
import me.dm7.barcodescanner.zxing.ZXingScannerView;

public class Scanner extends AppCompatActivity implements ZXingScannerView.ResultHandler {
   private static final String CAMERA_ID = "CAMERA_ID";
    private ZXingScannerView mScannerView;
   private int mCameraId = -1;
    Intent intent;

    @Override
    public void onCreate(Bundle state) {
        super.onCreate(state);
        setContentView(R.layout.barcode_scanner);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);


        if(state != null) {
           mCameraId = state.getInt(CAMERA_ID, -1);
        } else {
           mCameraId = -1;
        }


        RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.ScannerLayout);
        mScannerView = new ZXingScannerView(this);
        relativeLayout.addView(mScannerView);
    }


    @Override
    public void onResume() {
        super.onResume();
        mScannerView.setResultHandler(this);
        mScannerView.startCamera(mCameraId);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putInt(CAMERA_ID, mCameraId);
    }


    @Override
    public void handleResult(Result rawResult) {
            Intent intent = new Intent(Scanner.this, LoadingData.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);
        }
    }


    @Override
    public void onPause() {
        super.onPause();
        mScannerView.stopCamera();
    }
}
 
Da kann man dir nicht so ohne weiteres helfen hier. Das "Problem" liegt im Framework. Wie es die Bilddaten liest findet nicht in deinem Code statt und da kannst du nichts machen.

Ich habe nach kurzer Recherche jedenfalls keine Möglichkeiten in den Docs gefunden wie man die Leseausrichtung ändert. Du hast ja die rote Linie in der Mitte. Darüber scannt er ja bestimmt den Code und wenn du das Telefon schräg hältst liest er halt nichts.

Vllt kann dir dort jrmand weiterhelfen.
Google Groups


Oder andere Idee:

Das ist ein Ausschnitt aus der ZXingScannerView wo ich die Auswertung vermute:
Code:
@Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        if(mResultHandler == null) {
            return;
        }
      
        try {
            Camera.Parameters parameters = camera.getParameters();
            Camera.Size size = parameters.getPreviewSize();
            int width = size.width;
            int height = size.height;

            if (DisplayUtils.getScreenOrientation(getContext()) == Configuration.ORIENTATION_PORTRAIT) {
                byte[] rotatedData = new byte[data.length];
                for (int y = 0; y < height; y++) {
                    for (int x = 0; x < width; x++)
                        rotatedData[x * height + height - y - 1] = data[x + y * width];
                }
                int tmp = width;
                width = height;
                height = tmp;
                data = rotatedData;
            }

            Result rawResult = null;
            PlanarYUVLuminanceSource source = buildLuminanceSource(data, width, height);

            if (source != null) {
                BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
                try {
                    rawResult = mMultiFormatReader.decodeWithState(bitmap);
                } catch (ReaderException re) {
                    // continue
                } catch (NullPointerException npe) {
                    // This is terrible
                } catch (ArrayIndexOutOfBoundsException aoe) {

                } finally {
                    mMultiFormatReader.reset();
                }
            }

            final Result finalRawResult = rawResult;

            if (finalRawResult != null) {
                Handler handler = new Handler(Looper.getMainLooper());
                handler.post(new Runnable() {
                    @Override
                    public void run() {
                        // Stopping the preview can take a little long.
                        // So we want to set result handler to null to discard subsequent calls to
                        // onPreviewFrame.
                        ResultHandler tmpResultHandler = mResultHandler;
                        mResultHandler = null;

                        stopCameraPreview();
                        if (tmpResultHandler != null) {
                            tmpResultHandler.handleResult(finalRawResult);
                        }
                    }
                });
            } else {
                camera.setOneShotPreviewCallback(this);
            }
        } catch(RuntimeException e) {
            // TODO: Terrible hack. It is possible that this method is invoked after camera is released.
            Log.e(TAG, e.toString(), e);
        }
    }

Vor allem hier drauf achten dort werden die Daten entweder gedreht oder nciht so wie es aussieht je nach Stellung des Screens.

Code:
            if (DisplayUtils.getScreenOrientation(getContext()) == Configuration.ORIENTATION_PORTRAIT) {
                byte[] rotatedData = new byte[data.length];
                for (int y = 0; y < height; y++) {
                    for (int x = 0; x < width; x++)
                        rotatedData[x * height + height - y - 1] = data[x + y * width];
                }
                int tmp = width;
                width = height;
                height = tmp;
                data = rotatedData;
            }

Ich hab auf SO gelesen dass das Framework mit der Rotation des Gerätes mitgeht. Du könntest aus deiner App heraus die Rotation des Androids vllt (Ob das so einfach ist ohne Root weiß ich nicht, noch nie gemacht) ändern um so den gewünschten Effekt zu kriegen. Ob Automatisch oder Manuell vom User einstellbar ist dir überlassen.

Aber auf der anderen Seite kann man das auch so lassen wie es ist. Es gibt unzählige scanner die ganauso arbeiten, wie z.B. in Tankstellen wo man so ein Handgerät benutzt da muss man bei manchen Geräten eben auch darauf achten dass der Laser waagerecht steht und den gesamten Code erfasst
 
  • Danke
Reaktionen: SpecialFighter108
Zurück
Oben Unten