Unwanted result by locations calculations - java

In my application I generate a location every 5 minutes and send it to the db if it fits my standards.
One of the standards is that the new location that generated is not equal to the old one.
The following condition should cover it (and some other things) but in real time it doesn't.
if(newLocation != null)
{
if(location != null)
{
if(location.getAccuracy() > newLocation.getAccuracy() + 100)
sendTask();
else
if(newLocation.distanceTo(location) > 1800)
sendTask();
}
else
sendTask();
}
The send task method means, send to db. If the newLocation and the Location has the same coordinates the sendTask method shouldn't be exceuted and it is!
Why?

Related

Finding the next location in a grid

I am creating a method to help me find the next position in a grid of islands/objects in a 3d world(but ignoreing the Y coordinate for now), they have a distance of 200 for each island(islandDistance).
What I currently have is this:
public static Location findLocation(String latest,String server) {
if (latest == null) {
latest = sql.findLatestIslandEntry(server);
if (latest != null && latest.isEmpty()) // first creation
latest = "0,4,0";
else if (latest == null)
return null;
}
String split[] = latest.split(",");
List<String> locationString = Arrays.asList(split);
List<Double> locations = new ArrayList<>();
for (String xyz : locationString) {
locations.add(Double.valueOf(xyz));
}
String world = CC.getSTDConfig().getString("worldname");
Location l = new Location(Bukkit.getWorld(world),0,4,0);
if (locations.get(0) <= 0) {
l.setX(Math.abs(locations.get(0)) + islandDistance);
} else {
l.setX(0 - locations.get(0));
}
if (locations.get(2) <= 0) {
l.setZ(Math.abs(locations.get(2)) + islandDistance);
} else {
l.setZ(0 - locations.get(2));
}
return l;
}
Even before testing I could see that this wouldn't work. I would end always adding to both x and z when thats not always what I want. I made an example of the dataset I want as output here:
Basicly what I want to is to get the next position depending on how many I have already inserted and maybe the last one inserted ? thats the info I use in my code currently atleast. Say I just inserted island number 25 and now want island 26 I should get the result 0,600(the order can be different I just want to fill the grid out)
You want to generate integer coordinates ordered by Euclidean distance. To diminish calculation, it is enough to generate coordinates in the first octant (for 2d case), so X and Y are non-negative and Y<=X. For every calculated (X,Y)pair just generate also (X,-Y), (-X,Y), (-X,-Y),(Y,X),(Y,-X), (-Y,X), (-Y,-X) (except for zero components).
Create priority queue where comparison key is sum of squares (squared distance X*X+Y*Y). Push (0,0) item. At every step extract minimum item (MX, MY) and push next points
Output MX, MY and all permutations
if (MY = 0) and (MX < SomeBorderValue)
push (MX+1, 0)
if MY < MX
push (MX, MY+1)

Android BLE: Message Length issue

I am developing an android application with BLE. The requirement of this application is to update the voltage variation in a specific hardware with various inputs.
So I am writing the characters to the BLE as 8-bit input. Each bit value contains its own representations. Based on each request hardware will respond and provide various output combinations. The output contains 24 bytes of information. Each byte position represents different value. eg: position 1& 2 represent current, 3 & 4 represent voltage etc.
My problem here is, I am getting the output as 4 parts. Each message contains 6 bytes. Is it possible to get the same in a single message?
Implementation
public void writeCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) { //Check that we have access to a Bluetooth radio
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
int test = characteristic.getProperties(); //Get the properties of the characteristic
if ((test & BluetoothGattCharacteristic.PROPERTY_WRITE) == 0 && (test & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) == 0) { //Check that the property is writable
return;
}
DebugLogs.writeToFile("BLE MODULE Before Write " + characteristic);
if (mBluetoothGatt.writeCharacteristic(characteristic)) { //Request the BluetoothGatt to do the Write
Log.v(TAG, "****************WRITE CHARACTERISTIC SUCCESSFULL**" + characteristic); //The request was accepted, this does not mean the write completed
DebugLogs.writeToFile("BLE MODULE AFTER Write SUCCESS " + characteristic);
} else {
Log.d(TAG, "writeCharacteristic failed"); //Write request was not accepted by the BluetoothGatt
DebugLogs.writeToFile("BLE MODULE AFTER Write FAIL " + characteristic);
}
}
And the response is getting in the Gatt callback
#Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
Log.w(TAG, "**ACTION_DATA_AVAILABLE**" + characteristic.getUuid());//Indication or notification was received
broadcastUpdate(BLEConstants.ACTION_DATA_AVAILABLE, characteristic); //Go broadc
ast an intent with the characteristic data
}
Unfortunately not. While you could reduce the number of transmissions IF you are the author of the code in the BLE peripheral, you cannot fit 24 bites into a single characteristic, because BLE limits the width of a characteristic to 20 bytes. If you are the BLE peripheral author, you could perhaps change it to send 2 12 byte packets.
If you aren't, then you are probably trying to collect all the data before sending it. An easy way to do this would be create a byte array of length 24 when onCharacteristicWrite is called. Then, every time onCharacteristicChanged is called, add the data to the array. Once you've added all 24 bytes to the array, broadcast it.
Hope this helps!

Null Pointer Warning - BatteryManager.EXTRA_LEVEL

I am attempting to get the device's current battery level with the following:
Intent batteryIntent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, -1);
Log.i(LOG_FILTER, "Battery level = " + (level*100)/scale);
// error check values
if (level == -1 || scale == -1) {
return -1;
} else {
return (level * 100) / scale;
}
The code seems to work and has never failed me, but I am getting a warning:
Method invocation 'batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)' may produce 'java.lang.NullPointerException'
This may never actually affect my application but as there is an end product depending on it, I am wondering, how might I accommodate this potential issue?
Is there a way to reorganize the above to achieve the same result (obtaining the battery's current state of charge)?
The Javadoc for registerReceiver states:
* #return The first sticky intent found that matches <var>filter</var>,
* or null if there are none.
So there is the potential that this will return you a null event. You already handle the case where the values are invalid ((level == -1 || scale == -1)), so I would recommend that you just check whether the intent is null, and return that value early:
if (batteryIntent == null) {
return -1;
}
I would throw a try/catch around it because you know it could throw the error, and then you can handle it appropriately if/when it ever does occur.
try {
//your code here
} catch (NullPointerException e) {
//handle the error here, maybe return -1?
}

How to detect mouse click with JNI and C?

Since catching click event with Java is limited to the JVM environment and cannot be seen, eg, on my browser or on my text editor, I adopted JNI in order to use C API of Windows and be more flexible.
I'm using Eclipse on Windows 7.
The following code catches with success every key I press on keyboard, except the left and right click of my mouse.
Do I need to use a special handling for the mouse clicks?
Thanks in advance :)
while(1) {
// to prevent 100% CPU usage
Sleep(10);
for(character=8; character<=222; character++) {
if(GetAsyncKeyState(character) == -32767) {
file = fopen(FileName,"a+");
if(file == NULL)
return 1;
if(file != NULL) {
if((character>=39) && (character<=64)) {
fputc(character,file);
i++;
fclose(file);
break;
} else if((character>64) && (character<91)) {
character += 32;
fputc(character,file);
i++;
fclose(file);
break;
}
else {
switch(character) {
case VK_LBUTTON:fputs("[LEFT CLICK]",file);i++;fclose(file);break;
case VK_RBUTTON:fputs("[RIGHT CLICK]",file);i++;fclose(file);break;
case VK_BACK:fputs("[BACKSPACE]",file);i++;fclose(file);break;
// follow all the others detections of the remaining virtual keys...
VK_LBUTTON == 0x01, VK_RBUTTON == 0x02. You are checking the codes from 8 upwards.

Gps lat & long randomly displays very inaccurate results

Im listening to my phones GPS and post latitude and longitude to my webservice evey time onLocationChanged gets called. My problem is that in about 2% of my posts, it displays a VERY inaccurate result (several miles off). Should i check the accuracy from my location object before i post? Or do you have any other suggestions? Thanks!
public void onLocationChanged(Location location) {
locationManager.removeUpdates(networkLocationListener);
textView.setText(textView.getText().toString() + "New GPS location: "
+ String.format("%9.6f", location.getLatitude()) + ", "
+ String.format("%9.6f", location.getLongitude()) + "\n");
//float accuracy = location.getAccuracy(); check this value?
postLocationToWebservice(location);
}
This is a very common problem while using the Location services of Android.There are few checks you can introduce to make sure that only the accurate location gets posted to you web service.
1.Compare the accuracy of all the location services.
2.Define a minimum limit for accuracy and a maximum limit for time.(Because some times the location obtained is accurate but it is an old one).
Check this code snippet and make necessary changes to accomplish what you want.Make sure you make a
log build that checks the accuracy of your algorithm.
List<String> matchingProviders = myLocation.lm.getAllProviders();
for (String provider: matchingProviders)
{
Location location = myLocation.lm.getLastKnownLocation(provider);
if (location != null) {
float accuracy = location.getAccuracy();
long time = location.getTime();
if ((time > minTime && accuracy < bestAccuracy)) {
bestResult = location;
bestAccuracy = accuracy;
bestTime = time;
}
else if (time < minTime && bestAccuracy == Float.MAX_VALUE && time > bestTime) {
bestResult = location;
bestTime = time;
}
}
}
It could be possible that the updated location is reported by NETWORK_PROVIDER instead of GPS_PROVIDER
you can always get the last updated GPS location by
mLocationMgr.getLastKnownLocation(LocationManager.GPS_PROVIDER);

Categories