I am struggling with an issue relating to the licensing service and network connection.
The bottom line is I want the LVL to work if the user is in the middle of nowhere with no signal, but I don't want them to be able to 'cheat' and turn off the data connection.
I already have detected and intercepted airplane mode, but some phones or apps let you turn data connection on or off. (some don't)
My Epic 4g allows this, and I think the hidden API letting us control this is not working past 2.0 release. (iTelephony)
However is it possible to simply detect if the connection was disabled and not change that fact but simply react to it?
I can already detect whether or not there is a data connection or not- what I want is to tell the difference between a disabled antenna and simply not having signal. The market licensing check will fail and I want to give 'em a pass if they legitimately have no signal, but not if they forced it off.
Well, I don't need to check whether net has been disabled outside of airplane mode,
I found a different solution here:
http://code.google.com/p/androidbest/
What this code does is force the user to authenticate at least once. Then if it fails to connect to the LVL server, it uses a cached authentication. I had to change it a bit, notably it was launching the next activity twice, and now it solves my issue adequately.
Related
We want Android to automatically connect to our custom made BLE peripheral.
Our peripheral should regularly (but infrequently) advertise and attempt to Indicate some time-sensitive sensor data to the phone. Thus we want the phone to be ready to connect at any time.
Generally, you can pair a smart watch with an Android, and Android will then automatically connect to the smart watch whenever it is in range. So we believe our use case should be feasible.
I read a lot of answers that advise to set the "autoconnect" parameter to true when connecting. I have tried that and the reconnections don't persist through a reboot or even after disabling and re-enabling Bluetooth on Android. This answer by Brian says I should scan in the background, but Android made this unrealistic. If I use a foreground service, my users will hate the app. If I use a background service, I may miss the peripheral's attempts to connect during Android's Doze and the code becomes error prone.
Ideally, I want to do something like what Emil said in his answer here. Please read the follow up question and response.
However, we can't see our app through Android's Bluetooth settings. We can only connect to the peripheral and pair with it using our app (or nrf Connect). In desperation, I tried modifying the peripheral's advertising flags. Then I could see it in Android's Bluetooth settings. But when I try to pair using Android's settings, the attempt fails because the peripheral is not in "pairing mode".
We are building both the app and the peripheral, so we can change both. I want to know if our use case is possible and what we need to do to get it working. We are using the STM32WB for our peripheral.
Use a combination of these techniques:
Bond the device. This might be needed due to the crappy Android Bluetooth LE API design that doesn't take the "address type" as an extra parameter when connecting to a device. When you connect using the Bluetooth device address, it looks up a device with this address in the bonding info, and uses the corresponding address type (random or public).
Use connectGatt with autoConnect set to true. This means no timeout, as well as auto-reconnect if the connection drops. Even if it takes days or weeks until the peripheral starts advertising, it will still work.
Listen to https://developer.android.com/reference/android/bluetooth/BluetoothAdapter#ACTION_STATE_CHANGED and restart your connections when Bluetooth is re-started.
Use a Foreground Service in your application's process to prevent the OS from killing the process. Users can nowadays hide the annoying notification in Android settings if they want to.
Listen to https://developer.android.com/reference/android/content/Intent#ACTION_BOOT_COMPLETED to start your app after boot, including your Foreground Service.
Listen to https://developer.android.com/reference/android/content/Intent#ACTION_PACKAGE_REPLACED to automatically restart your app after an app update. See https://stackoverflow.com/a/2134443/556495 for some instructions.
The best approach is to make sure your peripheral can be bonded. Once you have bonded with it you can ALWAYS use autoconnect because Android stores info about bonded devices and you don't have to scan for it anymore. Hence you avoid the issues with scanning in the background.
Although that resolves the need for scanning, you still need to deal with your app being killed once it is in the background. Using a Foreground Service is still the best solution to my knowledge. I don't think you users will hate your app for it...
I'd like to use android's bluetooth for some kind of sensing devices. But I don't want to connect to these devices. As far as I know Devices won't react to scanning when their own bluetooth is disabled. But is there any way to get my app noticed when such a scan has been performed by a remote device, even when my app is running with bluetooth turned off?
I don't want to force toggling bluetooth on, but I need to get some kind of Action started in other devices running the same app. So I'm wondering if some there is any description/data field that can be sent with a bluetooth scan, so if scan is rejected the app has the opportunity to read that data just to know there was this specific call?
I need to leverage context-awareness within my system as to users, not knowing each other, still can interchange content (if they agree). But I need to find some ways of sensing while I also don't want to have all sensors activated all the time.
Hope you can give me a hint, or tell me that this is simply not possible, which would also help me not spending any more time on that.
Thanks.
My app connects with a persistent connection to a server. If the device is currently using 3G it will connect over 3g.
The problem is that if it connected using 3G and moved into wifi the connection drops. How do I prevent it from disconnecting?
Sounds like the server is unable to accommodate clients seamlessly switching to a different IP address, or it may be using something like keep-alive packets to maintain connection state, and when the 3G connection drops, it disconnects your session.
This may not be something you have control over. From the Android point of view - the device will prefer WiFi depending on user preferences and you will likely not have any direct control over that either.
In a nutshell - if you can't modify or reconfigure the communications protocol to allow client IP changes on the fly, then there's nothing you can do with Android to mitigate the problem.
All mobile devices, and to a lesser extent, desktops/laptops will at some point change their public facing IP address, so it sounds like a bug or oversight in the server/protocol design to me.
EDIT:
In response to your comment, and in the interests of UX, you should be very careful about finding a way to force your app (possibly even the entire device) to remain on 3G when the user has requested that it use WiFi.
Most people have capped data plans with their device and wouldn't be very pleased if they think they are using WiFi (which is most likely free, or at least no additional cost) when in fact you've forced their device to continue using potentially very expensive 3G data instead.
This is especially important when any method would likely be actively circumventing the reasonable limits the Android environment presents you with, and therefore would probably not be flagged as a "Service that costs you money" when installed.
EDIT 2:
So, there may be a way for you to do it, but it relies on unsupported, private Android APIs which may change at any moment - usual disclaimer applies.
Take a look here where they access the ConnectivityManager object to allow you to enable mobile data.
This method does require you to build against the Android source tree, and use a shared user ID with "system" so may or may not be suitable, but these APIs are private (as apps are not supposed to be able to do this without user action), but it may help you.
This is how Android works. You're app should not maintain a persistent connection, it should only open a connection when needed.
I was reading this
http://developer.android.com/guide/topics/wireless/bluetooth.html#QueryingPairedDevices
which is allot of help on how to pair,connect to a bluetooth device.
I have a situation where I have several BT devices that are in Non-Discover mode always. I know the MAC and the PIN of these devices. IS there a way in Android Dev to manually add devices to the PAIRED list so i can just use the connect as a client.
I understand this maual is written allot for V3. i think i will need to do this on 2.0 ; 2.1- has anybody done this before?
Basically these devices I want to connect to are power saving modules I used pre built BT modules to monitor daylight, another one humidity, etc.. every 3hrs or when interrupted and runs of a single battery for months. So turning off divcory on server saves immense power and prevents other people trying to connect and waste battery.
Not sure what you mean by "manually": Do you mean "manually" as in GUI/user interaction, or "manually" as "I do it in my own application code"?
Some suggestions though:
If you can make your BT devices discoverable at all, you could do it this way:
Make your BT device discoverable
Let Android search for and find the device and then initiate a connection
Android will ask for the PIN for pairing with the device; enter the PIN.
Once pairing was successful, Android stores the pairing information for future use, so that you can
Make your BT device invisible again.
From then on your app should be able to connect to the BT device at any time without further pairing operations.
If the said is not an option for you, maybe you want to go another way:
In current Android versions there are different API routines implemented which are neither documented nor exposed in the normal SDK. A hack kind of solution may be to use some of these "hidden" ("#hide"...) APIs, either via reflection or via modification of your SDK installation.
But be aware that this is always a hack and it may work on a specific device with a specific version of Android and is likely to break your app on another device and/or any other Android version.
Having said that, here comes some reference:
Example of how to access "hidden" bluetooth API.
Then, have a look at the source code for android.bluetooth.BluetoothDevice, e.g. here.
In there, public boolean createBond(){...} may do what you want.
Backround: Android 2.x on a tablet
That a the second post on this. Now the WiFi don't get turned off by android but I although loose the connectivity after some, means the server can no longer reach the android device (I get a timeout). I tried this at least on four different tablets so I don't think that it depends on the hardware. A continous polling prevent this but this should be just a workaround.
The answer lays in the wifi router AP (access point). There is a value thats called TTL (time to live) which controls how long a connection is held open after last activity before closing from no activity. You need to change this value in the router.