Is there a way to detect when a USB flash drive is plugged into an Android device? I'm able to detect an SD card using a broadcast receiver, but it doesn't work for USB. I'd like to avoid polling.
code to register receiver:
private void RegisterUpdateReceiver()
{
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.intent.action.MEDIA_MOUNTED");
intentFilter.addDataScheme("file");
myReceiver = new MyReceiver();
this.registerReceiver(myReceiver, intentFilter);
}
receiver code:
public class MyReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
String action = intent.getAction();
if (action.equals("android.intent.action.MEDIA_MOUNTED"))
{
// react to event
}
}
If detecting attaching and detaching the USB will work "android.hardware.usb.action.USB_DEVICE_ATTACHED" can be used.
Make sure the definition of the receiver and the intent filter is added in the manifest as well.
Android, at the SDK level, has no concept of USB drives. There are no rules for where they should be mounted, broadcasts for when they appear/disappear, etc. Perhaps some standardization in this area will come in future Android releases, but it is not there today.
This is the xml version of the receiver in the AndroidManifest.xml:
<receiver
android:name="MyMountBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MEDIA_MOUNTED"/>
<action android:name="android.intent.action.MEDIA_UNMOUNTED"/>
<data android:scheme="file" />
</intent-filter>
</receiver>
This is how I made it work on Android 6.0.
Basically, what we need to detect is when the drive is mounted which can be done by ACTION_MEDIA_MOUNTED that is "android.intent.action.MEDIA_MOUNTED".
Follow the steps below:
Register a broadcast receiver for "ACTION_USB_DEVICE_ATTACHED"
Register a broadcast receiver for "ACTION_MEDIA_MOUNTED"
Seek permission for using the device when "ACTION_USB_DEVICE_ATTACHED" action is received.
Then you will receive broadcast for "ACTION_MEDIA_MOUNTED"
You can refer: https://developer.android.com/reference/android/content/Intent#ACTION_MEDIA_MOUNTED
Note: Registering broadcast receiver for ACTION_MEDIA_MOUNTED alone does not work. So used broadcast "ACTION_USB_DEVICE_ATTACHED" for permission purpose.
Related
I'm trying to use a broadcastreceiver to capture a network change but it doesn't seem to be working at all.
My broadcastreceiver:
public class btReceiver extends BroadcastReceiver {
public btReceiver() {
}
#Override
public void onReceive(Context context, Intent intent)
{
Log.d("BB","Received!");
Toast.makeText(context, "Action: " + intent.getAction(), Toast.LENGTH_LONG);
}
}
The way I call it:
IntentFilter filter = new IntentFilter();
filter.addAction(getPackageName() + "android.net.conn.CONNECTIVITY_CHANGE");
btReceiver myReceiver = new btReceiver();
registerReceiver(myReceiver, filter);
But when I try to toggle let's say wifi, nothing happens at all. I also tried declaring it in the manifest like so:
<receiver android:name=".btReceiver" android:enabled="true" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
But that also doesn't work.
I have declared sufficient permissions in my manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
My test device is running Android 7.1.1, does anyone know why it's not firing?
Apps targeting Android N (Nougat) do not receive CONNECTIVITY_ACTION broadcasts, even if they have manifest entries to request notification of these events. Apps that are running can still listen for CONNECTIVITY_CHANGE on their main thread if they request notification with a BroadcastReceiver.
You should register it programmatically or use JobScheduler, GcmNetworkManager or android-job library
Your package name shouldn't be part of the Intent action. So try with:
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
Even better, there's a constant for that:
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
I am trying to make an app that shows a toast when the device's Bluetooth turned on. I wanna do that even when my app is not running. So I should use a broadcast receiver, add some permissions, an intent-filter to android manifest and make a java class but I don't know the details.
What should I do? Which permissions should I use?
AS far as permissions go, to detect the state change of bluetooth you need to add this to your AndroidManifest.xml.
<uses-permission android:name="android.permission.BLUETOOTH" />
An example receiver would look like this, you add this code to where you want to handle the broadcast, for example an activity:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive (Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
if(intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1)
== BluetoothAdapter.STATE_OFF)
// Bluetooth is disconnected, do handling here
}
}
};
To use the receiver, you need to register it. Which you can do as follows. I register the receiver in my main activity.
registerReceiver(this, new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED));
You could also decide to add all of it to your AndroidManifest.xml. This way you can make a special class for the receiver and handle it there. No need to register the receiver, just make the class and add the below code to the AndroidManifest
<receiver
android:name=".packagename.NameOfBroadcastReceiverClass"
android:enabled="true">
<intent-filter>
<action android:name="android.bluetooth.adapter.action.STATE_CHANGED"/>
</intent-filter>
</receiver>
You have to take following permission.
<uses-permission android:name="android.permission.BLUETOOTH" />
and you have to write this as your intent filter in receiver tag.
<action android:name="android.bluetooth.adapter.action.STATE_CHANGED" />
Unfortunately, for apps targeting api 26 or higher, manifest declared broadcast receivers don't work anymore (reference here: https://developer.android.com/guide/components/broadcast-exceptions), with some exceptions.
android.bluetooth.adapter.action.STATE_CHANGED is not in that list.
For bluetooth, you can only listen for changes on:
ACTION_CONNECTION_STATE_CHANGED, ACTION_ACL_CONNECTED, ACTION_ACL_DISCONNECTED
I want to start my application at startup in Android 4.0. To do that, I wrote some codes and these are completely the same with the #Ahmad's codes (in the answer). However, although I select my application as always, when tablet opens, it asks 'What do you prefer?' (Android's default launcher or my application). I don't want it to ask that question and it must start my application automatically.
Use the BOOT_COMPLETED Intent.
Broadcast Action: This is broadcast once, after the system has
finished booting. It can be used to perform application-specific
initialization, such as installing alarms. You must hold the
RECEIVE_BOOT_COMPLETED permission in order to receive this broadcast.
In your Manifest:
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
Set up a Broadcastreceiver:
<receiver android:name="com.example.MyBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
This is how your BroadcastReceiver could look like:
public class MyBroadcastreceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, MyActivity.class);
startActivity(i);
}
}
I have a broadcast receiver registered in Manifest:
<application ...>
<receiver android:name="com.some.pkg.NewAppReceiver" >
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
</intent-filter>
</receiver>
</appcication>
And the receiver:
public class NewAppReceiver extends BroadcastReceiver {
private static final String TAG = "NewAppReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Intent: " + intent.getAction());
}
}
And nothing is received when I install APK manually or from the Android Market. Why?
Did you run the app that contains this broadcastReceiver before installing the other apps?
Starting at some API version, broadcastReceivers will not work till you execute the app. Put an activity and execute it.
Also , don't forget to add the following into the broadcastReceiver:
<data android:scheme="package" />
EDIT: On Android 8 and above, if your app targets API 27 or more, it will work partially, so you have to register to those events in code and not in manifest. Here's a list of intents that are still safe to use in manifest: https://developer.android.com/guide/components/broadcast-exceptions.html .
The rest should be used in code. More info here
Since android.intent.action.PACKAGE_ADDED is a System Intent (note that your own app will not receive it at its installation), your BroadcastReceiver will receive messages from sources outside your app. Thus, check you did NOT put: android:exported="false"
You also may need to add:
<data android:scheme="package" />
So, your BroadcastReceiver in your AndroidManifest.xml should look like this:
<application ...>
<receiver android:name=".NewAppReceiver" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PACKAGE_ADDED" />
<data android:scheme="package" />
</intent-filter>
</receiver>
</appcication>
If it still doesn't work, you may try to put an higher priority, such as: android:priority="1000"
Take a look at: http://developer.android.com/guide/topics/manifest/receiver-element.html
Registering receiver from manifest would not work from API 26(android 8). Because it had performance impact on older versions.
But we can register receiver from java code and receive updates of removed and added applications.
val intentFilter = IntentFilter()
intentFilter.addAction(Intent.ACTION_PACKAGE_ADDED)
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED)
intentFilter.addDataScheme("package")
registerReceiver(YourBroadcastReceiver(), intentFilter)
Are you trying to receive the intent in the application you are installing? The documentation for ACTION_PACKAGE_ADDED says:
Note that the newly installed package does not receive this broadcast.
Another possibility is that this intent might not be delivered to components registered via the manifest but only manually (as described in an answer by Mark Murphy to Stack Overflow question Can't receive broadcasts for PACKAGE intents).
If you try to receive some other package it must be worked.
(As #Savvas noted) If you try to receive your own package's addition you can't receive it. Even if your broadcast receiver has action.PACKAGE_ADDED, receiver's onReceive method isn't triggered.
In this case your best bet is saving this data. By using sharedPreferences, add a key something like "appIsWorkedBefore", and on your launcher Activity's onCreate method set this variable as "true". And you can make your works with respect to this Boolean.
This intent action is no longer available for applications.
This is a protected intent that can only be sent by the system.
https://developer.android.com/reference/android/content/Intent#ACTION_PACKAGE_ADDED
My code misses something, need your eyes to locate.
I created a USBOnReciever broadcastreceiver.
public class USBOnReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
Toast.makeText(context, "Phone was connected to power" ,Toast.LENGTH_LONG).show();
Log.d("tag", "Phone was connected to power");
}
}
My manifest is:
<application>
<receiver android:name=".USBOnReceiver" android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.UMS_CONNECTED" />
</intent-filter>
</receiver>
</application>
and here is when I stuck.
nothing appears to happen when connecting the USB ( I also tried with power_connected).
I understand I can register the BR either through the manifest or programmaticaly. But not sure how to implement.
In my activity I added
USBOnReceiver myReceiver = new USBOnReceiver();
But it looks so unconnected and useless :-/
Will appreciate your eyes here.
Your code is seems complete. If im not mistaken,
the only issue you have is: You wrote reciever inside your manifest instead of receiver.
So the BroadcastReceiver never got registered correctly.
To the topic of registering in code:
Yeah thats possible. Just create an instance of your receiver
and use Context.registerReceiver(mReceiver, new IntentFilter(...)).
If you have registered in your manifest, there is no need to do that.
BroadcastReceivers only live for the execution of onReceive(). Therefore
the system creates the instances and kills them afterwards.