Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QR code scanning without fullscreen camera

I need to continuously scan QR codes in my Android app while the main View of the app is on the screen. The main view should contain a window with camera preview, but not a fullscreen camera preview.

An example of usage: Main view containing a list of scanned QR codes and a camera preview. When new QR code is scanned, it is added to the list.

Is it possible?

like image 791
tomashnilica Avatar asked May 16 '13 10:05

tomashnilica


People also ask

Can you scan QR codes without camera?

If you have access to a web browser (any browser – on your phone, laptop/desktop or “other”) you can upload the QR code to a site that will decode it for you. If you're using an Android device or you already have the Google App (which is also available for the iPhone or iPad).

Can I scan QR code with front camera?

You can scan QR codes on an Android device using the default camera app or the Google Lens app.

Is it possible to scan a QR code through a screenshot?

Open the Google Lens app, and go to the “image” option. Select the screenshot with the QR code. The app will scan the code, and generate its link in seconds. You can select the “only the QR code” option if there is text, or any other element on the image.

How do I scan a QR code if my camera is not working?

If you're holding your phone too close or too far away, it won't scan the code. Try holding your phone about 30 cm (1 foot) away and slowly moving it towards the QR code. Some phone cameras can't focus as well as others close up, so you may have to hold your phone a bit further away.


2 Answers

I don't have an fully working example, but I can give you snippets from an project of mine where I also put the camera previews in an smaller view than the full screen. I just want to convey the idea.

What you need is a FrameLayout which will hold the camera preview

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/absoluteLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@android:color/transparent"
    android:orientation="vertical" >

    <FrameLayout
        android:id="@+id/camera_preview"
        android:layout_width="200dp"
        android:layout_height="200dip" >
    </FrameLayout>

</RelativeLayout>

Now we need a PreviewListener which is also an View

import java.io.IOException;

import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/** A basic Camera preview class */
public class CameraPreviewListener extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder mHolder;
    private Camera mCamera;

    public CameraPreviewListener(Context context, Camera camera) {
        super(context);
        mCamera = camera;

        // 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.
        mCamera.setPreviewDisplay(holder);
        mCamera.startPreview();
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        // Take care of releasing the Camera preview in your activity.
        Log.d("camera", "surfaceDestroyed");
        if(holder.equals(mHolder)){
            holder.removeCallback(this);            
        }else{
            holder.removeCallback(this);
            mHolder.removeCallback(this);
        }
    }

    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
        // 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){
            e.printStackTrace();
          // ignore: tried to stop a non-existent preview
        }

        // set preview size and make any resize, rotate or
        // reformatting changes here

        // start preview with new settings
        try {
            mCamera.setPreviewDisplay(mHolder);
            mCamera.startPreview();

        } catch (Exception e){
            Log.d("camera", "Error starting camera preview: " + e.getMessage());
        }
    }

    public void removeCallback(){
        mHolder = getHolder();
        mHolder.removeCallback(this);
    }
}

Finally you need to assemble everything in you activity

import android.hardware.Camera;

Camera mCamera =  = getCameraInstance();
CameraPreviewListener cpl = new CameraPreviewListener(this, mCamera);
FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
preview.addView(cpl);

To get the camera you can use the following method

/** A safe way to get an instance of the Camera object. */
public Camera getCameraInstance() {
    Camera c = null;
    try {
        c = Camera.open(); // attempt to get a Camera instance
        Parameters p = c.getParameters();
        List<Size> sizes = p.getSupportedPictureSizes();

        Size x = null;

        if (sizes.size() < 1) {
            throw new Exception("there are not supported picture sizes at all !!!");
        }

        for (Size s : sizes) {
            if (s.width == 640 && s.height == 480) {
                x = s;
            }
        }

        if (x == null) {
            x = sizes.get(0);
            p.setPictureSize(x.width, x.height);
        } else {
            p.setPictureSize(640, 480);
        }
        p.setJpegQuality(20);
        p.setGpsLatitude(MapViewer.latitude);
        p.setGpsLongitude(MapViewer.longitude);
        c.setParameters(p);
    } catch (Exception e) {
        // Camera is not available (in use or does not exist)
        Log.d(TAG + "(getCameraInstance)", e.getMessage());
    }
    return c; // returns null if camera is unavailable
}
like image 115
Westranger Avatar answered Oct 01 '22 22:10

Westranger


Hope this work with you, You can capture image from background without opening camera app

https://stackoverflow.com/a/24849344/1312796

like image 24
Ibrahim AbdelGawad Avatar answered Oct 02 '22 00:10

Ibrahim AbdelGawad