Android - How to trigger standalone navigation applications with multiple way points via intent? - google-maps

Today I'm using Android Intent in the following format to trigger navigation from my application on standalone navigation applications:
Action : "android.intent.action.VIEW"
URI : "google.navigation:q=48.605086,2.367014/48.607231,2.356997"
Component Name of the navigation app : For example Google Maps "com.google.android.apps.maps/com.google.android.maps.MapsActivity"
For example:
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
from : https://developers.google.com/maps/documentation/urls/android-intents
I want to trigger navigation with multiple way points, Is it possible on TomTom Go Mobile, Google Maps, Waze, Here WeGo and Sygic via Intent ?
Can I trigger navigation on the application above and start driving automatically? Without user interaction ?
I tried to trigger the above intent via ADB and do some tweaking by adding "," , ";", "and". Nothing worked.

In order to open the navigation mode in the HERE WeGo app you can use the following function
private fun navigateToDestination(destination: GeoCoordinate) {
try {
val intent = Intent().apply {
action = "com.here.maps.DIRECTIONS"
addCategory(Intent.CATEGORY_DEFAULT)
data = Uri.parse("here.directions://v1.0/mylocation/${destination.latitude},${destination.longitude}")
}
intent.resolveActivity(packageManager)?.let {
startActivity(intent)
}
} catch (t: Throwable) {
Timber.e(t)
}
}
Sygic:
private fun navigateToDestination(destination: GeoCoordinate) {
try {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("com.sygic.aura://coordinate|${destination.longitude}|${destination.latitude}|drive"))
intent.resolveActivity(packageManager)?.let {
startActivity(intent)
}
} catch (t: Throwable) {
Timber.e(t)
}
}
Waze:
private fun navigateToDestination(destination: GeoCoordinate) {
try {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("waze://?ll=${destination.latitude}, ${destination.longitude}&navigate=yes"))
intent.resolveActivity(packageManager)?.let {
startActivity(intent)
}
} catch (t: Throwable) {
Timber.e(t)
}
}
You can also resolve the installed apps that can be used for navigation and let the user decide which one s/he wants to use:
private fun navigateToDestination(destination: GeoCoordinate) {
try {
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("google.navigation:q=${destination.latitude}, ${destination.longitude}"))
val resolvedPackages = packageManager.queryIntentActivities(intent, PackageManager.MATCH_ALL)
if (resolvedPackages.isNotEmpty()) {
val packageNames = resolvedPackages.map { it.activityInfo.packageName }
val targetIntents = packageNames.map { packageManager.getLaunchIntentForPackage(it) }
val intentChooser = Intent.createChooser(Intent(), "Choose a navigation app")
intentChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetIntents.toTypedArray())
startActivity(intentChooser)
}
} catch (t: Throwable) {
Timber.e(t)
}
}

Related

Hook instagram apk using Frida

I wanted to hook some functions from instagram apk using frida, decompiled the apk with
jadx/JEB, one of the functions I wanted to hook was in this:
public static void A00(HGf arg8, I1Y arg9) {
arg8.A0P();
Boolean v0 = arg9.A0v;
if(v0 != null) {
arg8.A0l("about_your_account_bloks_entrypoint_enabled", v0.booleanValue());
}
//some other code here
}
Tried to hook the function with this frida script:
try {
//
let I1X = Java.use("X.I1X")
console.log("this is instance: ", I1X)
console.log(
"these are the methods:: ",
Java.use("X.I1X").class.getDeclaredMethods()
)
I1X.A00.overload().implemention = function (HGf, I1Y) {
console.log("A0l is called")
let ret = this.A0l(str, z)
console.log("A0l ret value is " + ret)
}
} catch (e) {
console.log("failed!" + e)
}
})
this script outputs:
this is instance: <class: X.I1X>
these are the methods::
failed!TypeError: not a function
apparently the A00 here is not a function, so back to jadx in the compiled code there is another class with the same name within same package but consisting of some other code, here it is:
/* renamed from: X.I1x reason: case insensitive filesystem */
/* loaded from: classes7.dex */
public final class C39227I1x {
public C39229I1z A00 = null;
}
apparently Frida is hooking this variable instance A00 In my opinion that is why
it is returning not a function here.
So my question, how can I hook like this situation?
Edit:
the two classes are somewhat different in jadx.

I want to add a random Maps Activity Location, how can I do it?

I want to add a button to my map, every time this button is clicked, I want to turn the camera to a different location. How can I do it? I can't generate a random location
What I can do at the moment is the location of the user, adding a listening marker, a number of more operations depending on the location he chose
I can do it, I want the camera to go anywhere in the world with the menu key I assigned. How can I do it?
override fun onLocationChanged(p0: Location) {
mMap.clear()
val guncelKonum =LatLng(p0.latitude,p0.longitude)
println("${p0.latitude}"+"${p0.longitude}")
mMap.addMarker(MarkerOptions().position(guncelKonum).title("Guncel Konumunuz"))
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(guncelKonum,12f))
val geocoder =Geocoder(this#MapsActivity, Locale.getDefault())
try {
val adresListesi= geocoder.getFromLocation(p0.latitude,p0.longitude,1)
if (adresListesi.size>0){
println(adresListesi.get(0).toString())
}
}catch (e:Exception){
e.printStackTrace()
}
}
}
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION) !=PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),1)
}else {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1,1f,locationListener)
val sonBilinenkonum = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
if (sonBilinenkonum !=null){
val sonbilinenLatLang =LatLng(sonBilinenkonum.latitude,sonBilinenkonum.longitude)
mMap.addMarker(MarkerOptions().position(sonbilinenLatLang).title("Son Bilinen Konumunuz"))
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sonbilinenLatLang,12f))
}
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
if (requestCode==1){
if (grantResults.size > 0){
if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)==PackageManager.PERMISSION_GRANTED){
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1,4f,locationListener)
}
}
}
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
}

Kotlin recommended way of unregistering a listener with a SAM

So i have an interactor which performs an insert operation with Realm and then notifies that the insertion is completed with a RealChangeListener. It is something like this:
fun insertCar(item: Car) {
realm.doInTransaction {
val car = Car(...)
val copy = copyToRealm(car)
copy.addChangeListener(...)
}
}
I can do it this way:
fun insertCar(item: Car, listener: RealmChangeListener<Car>) {
realm.doInTransaction {
val car = Car(...)
val copy = copyToRealm(car)
copy.addChangeListener(listener)
}
}
And access like this:
realmInteractor.insertCar(item, RealmChangeListener {
// do something here
})
But then i have no way of removing this listener
realmInteractor.insertCar(item, RealmChangeListener {
// do something here
it.removeChangeListener(this)
})
this will point to the class its located not the actual listener
I can also do this:
fun insertCar(item: Car, doAfterChange (Car) -> Unit) {
realm.doInTransaction {
val car = Car(...)
val copy = copyToRealm(car)
copy.addChangeListener(RealmChangeListener{
doAfterChange()
})
}
}
But then i have a SAM inside another SAM (too overkill imo)
I can do it like this:
fun insertCar(item: Car, listener: RealmChangeListener<Car>) {
realm.doInTransaction {
val car = Car(...)
val copy = copyToRealm(car)
copy.addChangeListener(listener)
}
}
realmInteractor.insertCar(item, object : RealmChangeListener<Car> {
override fun onChange(element: Car?) {
...
element?.removeChangeListener(this)
}
})
Which works but it is too verbose.
So how do you deal with this and what is considered the best approach?
You can create a generic method to perform a run-once listener. Something along the lines of:
fun <T> createInRealm(objectFactory: () -> T, changeListener: (T) -> Unit) {
realm.doInTransaction {
val obj = objectFactory()
val copy = copyToRealm(obj)
copy.addChangeListener(object : RealmChangeListener<T> {
override fun onChange(element: T) {
changeListener()
element.removeChangeListener(this)
}
}
}
}

ES6 Classes implement indexer like arrays

I want to implement indexer to get elements from data property with index as JavaScript arrays. I heard about ES6 proxies but I couldn't implement it to my class. Is it possible now or should I wait more to come with ES7.
class Polygon {
constructor() {
this.data = new Set(arguments)
}
[Symbol.iterator](){
return this.data[Symbol.iterator]()
}
add(vertex){
this.data.add(vertex)
}
remove(vertex){
this.data.delete(vertex)
}
get perimeter(){
}
get area(){
}
}
let poly = new Polygon()
let first_vertex = poly[0]
AFAIK there is no proposal for something like "indexing" into arbitrary objects, so yes, you would have to go with proxies.
I couldn't really test this since no environment seems to support both classes and proxies, but in theory, you'd have to return the new proxied object from the constructor. Tested in Chrome v52.
Example:
class Test {
constructor(data) {
let self = this;
this.data = data;
this.foo = 'bar';
return new Proxy(this, {
get(target, prop) {
if (Number(prop) == prop && !(prop in target)) {
return self.data[prop];
}
return target[prop];
}
});
}
}
var test = new Test([1,2,3]);
console.log(test[0]); // should log 1
console.log(test.foo); // should log 'bar'

store and retrieve game state using HTML5 DOM storage and JSON

I am using helper functions to store and retrieve game state using HTML5 DOM storage and the JSON features built into ECMAScript5, my code is:
function saveState(state) {
window.localStorage.setItem("gameState",state);
}
function restoreState() {
var state = window.localStorage.getItem("gameState");
if (state) {
return parse(state);
} else {
return null;
}
}
but anyhow I am not getting desired output, as i am new to JSON its hard to resolve. HELP please !
Try below code:
function saveState(state) {
window.localStorage.setItem("gameState", JSON.stringify(state));
}
function restoreState() {
var state = window.localStorage.getItem("gameState");
if (state) {
return JSON.parse(state);
} else {
return null;
}
}