Sergey Vakulenko
Sergey Vakulenko

Reputation: 1667

usb accessory, catch USB_ACCESSORY_ATTACHED by intent-filter of Service

In android usb accessory documentation, there is example of android manifest, where Activity catch USB_ACCESSORY_ATTACHED by intent-filter. Im asking myself, its possible to catch the same intent by intent-filter of Service/IntentService ?

EDIT

I tried this,but without success:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.entreprise.ws.main"
    android:versionCode="1"

    android:versionName="1.0" >


    <uses-sdk android:minSdkVersion="10" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />


    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"

        >
            <activity
            android:name="com.entreprise.ws.main.WeatherStationClientActivity"
            android:exported="true"
            android:screenOrientation="portrait"
             >
<!--              <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

        </activity>

        <activity android:name=".EntryPointActivity"

            android:screenOrientation="portrait" >

            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

            <activity
            android:name="com.entreprise.ws.main.WiFiListActivity"
            android:label="@string/appname_wifilist" >
            </activity> 


            <uses-library android:name="com.android.future.usb.accessory" />


         <activity
            android:screenOrientation="portrait"
            android:name=".WSInstallatorActivity"
            android:exported="true"
             >



        </activity> 

    <service class="services.MyService" android:name="services.MyService">
                     <intent-filter>
            <action android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED" />
            <action android:name="android.hardware.usb.action.USB_ACCESSORY_DETACHED" />
        </intent-filter>

                                <meta-data android:name="android.hardware.usb.action.USB_ACCESSORY_ATTACHED"
                android:resource="@xml/accessory_filter" />
    </service>




    </application>

</manifest>

service:

package services;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;

public class MyService extends Service {

    final static String TAG = "MyService";
    @Override
    public void onCreate() {
        super.onCreate();
        Log.i("TAG", "onCreate");
        Toast.makeText(this, "Service created...", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.i("TAG", "onDestroy");
        Toast.makeText(this, "Service destroyed...", Toast.LENGTH_LONG).show();
    }
    @Override
    public IBinder onBind(Intent intent) {
        Log.i("TAG", "onBind");
        // TODO Auto-generated method stub
        return null;
    }
}

P.S for activity, this works fine

EDIT2

I experimenting by moving intent-filter and meta-data to my broadcast receiver: I not receive no more attach event. What is funny, I continue receive detach event. Its looks like USB_ACCESSORY_ATTACHED works only with activity, despite "Broadcast Action" classification in documentation.

EDIT3: Final conclusion

Its looks like USB_ACCESSORY_ATTACHED can be caught only in activity (in reason of possible dialog with user ?! ). detach event can be catch in receivers.

Upvotes: 4

Views: 8030

Answers (4)

anton
anton

Reputation: 1

I can also confirm that ACTION_USB_ACCESSORY_ATTACHED does not work inside activity broadcast receiver. But I have also noted, that ACTION_USB_ACCESSORY_DETACHED which normally works with broadcast recever, stops coming to broadcast receiver if the user forbids access to accessory in request permission dialog.

E.g. 0. Register ACTION_USB_ACCESSORY_DETACHED with broadcast receiver.

  1. In the opened activity get accessory like:

    final UsbAccessory[] accessories = usbManager.getAccessoryList();
    final UsbAccessory accessory = (accessories == null ? null : accessories[0]);
    
  2. Request permission from user:

    usbManager.requestPermission(accessory, permissionIntent);
    
  3. In the popup dialog:

    1. If press "OK" to grant permission, then disconnect accessory and make sure ACTION_USB_ACCESSORY_DETACHED is received in broadcast receiver.

    2. If press "Cancel" to discard permission, then disconnect accessory and see that ACTION_USB_ACCESSORY_DETACHED is NOT received in broadcast receiver in this case.

So this could be intended behaviour in case if Android system does not send notifications (attached/detached) to broadcast receivers about accessories to which user did not grant permission from dialog. So as soon as just attached accessory is not permitted by the user, the attach event will never come to broadcast receiver. In any case this looks like a bug or a broken design, because without being able to receive ACTION_USB_ACCESSORY_ATTACHED event in broadcast receiver, the user will have to restart the app each time accessory is reconnected or to force connection by manual action.

Upvotes: 0

st2000
st2000

Reputation: 276

Had the same problem:

Could not get a service to start based on plugging in a USB device.

Not so great solution:

We added an activity to the application which already contained the service. All the activity does is start the service and passes to the service the intent upon plugging in the USB device. Then the activity exits. (ONLY the activity ends.) This leave the service to continue to run. We called "System.exit(0);" in the activity to do this "silently" (i.e. w/o a pop up).

Why it's not so great?:

  1. This puts an useless icon for the application in the launcher.
  2. Momentarily starting an activity does take over the GUI (momentarily). Not sure what will happen if other applications with activities are running.

So if anyone has a better solution... PLEASE POST!

OTOH, if this is a bug in Android... Well, I'm a bit too green to know this for sure, but if it is a bug - how's about some help WRT how to follow up w/Google.

-thanks

Upvotes: 1

rajan goswami
rajan goswami

Reputation: 610

I am also exploring USB support on android for my project, and ended up browsing through Android source for this matter.

Yes USB_ACCESSORY_ATTACHED and USB_DEVICE_ATTACHED both intents can be caught only in activities but Not in Service. I could not find yet exactly why is it so. Like you, I believed it should be possible to directly notify a Service about USB state(device attached, accessory attached). But this is not the way it is implemented in Android. will post if I find something more on this.

Detach intents can be caught in BroadCastReceivers.

If you want to adventure yourself in Android source you can start from this directory - ICS_SOURCE/frameworks/base/services/java/com/android/server/usb and read from there.

Upvotes: 7

Ovidiu Latcu
Ovidiu Latcu

Reputation: 72341

Yes it should be possible. If you look at the <service> documentation, you can see that the Service element in the Manifest has an <intent-filter> just like an Activity.

If you look at USB_ACCESSORY_ATTACHED action, there is no mention that this is not meant to be for a Service.

If you look at the SEARCH_LONG_PRESS action it is mentioned that :

Activity Action: Start action associated with long pressing on the search key.

So, you should be able to catch your desired Broadcast(USB_ACCESSORY_ATTACHED) in your Service.

Upvotes: 1

Related Questions