5

I have an android 5.1.1 device, an OTG cable and an ACS CardReader. I want to detect when CardReader is plugged in via OTG cable. I can detect DETACH but no luck with ATTACH.

Here is what I have:

Manifest file:

<uses-feature android:name="android.hardware.usb.host" />

<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"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <meta-data
            android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
            android:resource="@xml/device_filter" />
    </activity>
</application>

XML Filter file:

<?xml version="1.0" encoding="utf-8"?>

<resources>
    <!--usb-device vendor-id="1234" product-id="5678" class="255" subclass="66" protocol="1" /-->
    <usb-device />
</resources>

MainActivity:

private static final String TAG = MainActivity.class.getSimpleName();

private static final String ACTION_USB_PERMISSION = "com.guness.deleteme.USB_PERMISSION";
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (ACTION_USB_PERMISSION.equals(action)) {
            synchronized (this) {
                UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    if (device != null) {
                        //call method to set up device communication
                        Log.e(TAG, "permission granted " + device);
                    }
                } else {
                    Log.e(TAG, "permission denied for device " + device);
                }
            }
        }
    }
};

private PendingIntent mPermissionIntent;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.e(TAG, "onCreate");
    setContentView(R.layout.activity_main);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);

    mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    registerReceiver(mUsbReceiver, filter);
}

@Override
protected void onResume() {
    super.onResume();
    Log.e(TAG, "onResume");
}

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    Log.e(TAG, "onNewIntent");
}

I haven't asked for permission yet, I will ask when detected. No matter what I cannot see expected Logs.

Well I have checked a mouse, and usb stick; cannot detect them too. Android Device supports OTG, and CardReader; checked with other applications. I guess they have timer periodically checking if a USB device was attached.

guness
  • 6,336
  • 7
  • 59
  • 88

1 Answers1

1

Try create intent filter by programmable way:

1) remove

<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />

and

<meta-data
            android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
            android:resource="@xml/device_filter" />

lines from Manifest file (also You may delete XML Filter file)

2) create IntentFilter in MainActivity (something like this):

private static final String TAG = MainActivity.class.getSimpleName();

private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
            Log.d(TAG, "USB device attached");

        } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
            Log.d(TAG, "USB device detached");
        }
    }
};

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.e(TAG, "onCreate");
    setContentView(R.layout.activity_main);

    IntentFilter filter = new IntentFilter();
    filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
    filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
    registerReceiver(mUsbReceiver, filter);
}

3) work with permissions in

UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)

case.

Andrii Omelchenko
  • 13,183
  • 12
  • 43
  • 79
  • Will try soon, but problem seems to be android version 5.1.1 – guness Oct 12 '16 at 20:01
  • it is a device or android version issue. – guness Oct 13 '16 at 21:41
  • 1
    The problem with you solution is, the receiver will only be registered on application start. What means, the android system will only pass the Broadcast to the app, if you start it first. But it will not listen in background. – Radon8472 Jul 07 '17 at 06:14
  • 1
    @Radon8472 Agree, but it can be implemented, for example, in `Service` with `BOOT_COMPLETE`. It's just approach, not final solution. – Andrii Omelchenko Jul 07 '17 at 08:00