my onCreate() looks like:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new Thread(new IpAddressCallable()).start();
int n=100;
for(int i=1;i<=n&&!gotWifiUpOrFail;i++)
try {
Thread.sleep(100);
} catch(InterruptedException e) {
System.out.println("5 caught: "+e);
}
initialize();
}
i need to wait to force a wifi conection since the tablets come up in a: "no internet access detected won't automatically reconnect" mode (apparently since 5.1 or so).
the initialization buids the gui and does a: setContentView(relativeLayout), so i can not run this from another thread.
is this sane way to wait for something like this?
Don't you normally use intents or receivers for this sort of thing? I thought hard-coded wait loops were frowned upon. Maybe these will help:
How to detect when WIFI Connection has been established in Android?
Wifi Connect-Disconnect Listener
CONNECTIVITY_ACTION intent received twice when Wifi connected
I am developing an application that communicates with an Embedded Device via the Android Devices USB Host port. I noticed that when the screen is locked USB Host port is disabled and no communication occurs.
How can I prevent the USB Host port from turning off so that communication can occur when the screen is locked?
------------- USB Host ---------------
| Android | <------------------> | Device |
------------- ---------------
Note: I can have root access on the Android system if necessary.
Thanks for the tip Chris Stratton. Using a PARTIAL_WAKE_LOCK the screen can turn off yet the CPU remains running. This is suitable for my application.
I created a quick app to test this:
public class MainActivity extends Activity {
PowerManager pm;
PowerManager.WakeLock wl;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
}
#Override
protected void onStart() {
super.onStart();
if (wl != null) {
wl.acquire();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (wl != null) {
wl.release();
}
}
I tested it by connecting a mouse to the USB Host. When the screen was locked the mouse did not turn off as I would like.
Another option I came across which I have not tried. You may be able to adjust the system resource which controls the power management of the USB device. You probably need root access for this.
Changing the default idle-delay time
------------------------------------
The default autosuspend idle-delay time (in seconds) is controlled by
a module parameter in usbcore. You can specify the value when usbcore
is loaded. For example, to set it to 5 seconds instead of 2 you would
do:
modprobe usbcore autosuspend=5
Equivalently, you could add to a configuration file in /etc/modprobe.d
a line saying:
options usbcore autosuspend=5
Some distributions load the usbcore module very early during the boot
process, by means of a program or script running from an initramfs
image. To alter the parameter value you would have to rebuild that
image.
If usbcore is compiled into the kernel rather than built as a loadable
module, you can add
usbcore.autosuspend=5
to the kernel's boot command line.
Finally, the parameter value can be changed while the system is
running. If you do:
echo 5 >/sys/module/usbcore/parameters/autosuspend
then each new USB device will have its autosuspend idle-delay
initialized to 5. (The idle-delay values for already existing devices
will not be affected.)
Setting the initial default idle-delay to -1 will prevent any
autosuspend of any USB device. This has the benefit of allowing you
then to enable autosuspend for selected devices.
Source:
https://android.googlesource.com/kernel/common/+/android-3.10/Documentation/usb/power-management.txt
I have taken Code Aurora's FM Radio code and merged with my Android Gingerbread codebase.
The FM app framework tries to access the fm radio device ( /dev/radio ) using JNI which is implemented in a file by name android_hardware_fm.cpp . There is a function in this file which tries to acquire a file descriptor to the device node using open() in the read/write mode. However, the call fails with error code -13 : Permission denied.
I also made a small C executable which tries to open the /dev/radio file ( in RDWR mode), prints its fd and closes it. It runs from /system/bin in the target system and displays a valid fd.
Btw, the JNI implementation is part of the android core library. It is located in frameworks/base/core/jni and is compiled as part of libandroid_runtime.so
Any ideas/solutions? Thanks in advance.
Clearly you donot have permissions to open the device from user space. In the second case when you are running the executable from terminal, you are having permissions probably because you have done su before running the executable.
For your problem here, two things can be done.
1) Change the permissions of the node from terimnal.
Steps involved:
Open the terminal (adb shell)
Do su(In order to do this your device must be rooted)
Do chmod 777 /dev/radio in the terminal
Once this is done, your radio node is having proper permissions for the user to read and write. So you can now do open() call and it will work.
2) Programmatically you can achieve this (assuming your device is rooted and su is running on your device) by calling the below function - changePerm(). This is a small function I have written which will change the permissions of the device nodes or rather any system file that does not have user access. Once you have permissions, you can open it from user space. open() call will work properly after this.
void changePerm()
{
Process chperm;
try {
chperm=Runtime.getRuntime().exec("su");
DataOutputStream os =
new DataOutputStream(chperm.getOutputStream());
os.writeBytes("chmod 777 /dev/radio\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
chperm.waitFor();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I have tested this for other nodes. So it should also work for radio aswell. Let me know in case yo are facing any difficulty. Thanks
I am facing one strange problem, when i run my android application on the device so either it will be running on foreground or background , it should not loose the WiFi connection, for that I have get the WiFiManager and acquired the lock in Service's onCreate() method and release it on onDestroy method. But facing problem to keep WiFi turned on when device goes to sleep mode, so is there any way to make WiFi turned on even if device goes to sleep mode.
I can't acquire the lock to wake up the device because scenario is our application will run always so whenever user will not use, device should go to sleep mode but wifi connection should always be turned on.
Please do help me resolve this issue, please share some sample code also.
Regards,
Piks
Try to use Services. Just insert you wifi connection code in a service, and this will run forever in background.
Maybe this will help..
private void setNeverSleepPolicy() {
try {
ContentResolver cr = getContentResolver();
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.JELLY_BEAN) {
int set = android.provider.Settings.System.WIFI_SLEEP_POLICY_NEVER;
android.provider.Settings.System.putInt(cr, android.provider.Settings.System.WIFI_SLEEP_POLICY, set);
} else {
int set = android.provider.Settings.Global.WIFI_SLEEP_POLICY_NEVER;
android.provider.Settings.System.putInt(cr, android.provider.Settings.Global.WIFI_SLEEP_POLICY, set);
}
} catch (Exception e) {
e.printStackTrace();
}
}
Has anyone out there been able to get the android.hardware.usb.action.USB_DEVICE_ATTACHED" to work?
Ok so i'm trying to use the new usb host mode features to detect when a usb device is attached. For my purposes i want to be notified any time a device is attached. I was not able to see it happen. I'm using a broadcast reciever that i know works (when i have it listen for other things such as the home button being pressed. No matter what i try i can't seem to get the intent to fire.... So to make things simpler i decided to forget about my project and attempt to use google's own sample code and see if i could at least make that work. I don't have one of the missle launcher but i figured i could at least get it the USB_Device_Attached to fire. No go. I adapted the code to work for other devices. First i tried adjusting the device filter xml.
I added my device (a keyboard):
<usb-device vendor-id="1050" product-id="0010" />
I got the vendor and product from an lsusb command. When the device is attached the logcat shows that the device is found
D/EventHub( 144): No input device configuration file found for device 'Yubico Yubico Yubikey II'.
I/EventHub( 144): New device: id=43, fd=219, path='/dev/input/event8', name='Yubico Yubico Yubikey II', classes=0x80000003, configuration='', keyLayout='/system/usr/keylayout/Generic.kl', keyCharacterMap='/system/usr/keychars/Generic.kcm', builtinKeyboard=false
I/InputReader( 144): Device added: id=43, name='Yubico Yubico Yubikey II', sources=0x00000101
I/ActivityManager( 144): Config changed: { scale=1.0 imsi=0/0 loc=en_US touch=3 keys=2/1/1 nav=1/2 orien=L layout=0x10000014 uiMode=0x11 seq=47}
D/MissileLauncherActivity(16191): intent: android.intent.action.MAIN
I/EventHub( 144): Removed device: path=/dev/input/event8 name=Yubico Yubico Yubikey II id=43 fd=219 classes=0x80000003
I/InputReader( 144): Device removed: id=43, name='Yubico Yubico Yubikey II', sources=0x00000101
I/ActivityManager( 144): Config changed: { scale=1.0 imsi=0/0 loc=en_US touch=3 keys=1/1/2 nav=1/2 orien=L layout=0x10000014 uiMode=0x11 seq=48}
D/dalvikvm( 144): GC_EXPLICIT freed 78K, 26% free 14717K/19719K, paused 3ms+3ms
D/MissileLauncherActivity(16191): intent: android.intent.action.MAIN
The xoom does find the keyboard and it is usable from the device (i can use it in the browser to type letters). And the intent sort of fires (but it only fires the android.intent.action.MAIN) i don't ever get the DEVICE_ATTACHED Intent. The log entry comes from the sample code:
Log.d(TAG, "intent: " + intent.getAction().toString());
In the resume function. After more digging and removing any reference to usb i found that every app i make get's the resume called when a keyboard is attached/detached (hence the intent: android.intent.action.MAIN log entry).
Right now the only thing i can figure is that it's a bug in the android source.
By the way i'm using a wifi xoom with os 3.1.
I also had the same problem. I finally figured out that in the device filter xml we should add following line.
<usb-device vendor-id-"xxxxx" product-id="yyyyy">
the xxxxx and yyyyy should be decimal numbers. NOT HEX CODES. Then it all works as advertised!
I know it is late but I hope it helps.
So I found a solution to my problem and I've learned a lot hopefully it can help someone else.
So first off HID devices do not kick off any intent. Nor do they show up in the mUsbManager.getDeviceList() list. Other things however do. I gave a usb memory stick a go and what do you know the device is listed in the device list. I also found out that the device returned does not have the a class,subclass, or protocol. Debugging revealed that the parent interface did however have the proper class/subclass/and protocol.
Also if you must have a device filter. I ended up with a class=0008 (USB STORAGE) to work for my purposes. I'm guessing other classes would work as well.
So now on to figuring out intents. Turns out that the intent must be attached to a launcher activity. My attempts to attach it to a service or receiver will not bear any fruits. So now that I'm getting intents to fire I now see notifications popup when I attach my device (usb memory stick) it asks me to set my app as the default for that device. Perfect now my app gets run every time I attach that device. Note that you will be prompted for each unique device. But only once. It seems to be registered much like default programs.
Well, I think that about sums up what I found. too bad you can't get notified when an keyboard/mouse gets attached. Oh and one more thing. There are not any problems with the tiamat kernel, running it right now and no problems.
I recently discovered a solution to a similar issue.
As someone has already noted, HID devices do not kick off an intent, which I think was your issue.
However, a related issue is that, if your program is set to run when a USB device is connected, then even once your application is running, you can't capture the USB_DEVICE_ATTACHED action. Instead, the system sees that intent, and says "oh that means this application wants to run (as declared in your manifest) and then it sends you the android.intent.action.MAIN action instead of the USB_DEVICE_ATTACHED action, and it calls onResume(). Even if your app is running. So as far as I can tell, you CAN'T capture the USB_DEVICE_ATTACHED intent if your manifest declares that your app will run when USB devices are attached. You just have to put some code in onResume() to check to see if USB is connected. Even if your program is running, onResume will get called again when a USB device is attached.
I note my solution in more detail here: Android 3.1 USB-Host - BroadcastReceiver does not receive USB_DEVICE_ATTACHED
Enumerating devices
If your application is interested in inspecting all of the USB devices currently connected while your application is running, it can enumerate devices on the bus. Use the getDeviceList() method to get a hash map of all the USB devices that are connected. The hash map is keyed by the USB device's name if you want to obtain a device from the map.
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
If desired, you can also just obtain an iterator from the hash map and process each device one by one:
UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while(deviceIterator.hasNext()){
UsbDevice device = deviceIterator.next()
//your code
}
I had the same problem. My ultimate solution was to use the old fashioned polling technique. Here is a fairly minimal class which solves the problem to my satisfaction.
package com.YourCompancy.YourProduct;
import android.app.*;
import android.content.*;
import android.hardware.usb.*;
import java.util.*;
import android.util.*;
import android.os.*;
public class UsbDeviceWatcher extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent)
{
if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED))
{
UsbDevice d = (UsbDevice)
intent.getExtras().get(UsbManager.EXTRA_DEVICE);
DeviceConnect(d, false);
}
}
public void DeviceConnect(UsbDevice device, boolean Attached)
{
if (Attached)
{
// Some suggestions ...
// play sound effect
// notify consumer software
// determine if interested in device
// etc
Log.i("usb", "device attached");
} else
{
Log.i("usb", "device detached");
}
}
public UsbManager manager;
public Handler handler;
public UsbDeviceWatcher(Context context, Handler handle)
{
this.handler = handle;
manager = (UsbManager)
context.getSystemService(Context.USB_SERVICE);
IntentFilter dev = new IntentFilter();
dev.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
context.registerReceiver(this, dev);
final UsbDeviceWatcher _this = this;
Thread thread = new Thread(new Runnable()
{
public void run()
{
LinkedList<UsbDevice> seen = new LinkedList<UsbDevice>();
LinkedList<UsbDevice> attached = new LinkedList<UsbDevice>();
//there is a need for multithread support here
// so the thread can watch for an exit condition
while (true)
{
HashMap<String, UsbDevice>
D = manager.getDeviceList();
for (UsbDevice d : D.values())
{
if (!seen.contains(d))
{
if (!attached.contains(d))
{
final UsbDevice dev = d;
handler.post(new Runnable(){
public void run()
{
DeviceConnect(dev, true);
}
});
}
seen.add(d);
}
}
for (UsbDevice d : seen)
{
if (!D.values().contains(d)) seen.remove(d);
}
try
{
Thread.sleep(500);
} catch (InterruptedException exception)
{
return;
}
}
}
});
thread.start();
}
}
Another workaround is to use
new FileObserver("/dev/input") {
#Override public void onEvent(int event, String path) {
//gets called on input device insert / remove
}
};
which will work for some usb devices (keyboard, mouse)
I have my app set as launchMode="singleTop" and in that mode it seems like the getIntent().getAction() is always equal to the action that first started the app.
So if you start the app manually and then plug in a device (even after switching away from that app), you will receive android.intent.action.MAIN.
If you kill the app and then plug in the device, you will always get android.hardware.usb.action.USB_DEVICE_ATTACHED, even from switching away and back to your app, or even for rotating the device.
I actually weirdly receive intents when unplugging the USB device, which I don't think is documented - but of course I receive USB_DEVICE_ATTACHED when my device is detached.
Without singleTop, it does kind of work as expected, but then you get another stupid extra activity if your app is already open and you plug in the device.
Once again Android's API is buggy, overly complicated and difficult to use.
OK more work, more failure, but some progress.
I found out more from the sdk documentation. it appears that you have to have the device filter in order to use the intents. so I decided to try using a class filter instead of the vendor/product ids. I figure that it would be more general and hopefully catch the hid device. I used 03h as the class id , I tried various formats, I tried the subclasses, I even used lsusb to discover, class, subclass, and protocol of my device. these didn't seem to help at all. so I went further in to the sdk documentation and decided to try enumerating all of the devices to see what the os saw the class/subclass/protocol integers. I copied the code pasted it into the click listener and adding log.v statements. nothing shows in the logcat .
it looks, like the us system isn't seeing any device (even though the device actually works.) now this is very indicitive of the USB device connected intent not firing. now I must say that I am using a custom kernel in my xoom (tiamat). I thought this might have something to do with the problem a while ago, so I reverted to stock 3.1. and still now progress. now this was a while ago, before I tried enumerating, so now I will revert agaian and keep working with stock until I am sure the kernel is not the issue. I'll check back In when I found out more. success or failure. ofcourse if anyone else unterstands this better than me please chime in.
one last note I'm a big worried about the whole otg host mode when I saw this in the documentation.. notice that the coe is identical even thought it references two methods of enumeration. probably just a copy writers mistake, but still worry some in light of all this failure.
This is what I did to detect USB/Media Connect.
Manifest file
<receiver
android:name=".UsbReceiver"
android:enabled="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>
I didn't do anything in the activity nor my receiver.
looks like this line is doing the stuff.
<data android:scheme="file"/>
Connect Usb Keyboard WONT fire USB_DEVICE_ATTACHED.
Instead, the System will fire Intent.ACTION_CONFIGURATION_CHANGED. However, as there is a configuration change, system will restart the Activity. You wont catch the action with the Activity restarted. In this case, you need to add android:configChanges="keyboard|keyboardHidden" in your Android Manifest so that the Activity wont be restarted once a external keyboard is connected.
From my testing, Android can fire an intent when an HID device is connected. (The MissileLauncher sample application does just that. See the sample source code for more info.)
The Missile Launcher (Dream Cheeky USB Missle Launcher) HID Device has its subclass and protocol set to 0x00. For more info see: http://www.mattcutts.com/blog/playing-with-a-usb-missile-launcher/
The caveat is that Android does not throw an intent for mouse and keyboard devices specifically (maybe more). I can however detect HID devices that have their InterfaceClass = 0x03, InterfaceSubClass = 0x00, InterfaceProtocol = 0x00. For my application, my HID device is an embedded controller so setting the subclass and protocol is not an issue.