So I have a need to force an android phone to register/de-register itself repeatedly. I'm accomplishing this via AT commands while the phone is in modem/diag mode over a USB serial connection. I check the current registration state via +CGREG and then assuming it's registered I kill the RF with +CFUN, check again, then turn the RF back on and allow the phone to search out and re-register itself normally. I issue the +CGREG command every few seconds to check on the status and once it's re-registered I repeat.
Now, sometimes I'll do this once or twice, sometimes it'll go five times and then the phone will decide to restart itself... it's a little frustrating and not the desired result.
Anyone have any ideas why the phone would reboot without command due to what I'm doing here? The phone will operate normally any number of hours while I'm not running these tests.
Psudo-Process:
while(true)
AT+CGREG? // starting state < usually registered>
AT+CFUN=4,0 // turn off RF
AT+CGREG? // verify it's not registered
AT+CFUN=1,0 // turn RF back on
while ( )
AT+CGREG? // check registration state every 2 seconds
end
end
On a side note: +COPS is a better option here, however the phone doesn't [fully] support it. The phone is an HTC Thunderbolt.
Related
I have a ble device that I need to regularly extract data from securely and constantly. So on startup I want to make sure to bond the device if it is not already. I have the Mac address of the device in this case.
public void startApp(){
remoteDevice = bluetoothManager.getAdapter().getRemoteDevice(MAC_AD);
if(remoteDevice.getBondState()!=12){
remoteDevice.createBond();
}
}
What ends up happening is that the bond state will alternate between unbonded and currently_bonding but not fully bond.
The strange thing is that sometimes it will work, but usually not, particularly on my google pixel. Bonding through the settings is also very inconsistent.
Is there any way to retry this or some kind of Bluetooth reset that should be done so that I can bond consistently?
I've tried calling createBond() in intervals;
I've often found that calling createBond() directly can have hit-and-miss results depending on the platform (both ends). Logically it should use the same mechanism internally, but I've tended to get better results by calling read on a simple characteristic which has bonded requirements.
It either successes - meaning your connection is bonded - and you can continue. Or it fails, which internally triggers the bonding, and then you can try again after a short delay, at which point it should now be bonded.
I've developed an application that streams music (via internet connection) using service and having trubles streaming content without phone going idle.
While i was developing my application each time i tried case mentioned below the music was reproducing fine.
Use case : search song, select song from results, play song, screen off -> auto play next song from result list
I'm developing using real device - Huawei Mate 20 Lite - OS v8.01 so while debugging it gotta use USB cabel.
Like i said following the use case above while hooked on USB the auto play while screen off works good. The case it doesn't work good is when the cable is not connected (only mobile data turned on).
What I've figured out is that phone when connected on USB is probably keeping the device awake and it doesn't go to idle mode while when not connected after around 5mins the device probably shuts down processes that cost energy or it shuts down connection to mobile data i'm not sure and there's where i need you guys.
Also I've tested app using HTC U Play - OS v6.0 and the streaming goes smooth without interrupts while screen off and phone wasn't touched for 10+mins.
Also I've tried to acquire wakelock inside oncreate and without releasing it just to see if it helps and it doesn't.
pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakeLock");
wl.acquire();
This problem you are facing can be due to the fact that after Andriod 6.0, all apps are getting optimized for optimizing the battery usage.
If you really think, the reason behind the application to go killed is inactivity. Then, probably, its because of battery optimization software itself.
You can enable another permission while installing the app on the device where you can update the list of unoptimized app by adding an entry for your app.
Originally, you will be able to do the manual settings by following below instruction.
. Head for the ‘Settings‘ app and then ‘Battery‘
. On the ‘three dots‘ menu, top right, you’ll find ‘Battery optimisation‘.
. Here you’ll see a list of all applications which shouldn’t be ‘optimised‘ (for which read ‘can be handled by Doze and App Standby’) – by default the list is usually very small, with almost all apps enabled for ‘optimisation’. Which is fine for general users, but if, like me, you want a few applications to live outside of the new battery optimisations, then tap on the ‘Not optimised‘ pick list and choose ‘All apps‘
. As you’d expect, every application on your phone is listed (this may be quite long) – swipe down until you find the application(s) that you particularly want to always keep running. Tap on the application name
. From the two choices, check the box for ‘Don’t optimise‘.
I have an Asus P00A tablet (Android 7.0, API24) on which the BLE stops after some hours. (This affects any BLE app, not just my app using Android Beacon Library). Apps start working again if I manually switch off BLE then switch it back on.
The BluetoothMedic auto-fix system did not work for my tablet. It runs every 15 minutes but does not find a fault and so does not "power cycle" the Bluetooth. However, I hacked the BluetoothMedic class, adding this:
public void cycleBluetooth(Context context) {...}
and attached this to a button. I find this will restore BLE functionality. So I wondered what would happen if I unconditionally reset the BLE every 15 minutes. I added:
public static final int ALWAYS_RESET = 4;
and then call medic.enablePeriodicTests(context, BluetoothMedic.ALWAYS_RESET);
and add code inside BluetoothTestJob.onStartJob() which then calls BluetoothMedic.cycleBluetooth(). This behaves as expected and so far my app has run perfectly for 18 hours.
I am interested in any advice, such as:
1 Are there any tests other than the two in BluetoothMedic that I can run to detect that my tablet's Bluetooth has stopped? (I am happy to experiment).
2 Any comments on the hack I describe above? Should it be OK to unconditionally reset the Bluetooth every 15 minutes?
3 If the Bluetooth is reset ("power cycled") then is the rest of the Android Bluetooth Library OK with this? That is, will it carry on with monitoring and ranging that has been previously set up, or does the application code need to set take any action to get things going again? Note that this would apply to resets by the existing enablePowerCycleOnFailures() code as well as my ALWAYS_RESET hack above. (Maybe there are some crashes that could happen if the power cycling came at the wrong time?).
4 Could I suggest adding a callback so the application can learn if the Bluetooth has been cycled? Perhaps as a parameter to enablePowerCycleOnFailures()
5 I understand that background activities can be stopped by the OS, especially with Android 8. Would this also affect the regular 15 minute tests set up by enablePeriodicTests()?
The Android Beacon LIbrary's BluetoothMedic, as currently built, relies on the operating system's error code returned by a scan failure (or an advertising failure) to decide if the bluetooth stack is in a bad state warranting a power cycle.
For scans, if the onScanFailed callback is called with an error code of SCAN_FAILED_APPLICATION_REGISTRATION_FAILED which has the value of 2, the module considers it worthy of a power cycle..
For advertisements, if the onStartFailed callback is called with an error code of ADVERTISE_FAILED_INTERNAL_ERROR which has a value of 4, the module considers it worth of a power cycle..
These values were determined via experimentation, witnessing that on some devices, once an error callback is called with these values, bluetooth on the device would not work again without turning it off and back on. You can see the discussion of this in this thread.
You may want to see if there are other error codes on the Asus P00A that indicate a problem worthy of cycling bluetooth. To do this, wait for a failure, and see if attempts to start scanning call the onScanFailed callback with a distinct error code. If such error codes exist, this would be a better solution than cycling power to bluetooth regularly, as cycling power to bluetooth does break BLE GATT connections and the operation of bluetooth classic functions like speakers. The Android Beacon Library itself recovers from these power cycles just fine, although it will obviously not detect beacons until bluetooth is back on.
Because the BluetoothMedic uses the Android Job Scheduler for periodic tests, it is not affected by background limitations on Android 8+.
If you are interested in augmenting these functions in the library, please feel free to open an issue in the Github repo, and issue a Pull Request if you have code to share.
In my application I need to start some BLE scans, get the results and then show them in a list or in a grid.
When i start the scan my device start to look for advertisements basing on which ScanFilters I wrote.
Every time a Pheriperal is found I the application trigger the scan callback method and i can add the new device into the list.
If i got an error the app trigger the callback method and i can tell the user about the broblem.
Example
Imagine the Scan going on for 30s.
At the moment it starts i get 3 Ble Pheriperal.
At second 15 one of them stop to advertise and turn bluetooth off.
At the end of the scan my list will have 3 Ble devices but i will not be able to connect to one of them.
How do I know which of them is the one which turned off?
Where do i get his status?
Thanks for the help.
You can try this, technically it is possible as per the documentation. in onScanResult callback, check for the callbackType parameter. If it is CALLBACK_TYPE_MATCH_LOST then get the device from the results and remove it from your cache.
I'm working on a research project which involves Bluetooth and the Android OS. I need to make Bluetooth discoverable indefinitely in order for the project to continue.
The Problem:
Android limits discoverability to 300 seconds.
I cannot ask the user every 300 seconds to turn discoverability back on as my application is designed to run in the background without disturbing the user.
As far as I am aware, there is no way to increase the time though Android's GUI. Some sources have called this a safety feature, others have called this a bug. There may be a bit of truth in both...
What I'm Trying / Have Tried:
I'm trying to edit a stable release of cyanogenmod to turn the discoverability timer off (it's possible; there's a configuration file that needs to have a single number changed). This isn't working because I'm having verification problems with the resulting package.
During the past week, I downloaded the cyanogenmod source code, changed a relevant class in the hope that it would make Bluetooth discoverable indefinitely, and tried to recompile. This did not work because (a) the repo is frequently changed, leading to an unstable code base which fails to compile (OR, it could be that I'm using it incorrectly; just because it looked like it was the code's fault in many instances doesn't mean I should blame it for all the problems I encountered!) and (b) the repo decides to periodically "ignore" me (but not always, as I have gotten the code base before!), replying to my synchronization/connection attempts with:
fatal: The remote end hung up unexpectedly
As you might imagine, the above two issues are problematic and very frustrating to deal with.
More Info:
I'm running Android 2.1 via cyanogenmod (v5 I believe). This means the phone is also rooted.
I have a developer phone, which means that the bootloader is unlocked.
My phone is an HTC Magic (32B).
The Big Question:
How can I make Bluetooth indefinitely discoverable on Android?
See the following link:
http://developer.android.com/guide/topics/wireless/bluetooth.html#ConnectingDevices
Specifically, the last sentence in the paragraph below:
Enabling discoverability
If you would like to make the local device discoverable to other devices, call startActivityForResult(Intent, int) with the ACTION_REQUEST_DISCOVERABLE action Intent. This will issue a request to enable discoverable mode through the system settings (without stopping your application). By default, the device will become discoverable for 120 seconds. You can define a different duration by adding the EXTRA_DISCOVERABLE_DURATION Intent extra. The maximum duration an app can set is 3600 seconds, and a value of 0 means the device is always discoverable.
So, this should work:
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
startActivity(discoverableIntent);
If you check out the BluetoothAdapter class
you will find the hidden method:
public void setDiscoverableTimeout(int timeout)
Now you only have to find out how to use it. You have to do a method invocation to do so.