Reputation: 1667
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
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.
In the opened activity get accessory like:
final UsbAccessory[] accessories = usbManager.getAccessoryList();
final UsbAccessory accessory = (accessories == null ? null : accessories[0]);
Request permission from user:
usbManager.requestPermission(accessory, permissionIntent);
In the popup dialog:
If press "OK" to grant permission, then disconnect accessory and make sure ACTION_USB_ACCESSORY_DETACHED
is received in broadcast receiver.
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
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?:
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
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
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