2016-09-22 6 views
7

को फ्रीज करने का कारण बन रहा है, मैं एक ऐप बना रहा हूं जिसमें Google दृष्टि एपीआई का उपयोग कर एक क्यूआर स्कैनर है। क्यूआर कोड पढ़ने के बाद मुझे कैमरे को रोकने में परेशानी हो रही है। प्रवाह MainActivity -> QrActivity एक बार qr-code को पहचानने के बाद ऐप को मुख्य गतिविधि पर वापस जाना चाहिए।एंड्रॉइड कैमरासोर्स.स्टॉप() ऐप को

यदि मैं cameraSource.release() पर कॉल नहीं करता हूं तो यह ठीक काम करता है लेकिन डिवाइस बहुत गर्म हो जाता है और बैटरी नाली पर इसका महत्वपूर्ण प्रभाव पड़ता है। हालांकि अगर मैं कैमरा स्रोत जारी करता हूं तो मुख्य गतिविधि असंगत हो जाती है और ऐप क्रैश हो जाएगा।

यह उत्तरदायी क्यों हो रहा है? और कैमरा स्रोत को जारी करने के लिए सही जगह कहां है?

QrActivity

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_qr); 
    cancelBtn = (Button) findViewById(R.id.cancel_button); 
    cancelBtn.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      onBackPressed(); 
     } 
    }); 

    new QrReader(this); 
} 

QrReader कक्षा

public class QrReader { 

    private static final String TAG = "QrReader"; 

    private SurfaceView cameraView; 
    private TextView barcodeInfo; 
    private BarcodeDetector barcodeDetector; 
    private CameraSource cameraSource; 
    private Activity mActivity; 
    private AccessPointCredentials barCodeData; 

    public QrReader(Activity activity) { 
     this.mActivity = activity; 

     cameraView = (SurfaceView) mActivity.findViewById(R.id.camera_view); 
     barcodeInfo = (TextView) mActivity.findViewById(R.id.code_info); 

     barcodeDetector = 
       new BarcodeDetector.Builder(mActivity) 
         .setBarcodeFormats(Barcode.QR_CODE) 
         .build(); 

     cameraSource = new CameraSource 
       .Builder(mActivity, barcodeDetector) 
       .setAutoFocusEnabled(true) 
       .build(); 

     cameraView.getHolder().addCallback(new SurfaceHolder.Callback() { 

      @Override 
      public void surfaceCreated(SurfaceHolder holder) { 

       cameraSource = new CameraSource 
         .Builder(mActivity, barcodeDetector) 
         .setAutoFocusEnabled(true) 
         .setFacing(0) 
         .build(); 
       try {     
        cameraSource.start(cameraView.getHolder()); 

       } catch (Exception ioe) { 
        ioe.printStackTrace(); 
       } 
      } 

      @Override 
      public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
      } 

      @Override 
      public void surfaceDestroyed(SurfaceHolder holder) { 
        // Log.i(TAG, "surfaceDestroyed: stopping camera Source"); 

        // cameraSource.release(); 
      } 
     }); 

     barcodeDetector.setProcessor(new Detector.Processor<Barcode>() { 
      @Override 
      public void release() { 
       Log.i(TAG, "release: "); 
      } 

      @Override 
      public void receiveDetections(Detector.Detections<Barcode> detections) { 
       final SparseArray<Barcode> barCodes = detections.getDetectedItems(); 

       if (barCodes.size() != 0) { 

        Log.i(TAG, "received a Barcode"); 
        barcodeInfo.post(new Runnable() { // Use the post method of the TextView 
         public void run() { 
          barcodeInfo.setText(barCodes.valueAt(0).displayValue); 

         } 
        }); 
        Gson g = new Gson(); 
        try { 
         barCodeData = g.fromJson(barCodes.valueAt(0).rawValue, AccessPointCredentials.class); 
        } catch (Exception e) { 
         barCodeData = new AccessPointCredentials(); 
         barCodeData.setSsid(barCodes.valueAt(0).rawValue); 
         barCodeData.setPass(null); 
         e.printStackTrace(); 
        } 

        connectToWifi(barCodeData); 

        // CameraSource.release causes app to freeze 

        // cameraSource.release(); 
       } 
      } 
     }); 
    } 

    private void connectToWifi(final AccessPointCredentials credentials) { 

       //wificonnect code 

    } 

} 
+1

यकीन है, लेकिन ध्यान दें CameraSource का एक खुला स्रोत की नकल है कि आप अगर आप आगे इस में खुदाई करने के लिए करना चाहते हैं की कोशिश कर सकते है कि वहाँ: https://github.com/googlesamples/android-vision /blob/master/visionSamples/barcode-reader/app/src/main/java/com/google/android/gms/samples/vision/barcodereader/ui/camera/CameraSource.java#L322 – pm0733464

+0

मैंने 'कैमरा सॉस' को कॉल करने का प्रयास किया है। रिलीज() 'दो स्थानों पर टिप्पणी की गई है (' सतह पर आधारित() 'और' प्राप्तकर्ताओं() ' – Lonergan6275

उत्तर

7

यह 3 महीने हो गया है, लेकिन मैं सिर्फ एक ही समस्या पर ठोकर खाई और यह पता लगा। कोड receiveDetections विधि के अंदर एक अलग धागा पर चल रहा है अगर आप कुछ है जो यूआई धागा आप एक हैंडलर से पोस्ट करने की आवश्यकता की जरूरत है क्या करना चाहते हैं तो:

Handler handler = new Handler(Looper.getMainLooper()); 
handler.post(new Runnable() { 
    @Override 
    public void run() { 
     cameraSource.release(); 
    } 
}); 
+0

उत्तर के लिए धन्यवाद, मुझे मौका मिलने के बाद मैं इसे देख लूंगा। – Lonergan6275

+1

निराशाजनक क्रैश के कई घंटों के बाद मैं वास्तव में यह पुष्टि कर सकता हूं कि यह एक थ्रेड मुद्दा है। इस कोड को ursing ^^ के साथ या '' 'view.post (नया रननेबल() {cameraSource.release()} का उपयोग करके)' '' आप इसे ठीक कर सकते हैं – Spidfire

0

heyo, किसी भी अद्यतन? मुझे बस एक ही समस्या का सामना करना पड़ा, मैं उन release विधियों से निपटने का प्रयास करता हूं, लेकिन काम नहीं करता हूं। मुझे केवल एक त्वरित फिक्स/वर्कअराउंड मिला। एक सुरुचिपूर्ण समाधान चाहते हैं।

मेरा मामला है, एक ऐप उपयोगकर्ता एक क्यूआर-कोड स्कैन कर सकता है और फिर भुगतान कर सकता है।

MainActivity

  1. दराज मेनू (https://github.com/mikepenz/MaterialDrawer)
  2. टुकड़ा कंटेनर (परिवर्तन टुकड़े जब उन दराज मेनू पर क्लिक करें)

मेरे सभी अन्य विचार कर रहे हैं टुकड़ा/ListFragment

ScanMainController

  1. BarcodeDetector
  2. CameraSource
  3. SurfaceView

मेरे परिदृश्य इस तरह है, एक बार मैं QR कोड स्कैन किया, मैं एक पृष्ठ पर उपयोग के लिए धक्का भुगतान करने के लिए। लेकिन मुझे क्यूआरकोड स्कैनर को रोकने के लिए एक रास्ता खोजने की जरूरत है क्योंकि मैं केवल receiveDetections को केवल एक बार कॉल करने के लिए चाहता हूं। आईओएस में, मैं delegate to nil सेट करता था जो एंड्रॉइड में cameraSource.release(); के समान काम करता है। लेकिन फिर, मुझे release() विधि को कॉल करने के लिए उचित स्थिति नहीं मिल रही है।

यदि मैं सक्रिय रूप से release() पर कॉल करता हूं, तो जब ड्रॉवर मेनू पर क्लिक करके अन्य पेज पर नेविगेट करना चाहते हैं, तो मेरी फ्रैगमेंट ट्रांज़ेक्शन प्रतिबद्धता पूरे ऐप फ्रीज द्वारा निकाल दी जाएगी। और फिर एंड्रॉइड सिस्टम पॉप अप करेगा मुझे बताओ कि ऐप जवाब नहीं दे रहा है।

मैं 'प्राप्तकर्ताओं' के अंदर 'बूलियन' ध्वज जोड़कर त्वरित रूप से तय करता हूं कि मैं केवल एक बार दृश्य को धक्का दूंगा। यह काम करता हैं। लेकिन मैं इसे करने के लिए एक और अधिक सुरुचिपूर्ण तरीका और 'उचित' तरीका ढूंढ रहा हूं।

धन्यवाद

नहीं