I want to write a service in Android which starts based on USB_DEVICE_ATTACHED intent. So, basically my service should start when a specific USB Device(FT232C - VID:PID 0403:6010) is connected and stop when that USB device is detached. Is it possible to do that or should I always have an Activity which starts this service in case it is not already started? The intent of the service in the end is to update the location on the LocationProvider with a TEST_PROVIDER based on what location is provided from this USB device.
I already tried creating a service with this configuration in AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.testlocservice"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="12" android:targetSdkVersion="15" />
<uses-feature android:name="android.hardware.usb.host"/>
<supports-screens android:resizeable="true" android:smallScreens="true" android:anyDensity="true" android:largeScreens="true" android:xlargeScreens="true" android:normalScreens="true"/>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<application android:label="#string/app_name"
android:icon="#drawable/ic_launcher"
android:theme="#style/AppTheme">
<service android:name="com.testlocservice.LocationService" android:process=":LocService" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="#xml/device_filter" />
</service>
</application>
</manifest>
The xml/device_filter.xml contains this
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device vendor-id="0403" product-id="6010"/>
</resources>
My LocationService class has overridden onStartCommand() which handles the USB_DEVICE_ATTACHED intent
From my experience a <service> cannot receive the USB intents. I overcame this by creating a hidden activity to receive the intent and re-broadcast it. Of course this activity could also handle starting/stopping your service.
I have already put up some working code here:
https://stackoverflow.com/a/15151075/588476
You will just have to change it so it starts and stops your service automatically.
I believe the main problem is the number base for the vendor and product id's. The format in the device filter xml should be decimal, so vendor-id="1025" and product-id="24592".
Aside from that, it absolutely should be USB_DEVICE_ATTACHED, rather than UMS_CONNECTED (the latter is not USB host mode at all).
I don't have the authoritative answer as to whether a service could receive a broadcast intent, or whether you have to use an activity for that, but it seems like Wayne Uroda has good experience with this question.
Yes, it is very well possible, sorry to say that you are using wrong intent-filter in your reveiver tag in AndroidManifest.xml. Let me guide you
AndroidManifest.xml
.
.
.
<receiver android:name=".DetactUSB">
<intent-filter>
<action android:name="android.intent.action.UMS_CONNECTED" />
<action android:name="android.intent.action.UMS_DISCONNECTED" />
</intent-filter>
</receiver>
BroadcastReceiver file
public class DetactUSB extends BroadcastReceiver
{
private static final String TAG = "DetactUSB";
#Override
public void onReceive(Context context, Intent intent)
{
// TODO Auto-generated method stub
if (intent.getAction().equalsIgnoreCase( "android.intent.action.UMS_CONNECTED"))
{
// Fire your Intent to start Activity
Log.i(TAG,"USB connected..");
}
if (intent.getAction().equalsIgnoreCase( "android.intent.action.UMS_DISCONNECTED"))
{
}
}
}
Related
I am trying to develop a ToDo application which helps user make notes as soon as call ends. In general life we are told many things to be done on phone. For example : buy grocery on way back to office.
I am facing difficulty in starting this application. I am using BroadcastReceiver How should I implement onReceive() method?
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.your"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<receiver android:name=".CallTracker">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
BroadcasrReceiver
public class CallTracker extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
}
}
Look for the 'state' in the bundle. When the state changes from OFFHOOK to IDLE start your application.
From activity you can use this example
I am making a app for a android phone development company. I need to run the app in the background there should not be any user interaction like google play service. So I made a application and placed it in the "system/app" so that user can't uninstall the app but I need to open the application to run the service in the background how can I skip that.
Look here: Android BroadcastReceiver on startup - keep running when Activity is in Background
Once you have broadcast receiver that is being called when system boots, you should start sticky service. Look here: START_STICKY and START_NOT_STICKY
That way your application will be started on system each system boot.
I think you should register for some BroadcastReceivers, so it will start yous app. You can use for example the boot_completed action so like this:
public class Autostart extends BroadcastReceiver
{
public void onReceive(Context arg0, Intent arg1)
{
Log.i("Autostart", "**********started************");
}
}
and the manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pack.saltriver" android:versionCode="1" android:versionName="1.0"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<application android:icon="#drawable/icon" android:label="#string/app_name">
<receiver android:name=".Autostart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
</manifest>
but you can use a different type, you just need to modify the name of the intent . Here is the list of all BroadcastReceiver Intent.
There are many intent filter you can use fro ex- boot completed or Power plugged.
In both cases you can use broadcast receiver to to launch the active.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pack.saltriver" android:versionCode="1" android:versionName="1.0"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<application android:icon="#drawable/icon" android:label="#string/app_name">
<receiver android:name=".tart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"></uses-permission>
I have a broadcast receiver for incoming call.I want to launch a new activity when an incoming call comes.I am aware of the changes that are made from android 3.0,that the broadcast receiver will not work unless user manually starts an application
For that purpose I launch a dummy activity with just a toast message in it.Still the broadcast receiver is not working.
Here is my code
My broadcastreceiver
public class IncomingCallResult extends BroadcastReceiver
{
String TAG="IncomingCallResult";
#Override
public void onReceive(Context arg0, Intent I1)
{
Log.i(TAG,"inside on receive........");
Bundle bundle=I1.getExtras();
String state=bundle.getString(TelephonyManager.EXTRA_STATE);
if(state.equals(TelephonyManager.EXTRA_STATE_RINGING))
{
Intent flash_intent=new Intent(arg0,LedFlasher.class);
flash_intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
arg0.startActivity(flash_intent);
}
}
}
manifest file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.blinker"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver
android:name=".IncomingCallResult"
android:enabled="true">
<intent-filter
android:priority="214783648"
android:name="android.intent.action.PHONE_STATE">
</intent-filter>
</receiver>
<activity
android:name=".LedFlasher"
android:label="#string/title_activity_incoming_call_result" >
</activity>
<activity
android:name=".Dummy">
<intent-filter >
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
What is wrong with the code?
Please help
As you have already known that the broadcast receiver will not work unless user manually starts an application For that purpose, you should not be surprised that your broadcast receiver will not work until user Manually open your application once. That is to say, you have to make a launcher activity which user is able to click and open it manually.
And what's more, it is better to Open and stay in your application for like 20s since I remember that the change of application configuration will take 10 or 20s to be saved.
None of this broadcast receivers are not triggered, but in another my application is working where I used to check network state. I have nothing else to say about this problem.
package monitor;
import android.content.BroadcastReceiver;
public class Monitor extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("jupi");
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="monitor"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="9"
android:targetSdkVersion="15"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<application
android:icon="#drawable/icon"
android:label="#string/app_name">
<service
android:name=".MonitorService">
</service>
<receiver
android:name=".Monitor">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
</application>
If you are seeing this behaviour on Android 3.1 or later, you are probably seeing the results of this change:
http://developer.android.com/about/versions/android-3.1.html#launchcontrols
Especially read this:
Note that the system adds FLAG_EXCLUDE_STOPPED_PACKAGES to all
broadcast intents. It does this to prevent broadcasts from background
services from inadvertently or unnecessarily launching components of
stoppped applications.
Since your application only contains a service and receivers, the user will never start this application and therefore if will remain in the "stopped" state, preventing it from seeing any broadcast intents.
When you added the Activity to your application, running it once was enough to remove the application from the "stopped" state so that your receivers were then eligible to receive broadcast intents. You actually don't need to dynamically register the receivers. It is enough to just have the user "start" the application once after installation.
I have an already built application and I want to add a feature that has to be started when a call ends.
How can I achieve that?
I thought that declaring in my manifest something like this
<activity android:name="Filter">
<intent-filter>
<category android:name="android.intent.SOMETHING" />
</intent-filter>
</activity>
could be enough, but what kind of Intent I have to put on the filter?
Looking in the documentation I found only the intents that detects when a call is started.
Is what I'm looking for possible?
I have done this using a broadcast receiver. Works! code looks like this -
AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gopi"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application android:icon="#drawable/icon" android:label="#string/app_name">
<receiver android:name=".IncomingCallTracker">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
</application>
</manifest>
The IncomingCallTracker code snippet looks like -
public class IncomingCallTracker extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
Set<String> keys = bundle.keySet();
for (String key : keys) {
Log.i("MYAPP##", key + "="+ bundle.getString(key));
}
}
}
You can look for the key 'state' in the bundle. When its value is 'IDLE' it means call has ended and you can perform whatever action you want to based on this.
You can use the PhoneStateLisenter to listen out for changes in the call state.
So you listen for the LISTEN_CALL_STATE change.
With the onCallStateChanged method.
So when the state changes from OFFHOOK to IDLE start your application