I'm working on a personal electronics project and I would like to create an app to log GPS data in addition to several other things.
The project is an automatic bicycle derailleur (it will shift gears automatically based on a number of factors such as speed, pedal cadence, gyroscope angle, etc). In addition I would like to create an app which will log things like speed, routes taken, number of hours ridden, etc. To save money, I would like to use my Android phone as both a screen for displaying some of these vitals as well as logging data with the GPS.
I'm very new to Android development, but my question is this: Would it be possible to tell the phone to automatically begin logging data (and possibly open the app, depending on what I decide) once it has been connected to the bike via bluetooth? And concurrently, I'd like it to stop and close the app once it's been disconnected.
Thanks
The problem as I see it, is how you plan on connecting to the bike's Bluetooth radio. Typically an application will initiate a Bluetooth connection (which is different from pairing.) Running a service in the background looking for your Bluetooth device and connecting typically wouldn't be a good solution because searching for Bluetooth devices is very resource intensive.
You might be better off just having the connection initiate when the user starts the app.
The second part, to stop the app once the connection is dropped (becomes out of range, or the device on the bike drops the connection,) is quite straight forward. Make a broadcast receiver:
public class DisconnectBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(BasicDMMView.this, "Device disconnected!", Toast.LENGTH_SHORT).show();
// Close anything you need to (log files etc.)
finish();
}
}
And then register the receiver once you've opened the bt connection:
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
mReceiver = new DisconnectBroadcastReceiver();
registerReceiver(mReceiver, filter);
And don't forget to unregister the receiver when you leave the Activity:
unregisterReceiver(mReceiver);
Related
I was working with a BLE device, which needs to set the device time during pairing. Writing to the time characteristic in any other time does not effectively set the time.
Currently I am using the Android OS's Bluetooth Manager for pairing. And the progress of pairing is notified to my app through broadcast intent.
public void onReceive(Context context, Intent intent) {
....
switch (action) {
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
if(state == BluetoothDevice.BOND_BONDED){
//Write to the Date-Time Characteristic
}
else if(state==BluetoothDevice.BOND_BONDING){
}
else if(state==BluetoothDevice.BONE_NONE){
}
....
}
...
}
My question is how to inject code to the position commented above to complete the Date-Time setting? Apparently, the Android OS Bluetooth Manager does not set the time during its entire pairing process. Does Android allow two applications (OS Bluetooth Manager and my application) write to the remote gatt within a single connection session?
It may not possible for you to write the data-time i.e. the characteristic during the pairing procedure(well if you do not need pairing that should be fine). Reason is that you may first get service and get characteristic handle then write it, this may not happen with the same time of the pairing; it depends your remote device's security level setting.
My question is how to inject code to the position commented above to complete the Date-Time setting?
You can register a broadcast receiver to receive the bonding event.
Does Android allow two applications (OS Bluetooth Manager and my application) write to the remote gatt within a single connection session?
Sure, because you are using the same BluetoothAdapter :-)
I want to get the Signal strength of the WiFi network I am connected to , as it changes .
This is my broadcast receiver
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int info = Wifi.getConnectionInfo().getRssi();
textStatus.append("\n\n : " + Integer.toString(info));
}
}, new IntentFilter(WifiManager.RSSI_CHANGED_ACTION));
I am getting it only once . How do i get it as it changes ?
Update: From tests in Android 4.4 and 5.0 the interval between sequential WiFi scans seems to be less than a second. You can take a look at my demo for RF measurements using Android device, here:
https://github.com/panosvas/Measurements
where you can find an implementation of WiFi measurements one after another. I have also created a Server for storing these measurements as well as a remote trigger app using UDP packets where you can find here:
https://github.com/panosvas/IndoorPositioningServer
Actually, you cannot take the RSSI each time it changes because it is possible that the RSSI value changes in a period of mseconds or even faster and each wifi measurement in Android takes approximately 5 seconds depending also on the device.
So, what you advice my answers in the following posts for that:
Wifi Scanner which scans 20 times
How to update wifi RSSI values without a click button
I am working on Bluetooth related application where I provide user a list of nearby Bluetooth devices and also I provide a rescan button to restart scanning process. When user comes to this view application start discovery process and if application founds device it get display in a list. But if the user presses rescan button, first application clear list and then restart scanning process then application fails to list same device again.
I don't know why application fails to rescan same device again.
Check out code below :
Starting search
mBluetoothAdapter.startDiscovery();
mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Finding devices
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
The Discovery procedure is in some sense a probabilistic, so if you can't get identical lists in two sequential calls it is ok. I'd rather wonder are you able to enumerate any other BT-devices during subsequent calls. And if answer is always 'yes', and you experience problems with that only device, check if it is operating correctly. If after first successful call you can't enumerate the devices - either your code is incorrect or your device you're using for debugging works not very well (that's happens quite often in the Android World).
Is it possible to create a service that can listen for devices nearby and log device info to a file?
Yes, your service can listen for new Bluetooth devices, as described by Vipul Shah, but the real issue is how do you cause your device to find other Bluetooth devices in the first place.
ACTION_FOUND is sent when a remote device is found during discovery. You can call BluetoothAdapter.startDiscovery() to start the discovery process, but the problem is that very few devices are normally discoverable. A couple of years ago it was common for devices to remain discoverable all the time, but now the user is expected to make a device temporarily discoverable as needed to pair it.
So, it doesn't make sense to have a service that periodically does discovery (and listen for ACTION_FOUND) both because it consumes a lot of battery and because you won't find anything.
If you know the Bluetooth address of the devices that you are looking for then you could try to connect to them, but I assume that is not the case.
Yes it is very much possible
Step 1 You will need to create one service
Step 2 You will need BluetoothDevice.ACTION_FOUND Broadcast Receiver to look for nearby devices.
Step 3 Then you can query all found devices one by one.
Step 4 As you will fast enumerate over found devices dump their information inside file.
Below is broadcast Receiver
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
// You will log this information into file.
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
Register the broadcast receiver for intent action as follows
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // Don't forget to unregister during onDestroy
Hope this helps.
I need to continuously poll for getting bluetooth devices connections/disconnections in my activity to update a listView with the currenctly available devices.
I use btAdapter.startDiscovery() but it is not permanent ... how can i correctly get the on/off events for the devices?
I would suggest using a broadcastreceiver to listen for the specific events you are talking about. You could even fire off another discovery mode after it comes out of its current discovery mode to have it keep scanning
BluetoothAdapter.ACTION_DISCOVERY_FINISHED
BluetoothDevice.ACTION_ACL_CONNECTED
BluetoothDevice.ACTION_ACL_DISCONNECTED
You can use the intent extra's to be able to get the name (ect) from the device that connects
I would read http://developer.android.com/guide/topics/wireless/bluetooth.html and
http://developer.android.com/reference/android/content/BroadcastReceiver.html