Search code examples
androidusbandroid-5.0-lollipopsonysony-xperia

Sony Xperia Z with android lollipop not registering ACTION_USB_DEVICE_ATTACHED


I have an external usb device that attaches to the micro usb port on android devices, and everything was working fine on all devices until android lollipop came out. Now it no longer works on Sony Xperia Z phones.

So it works on all devices with 4.0 or greater (and that have usb hosting) except the Sony Xperia Z with lollipop (works fine on the Sony before lollipop).

So the question is, why would it stop working on lollipop and only specifically on the Xperia Z? Something changed on that phone, but I don't know what.

Here is my setup for registering usb devices.

The Manifest File

    <activity
        android:name="com.edgetechlabs.drinkmate_play.MainActivity"
        android:windowSoftInputMode="adjustPan"
        android:screenOrientation="portrait"
        android:launchMode="singleTask"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter>
            <action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"/>
            <action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"/>
        </intent-filter>
        <meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
            android:resource="@xml/device_filter" />
        <meta-data android:name="android.hardware.usb.action.USB_DEVICE_DETACHED"
            android:resource="@xml/device_filter" />
    </activity>

The Device Filter

<resources>
    <usb-device vendor-id="8352" product-id="16881"/>
</resources>

The MainActivity

@Override
public void onResume() {
    super.onResume();
    //get the intent of the activity
    Intent intent = getIntent();
    String action = intent.getAction();
    Log.i(TAG, "MainActivity Resumed with intent " + action);

    //if the device has been plugged in
    if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
        Log.i(TAG, "Device Attached to start app");
        UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
        setDeviceConnection(device);
    }
}

@Override
public void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    Log.i(TAG, "New Intent Recieved " + intent.getAction() + " with dmPluggedIn = " + dmPluggedIn);

    // whenever a new intent is received from an app re-launch due to the device being plugged in
    // or an intent being manually set, set the intent of the app to it only if it was from
    // a device being attached. That way, when the app goes to the background with the device still attached
    // the ATTACHED intent remains (because the MAIN intent is blocked)
    if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
        System.out.println("changing intent to usb");
        setIntent(intent);
    }
}

To specify why it isn't working, it never registers the USB_DEVICE_ATTACHED intent (either when I plug in the device to start the app, or plug it in when the app has started). All the phone does is ask what kind of keyboard it is you just inserted. I don't know a ton about the device itself (someone else built it), but I can try to get as much information as requested. But it hasn't changed, this code hasn't changed at all since before lollipop came out. The only thing that has changed, is it no longer works on Sony Xperia Z with Lollipop.

UPDATE 1

reading through the logs I discovered

    W/ContextImpl(  858): Calling a method in the system process without a 
qualified user: android.app.ContextImpl.sendBroadcast:1355 
com.android.server.usb.UsbSettingsManager.blacklistedDeviceDetached:777 
com.android.server.usb.UsbHostManager.usbDeviceRemoved:397 
com.android.server.usb.UsbHostManager.monitorUsbHostBus:-2 
com.android.server.usb.UsbHostManager.access$000:54 

    W/BroadcastQueue(  858): Permission Denial: receiving Intent
{act=android.hardware.usb.action.USB_DEVICE_DETACHED flg=0x10 (has extras) } 
    to ProcessRecord{3f67a3f 9138:com.edgetechlabs.drinkmate_play/u0a276}
    (pid=9138, uid=10276) 
    requires com.sonyericsson.permission.BLACKLISTED_USB_DEVICE due to sender  android (uid 1000)

so I added

<permission
    android:name="com.sonyericsson.permission.BLACKLISTED_USB_DEVICE"
    android:protectionLevel="signature" />

to my manifest but I get

W/PackageManager(  858): Package com.edgetechlabs.drinkmate_play 
attempting to redeclare system permission 
com.sonyericsson.permission.BLACKLISTED_USB_DEVICE; ignoring new declaration

So something changed with permission with usb devices but I am not sure how to fix the problem. How can i get the device to accept this usb?


Solution

  • I was having similar problem before some days. But as Xperia-Z is not a BLACKLISTED_USB_DEVICE, the system permission

    <permission
        android:name="com.sonyericsson.permission.BLACKLISTED_USB_DEVICE"
        android:protectionLevel="signature" />
    

    would not hep you.

    You need to request for permissions manually to detect device. Please refer: http://developer.android.com/guide/topics/connectivity/usb/host.html#permission-d for more details.

    But launching an app on USB attachment is still need to be reached. As per my finding there might be two reasons of failure: