Since my Google Maps app updated recently, now version 10.11.1, the following code does not show the label as expected, documented, and previously working:
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("geo:38.8951,100.0364?q=38.8951,100.0364(foo)")).setPackage("com.google.android.apps.maps")
if (intent.resolveActivity(packageManager) == null) {
intent.setPackage(null)
}
startActivity(intent)
And neither does this version (with 0,0 immediately after geo:):
val intent = Intent(Intent.ACTION_VIEW, Uri.parse("geo:0,0?q=38.8951,100.0364(foo)")).setPackage("com.google.android.apps.maps")
if (intent.resolveActivity(packageManager) == null) {
intent.setPackage(null)
}
startActivity(intent)
Neither does the example code in the official documentation show a label:
// Display a label at the location of Google's Sydney office
Uri gmmIntentUri = Uri.parse("geo:0,0?q=-33.8666,151.1957(Google+Sydney)");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
Update: Scheduled to be fixed in v11.12 perhaps before the end of January 2022.
No solution still even with latest map update 10.12.1 the label still does not show even if the documentation still says it should
I've created an issue on Google's Issue tracker: https://issuetracker.google.com/issues/129726279
hopefully we'll have some information shortly.
Per Google, it's a bug in the Google Maps app. It's fixed in version 11.12.
I think we are going about it the wrong way here. If I was Google, I would also feel insecure about allowing developers to post directions with an abstract destination label, I am sure they never plan to fix this.
I recommend the following solution according to Google's new standards. https://developers.google.com/maps/documentation/urls/android-intents:
https://www.google.com/maps/dir/?api=1&destination=LATITUDE,LONGITUDE
If you look at most apps these days, including the ones I have built, this allows us to post a LAT/LONG for the user to go to with Google's own Address values built in as the destination label.
To actually launch the Google Maps application, simply launch a web intent, I use the application context in this case.
fun startGoogleMaps(context: Context, lat: Double, long: Double) {
startWebBrowser(
context,
Uri.parse("https://www.google.com/maps/dir/?api=1&destination=$lat,$long")
)
}
fun startWebBrowser(context: Context, link: Uri?) {
if (link != null) {
val webIntent = Intent(Intent.ACTION_VIEW, link).apply {
addFlags(FLAG_ACTIVITY_NEW_TASK)
}
if (webIntent.resolveActivity(context.packageManager) != null) {
context.startActivity(webIntent)
}
}
}
Related
In Android 12 if you add informations as subject(EXTRA_SUBJECT) and message(EXTRA_TEXT) when you use ACTION_SENDTO Intent to send a text email, these don't appear in the email client message, contrarely to all previous versions.
An user in a similar Kotlin question seems has solved the problem using apply selector in this way:
private fun createIntent(
metadata: String
): Intent {
return Intent(ACTION_SEND)
.putExtra(
EXTRA_EMAIL,
arrayOf(EMAIL)
)
.putExtra(
EXTRA_SUBJECT,
TITLE
)
.putExtra(
EXTRA_TEXT,
metadata
)
.apply {
selector = Intent(ACTION_SENDTO).setData(Uri.parse("mailto:"))
}
}
What is the reason of this issue? What is the proper way to fix the issue in Java?
these don't appear in the email client message, contrarely to all previous versions
How apps handle inbound extras is up to the developers of the apps. And, since ACTION_SENDTO is not documented to have those extras, you should not be surprised when apps ignore those extras.
What is the proper way to fix the issue in Java?
Do what you have there in Kotlin, if ACTION_SEND will work for you. Intent works the same way whether you use it in Java, Kotlin, or any other suitable programming language. Your selector will limit your Intent to apps that have activities that support that mailto: Uri for ACTION_SENDTO (which may be more than just email apps).
By eyeball, the Java equivalent should be something like this:
private Intent createIntent(String metadata) {
Intent result = new Intent(ACTION_SEND)
.putExtra(
EXTRA_EMAIL,
new String[] { EMAIL }
)
.putExtra(
EXTRA_SUBJECT,
TITLE
)
.putExtra(
EXTRA_TEXT,
metadata
);
result.setSelector(new Intent(ACTION_SENDTO).setData(Uri.parse("mailto:")));
return result;
}
Looking to handle a deep link from the Google Assistant. As I only have an emulator at the moment I am having trouble testing it (from what I have read it requires a real device). That said, I was wondering if I am handling it the correct way. I am unfamiliar with Kotlin and my code was turning into Spaghetti trying to integrate, so I put this together in my existing launcher activity just to try and get it bootstrapped for now. The manifest and actions.xml were set up like the fitness app tutorial.
Am I doing this correctly?
if (mAuth.getCurrentUser() != null) {
data = this.getIntent().getData();
if (data != null && data.isHierarchical()) {
uriData = data.toString();
containsStart = containsIgnoreCase(uriData,"start");
containsRun = containsIgnoreCase(uriData,"run");
if(containsStart && containsRun) {
Intent intent = new Intent(getApplication(), RunActivity.class);
intent.putExtra("runStart", true);
startActivity(intent);
}
}
else {
checkUserAccType();
}
//Else, if there is no current user, start the Authentication activity
}
A few observations and recommendation about your code:
Instead of using containsIgnoreCase uses getPath() and match the path. See example.
Also, for the activity parameter use URL query param instead of containsIgnoreCase. See example
Starting the activity or fragment. I assume startActivity and checkUserAccType will handle that part. See example.
// Else... section should go one line below.
Authentication. It looks fine. And it seems you're using Firebase by the getCurrent method signature. See example
I have implemented Google Maps in my App and doing reverse geocoding when clicking on map.Im using This API. but it gives me more than one result on Single tap. I know why Google behave like this.
Then I look into PlacePicker widget for Android, but Im unable to use that widget without opening another Map screen to pick place.
What I want is that I want to use my Google Map screen to get tapped place instead of opening PlacePicker screen. I just want PlacePicker work with my implemented Map i.e want PlacePicker to respond map click and give place without opening widget if this is not possible then inform me about other solution to get exactly one and correct place on Map tap? Thank you in advance
Updated
Why Im getting closed vote for question? it is not too broad? Simply,I want to know whether is it possible to use Google Map (MapView|SuportFragment) as PlacePicker's main screen. Have look code below
int PLACE_PICKER_REQUEST = 1;
PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
// I don't want this line, Don't want PlacePicker to open another Map Screen to allow user to pick place.
startActivityForResult(builder.build(this), PLACE_PICKER_REQUEST);
now look at below code
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PLACE_PICKER_REQUEST) {
if (resultCode == RESULT_OK) {
Place place = PlacePicker.getPlace(data, this);
String toastMsg = String.format("Place: %s", place.getName());
Toast.makeText(this, toastMsg, Toast.LENGTH_LONG).show();
}
}
}
above code is executed when user pick a place from PlacePicker screen and that screen returns a Intent with picked place. Is there any way to make that type of 'Intent' on Google Map tap with lat,lng? so that I could get Place detail. I don't want to user reverse geocoding as it gives me many results.
I Donot know anything about the google geo api or PlacePicker api.
The google independent android standard way would be to use "ACTION_PICK" with a geo uri.
For more infos see https://github.com/k3b/k3b-geoHelper/wiki/Android-Geo-howto.
This only works if you have installed a geo-pick-aware app that supports geo-pick.
Note: you do not have to use the lib. All you need to do is to decode the geo-uri returned by activity result
I have found solution to my problem, To get rid of reverse geocoding to many results and to get clicked place I use following code
googleMap.setOnPoiClickListener(new GoogleMap.OnPoiClickListener() {
#Override
public void onPoiClick(PointOfInterest pointOfInterest) {
String SS="";
isPOI=true;
poiPlaceID=pointOfInterest.placeId;
// Then using Google PlaceDetail API with placeId, It gives me exact Location click
}
});
I have an intent designed to open the Data Usage Summary view of the system settings app (undocumented; from this Stack Overflow answer):
Intent openIntent = new Intent(Intent.ACTION_MAIN);
openIntent.setComponent(new ComponentName("com.android.settings", "com.android.settings.Settings$DataUsageSummaryActivity"));
openIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(openIntent);
Is it possible to check whether this component exists and whether the intent will execute successfully?
A similar question gave answers that do not work for this intent in the Android (5.0) Emulator (causing the Settings app to crash several times over – see stacktrace). The below code answers return true (i.e. success), even though my above code will crash the Settings app. My activity intent has so far only crashed on the Emulator presumable due to there being no data plan set(?)
private boolean isCallable(Intent intent) {
List<ResolveInfo> list = getPackageManager().queryIntentActivities(intent,
PackageManager.MATCH_DEFAULT_ONLY);
return list.size() > 0;
}
From this answer..
and
boolean activityExists = intent.resolveActivityInfo(getPackageManager(), 0) != null;
From this one..
Thanks.
The reason why the code snippets you tried are saying that the component is available is because the component is available. The component happens to crash when you try starting it. Whether this is due to an emulator bug, an Android bug, or the fact that you happen to be starting an activity that isn't documented to be started by third-party apps, I can't say.
Is it possible to check whether this component exists
Use the code snippets from your question. In this case, the component exists.
Is it possible to check whether... the intent will execute successfully?
Not in general. Third-party applications are written by third parties. Not only might they have bugs/limitations, but you have no means of determining whether they do from your app.
How to launch specific intent (such as call) using google voice? How to pass phone number using intent? Following code launches google voice but what value to be passed for making call using google voice as intent extras?
final Intent intent = new Intent();
intent.setComponent(new ComponentName("com.google.android.apps.googlevoice", "com.google.android.apps.googlevoice.activity.conversationlist.ConversationListActivity"));
intent.putExtra("label", "<phone number>");
startActivity(intent);
Here what should i put in label to start the intent that launches a call using google voice?
Any help is appreciated... Thanks in Advance...
NEVER target applications directly like that UNLESS it is in your package. You should be using the Intent filter to catch that particular application. Sometimes you have to target an application like this, but this brings up the risk of change in package name errors.
To handle your particular application, you need to look at how information is being passed into Google voice. this will give you insight and how to target it WITHOUT targeting the exact package name.
What #JoxTraex said makes sense. However some clients need funny features like this, so we have no way but to implement this:
try {
Intent intent = new Intent(Intent.ACTION_DIAL,Uri.parse("tel:" + mobile));
intent.setPackage("com.google.android.apps.googlevoice");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} catch (ActivityNotFoundException anfe) {
GMHintManager.getInstance().showError(context, "Google Voice not installed");
}
Yes, you should try-catch ActivityNotFoundException.