Câu trả lời:
Bạn nên tạo một Intent
đối tượng với URI địa lý:
String uri = String.format(Locale.ENGLISH, "geo:%f,%f", latitude, longitude);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);
Nếu bạn muốn chỉ định một địa chỉ, bạn nên sử dụng một dạng URI địa lý khác : geo:0,0?q=address
.
tham khảo: https://developer.android.com/guide/components/intents-common.html#Maps
String.format("geo:%f,%f", latitude, longitude)
trả về chuỗi bằng dấu phẩy : geo:59,915494,30,409456
.
Bạn cũng có thể chỉ cần sử dụng http://maps.google.com/maps làm URI của mình
String uri = "http://maps.google.com/maps?saddr=" + sourceLatitude + "," + sourceLongitude + "&daddr=" + destinationLatitude + "," + destinationLongitude;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(intent);
hoặc bạn có thể đảm bảo rằng chỉ ứng dụng Google Maps được sử dụng, điều này ngăn bộ lọc ý định (hộp thoại) xuất hiện, bằng cách sử dụng
intent.setPackage("com.google.android.apps.maps");
như vậy
String uri = "http://maps.google.com/maps?saddr=" + sourceLatitude + "," + sourceLongitude + "&daddr=" + destinationLatitude + "," + destinationLongitude;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setPackage("com.google.android.apps.maps");
startActivity(intent);
hoặc bạn có thể thêm nhãn vào các vị trí bằng cách thêm một chuỗi bên trong dấu ngoặc đơn sau mỗi bộ tọa độ như sau:
String uri = "http://maps.google.com/maps?saddr=" + sourceLatitude + "," + sourceLongitude + "(" + "Home Sweet Home" + ")&daddr=" + destinationLatitude + "," + destinationLongitude + " (" + "Where the party is at" + ")";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setPackage("com.google.android.apps.maps");
startActivity(intent);
Để sử dụng vị trí hiện tại của người dùng làm điểm bắt đầu (thật không may, tôi chưa tìm được cách gắn nhãn vị trí hiện tại), sau đó chỉ cần bỏ saddr
tham số như sau:
String uri = "http://maps.google.com/maps?daddr=" + destinationLatitude + "," + destinationLongitude + " (" + "Where the party is at" + ")";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setPackage("com.google.android.apps.maps");
startActivity(intent);
Để đầy đủ, nếu người dùng không cài đặt ứng dụng bản đồ thì sẽ là một ý tưởng hay để bắt ActivityNotFoundException, như @TonyQ, sau đó chúng tôi có thể bắt đầu lại hoạt động mà không bị hạn chế ứng dụng bản đồ, chúng tôi có thể khá chắc chắn cuối cùng chúng ta sẽ không bao giờ đến Toast vì trình duyệt internet là một ứng dụng hợp lệ để khởi chạy lược đồ url này.
String uri = "http://maps.google.com/maps?daddr=" + 12f + "," + 2f + " (" + "Where the party is at" + ")";
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setPackage("com.google.android.apps.maps");
try
{
startActivity(intent);
}
catch(ActivityNotFoundException ex)
{
try
{
Intent unrestrictedIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
startActivity(unrestrictedIntent);
}
catch(ActivityNotFoundException innerEx)
{
Toast.makeText(this, "Please install a maps application", Toast.LENGTH_LONG).show();
}
}
BIÊN TẬP:
Đối với chỉ đường, mục đích điều hướng hiện được hỗ trợ với google.navulation
Uri navigationIntentUri = Uri.parse("google.navigation:q=" + 12f + "," + 2f);
Intent mapIntent = new Intent(Intent.ACTION_VIEW, navigationIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
Sử dụng định dạng Chuỗi sẽ giúp ích nhưng bạn phải quan tâm đầy đủ với miền địa phương. Trong phao nổi ở Đức sẽ được phân tách bằng dấu phẩy thay vì một điểm.
Sử dụng String.format("geo:%f,%f",5.1,2.1);
trên tiếng Anh địa phương kết quả sẽ được "geo:5.1,2.1"
nhưng với tiếng Đức địa phương, bạn sẽ nhận được"geo:5,1,2,1"
Bạn nên sử dụng ngôn ngữ tiếng Anh để ngăn chặn hành vi này.
String uri = String.format(Locale.ENGLISH, "geo:%f,%f", latitude, longitude);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);
Để đặt nhãn thành điểm địa lý, bạn có thể mở rộng uri địa lý của mình bằng cách sử dụng:
!!! nhưng hãy cẩn thận với điều này, ge-uri vẫn còn chưa được phát hiện http://tools.ietf.org/html/draft-mayrhofer-geo-uri-00
String uri = String.format(Locale.ENGLISH, "geo:%f,%f?z=%d&q=%f,%f (%s)",
latitude, longitude, zoom, latitude, longitude, label);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);
Kiểm tra trang này từ google:
http://developer.android.com/guide/appcill/g-app-intents.html
Bạn có thể sử dụng URI của biểu mẫu
geo:latitude,longitude
để mở trình xem bản đồ Google và trỏ nó đến một vị trí.
Bạn cũng có thể sử dụng đoạn mã dưới đây, với cách này, sự tồn tại của google maps được kiểm tra trước khi ý định được bắt đầu.
Uri gmmIntentUri = Uri.parse(String.format(Locale.ENGLISH,"geo:%f,%f", latitude, longitude));
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
if (mapIntent.resolveActivity(getPackageManager()) != null) {
startActivity(mapIntent);
}
Tham khảo: https://developers.google.com/maps/documentation/android-api/intents
Để đi đến vị trí có mã PIN trên đó, hãy sử dụng:
String uri = "http://maps.google.com/maps?q=loc:" + destinationLatitude + "," + destinationLongitude;
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
intent.setPackage("com.google.android.apps.maps");
startActivity(intent);
cho không có pin, sử dụng này trong uri:
String uri = "geo:" + destinationLatitude + "," + destinationLongitude;
Tôi có một ứng dụng mẫu nơi tôi chuẩn bị ý định và chỉ cần vượt qua CITY_NAME trong ý định cho hoạt động đánh dấu bản đồ để tính toán kinh độ và vĩ độ theo Geocoder bằng cách sử dụng CITY_NAME.
Dưới đây là đoạn mã bắt đầu hoạt động đánh dấu bản đồ và MapsMarkerActivity hoàn chỉnh.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
} else if (id == R.id.action_refresh) {
Log.d(APP_TAG, "onOptionsItemSelected Refresh selected");
new MainActivityFragment.FetchWeatherTask().execute(CITY, FORECAS_DAYS);
return true;
} else if (id == R.id.action_map) {
Log.d(APP_TAG, "onOptionsItemSelected Map selected");
Intent intent = new Intent(this, MapsMarkerActivity.class);
intent.putExtra("CITY_NAME", CITY);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
public class MapsMarkerActivity extends AppCompatActivity
implements OnMapReadyCallback {
private String cityName = "";
private double longitude;
private double latitude;
static final int numberOptions = 10;
String [] optionArray = new String[numberOptions];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Retrieve the content view that renders the map.
setContentView(R.layout.activity_map);
// Get the SupportMapFragment and request notification
// when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
// Test whether geocoder is present on platform
if(Geocoder.isPresent()){
cityName = getIntent().getStringExtra("CITY_NAME");
geocodeLocation(cityName);
} else {
String noGoGeo = "FAILURE: No Geocoder on this platform.";
Toast.makeText(this, noGoGeo, Toast.LENGTH_LONG).show();
return;
}
}
/**
* Manipulates the map when it's available.
* The API invokes this callback when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user receives a prompt to install
* Play services inside the SupportMapFragment. The API invokes this method after the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
// Add a marker in Sydney, Australia,
// and move the map's camera to the same location.
LatLng sydney = new LatLng(latitude, longitude);
// If cityName is not available then use
// Default Location.
String markerDisplay = "Default Location";
if (cityName != null
&& cityName.length() > 0) {
markerDisplay = "Marker in " + cityName;
}
googleMap.addMarker(new MarkerOptions().position(sydney)
.title(markerDisplay));
googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
/**
* Method to geocode location passed as string (e.g., "Pentagon"), which
* places the corresponding latitude and longitude in the variables lat and lon.
*
* @param placeName
*/
private void geocodeLocation(String placeName){
// Following adapted from Conder and Darcey, pp.321 ff.
Geocoder gcoder = new Geocoder(this);
// Note that the Geocoder uses synchronous network access, so in a serious application
// it would be best to put it on a background thread to prevent blocking the main UI if network
// access is slow. Here we are just giving an example of how to use it so, for simplicity, we
// don't put it on a separate thread. See the class RouteMapper in this package for an example
// of making a network access on a background thread. Geocoding is implemented by a backend
// that is not part of the core Android framework, so we use the static method
// Geocoder.isPresent() to test for presence of the required backend on the given platform.
try{
List<Address> results = null;
if(Geocoder.isPresent()){
results = gcoder.getFromLocationName(placeName, numberOptions);
} else {
Log.i(MainActivity.APP_TAG, "No Geocoder found");
return;
}
Iterator<Address> locations = results.iterator();
String raw = "\nRaw String:\n";
String country;
int opCount = 0;
while(locations.hasNext()){
Address location = locations.next();
if(opCount == 0 && location != null){
latitude = location.getLatitude();
longitude = location.getLongitude();
}
country = location.getCountryName();
if(country == null) {
country = "";
} else {
country = ", " + country;
}
raw += location+"\n";
optionArray[opCount] = location.getAddressLine(0)+", "
+location.getAddressLine(1)+country+"\n";
opCount ++;
}
// Log the returned data
Log.d(MainActivity.APP_TAG, raw);
Log.d(MainActivity.APP_TAG, "\nOptions:\n");
for(int i=0; i<opCount; i++){
Log.i(MainActivity.APP_TAG, "("+(i+1)+") "+optionArray[i]);
}
Log.d(MainActivity.APP_TAG, "latitude=" + latitude + ";longitude=" + longitude);
} catch (Exception e){
Log.d(MainActivity.APP_TAG, "I/O Failure; do you have a network connection?",e);
}
}
}
Liên kết hết hạn vì vậy tôi đã dán mã hoàn chỉnh ở trên nhưng chỉ trong trường hợp nếu bạn muốn xem mã hoàn chỉnh thì có sẵn tại: https://github.com/gosaliajigar/CSC519/tree/master/CSC519_HW4_89753
Điều này được viết bằng Kotlin, nó sẽ mở ứng dụng bản đồ nếu nó được tìm thấy và đặt điểm và cho phép bạn bắt đầu chuyến đi:
val gmmIntentUri = Uri.parse("http://maps.google.com/maps?daddr=" + adapter.getItemAt(position).latitud + "," + adapter.getItemAt(position).longitud)
val mapIntent = Intent(Intent.ACTION_VIEW, gmmIntentUri)
mapIntent.setPackage("com.google.android.apps.maps")
if (mapIntent.resolveActivity(requireActivity().packageManager) != null) {
startActivity(mapIntent)
}
Thay thế requireActivity()
bằng của bạn Context
.
lat: 59.915494, lng: 30.409456
nó trả lại vị trí sai.