2016-12-23 15 views
5

Podążam za następującą wersją tutorial, która korzysta z mobilnego api wizji do stworzenia skanera kodów kreskowych/kodów QR. Mimo, że wprowadziłem dokładny kod, o którym mówiono (przynajmniej myślę), kamera jest zasilana z cameraSource.Barcode Mobile VisionScanner: Dlaczego SurfaceView nie aktualizuje CameraSource?

Dodałem dodatkowy kod w procesie, aby sprawdzić, czy to by miało znaczenie, ale nadal nie ma. Problem polega na tym, że po uruchomieniu aplikacji SurfaceView powinien być wyświetlany kanał informacyjny CAMERA_FACING_BACK, ale zamiast tego jest on czarny. Jeśli mógłbyś mi powiedzieć, dlaczego plik nie pojawia się, a jeśli jest, kod, który musi się zmienić, będzie to bardzo doceniane.

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> 

Odpowiedz

1

Nieważne, wyobraziłem to na własną rękę, choć myślę, że inni mogą zadać to samo pytanie po tutorialu, więc pokażę ci, co poszło nie tak. Widzisz, chociaż zadeklarowałem pozwolenie w Manifeście, android.permissions.CAMERA jest "zezwoleniem na wysokie ryzyko", co oznacza, że ​​użytkownik musi ręcznie wyrazić na to zgodę, zanim zostanie wprowadzony w błąd. Ponieważ nigdy nie utworzyłem okna dialogowego uprawnień, aby poprosić o nie bezpośrednio użytkownika, nie można wykonać całego kodu za pomocą uprawnień kamery, co daje nam pusty ekran w porównaniu do kanału kamery. Prostą poprawką jest przejście do ustawień i zezwolenie tam, ale zamiast tego można użyć następującego kodu, wygodnie żądając pozwolenia kamery z okna dialogowego;

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's 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's 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; 
      } 
     } 
    } 
} 

Proszę wybaczyć niektóre z mojego kodu serwera. Przesyłałem także wyniki do bazy danych typu firebase. Reszta jest jednak identyczna. Układy mają kilka drobnych poprawek do skalowania, ale reszta jest taka sama. Powodzenia!

+1

Kiedy użytkownik zezwala na ponowne uruchamianie pełnej aktywności? – androidnoobdev

+0

@androidnoobdev Tak, działanie zostanie wznowione. –