Mobile Vision barcodeScanner: Why SurfaceView does not update CameraSource?

I am following the next tutorial , which uses mobile vision api to create a barcode / qr code scanner. Although I entered the exact code that he said (at least I think), the camera is powered by cameraSource .

I added extra code to this process to see if it would make a difference, but it still doesn't. The problem is that when you start the SurfaceView application, which should display the CAMERA_FACING_BACK feed, but instead it's just black. If you could tell me why the feed is not displayed, and if there is one, then the code that needs to be changed will be very grateful.

MainActivity.java:

 package com.example.neekondev.barcodeshortened; import android.Manifest; import android.content.pm.PackageManager; import android.support.v4.app.ActivityCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; 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.CameraSource; 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; import static com.google.android.gms.vision.CameraSource.CAMERA_FACING_BACK; import static com.google.android.gms.vision.CameraSource.CAMERA_FACING_FRONT; public class MainActivity extends AppCompatActivity { SurfaceView cameraView; TextView barcodeInfo; BarcodeDetector barcodeDetector; CameraSource cameraSource; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); cameraView = (SurfaceView) findViewById(R.id.camera_view); barcodeInfo = (TextView) findViewById(R.id.code_info); barcodeDetector = new BarcodeDetector.Builder(this) .setBarcodeFormats(Barcode.CODE_39 | Barcode.CODE_93 | Barcode.CODE_128) .build(); cameraSource = new CameraSource .Builder(this, barcodeDetector) .setRequestedPreviewSize(640, 480) .setRequestedFps(20.0f) .setFacing(CAMERA_FACING_BACK) .build(); cameraView.getHolder().addCallback(new SurfaceHolder.Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { try { if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { // TODO: Consider calling // ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; } 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) { barcodeInfo.post(new Runnable() { // Use the post method of the TextView public void run() { barcodeInfo.setText( // Update the TextView barcodes.valueAt(0).displayValue ); } }); } } }); } } 

activity_main.xml:

 <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.neekondev.barcodeshortened.MainActivity"> <SurfaceView android:layout_width="640px" android:layout_height="480px" android:layout_centerVertical="true" android:layout_alignParentLeft="true" android:id="@+id/camera_view" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/code_info" android:layout_toRightOf="@+id/camera_view" android:textSize="20sp" android:layout_marginLeft="16dp" android:text="Nothing yet..." android:layout_alignParentTop="true" /> </RelativeLayout> 

manifest.xml:

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.neekondev.barcodeshortened"> <meta-data android:name="com.google.android.gms.vision.DEPENDENCIES" android:value="barcode"/> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.Camera"/> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 
+5
source share
1 answer

Never think, I understood this on my own, although I think that others may ask the same question after the tutorial, so I will show you what went wrong. You see, although I proclaimed permission in the manifest, android.permissions.CAMERA is a β€œhigh risk resolution”, which means that the user must manually agree with him before it can be implanted. Since I never made a dialog box with permissions to request it directly from the user, all the code using the camera resolution could not be executed, which gave us a blank screen and camera feed. A simple fix is ​​to enter the settings and allow access there, but instead, you can use the following code, conveniently requesting camera resolution using the dialog box;

 import android.Manifest; import android.content.Intent; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.hardware.Camera; import android.media.Image; import android.os.Bundle; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.util.SparseArray; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.TextView; import com.google.android.gms.vision.CameraSource; import com.google.android.gms.vision.Detector; import com.google.android.gms.vision.barcode.Barcode; import com.google.android.gms.vision.barcode.BarcodeDetector; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import java.io.IOException; import java.text.DateFormat; import java.util.ArrayList; import java.util.Date; import static junit.framework.Assert.assertNotNull; public class MainActivity extends AppCompatActivity { FirebaseDatabase database; DatabaseReference myRef; SurfaceView cameraView; TextView barcodeInfo; BarcodeDetector barcodeDetector; CameraSource cameraSource; private static final int CAMERA_PERMISSION_CAMERA = 0x000000; public static boolean position = false; //Camera cam; //Camera.Parameters p; @Override protected void onCreate(Bundle savedInstanceState) { setRequestedOrientation(ActivityInfo .SCREEN_ORIENTATION_PORTRAIT); super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (ContextCompat.checkSelfPermission(MainActivity .this, Manifest .permission .CAMERA) != PackageManager .PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity .this, Manifest .permission .CAMERA)) { // Show an explanation to the user *asynchronously* -- don't block // this thread waiting for the user response! After the user // sees the explanation, try again to request the permission. } else { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(MainActivity .this, new String[]{Manifest.permission .CAMERA}, CAMERA_PERMISSION_CAMERA); // CAMERA_PERMISSION_CAMERA is an // app-defined int constant. The callback method gets the // result of the request. } } cameraView = (SurfaceView) findViewById(R .id .camera_view); barcodeInfo = (TextView) findViewById(R .id .code_info); MainActivity .this .getPackageManager() .hasSystemFeature (PackageManager .FEATURE_CAMERA_FLASH); barcodeDetector = new BarcodeDetector.Builder(getApplicationContext()) .setBarcodeFormats(Barcode.ALL_FORMATS) .build(); cameraSource = new CameraSource .Builder(getApplicationContext(), barcodeDetector) .setFacing(CameraSource.CAMERA_FACING_BACK) .setRequestedFps(35.0f) .setRequestedPreviewSize(960, 960) .setAutoFocusEnabled(true) .build(); //setupButtons(); cameraView.getHolder().addCallback(new SurfaceHolder .Callback() { @Override public void surfaceCreated(SurfaceHolder holder) { try { if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { // TODO: CONSIDER CALLING //ActivityCompat#requestPermissions // here to request the missing permissions, and then overriding // public void onRequestPermissionsResult(int requestCode, String[] permissions, // int[] grantResults) // to handle the case where the user grants the permission. See the documentation // for ActivityCompat#requestPermissions for more details. return; } 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(); database = FirebaseDatabase.getInstance(); myRef = database .getReference(getTime()); if (barcodes .size() != 0) { barcodeInfo .post(new Runnable() { // Use the post method of the TextView public void run() { barcodeInfo.setText(barcodes .valueAt(0) .displayValue ); myRef.setValue(barcodes .valueAt(0) .displayValue ); } }); } } }); } /* public void FLASH_ON() { cam = Camera.open(); p = cam.getParameters(); p.setFlashMode(Camera .Parameters .FLASH_MODE_TORCH); cam.setParameters(p); cam.startPreview(); } public void FLASH_OFF() {cam.stopPreview(); cam.release();} public void setupButtons() { ImageButton flash = (ImageButton)findViewById(R.id.flash); flash.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (position == false) { FLASH_ON(); position = true; } if (position == true) { FLASH_OFF(); position = false; } } }); }*/ public String getTime() { String downToSeconds = DateFormat .getDateTimeInstance() .format( new Date()); return downToSeconds; } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case CAMERA_PERMISSION_CAMERA: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager .PERMISSION_GRANTED) { Intent startMain = new Intent(MainActivity .this, MainActivity .class); startActivity(startMain); } else { if (ContextCompat.checkSelfPermission(MainActivity .this, Manifest .permission .CAMERA) != PackageManager .PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity .this, Manifest .permission .CAMERA)) { // Show an explanation to the user *asynchronously* -- don't block // this thread waiting for the user response! After the user // sees the explanation, try again to request the permission. } else { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(MainActivity .this, new String[]{Manifest.permission .CAMERA}, CAMERA_PERMISSION_CAMERA); // CAMERA_PERMISSION_CAMERA is an // app-defined int constant. The callback method gets the // result of the request. } } } return; } } } } 

Please excuse my server code. I also uploaded the results to the firebase database. The rest are identical. Layouts have some minor adjustments for scaling, but the rest is the same. Good luck

+1
source

Source: https://habr.com/ru/post/1261756/


All Articles