2016-02-06 24 views
7

I È stata creata un'applicazione Android basata sul collegamento con la webcam. L'applicazione funziona con fascino durante la connessione con la webcam. Ma quando disconnetto, il mio cellulare si blocca e mostra "purtroppo l'applicazione è stata interrotta".Come risolvere lo scollegamento dell'errore del cavo USB in Android con la web cam usb?

Attività Video:

public class VideoActivity extends AppCompatActivity { 
ActionBar actionBar; 


public static int mCurrentPosition = -1; 
private Handler handler; 
private Runnable mRunnable; 

//-------------------------------- 
private static final boolean DEBUG = true; 
private static final String TAG = "VIDEO ACTIVITY"; 


private static final int DEFAULT_WIDTH = 640; //640 
private static final int DEFAULT_HEIGHT = 480; //480 

private USBMonitor mUSBMonitor; 
private ICameraClient mCameraClient; 

private CameraViewInterface mCameraView; 

private boolean isSubView; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.new_video_layout); 

    if (mUSBMonitor == null) { 
     mUSBMonitor = new USBMonitor(getApplicationContext(), mOnDeviceConnectListener); 
     final List<DeviceFilter> filters = DeviceFilter.getDeviceFilters(getApplicationContext(), R.xml.device_filter); 
     mUSBMonitor.setDeviceFilter(filters); 
    } 
    if (savedInstanceState != null) { 
     mCurrentPosition = savedInstanceState.getInt("STATE"); 
    } 

    actionBar = getSupportActionBar(); 
    assert actionBar != null; 
    actionBar.setDisplayShowCustomEnabled(true); 
    actionBar.setBackgroundDrawable(new ColorDrawable(Color.WHITE)); 
    actionBar.setDisplayShowTitleEnabled(false); 
    actionBar.setDisplayShowHomeEnabled(false); 

    LayoutInflater inflator = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    View v = inflator.inflate(R.layout.custom_actionbar, null); 
    actionBar.setCustomView(v); 



    mCameraView = (CameraViewInterface) findViewById(R.id.camera_view); 
    mCameraView.setAspectRatio(DEFAULT_WIDTH/(float) DEFAULT_HEIGHT); 
     mCameraView.setCallback(mCallback); 
} 

@Override 
public void onBackPressed() { 
    finish(); 
    moveTaskToBack(true); 
    super.onBackPressed(); 
} 


private final USBMonitor.OnDeviceConnectListener mOnDeviceConnectListener = new USBMonitor.OnDeviceConnectListener() { 
    @Override 
    public void onAttach(final UsbDevice device) { 
     if (DEBUG) Log.v(TAG, "OnDeviceConnectListener#onAttach:"); 
     if (!updateCameraDialog() && (mCameraView.getSurface() != null)) { 
      tryOpenUVCCamera(true); 
     } 
    } 

    @Override 
    public void onConnect(final UsbDevice device, final USBMonitor.UsbControlBlock ctrlBlock, final boolean createNew) { 
     if (DEBUG) Log.v(TAG, "OnDeviceConnectListener#onConnect:"); 
    } 

    @Override 
    public void onDisconnect(final UsbDevice device, final USBMonitor.UsbControlBlock ctrlBlock) { 
     if (DEBUG) Log.v(TAG, "OnDeviceConnectListener#onDisconnect:"); 
    } 

    @Override 
    public void onDettach(final UsbDevice device) { 
     if (DEBUG) Log.v(TAG, "OnDeviceConnectListener#onDettach:"); 
     if (mCameraClient != null) { 
      mCameraClient.disconnect(); 
      mCameraClient.release(); 
      mCameraClient = null; 
     } 
     updateCameraDialog(); 
    } 

    @Override 
    public void onCancel() { 
     if (DEBUG) Log.v(TAG, "OnDeviceConnectListener#onCancel:"); 

    } 
}; 

private boolean updateCameraDialog() { 
    final Fragment fragment = getFragmentManager().findFragmentByTag("CameraDialog"); 
    if (fragment instanceof CameraDialog) { 
     ((CameraDialog) fragment).updateDevices(); 
     return true; 
    } 
    return false; 
} 

private void tryOpenUVCCamera(final boolean requestPermission) { 
    if (DEBUG) Log.v(TAG, "tryOpenUVCCamera:"); 
    openUVCCamera(0); 
} 

public void openUVCCamera(final int index) { 
    if (DEBUG) Log.v(TAG, "openUVCCamera:index=" + index); 
    if (!mUSBMonitor.isRegistered()) return; 
    final List<UsbDevice> list = mUSBMonitor.getDeviceList(); 
    if (list.size() > index) { 

     if (mCameraClient == null) 
      mCameraClient = new CameraClient(getApplicationContext(), mCameraListener); 
     mCameraClient.select(list.get(index)); 
     mCameraClient.resize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 
     mCameraClient.connect(); 
    } 
} 

private final CameraViewInterface.Callback mCallback = new CameraViewInterface.Callback() { 
    @Override 
    public void onSurfaceCreated(final Surface surface) { 
     tryOpenUVCCamera(true); 
    } 

    @Override 
    public void onSurfaceChanged(final Surface surface, final int width, final int height) { 
    } 

    @Override 
    public void onSurfaceDestroy(final Surface surface) { 

    } 
}; 

private final ICameraClientCallback mCameraListener = new ICameraClientCallback() { 
    @Override 
    public void onConnect() { 
     if (DEBUG) Log.v(TAG, "onConnect:"); 
     mCameraClient.addSurface(mCameraView.getSurface(), false); 
     isSubView = true; 
    } 

    @Override 
    public void onDisconnect() { 
     if (DEBUG) Log.v(TAG, "onDisconnect:"); 

    } 
};} 

UVCCamera:

public class UVCService extends Service { 
private static final boolean DEBUG = true; 
private static final boolean checkConn = true; 
private static final String TAG = "UVCService"; 

private USBMonitor mUSBMonitor; 

public UVCService() { 
    if (DEBUG) Log.d(TAG, "Constructor:"); 
} 

@Override 
public void onCreate() { 
    super.onCreate(); 
    if (DEBUG) Log.d(TAG, "onCreate:"); 
    if (mUSBMonitor == null) { 
     mUSBMonitor = new USBMonitor(getApplicationContext(), mOnDeviceConnectListener); 
     mUSBMonitor.register(); 
    } 
} 

@Override 
public void onDestroy() { 
    if (DEBUG) Log.d(TAG, "onDestroy:"); 
    if (checkReleaseService()) { 
     if (mUSBMonitor != null) { 
      mUSBMonitor.unregister(); 
      mUSBMonitor = null; 
     } 
    } 
    super.onDestroy(); 
} 

@Override 
public IBinder onBind(final Intent intent) { 
    if (DEBUG) Log.d(TAG, "onBind:" + intent); 
    if (IUVCService.class.getName().equals(intent.getAction())) { 
     Log.i(TAG, "return mBasicBinder"); 
     return mBasicBinder; 
    } 
    if (IUVCSlaveService.class.getName().equals(intent.getAction())) { 
     Log.i(TAG, "return mSlaveBinder"); 
     return mSlaveBinder; 
    } 
    return null; 
} 

@Override 
public void onRebind(final Intent intent) { 
    if (DEBUG) 
     Log.d(TAG, "onRebind:" + intent); 
} 

@Override 
public boolean onUnbind(final Intent intent) { 
    if (DEBUG) 
     Log.d(TAG, "onUnbind:" + intent); 
    if (checkReleaseService()) { 
     mUSBMonitor.unregister(); 
     mUSBMonitor = null; 
    } 
    return true; 
} 

//******************************************************************************** 
private final OnDeviceConnectListener mOnDeviceConnectListener = new OnDeviceConnectListener() { 
    @Override 
    public void onAttach(final UsbDevice device) { 
     if (DEBUG) Log.d(TAG, "OnDeviceConnectListener#onAttach:"); 
    } 

    @Override 
    public void onConnect(final UsbDevice device, final UsbControlBlock ctrlBlock, final boolean createNew) { 
     if (DEBUG) Log.d(TAG, "OnDeviceConnectListener#onConnect:"); 

     final int key = device.hashCode(); 
     CameraServer service; 
     synchronized (sServiceSync) { 
      service = sCameraServers.get(key); 
      if (service == null) { 
       service = CameraServer.createServer(UVCService.this, ctrlBlock, device.getVendorId(), device.getProductId()); 
       sCameraServers.append(key, service); 
      } else { 
       Log.w(TAG, "service already exist before connection"); 
      } 
      sServiceSync.notifyAll(); 
     } 
    } 

    @Override 
    public void onDisconnect(final UsbDevice device, final UsbControlBlock ctrlBlock) { 
     if (DEBUG) Log.d(TAG, "OnDeviceConnectListener#onDisconnect:"); 
     if (!checkConn) { 
      processStopService(UVCService.TAG); 
     } 
     removeService(device); 


     /*if(!checkConn){this.stopService(new Intent(this, MyService.class));} 
     ;*/ 
    } 

    @Override 
    public void onDettach(final UsbDevice device) { 
     if (DEBUG) Log.d(TAG, "OnDeviceConnectListener#onDettach:"); 
     if (!checkConn) { 
      processStopService(UVCService.TAG); 
     } 
     removeService(device); 
    } 

    @Override 
    public void onCancel() { 
     if (DEBUG) Log.d(TAG, "OnDeviceConnectListener#onCancel:"); 
     synchronized (sServiceSync) { 
      sServiceSync.notifyAll(); 
     } 
    } 
}; 

// ====================================================================================== 

private void processStopService(final String tag) { 
    Intent intent = new Intent(getApplicationContext(), UVCService.class); 
    intent.addCategory(tag); 
    stopService(intent); 
} 

// ====================================================================================== 
private void removeService(final UsbDevice device) { 
    final int key = device.hashCode(); 
    synchronized (sServiceSync) { 
     final CameraServer service = sCameraServers.get(key); 
     if (service != null) 
      service.release(); 
     sCameraServers.remove(key); 
     sServiceSync.notifyAll(); 
    } 
    if (checkReleaseService()) { 
     if (mUSBMonitor != null) { 
      mUSBMonitor.unregister(); 
      mUSBMonitor = null; 
     } 
    } 
} 

//******************************************************************************** 
private static final Object sServiceSync = new Object(); 
private static final SparseArray<CameraServer> sCameraServers = new SparseArray<CameraServer>(); 

/** 
* get CameraService that has specific ID<br> 
* if zero is provided as ID, just return top of CameraServer instance(non-blocking method) if exists or null.<br> 
* if non-zero ID is provided, return specific CameraService if exist. block if not exists.<br> 
* return null if not exist matched specific ID<br> 
* 
* @param serviceId 
* @return 
*/ 
private static CameraServer getCameraServer(final int serviceId) { 
    synchronized (sServiceSync) { 
     CameraServer server = null; 
     if ((serviceId == 0) && (sCameraServers.size() > 0)) { 
      server = sCameraServers.valueAt(0); 
     } else { 
      server = sCameraServers.get(serviceId); 
      if (server == null) 
       try { 
        Log.i(TAG, "waitting for service is ready"); 
        sServiceSync.wait(); 
       } catch (final InterruptedException e) { 
       } 
      server = sCameraServers.get(serviceId); 
     } 
     return server; 
    } 
} 

/** 
* @return true if there are no camera connection 
*/ 
private static boolean checkReleaseService() { 
    CameraServer server = null; 
    synchronized (sServiceSync) { 
     final int n = sCameraServers.size(); 
     if (DEBUG) Log.d(TAG, "checkReleaseService:number of service=" + n); 
     for (int i = 0; i < n; i++) { 
      server = sCameraServers.valueAt(i); 
      Log.i(TAG, "checkReleaseService:server=" + server + ",isConnected=" + (server != null ? server.isConnected() : false)); 
      if (server != null && !server.isConnected()) { 
       sCameraServers.removeAt(i); 
       server.release(); 
      } 
     } 
     return sCameraServers.size() == 0; 
    } 
} 

//******************************************************************************** 
private final IUVCService.Stub mBasicBinder = new IUVCService.Stub() { 
    private IUVCServiceCallback mCallback; 

    @Override 
    public int select(final UsbDevice device, final IUVCServiceCallback callback) throws RemoteException { 
     if (DEBUG) 
      Log.d(TAG, "mBasicBinder#select:device=" + (device != null ? device.getDeviceName() : null)); 
     mCallback = callback; 
     final int serviceId = device.hashCode(); 
     CameraServer server = null; 
     synchronized (sServiceSync) { 
      server = sCameraServers.get(serviceId); 
      if (server == null) { 
       Log.i(TAG, "request permission"); 
       mUSBMonitor.requestPermission(device); 
       Log.i(TAG, "wait for getting permission"); 
       try { 
        sServiceSync.wait(); 
       } catch (final Exception e) { 
        Log.e(TAG, "connect:", e); 
       } 
       Log.i(TAG, "check service again"); 
       server = sCameraServers.get(serviceId); 
       if (server == null) { 
        throw new RuntimeException("failed to open USB device(has no permission)"); 
       } 
      } 
     } 
     if (server != null) { 
      Log.i(TAG, "success to get service:serviceId=" + serviceId); 
      server.registerCallback(callback); 
     } 
     return serviceId; 
    } 

    @Override 
    public void release(final int serviceId) throws RemoteException { 
     if (DEBUG) Log.d(TAG, "mBasicBinder#release:"); 
     synchronized (sServiceSync) { 
      final CameraServer server = sCameraServers.get(serviceId); 
      if (server != null) { 
       if (server.unregisterCallback(mCallback)) { 
        if (!server.isConnected()) { 
         sCameraServers.remove(serviceId); 
         if (server != null) { 
          server.release(); 
         } 
         final CameraServer srv = sCameraServers.get(serviceId); 
         Log.w(TAG, "srv=" + srv); 
        } 
       } 
      } 
     } 
     mCallback = null; 
    } 

    @Override 
    public boolean isSelected(final int serviceId) throws RemoteException { 
     return getCameraServer(serviceId) != null; 
    } 

    @Override 
    public void releaseAll() throws RemoteException { 
     if (DEBUG) Log.d(TAG, "mBasicBinder#releaseAll:"); 
     CameraServer server; 
     synchronized (sServiceSync) { 
      final int n = sCameraServers.size(); 
      for (int i = 0; i < n; i++) { 
       server = sCameraServers.valueAt(i); 
       sCameraServers.removeAt(i); 
       if (server != null) { 
        server.release(); 
       } 
      } 
     } 
    } 

    @Override 
    public void resize(final int serviceId, final int width, final int height) { 
     if (DEBUG) Log.d(TAG, "mBasicBinder#resize:"); 
     final CameraServer server = getCameraServer(serviceId); 
     if (server == null) { 
      throw new IllegalArgumentException("invalid serviceId"); 
     } 
     server.resize(width, height); 
    } 

    @Override 
    public void connect(final int serviceId) throws RemoteException { 
     if (DEBUG) Log.d(TAG, "mBasicBinder#connect:"); 
     final CameraServer server = getCameraServer(serviceId); 
     if (server == null) { 
      throw new IllegalArgumentException("invalid serviceId"); 
     } 
     server.connect(); 
    } 

    @Override 
    public void disconnect(final int serviceId) throws RemoteException { 
     if (DEBUG) Log.d(TAG, "mBasicBinder#disconnect:"); 
     final CameraServer server = getCameraServer(serviceId); 
     if (server == null) { 
      throw new IllegalArgumentException("invalid serviceId"); 
     } 
     server.disconnect(); 
    } 

    @Override 
    public boolean isConnected(final int serviceId) throws RemoteException { 
     final CameraServer server = getCameraServer(serviceId); 
     return (server != null) && server.isConnected(); 
    } 

    @Override 
    public void addSurface(final int serviceId, final int id_surface, final Surface surface, final boolean isRecordable) throws RemoteException { 
     if (DEBUG) 
      Log.d(TAG, "mBasicBinder#addSurface:id=" + id_surface + ",surface=" + surface); 
     final CameraServer server = getCameraServer(serviceId); 
     if (server != null) 
      server.addSurface(id_surface, surface, isRecordable, null); 
    } 

    @Override 
    public void removeSurface(final int serviceId, final int id_surface) throws RemoteException { 
     if (DEBUG) Log.d(TAG, "mBasicBinder#removeSurface:id=" + id_surface); 
     final CameraServer server = getCameraServer(serviceId); 
     if (server != null) 
      server.removeSurface(id_surface); 
    } 

    @Override 
    public boolean isRecording(final int serviceId) throws RemoteException { 
     final CameraServer server = getCameraServer(serviceId); 
     return server != null && server.isRecording(); 
    } 

    @Override 
    public void startRecording(final int serviceId) throws RemoteException { 
     if (DEBUG) Log.d(TAG, "mBasicBinder#startRecording:"); 
     final CameraServer server = getCameraServer(serviceId); 
     if ((server != null) && !server.isRecording()) { 
      server.startRecording(); 
     } 
    } 

    @Override 
    public void stopRecording(final int serviceId) throws RemoteException { 
     if (DEBUG) Log.d(TAG, "mBasicBinder#stopRecording:"); 
     final CameraServer server = getCameraServer(serviceId); 
     if ((server != null) && server.isRecording()) { 
      server.stopRecording(); 
     } 
    } 

    @Override 
    public void captureStillImage(final int serviceId, final String path) throws RemoteException { 
     if (DEBUG) Log.d(TAG, "mBasicBinder#captureStillImage:" + path); 
     final CameraServer server = getCameraServer(serviceId); 
     if (server != null) { 
      server.captureStill(path); 
     } 
    } 

}; 

//******************************************************************************** 
private final IUVCSlaveService.Stub mSlaveBinder = new IUVCSlaveService.Stub() { 
    @Override 
    public boolean isSelected(final int serviceID) throws RemoteException { 
     return getCameraServer(serviceID) != null; 
    } 

    @Override 
    public boolean isConnected(final int serviceID) throws RemoteException { 
     final CameraServer server = getCameraServer(serviceID); 
     return server != null ? server.isConnected() : false; 
    } 

    @Override 
    public void addSurface(final int serviceID, final int id_surface, final Surface surface, final boolean isRecordable, final IUVCServiceOnFrameAvailable callback) throws RemoteException { 
     if (DEBUG) 
      Log.d(TAG, "mSlaveBinder#addSurface:id=" + id_surface + ",surface=" + surface); 
     final CameraServer server = getCameraServer(serviceID); 
     if (server != null) { 
      server.addSurface(id_surface, surface, isRecordable, callback); 
     } else { 
      Log.e(TAG, "failed to get CameraServer:serviceID=" + serviceID); 
     } 
    } 

    @Override 
    public void removeSurface(final int serviceID, final int id_surface) throws RemoteException { 
     if (DEBUG) Log.d(TAG, "mSlaveBinder#removeSurface:id=" + id_surface); 
     final CameraServer server = getCameraServer(serviceID); 
     if (server != null) { 
      server.removeSurface(id_surface); 
     } else { 
      Log.e(TAG, "failed to get CameraServer:serviceID=" + serviceID); 
     } 
    } 
}; 

}

+0

Era l'intero messaggio di errore? Cosa vuoi che succeda invece quando la chiavetta USB è scollegata? Ci sono molti esperti su Android qui (io non sono uno di loro). Se non si ottiene una risposta alla domanda, questo link: [chiedi] contiene suggerimenti su quali informazioni includere in una buona domanda. –

+0

Senza traccia dello stack, non si può dire nulla. chissà qual'è la ragione. nessuno ha pillole magiche (a loro?). [le informazioni fornite sono come, ho avuto un incidente. tutto quello che so è che l'auto è distrutta] :) –

risposta

3

Probabilmente si dovrebbe usare alcune dichiarazioni prova di cattura per assicurarsi che il programma non va in crash a causa di errori non rilevati:

@Override 
public void onDettach(final UsbDevice device) { 
    if (DEBUG) Log.v(TAG, "OnDeviceConnectListener#onDettach:"); 
    try { 
     if (mCameraClient != null) { 
      mCameraClient.disconnect(); 
      mCameraClient.release(); 
      mCameraClient = null; 
     } 
     updateCameraDialog(); 
    } catch (Exception ex) { 
     Log.e("Exception occurred", ex); 
    } 
} 

Normalmente la cattura di tutte le eccezioni è una cattiva pratica, quindi è necessario verificare quale eccezione viene lanciata e modificare l'eccezione che si cattura a questa specifica eccezione.

+0

Mi stavo collegando e riproducevo webcam UVC nella mia applicazione Android. il codice sopra non rettificherà il mio errore. aggiorno il mio codice che contiene il servizio per trasportare tutte le opzioni di connessione e disconnessione relative alla fotocamera. –

+0

Quindi potresti aggiornare la tua domanda con l'errore che causa l'arresto anomalo. Magari guarda la [documentazione] (https://developer.android.com/tools/debugging/debugging-studio.html). – M0CH1R0N