Open tim292stro opened 2 months ago
thoughts:
background:
onNewIntent(Intent intent)
Intent
handleGeoData(point)
handleGeoData(LocPoint point)
handleFixedPosition(point)
proposal:
add support for a custom extra in the geo-Intent
onNewIntent(Intent intent)
would detect its value and bypass the dialog by transparently calling the appropriate function
private final static String EXTRA_PURPOSE = "purpose";
@Override protected void onNewIntent(Intent intent) { /*
if (intent == null) { handleNoData(null); return; }
final Uri uri = intent.getData(); if (uri == null) { handleNoData(null); return; }
final String uriString = uri.toString(); final GeoParsedPoint geoPoint = GeoPointParserUtil.parse(uriString); if (geoPoint == null) { handleNoData(getString(R.string.error_geo_intent, uriString)); return; } if (!geoPoint.isGeoPoint()) { handleNoData(getString(R.string.error_geo_intent, uriString)); return; }
final LocPoint point = new LocPoint( geoPoint.getLatitude(), geoPoint.getLongitude() );
*/
boolean handled = false; if (intent.hasExtra(EXTRA_PURPOSE)) { int purpose = intent.getIntExtra(EXTRA_PURPOSE, 0); handled = handleGeoDataPurpose(point, purpose); }
if (!handled) handleGeoData(point); }
private void handleGeoData(LocPoint point) { AlertDialog.Builder builder = new AlertDialog.Builder(GeoIntentActivity.this); builder.setTitle(R.string.geo_intent_menu_title); builder.setItems(R.array.geo_intent_menu_options, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { int purpose = which + 1; boolean handled = handleGeoDataPurpose(point, purpose);
if (handled)
dialog.dismiss();
}
});
builder.show();
}
private boolean handleGeoDataPurpose(LocPoint point, int purpose) { switch (purpose) { case 1: // fixed position handleFixedPosition(point); return true; case 2: // trip origin handleTripOrigin(point); return true; case 3: // trip destination handleTripDestination(point); return true; case 4: // new bookmark handleNewBookmark(point); return true; } return false; }
note to self:
MainActivity
.. which shows tabsFixedPositionActivity
deeper dive:
doStart(true)
private void doStart(boolean check_permissions)
LocationService.doStart(FixedPositionActivity.this, true, modifiedLoc, null, 0);
GeoIntentActivity
.. and then finish()
public static Intent doStart(Context context, boolean broadcast, LocPoint origin, LocPoint destination, int trip_duration)
updated proposal for diff:
import com.github.warren_bank.mock_location.service.LocationService;
// ...
private final static String EXTRA_SILENT_UPDATE = "silent_update";
@Override
protected void onNewIntent(Intent intent) {
/*
* --------------------------------------------------
* this section is unchanged, so I'll comment it out for clarity..
* --------------------------------------------------
if (intent == null) {
handleNoData(null);
return;
}
final Uri uri = intent.getData();
if (uri == null) {
handleNoData(null);
return;
}
final String uriString = uri.toString();
final GeoParsedPoint geoPoint = GeoPointParserUtil.parse(uriString);
if (geoPoint == null) {
handleNoData(getString(R.string.error_geo_intent, uriString));
return;
}
if (!geoPoint.isGeoPoint()) {
handleNoData(getString(R.string.error_geo_intent, uriString));
return;
}
final LocPoint point = new LocPoint(
geoPoint.getLatitude(),
geoPoint.getLongitude()
);
* --------------------------------------------------
*/
if (intent.getBooleanExtra(EXTRA_SILENT_UPDATE, false) && LocationService.isStarted()) {
LocationService.doStart(GeoIntentActivity.this, true, point, null, 0);
finish();
}
else {
handleGeoData(point);
}
}
Thanks for the feedback, I'll take your point 1, and if you don't object I'll create a fork of this project and then strip it down to a background type utility.
I could see additional utility to this type of tool, just in being able to bench test any mapping app by external control - with the dev-kit remote screen capture, makes closed loop testing possible.
no worries.. it's GPL-2.0
Please feel free to fork and make whatever changes you like.. just be sure to share your work so others can enjoy your efforts and take it even farther.
I actually do like the idea of supporting extras in the Intent. Though I think I'll extend the Service with some public methods.. so the Activity can bind to it and call them directly. I'll probably do that this afternoon.
Awesome, I'll wait a bit to see what public methods you drop in before a fork (don't rush it on account of me) - and of course it would remain open/public under GPL2.0 - I believe that's clause 2(b) under that license.
Done. I actually opted to remove my service binder, and instead made the one class that I would want to access a static singleton. That way.. I could avoid callback hell.. and just call the methods I wanted to use synchronously. I tested it.. it works. There's some instructions in both the README and the commit message. Although.. I should mention, that the "test" described in the README using the Bookmarks app won't work right now; trying to configure the test as it is described found a tiny (but not insignificant) bug. I'm going to release a minor update of that app in a few minutes to fix the problem (with how boolean strings are parsed); currently "true" doesn't resolve to true
.. because I used the wrong Java API call. woops.
update: Bookmarks is updated and now working, exactly as described.
fyi.. purely by happenstance.. there's another issue that was opened today and has been discussed concurrent to this one. Both are very similar, in so far as they both revolve around the idea of using the Intent to silently update the running service.
After implementing the changes mentioned in this thread, I think I might tackle something that I mentioned in the other thread. Which is to write a separate standalone app which would serve as a helper utility that:
I'll need to change which commit this tag is associated with.. because I've added this helper utility ("Mock Silently") to the repo in a subsequent commit, and it doesn't change either of the other pre-existing apps.. so no need for a new tag w/ rebuild.
at the moment, I haven't translated its strings yet.. but I added the APK for its english-only build to the v2.4.0 release.
I tested it out a bit.. and it works great.
update: replaced the english-only APK for one with all (51x) language translations, and updated the tag to reference the most-recent commit.
I did a quick search and found this..
I'm not familiar with the platform, but the overview says that it's a web app that imports/exports ".aia" files and can build APK files.
adb
..In any case, his project looks right up your alley.. might be a good starting point for reading and parsing raw GPS data from a data cable? Of course, instead of displaying the data in a UI.. you'd want to use a foreground Service that periodically starts an Intent. But that's mostly an exercise in removing unnecessary code.
https://github.com/freshollie/UsbGps4Droid https://github.com/freshollie/UsbGps4Droid/releases https://github.com/freshollie/UsbGps4Droid/releases/download/v2.2.1/UsbGps4Droid-v2.2.1.apk
If I'm reading this right, this app is all that you need.. it also handles the location mocking.
So response for all 4 options you found:
First, second, and fourth ones - these are primarily for USB-to-serial GPS receivers. I need the one USB-C port for networking, so this can't work.
The third one (PilaBlu GPS Connector) is potentially a match as it specifically calls out TCPIP location data sourcing, but it's not FOSS and on reading the info and reviews it seem that most of those options aren't even available until you pay for the pro license.
I appreciate the looking and options, but I think your code is actually most suitable as a starting point - and you appear to be actively maintaining it and responding to comments so that's a bonus.
here is something interesting..
https://github.com/tiagoshibata/Android-GPSd-Forwarder https://f-droid.org/packages/io.github.tiagoshibata.gpsdclient/
LocationManager
to receive NMEA sentences from the GNSSbyte[]
and written to the data socketif this is a standard data format, then this project is interesting for 2 reasons:
it makes it simple to test a server
it makes the code that a server would need to implement (ie: to read and parse these data sentences) a lot simpler to write
combine a simple data socket server..
that listens for new data..
reads byte[]
and converts it back to a String..
each of which is an NMEA sentence..
then uses this parser from the earlier UsbGps4Droid
project..
which does everything else: extracts location, handles location mocking and updates with each new NMEA sentence
you could either use it as-is.. or replace its internal mocking logic with some Intent logic.. to offload the mocking to this app.
to be honest.. doing it internally makes more sense. it's a special use-case.. better to use a specialized tool. mocking is actually super simple.. 99% of the work is UI.
well.. my last few comments kinda seem to have lost the plot.
for your particular use-case.. you could reuse a lot of the code in this "client" app..
LocationManager
that.. should do the trick
here is an explicit list of the relevant files:
Thanks again for this lead - and I think from your last comment you're starting to wrap your head around what I'm after.
I'm stewing on this information for a bit. It looks like there is a fairly low effort path to what I'm after. It would have been great of Google if they had just conceived of some other connection having a better location data set than the device and just putting in hooks in the OS, but at least this method gets there without needing to root a device (debug mode is "safer" as it's reversible).
I'm attempting to hook an Android OS device to a GPS 9DoF IMU that is external to the device on a wired network (USB-to-Ethernet adapter that can also charge the phone/tablet). Basically I want to feed the Android OS a mock location that is TCP pub-subbed from a network address/port. This would essentially allow a "full airplane mode" with no cellular-radio-based Assisted GPS (a battery killer) - but still providing precise location services over the hardwired data network.
I envision this mode running as a UI-less background service, with a configuration allowing an IP address and port number to be set for the GPS 9DoF IMU data, with an option to automatically use the Gateway IP from DHCP as the source, while still allowing the port to be specified. Data should ideally be a JSON format stream breaking out each data value. Since it would be providing orientation data as well 4x radio-buttons allowing the specification of "which way is up" given the current data would be needed.
The companion test bench is easy to build, a RaspberryPi Zero (Zero 2, Zero 2 W) can be put into a USB-OTG Ethernet Adapter mode, and it can run any of the services required to model data emission, or any USB-OTG ethernet adapter to a local network crossover-PC-direct can do the same.