How to Fix unplug usb cable error in android with usb web cam?
Asked Answered
I

1

7

I Was created a android application based on connecting with webcam. The application works charm while connection with webcam. But when i unplug, my mobile the application crashed and shows "unfortunately application was stopped its working".

Video Activity:

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);
        }
    }
};

}

Inexpressible answered 6/2, 2016 at 9:57 Comment(2)
Was that the entire error message? What do you want to happen instead when the usb is unplugged? There are many experts on android here (I'm not one of them). If you don't get an answer to the question, this link: How to Ask contains tips on what information to include in a good question.Golf
Without stack trace, nothing can be said. who knows what is the reason. no one has magic pills (to they?). [the provided information is like, i had an accident. all i know is that the car is smashed] :)Lacee
C
3

You should probably use some try catch statements to make sure your program doesn't crash because of uncaught errors:

@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);
    }
}

Normally catching all exceptions is bad practice, so you should check what exception is thrown and change the exception that you catch to this specific exception.

Conveyancer answered 6/2, 2016 at 11:48 Comment(2)
I was connecting and play UVC Webcam in my android application. the above code will not rectify my error. i update my code which contains service to carry all camera related connect and disconnect options.Inexpressible
Then could you please update your question with the error that causes the crash. Maybe look at the documentation.Conveyancer

© 2022 - 2024 — McMap. All rights reserved.