Stopping a service when the USB device is unplugged - android

I want to stop a running service when a usb is unplugged.
inside my activity onCreate I check the intent for its action
if (getIntent().getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
Log.d(TAG, "************** USB unplugged stopping service **********");
Toast.makeText(getBaseContext(), "usb was disconneced", Toast.LENGTH_LONG).show();
stopService(new Intent(this, myService.class));
} else {
init();
}
And inside my manifest I have another intent filter
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
And this intent filter as well which is being called.
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
But the detach is not being called.

Hmmm.. ACTION_USB_DEVICE_DETACHED is fired when a USB device (not the cable) is detached from the phone/tablet. This is not something you want.
I do not know if there is a straight forward API for detecting USB cable connections, but you can use ACTION_POWER_CONNECTED and ACTION_POWER_DISCONNECTED to accomplish your goal.
Use following filters for your receiver:
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
</intent-filter>
And in your receiver, you can check the state and implement the logic you want:
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
switch(intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1)) {
case 0:
// The device is running on battery
break;
case BatteryManager.BATTERY_PLUGGED_AC:
// Implement your logic
break;
case BatteryManager.BATTERY_PLUGGED_USB:
// Implement your logic
break;
case BATTERY_PLUGGED_WIRELESS:
// Implement your logic
break;
default:
// Unknown state
}
}
}

You need to register a BroadcastReceiver
BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
Log.d(TAG, "************** USB unplugged stopping service **********");
Toast.makeText(getBaseContext(), "usb was disconneced",
Toast.LENGTH_LONG).show();
stopService(new Intent(this, myService.class));
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(receiver, filter);

Related

Android After Reboot Broadcast Receiver is not running

I used this permission:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
and the receiver is:
<receiver android:name=".auth.NotificationBroadcast" android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
and receiver in code is:
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("BroadcastReceiverBroadcast--------------------ReceiverBroadcastReceiverBroadcastReceiver----------------BroadcastReceiver");
if (intent != null) {
String action = intent.getAction();
switch (action) {
case Intent.ACTION_BOOT_COMPLETED:
System.out.println("Called on REBOOT");
// start a new service and repeat using alarm manager
break;
default:
break;
}
}
}
After reboot it's still not getting called in lollipop, but on marshmallow it's running.
try to put this line in your receiver's intent-filter.
<action android:name="android.intent.action.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE" />
If your application is installed on the SD card, you should register this to get the android.intent.action.BOOT_COMPLETED event.
Updated: Since your app is using alarm service, it should not be installed on external storage. Reference: http://developer.android.com/guide/topics/data/install-location.html
Whenever the platform boot is completed, an intent with android.intent.action.BOOT_COMPLETED action is broadcasted. You need to register your application to receive this intent. For registering add this to your AndroidManifest.xml
<receiver android:name=".ServiceManager">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
So you will have ServiceManager as broadcast receiver to receive the intent for boot event. The ServiceManager class shall be as follows:
public class ServiceManager extends BroadcastReceiver {
Context mContext;
private final String BOOT_ACTION = "android.intent.action.BOOT_COMPLETED";
#Override
public void onReceive(Context context, Intent intent) {
// All registered broadcasts are received by this
mContext = context;
String action = intent.getAction();
if (action.equalsIgnoreCase(BOOT_ACTION)) {
//check for boot complete event & start your service
startService();
}
}
private void startService() {
//here, you will start your service
Intent mServiceIntent = new Intent();
mServiceIntent.setAction("com.bootservice.test.DataService");
mContext.startService(mServiceIntent);
}
}
Since we are starting the Service, it too must be mentioned in AndroidManifest:
<service android:name=".LocationService">
<intent-filter>
<action android:name="com.bootservice.test.DataService"/>
</intent-filter>
</service>

Alarm Manager after shutdown

When I tried this code, everything is working fine except, service is not getting start after device reboot. I want to start same service automatically. I am testing this example by connecting mobile with USB. what do I need to change ?
[http://javatechig.com/android/repeat-alarm-example-in-android]
try like this
<!-- for reboot event to reset alarms -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
then
<receiver
android:name="com.yourapp.receiver.RestartAppReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
next you have to create the BroadcastReceiver class
public class RestartAppReceiver extends BroadcastReceiver {
private static final String LOG_TAG = "RestartAppReceiver";
public RestartAppReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
String action = intent.getAction();
switch (action) {
case Intent.ACTION_BOOT_COMPLETED:
Log.i(LOG_TAG, "Start resetting alarms after reboot");
//restart what you need
Log.i(LOG_TAG, "Finish resetting alarms after reboot");
break;
default:
break;
}
}
}
}
You have to create a broadcast receiver that will listen for boot complete event and when that event is received start your service again
<receiver android:name=".Autostart">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
create a class like this and add your code in onReceive method
public class Autostart extends BroadcastReceiver
{
public void onReceive(Context arg0, Intent arg1)
{
Log.i("Autostart", "**********started************");
}
}

android: Headset plug listener

public class HeadsetIntentReceiver extends BroadcastReceiver {
private String TAG = "HeadSet";
public HeadsetIntentReceiver() {
Log.d(TAG, "Created");
}
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
int state = intent.getIntExtra("state", -1);
switch(state) {
case(0):
Log.d(TAG, "Headset unplugged");
break;
case(1):
Log.d(TAG, "Headset plugged");
break;
default:
Log.d(TAG, "Error");
}
}
}
}
Here's my code for listening for headphone plug, I initiated this from a Service class, but every time I plug and unplug it, nothing appears on the Logcat, any ideas?
AndriodManifest.xml
<service android:name="com.jason.automator.HeadphoneJackListenerService" />
<receiver android:name=".HeadsetIntentReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.HEADSET_PLUG" />
</intent-filter>
</receiver>
If the minimum SDK version of your application is LOLLIPOP, it is recommended to refer to the AudioManager constant AudioManager.ACTION_HEADSET_PLUG in your receiver registration code instead.
If you haven't registered your receiver in manifest you can do like below
<receiver android:name=".HeadsetIntentReceiver" >
<intent-filter>
<action android:name="android.intent.action.HEADSET_PLUG" />
</intent-filter>
</receiver>
Also you can register it dynamically.
When OS send this "HEADSET_PLUG" intent, OS set the flag "Intent.FLAG_RECEIVER_REGISTERED_ONLY" . That's why may be your code not working. So try registering dynamically like below in Activity or Service class instead of "AndroidManifest" things.
So try below code,
IntentFilter receiverFilter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
HeadsetIntentReceiver receiver = new HeadsetIntentReceiver();
registerReceiver( receiver, receiverFilter );

Detect USB Device Disconnection

I'm trying to detect USB device disconnection. I'm using the code below:
BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(
UsbManager.ACTION_USB_DEVICE_DETACHED)) {
Toast.makeText(getBaseContext(), "usb was disconneced",
Toast.LENGTH_LONG).show();
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(receiver, filter);
But it doesn't work. Nothing happens when I disconnect a USB storage. What is the problem?
Thanks.
You can receive power connected or disconnected events, like this by placing it in the android manifest.xml:
<receiver android:name=".PowerConnectionReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
</intent-filter>
</receiver>
and further more about details explanation about USB connect and disconnect follow the example

ACTION_SCREEN_ON and ACTION_SCREEN_OFF not working?

I'm trying to turn WiFi off when the screen is OFF (locked), and turn it on again when screen is ON (unlocked).
I made a BroadcastReceiver; put in manifest this code:
<receiver android:name="MyIntentReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.SCREEN_OFF" />
<action android:name="android.intent.action.SCREEN_ON" />
<action android:name="android.intent.action.USER_PRESENT" />
<category android:name="android.intent.category.HOME" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</receiver>
and this is the class MyIntentReceiver:
package org.androidpeople.boot;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class MyIntentReceiver extends BroadcastReceiver {
// Called when boot completes
public static boolean startup;
#Override
public void onReceive(Context context, Intent intent) {
// Set what activity should launch after boot completes
System.out.println("Intent Action: " + intent.getAction());
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
System.out.println("locked : ACTION_SCREEN_OFF");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
System.out.println("not locked : ACTION_SCREEN_ON ");
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
System.out.println("User Unlocking it ");
}
else if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
// this to indicate that program is running
// automaticlly not manually by user
startup = true;
System.out.println("Automatic BOOT at StartUp");
Intent startupBootIntent = new Intent(context, LaunchActivity.class);
startupBootIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(startupBootIntent);
}
}
}
And the result is - both ACTION_SCREEN_ON
and ACTION_SCREEN_OFF never fired!
USER_PRESENT and BOOT_COMPLETED worked fine but the other did not. I'm using an emulator, not a real device - can this cause the problem?
Any help?
I need to catch the screen on and off in order to enable/disable WiFi
to save battery.
Thanks in advance
To capture the SCREEN_OFF and SCREEN_ON actions (and maybe others) you have to configure the BroadcastReceiver by code, not through the manifest.
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver mReceiver = new ScreenStateBroadcastReceiver();
registerReceiver(mReceiver, intentFilter);
It's tested and works right.
You cannot catch those intents through XML (I forget why). However, you could use a Service that registers a BroadcastReceiver member in its onStartCommand() and unregisters it in its onDestroy(). This would require the service to be running in the background, constantly or as long as you need it to, so be sure to explore alternative routes.
You could define the BroadcastReceiver in your Service class like so:
private final class ScreenReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
//stuff
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
//other stuff
}
}
}
For a slightly complicated example, but one that shows how the BroadcastReceiver and Service interact see CheckForScreenBugAccelerometerService from my app, ElectricSleep.

Categories

Resources