Open pointDude opened 5 years ago
There are some misplaced commas:
In onCreate(SQLiteDatabase db)
it should be:
"GPSgateLatitude REAL," +
and
"GPSgateLongitude REAL," +
,
your SQL-table couldn't have been created at all with misplaced commas!
Then in formatRequest(String url, Position position, String alarm)
it should be:
+"," + "_SendMessage"
with no extra comma at the end.
Why you're saying
It does work some of the time
I really can't explain, because it shouldn't work at all if the commas are set in wrong places. You should see SQL-errors in Logcat (Android Studio).
Good Morning Reslin,
I just got back from military training so I'm sorry for the delay in response.
That you for the help, I didn't notice that I messed that one up.
Very Respectfully,
Michael Travis
So I made the changes that you suggested and I'm no longer getting the errors that I had, The SQL Error in logcat that I'm seeind is
2019-02-25 10:43:47.651 7472-11057/org.traccar.client E/CursorWindow: Failed to read row 0, column -1 from a CursorWindow which has 1 rows, 16 columns.
As for the What I mean by "It works sometimes" I mean when I send a SOS, which I assume does not use the SQL database, I do get a proper send code, that does map on the server.
It seems like I am getting lat, lon and time data, but I'm a little worried with the id.
2019-02-25 10:30:11.415 7472-7472/org.traccar.client D/TrackingController: write (id:0 time:1551115812 lat:43.63154864 lon:-116.2744972)
I did not see any code which limited the id length, but I will try to limit it from the IMEI to a smaller simple id and see if that helps.
Oh and before I forget the double comma is due to the GPSGate tracker one format see below.
HTTP GETSupported in GpsGate Server 2.0.6 and later. By default port 8008 is used. Only commands from the tracker to server can use HTTP. The respons body contans the server reply ($FRRET).Commands sent over HTTP do not need any checksum. Both commands with and without checksum isaccepted by the server.Syntax:http://hostname:8008/GpsGate/?cmd=$FRCMD...Example:http://online.gpsgate.com:8008/GpsGate/?cmd=$FRCMD,353857014816785,_SendMessage,,4748.00000,N,3530.00000,E,34.6,234,90,170109,120523.657,1
Update As of 5/19/2019 It is working, I have posted it in my github, only three files have changed, here is what the changes are In position.java The first Position function
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;
import static java.lang.Math.abs;
public class Position {
public Position() {
}
public Position(String deviceId, Location location, double battery) {
this.deviceId = deviceId;
time = new Date(location.getTime());
latitude = location.getLatitude();
longitude = location.getLongitude();
altitude = location.getAltitude();
speed = location.getSpeed() * 1.943844; // speed in knots
course = location.getBearing();
if (location.getProvider() != null && !location.getProvider().equals(LocationManager.GPS_PROVIDER)) {
accuracy = location.getAccuracy();
}
this.battery = battery;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
this.mock = location.isFromMockProvider();
}
if (latitude < 0) {
this.NsHem = "S";
}else {
this.NsHem = "N";
}
//doing the same with East West
if (longitude < 0){
this.EwHem = "W";
}else {
this.EwHem = "E";
}
// Changes to make the Tracker one Format Time
try{
Date date = new Date(location.getTime());
//DateFormat dateFormat = new SimpleDateFormat("ddMMYY,HHmmss.SS");
SimpleDateFormat dateFormat = new SimpleDateFormat("ddMMyy,HHmmss.SS");
dateFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
String preGPSgate = dateFormat.format(date);
GPSgateTime = preGPSgate;
}catch (Exception e){
GPSgateTime = "020304";
}
//Latitude and Longitude
//change to get DDMM.mmm format
double getsLatitude = (location.getLatitude());
String preLatitude = location.convert(getsLatitude, location.FORMAT_MINUTES);
String preLatitude2 = preLatitude.replace(":","");
double preLatitude3 = Double.parseDouble(preLatitude2);
GPSgateLatitude = abs(preLatitude3);
//Repeat change for Longitude
double getsLongitude = (location.getLongitude());
String preLongitude = location.convert(getsLongitude, location.FORMAT_MINUTES);
String preLongitude2 = preLongitude.replace(":","");
double preLongitude3 = Double.parseDouble(preLongitude2);
GPSgateLongitude = abs(preLongitude3);
}
and on the bottom add
//Added Fields
private String NsHem = "S";
public String getNsHem() {
return NsHem;
}
public void setNsHem(String NsHem) {
this.NsHem = NsHem;
}
//East and West Hemisphere
private String EwHem = "W";
public String getEwHem() {
return EwHem;
}
public void setEwHem(String EwHem){
this.EwHem = EwHem;
}
private String GPSgateTime;
public String getGPSgateTime(){
return GPSgateTime;
}
public void setGPSgateTime(String GPSgateTime){
this.GPSgateTime =GPSgateTime;
}
private double GPSgateLatitude;
public double getGPSgateLatitude() {
return GPSgateLatitude;
}
public void setGPSgateLatitude(double GPSgateLatitude) {
this.GPSgateLatitude = GPSgateLatitude;
}
private double GPSgateLongitude;
public double getGPSgateLongitude(){
return GPSgateLongitude;
}
public void setGPSgateLongitude(double GPSgateLongitude) {
this.GPSgateLongitude = GPSgateLongitude;
}
In database helper for creating the SQL database
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE position (" +
"id INTEGER PRIMARY KEY AUTOINCREMENT," +
"deviceId TEXT," +
"gpsGateLatitude REAL," +
"gpsGateLongitude REAL," +
"NsHem TEXT," +
"EwHEM TEXT," +
"gpsGateTime TEXT," +
"time INTEGER," +
"latitude REAL," +
"longitude REAL," +
"altitude REAL," +
"speed REAL," +
"course REAL," +
"accuracy REAL," +
"battery REAL," +
"mock INTEGER)");
}
For the insert position
public void insertPosition(Position position) {
ContentValues values = new ContentValues();
values.put("deviceId", position.getDeviceId());
values.put("gpsGateLatitude", position.getGPSgateLatitude());
values.put("gpsGateLongitude", position.getGPSgateLongitude());
values.put("NsHem", position.getNsHem());
values.put("EwHEM", position.getEwHem());
values.put("gpsGateTime", position.getGPSgateTime());
values.put("time", position.getTime().getTime());
values.put("latitude", position.getLatitude());
values.put("longitude", position.getLongitude());
values.put("altitude", position.getAltitude());
values.put("speed", position.getSpeed());
values.put("course", position.getCourse());
values.put("accuracy", position.getAccuracy());
values.put("battery", position.getBattery());
values.put("mock", position.getMock() ? 1 : 0);
db.insertOrThrow("position", null, values);
}
and add into the select position function
public Position selectPosition() {
Position position = new Position();
Cursor cursor = db.rawQuery("SELECT * FROM position ORDER BY id LIMIT 1", null);
try {
if (cursor.getCount() > 0) {
cursor.moveToFirst();
position.setId(cursor.getLong(cursor.getColumnIndex("id")));
position.setDeviceId(cursor.getString(cursor.getColumnIndex("deviceId")));
position.setGPSgateLatitude(cursor.getDouble(cursor.getColumnIndex("gpsGateLatitude")));
position.setGPSgateLongitude(cursor.getDouble(cursor.getColumnIndex("gpsGateLongitude")));
position.setNsHem(cursor.getString(cursor.getColumnIndex("NsHem")));
position.setEwHem(cursor.getString(cursor.getColumnIndex("EwHEM")));
position.setGPSgateTime(cursor.getString(cursor.getColumnIndex("gpsGateTime")));
position.setTime(new Date(cursor.getLong(cursor.getColumnIndex("time"))));
position.setLatitude(cursor.getDouble(cursor.getColumnIndex("latitude")));
position.setLongitude(cursor.getDouble(cursor.getColumnIndex("longitude")));
position.setAltitude(cursor.getDouble(cursor.getColumnIndex("altitude")));
position.setSpeed(cursor.getDouble(cursor.getColumnIndex("speed")));
position.setCourse(cursor.getDouble(cursor.getColumnIndex("course")));
position.setAccuracy(cursor.getDouble(cursor.getColumnIndex("accuracy")));
position.setBattery(cursor.getDouble(cursor.getColumnIndex("battery")));
position.setMock(cursor.getInt(cursor.getColumnIndex("mock")) > 0);
Finally in the ProtocolFormatter.java
public static String formatRequest(String url, Position position, String alarm) {
Uri serverUrl = Uri.parse(url);
Uri.Builder builder = serverUrl.buildUpon()
.path("GpsGate/")
.encodedQuery(
"cmd=$FRCMD"
+ addParameter(position.getDeviceId())
+ addParameter("_SendMessage,")
+ addParameter(String.valueOf(position.getGPSgateLatitude()))
+ addParameter(String.valueOf(position.getNsHem()))
+ addParameter(String.valueOf(position.getGPSgateLongitude()))
+ addParameter(String.valueOf(position.getEwHem()))
+ addParameter(String.valueOf(position.getAltitude()))
+ addParameter(String.valueOf(position.getSpeed()))
+ addParameter(String.valueOf(position.getCourse()))
+ addParameter(String.valueOf(position.getGPSgateTime()))
+ addParameter("1")
);
return builder.build().toString();
}
private static String addParameter(String data){
return "," + data;
}
}
The results I'm getting are looking good
Except where it runs out of coverage and then adds 106 to the value of the longitude
Now I only need help with finding out why the code does that one strange piece of behavior, and those of us running both gpsGate and Traccar can have a unified application that is open source.
I've only skimmed your source quickly, but why exactly do you use the abs()
function in position.java on the members preLatitude3
and preLongitude3
? It is perfectly "allowed" for geo-coordinates to have negative values.
Give it a try and get rid of the abs(...)
.
Also in position.java I see the lines
if (location.getProvider() != null && !location.getProvider().equals(LocationManager.GPS_PROVIDER)) { accuracy = location.getAccuracy(); }
which means: if we have a Provider AND the Provider is NOT from GPS, then set the accuracy
member. Is this your intention?
I would rather do this as follows:
if(location != null && location.hasAccuracy() { accuracy = location.getAccuracy(); }
which means: if the location is existing AND has an accuracy
value, then set the accuracy
member.
Will try that out and let you know how it goes.
Very Respectfully,
Michael Travis
So I forgot that GPSgate does not deal with negative numbers and that's why I put it in there, but it didn't fix the issue, It just made all of my tracks go to China and still skip when I get out of coverage. It's a constant number of 106, perhaps I should just add it in?
Your problem eludes me... but I don't advise in guessing to add or subtract the seemingly arbitrary value of "106" (which surely must have an origin?!) and not really knowing where this error stems from.
If you get out of coverage it seems best to not collect locations at all, because they will very likely not be usable.
Also I (generally) experienced an odd behaviour on my devices (an old Samsung S2, a not-so-old LG Stylus): if being worked as a mobile WLAN-Hotspot, locations get incorrect / erratic / jumpy and accuracy is really bad (1500 m at best). The old S2 even tends to locate itself at coordinates Lat/Lon 0.0/0.0.
I'm sorry that I cannot help you any further.
Well, where is the code ?
Well, where is the code ?
Apparently there are no changes pushed to the fork https://github.com/pointDude/traccar-client-android, so all altered code is only here within this issue-thread.
(Sadly enough I don't have the time to explain Git, Github and Android programming to pointDude, but perhaps someone has.)
Update, Found the Issue, Android FORMAT_DEGREES does not always return DD: MM:mmmm, if it counts down below the 10's digit it may report DD:M.mmmmm which leads to a situation where 11410.03675,W, can count down to 1149.96046,W. I'll be working on that in the meantime, perhaps doing a cut off after the : a count to the . and a if then formatting statement. I will post all fixs into my seperate fork after it's fully working. Besides for that all of the changes to the code is already posted here. Reslin do you happen to know a good way of addressing the formatting issue?
Good Morning,
I've already submitted this in the Forums, but I think this may be a more appropriate place to get some help. I'm attempting to modify the Traccar App code to report in the Fransen GPS Gate Tracker One format. I would like to do this so that I have one app for my clients who use both Traccar and GPS Gate. To accomplish this I have made several changes which have had mixed results in effectiveness. I am not familiar with the SQLight for android that the app uses and think that I have made a mistake, but every change I made is listed below.
The Changes I have made to the code are focused on three java files, the Position.java, the DatabaseHelper.java and the ProtocolFormatter.java.
Position.java got some extra dummy variables in order to get the proper date time format and the proper degree minute format.
I then added the declaration, set and get methods for the new additions
Next came the Database Helper, Here is where I think I made my mistakes, but I can't find them
I added my fields to the SQLite database creator
Then added the insert
and then added them to the query
The last and most messed up thing I did was change the format request entirely, This was some dirty quick programming to get it into the proper GPSgate protocol with commas being the only special character.
It does work some of the time, but I don't know what I've broken. I tried to leave all of the original variables in place for the degree, distance and time triggers. Can I please get some input/correction on where to go from here.