Launching a Streetview intent for a location doesn't guarantee that a Streetview exists for that location. If the Streetview doesn't exist, the user just sees a black screen that spins. Is there a way to programmatically check if it exists before launching the Streetview intent?
Use PackageManager and queryIntentActivities() with your Intent. If you get back a list of 0 matching activities, you know nothing on the device will handle your request.
A way to do that would be to use Google Street View Image API to check whether Google Street View exist or not.
https://developers.google.com/maps/documentation/streetview/
It returns an image with a different file size when Street View at a particular co-ordinates exist,than when it doesn't
http://maps.googleapis.com/maps/api/streetview?size=400x400&location=40.720032,%20-73.988354&fov=90&heading=235&pitch=10&sensor=false
You can compare these images and check if it exist or not.
I've not checked the Android API but with the JavaScript API there is a StreetViewService class with a getPanoramaByLocation method. If there is no Street View at that location, it returns NO_RESULTS.
i ll give you a snippet of my solution for checking if a streetview exists from my googe image api streetview image integration - guess you can use the StreetViewStatus.Ok boolean for ordinary streetview too.
streetViewService.getPanoramaByLocation(latLng, STREETVIEW_MAX_DISTANCE, function (streetViewPanoramaData, status) {
if (status === google.maps.StreetViewStatus.OK) {
var img = document.createElement("IMG");
img.src = 'http://maps.googleapis.com/maps/api/streetview?size=160x205&location='+ lat +','+ lng +'&sensor=false&key=AIzaSyC_OXsfB8-03ZXcslwOiN9EXSLZgwRy94s';
var oldImg = document.getElementById('streetViewImage');
document.getElementById('streetViewContainerShow').replaceChild(img, streetViewImage);
} else {
var img = document.createElement("IMG");
img.src = '../../images/ProfilnoProfilPicture.jpg';
img.height = 205;
img.width = 160;
var oldImg = document.getElementById('streetViewImage');
document.getElementById('streetViewContainerShow').replaceChild(img, streetViewImage);
}
});
Related
I have created an app in both Android & IOS. I am on the last hurdle of the app. I was able to get Android user working with IOS user whereas the IOS had a tableview.
Now I am faced with a different problem. If the "rider" on the iOS app is requesting a ride and the Android driver is available - how can I finish this use case?
If the iOS user makes a request, this is the process:
func requestPressed(_ sender: Any) {
print("... requestPressed")
let dict = selectedPin!.addressDictionary
if dict?.count == 0 {
// this isn't shown to the user, just in your debug window
print("no addresses available, try again in a few seconds")
return
}
destAddress = selectedPin!.addressDictionary!["Street"] as? String ?? "None"
if destAddress == "None" {
print("no valid address available, try again in a few seconds")
return
}
if userLocation != nil {
print("my userLocation: \(userLocation!)")
if canRequestRyde { // if true ...
// get the destination area name, and the price
areaNameDestination = DriveHandler.Instance.getAreaName(latitude: destLat, longitude: destLong)
print("destination area \(areaNameDestination)")
requestFarePrice()
rRideHandler.Instance.requestRide(latitude: Double(userLocation!.latitude), longitude: Double(userLocation!.longitude), destLat: Double(destLat), destLong: Double(destLong), currentAddress: self.currentAddress, destAddress: destAddress, farePrice: farePrice)
// reset the driver message
driverMessage = ""
canRequestRide(delegateCalled: true, request: nil)
} else {
riderCancelled()
}
}
}
The Firebase entry would look like this:
What I need to do from this is for the online Android Driver to either accept/decline the request and follow the steps as if it was Android Rider vs Android Driver.
Below are the steps if Android requests a ride and press "Request" btn:
private void requestPickupHere(String uid) {
Log.e(TAG, "requestPickupHere");
DatabaseReference dbRequest = FirebaseDatabase.getInstance().getReference(Common
.request_tbl); // "RideRequests"
GeoFire mGeoFire = new GeoFire(dbRequest);
mGeoFire.setLocation(uid, new GeoLocation(Common.mLastLocation.getLatitude(),
Common.mLastLocation.getLongitude()));
// write to db
if (search_bar_destination != null) {
dbRequest.child(uid).child("destination").setValue(search_bar_destination);
} else if (tap_on_map_destination != null) {
dbRequest.child(uid).child("destination").setValue(tap_on_map_destination);
}
dbRequest.child(riderId).child("status").setValue("");
if (mUserMarker.isVisible()) {
mUserMarker.remove();
}
// Add a new marker
mUserMarker = mMap.addMarker(new MarkerOptions()
.title("Pickup Here")
.snippet("")
.position(new LatLng(Common.mLastLocation.getLatitude(), Common.mLastLocation.getLongitude()))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED)));
mUserMarker.showInfoWindow();
btnRequest.setText("Getting your DRIVER ...");
location = getCompleteAddressString(Common.mLastLocation.getLatitude(), Common.mLastLocation.getLongitude());
Log.e(TAG, "riders location = " + location);
findDriver();
}
When the above code is run, it open an activity "Customer Call" located within the Driver Application, where the driver can either Accept / Deny the request.
How can I get the request to be sent from IOS Rider to the Android Driver in the same way it would work for Android to Android?
Using different platforms shouldn't be an issue, when a user requests a ride then you can add an attribute under the driver in the database for example:
DriverRides
DriverId
Name: peter
purpose: needs a ride
Then you can retrieve all the requests to be appear for that driver in a recyclerview. It shouldn't matter what phone the user is using, except if you want the android user to take requests and the ios user to send requests.
You are using the same database for both platforms, so when an ios user or android user store data it will go to the same place. For example if user x uses an iPhone and user y uses a Samsung, you would do the following in the database:
Users
UserId1
name: userx
age: 100
UserId2
name: usery
age: 120
I want to start Google map intent for direction with current location as starting position, one location as entry position and other location as destination.
After googling for this, following is the closest query I came with
https://maps.google.com/maps?f=d&daddr=41.3951982,-72.855568 to: 41.279386, -72.825098
OR
"https://www.google.com/maps/dir//41.3951982,-72.855568/41.279386,-72.825098"
Both of them work good when I paste on browser, but not on my mobile device. I just get source and destination. Any ideas?
EDIT:
Actually the second one works. Unlike browser, it only shows starting location and first point, but has a full navigation route. :)
There isn't any google approved way of doing it (as far as I looked to documentation). But I found this solution working pretty good
private void navigate(List<LatLng> latLngs) {
String uri = "";
for (LatLng latLng : latLngs) {
if (TextUtils.isEmpty(uri)) {
uri = String.format(
"http://maps.google.com/maps?saddr=%s, %s",
String.valueOf(latLng.latitude).replace(",", "."),
String.valueOf(latLng.longitude).replace(",", ".")
);
} else {
if (!uri.contains("&daddr")) {
uri += String.format(
"&daddr=%s, %s",
String.valueOf(latLng.latitude).replace(",", "."),
String.valueOf(latLng.longitude).replace(",", ".")
);
} else {
uri += String.format(
"+to:%s, %s",
String.valueOf(latLng.latitude).replace(",", "."),
String.valueOf(latLng.longitude).replace(",", ".")
);
}
}
}
Intent intent = new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(intent);
}
Google Maps app on Android doesn't support multiple destinations. You can try to draw on the map by using native Google Maps Android API. You can get the directions from Google Maps Directions API.
I'm building an application with the functionality of sending specific pre-determined (but dynamic) coordinates to the user's map app so he can trace a route to it.
Currently, I'm using:
String coordinates = String.format("geo:0,0?q=" + latitude + "," + longitude);
Intent intent = new Intent( Intent.ACTION_VIEW, Uri.parse(coordinates) );
startActivity( intent );
However, when it does open the map, instead of the requested location I get a "no results for [latitude], [longitude]" toast and my current location instead.
It's certainly not an issue with the coordinates themselves as manually searching for them work just fine and printing the request Uri show that it's correctly constructed. Surprisingly, only sending the first two digits of both coords sort of works and, while doesn't send me where I want to, does not give the toast error message.
Do I need to do any extra formatting when passing the values or some other thing?
I'm using them raw, -23.561261 and -46.681212 for example, am located in Brazil if that makes any difference and, yes, I do have to send the coordinates as sadly the data is inconsistent with the formatting of the actual addresses.
UPDATE: As it turns out, the code is fine, it works on my razr-i, however, in the Galaxy Express I used for the original tests, it's still a no go.
Any idea of what is going on? Both devices are running Android 4.1.2
Don't quite remember what the error was since it's been so long ago, but long story short, here's the working code:
String coordinates = "http://maps.google.com/maps?daddr=" + latitude + "," + longitude;
Intent intent = new Intent( Intent.ACTION_VIEW, Uri.parse(coordinates) );
startActivity( intent );
Your code is correct,
the values that you send are double?
double latitude = -23.561261;
double longitude = -46.681212;
String coordinates = String.format("geo:0,0?q=" + latitude + "," + longitude);
Intent intentMap = new Intent( Intent.ACTION_VIEW, Uri.parse(coordinates) );
startActivity( intentMap );
must be something similar to load directly in your browser the url:
http://www.google.com/maps?q=-23.561261+-46.681212
The problem is in locale. Your code will work on any phone if you call format() like this:
String coordinates = String.format(Locale.ENGLISH, "geo:%f,%f", latitude, longitude);
I have an Android application and I'm trying to populate a Google Map with a route, this route is store on a JSON array this way:
JSONArray.getString("points") = ["-33.45591917507404, -70.59198361376951","-33.453484420618416, -70.61635952929686"]
So in this case I have
Point A=(-33.49088437162095, -70.64043194102163) and
Point B=(-33.49423964397045, -70.63992768572683)
And my route or path is A-----B
I'm new to Android and I was wondering how to get this to work. Also, in this case my route is A-----B, but it can also be A----B----C----D. I can have any number of points on the path.
One thing you can try is the Google Maps Polyline object: https://developers.google.com/maps/documentation/javascript/reference#Polyline You specify to setPath() an ordered list of the points (either an Array of LatLng or an MVCArray or LatLng), you want to connect together on the map, and Google Maps will make a polyline for you to your specifications.
// path = Array of LatLng or MVCArray of LatLng
routeLine = new Polyline();
routeLine.setPath(JSONArray);
In your case, passing JSONArray into setPath should work OK.
If you want to get fancy and incorporate directions, you need to use the Google Directions API. https://developers.google.com/maps/documentation/javascript/directions
// All waypoints must be stopovers for the Directions service to optimize their route.
// start & end are of type String or LatLng, waypts is an array of String or LatLng
request = {
origin: start,
destination: end,
waypoints: waypts,
optimizeWaypoints: [type Boolean],
travelMode: [type TravelMode]
};
// go on and actually perform the request
directionsService.route(request, function(result, status) {
if (status == google.maps.DirectionsStatus.OK) {
// if successful, this will run
}
});
Once you finish constructing your object, you should be able to display it by running setMap(map:Map), such as
routeLine.setMap(map)
I'm developing an application with the MapView and the GPS.
My problem is that the user might disconnect while using my application, so he'll be walking in a fully grey map. I'd like to cache the map temporarily in order to see it later.
I know that cache the map isn't allowed by the google maps API, but I want to be sure if TEMPORARILY cache it (and delete it when the app is closed) is also forbidden.
I've heard about openstreetmaps / osmdroid, but I'd like to confirm that I HAVE to use it before deleting half of my code.
I know that cache the map isn't allowed by the google maps API, but I want to be sure if TEMPORARILY cache it (and delete it when the app is closed) is also forbidden.
There is no means of accomplishing this with the Google Maps Add-On for Android.
Because I need the satelliteView, I finally used a method that could be improved.
I start a thread that asks the controler to go to a location near the user. It's downloaded and the cache is managed by the MapView:
int latitudeSpan = mapView.getLatitudeSpan();
int longitudeSpan = mapView.getLongitudeSpan();
for(int i=-MEMORIZED_MAP_SIZE;i<=MEMORIZED_MAP_SIZE;i++)
{
for(int j=-MEMORIZED_MAP_SIZE;j<=MEMORIZED_MAP_SIZE;j++)
{
synchronized (this)
{
if(i==j&&j==0) j++;
Message msg = new Message();
msg.arg1=latitude+latitudeSpan*i;
msg.arg2=longitude+longitudeSpan*j;
msg.setTarget(MainActivity.handler);
msg.sendToTarget();
try
{
wait(5000);
}
catch(Exception e){}
}
}
}
Now, I just need to find another way than "wait(5000)" to know that the part of the map I'm looking at is downloaded. I'll modify this message if I find one.
Do you have the whole example of this?
int latitudeSpan = mapView.getLatitudeSpan();
int longitudeSpan = mapView.getLongitudeSpan();
for(int i=-MEMORIZED_MAP_SIZE;i<=MEMORIZED_MAP_SIZE;i++)
{
for(int j=-MEMORIZED_MAP_SIZE;j<=MEMORIZED_MAP_SIZE;j++)
{
synchronized (this)
{
if(i==j&&j==0) j++;
Message msg = new Message();
msg.arg1=latitude+latitudeSpan*i;
msg.arg2=longitude+longitudeSpan*j;
msg.setTarget(MainActivity.handler);
msg.sendToTarget();
try
{
wait(5000);
}
catch(Exception e){}
}
}
}
I managed to solve this partially using 2 MapView Fragments , one of them invisible.
Then a loop was moving the camera to create cache for the other MapView