เมื่อผู้ใช้กดปุ่มในแอปพลิเคชันของฉันฉันต้องการเปิดแอปพลิเคชัน Google แผนที่มาตรฐานและแสดงตำแหน่งเฉพาะ ฉันจะทำมันได้อย่างไร (ไม่ใช้com.google.android.maps.MapView
)
เมื่อผู้ใช้กดปุ่มในแอปพลิเคชันของฉันฉันต้องการเปิดแอปพลิเคชัน Google แผนที่มาตรฐานและแสดงตำแหน่งเฉพาะ ฉันจะทำมันได้อย่างไร (ไม่ใช้com.google.android.maps.MapView
)
คำตอบ:
คุณควรสร้างIntent
วัตถุด้วย geo-URI:
String uri = String.format(Locale.ENGLISH, "geo:%f,%f", latitude, longitude);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);
หากคุณต้องการที่จะระบุที่อยู่ที่คุณควรใช้แบบฟอร์มของทางภูมิศาสตร์ URI geo:0,0?q=address
อื่น:
การอ้างอิง: https://developer.android.com/guide/components/intents-common.html#Maps
String.format("geo:%f,%f", latitude, longitude)
geo:59,915494,30,409456
นอกจากนี้คุณยังสามารถใช้http://maps.google.co.th/mapsเป็น URI ของคุณได้
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);
หรือคุณสามารถตรวจสอบให้แน่ใจว่ามีการใช้แอป Google Maps เท่านั้นซึ่งจะเป็นการหยุดการแสดงตัวกรองเจตนา (โต้ตอบ) โดยการใช้
intent.setPackage("com.google.android.apps.maps");
ชอบมาก:
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);
หรือคุณสามารถเพิ่มป้ายกำกับไปยังที่ตั้งได้โดยการเพิ่มสตริงในวงเล็บหลังชุดพิกัดแต่ละชุดเช่น:
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);
หากต้องการใช้ตำแหน่งปัจจุบันของผู้ใช้เป็นจุดเริ่มต้น (น่าเสียดายที่ฉันไม่พบวิธีติดป้ายกำกับตำแหน่งปัจจุบัน) จากนั้นให้ย่อหย่อนsaddr
พารามิเตอร์ดังนี้:
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);
เพื่อความสมบูรณ์ถ้าผู้ใช้ไม่ได้ติดตั้งแอปแผนที่มันจะเป็นความคิดที่ดีที่จะจับ ActivityNotFoundException เป็นสถานะ @TonyQ จากนั้นเราสามารถเริ่มต้นกิจกรรมอีกครั้งโดยไม่มีข้อ จำกัด ของแอป Maps เราค่อนข้างแน่ใจ ที่เราจะไม่ไปถึง Toast ในตอนท้ายเนื่องจากเบราว์เซอร์อินเทอร์เน็ตเป็นแอปพลิเคชั่นที่ถูกต้องในการเปิดใช้รูปแบบ URL นี้เช่นกัน
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();
}
}
แก้ไข:
สำหรับทิศทางความตั้งใจในการนำทางได้รับการสนับสนุนด้วย google.navigation
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);
การใช้รูปแบบของสตริงจะช่วยได้ แต่คุณต้องระวังให้เต็มที่กับโลแคล ในประเทศเยอรมนีลอยจะถูกคั่นด้วยเครื่องหมายจุลภาคแทนจุด
การใช้String.format("geo:%f,%f",5.1,2.1);
locale english ผลลัพธ์จะเป็น"geo:5.1,2.1"
แต่ด้วย locale german คุณจะได้รับ"geo:5,1,2,1"
คุณควรใช้ภาษาอังกฤษเพื่อป้องกันพฤติกรรมนี้
String uri = String.format(Locale.ENGLISH, "geo:%f,%f", latitude, longitude);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
context.startActivity(intent);
หากต้องการตั้งค่าป้ายกำกับเป็นจุดภูมิศาสตร์คุณสามารถขยายขอบเขตภูมิศาสตร์โดยใช้:
!!! แต่ระวังด้วย geo-uri นี้ยังอยู่ภายใต้ develoment 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);
ตรวจสอบหน้านี้จาก google:
http://developer.android.com/guide/appendix/g-app-intents.html
คุณสามารถใช้ URI ของแบบฟอร์ม
geo:latitude,longitude
เพื่อเปิดโปรแกรมดูแผนที่ของ Google และชี้ไปที่ตำแหน่ง
บางครั้งหากไม่มีแอปพลิเคชันใด ๆ ที่เกี่ยวข้องกับ geo: protocal คุณสามารถใช้ try-catch เพื่อรับ ActivityNotFoundException เพื่อจัดการ
มันเกิดขึ้นเมื่อคุณใช้อีมูเลเตอร์บางตัวเช่น androVM ซึ่งไม่ได้ติดตั้งแผนที่ google โดยค่าเริ่มต้น
คุณยังสามารถใช้ข้อมูลโค้ดด้านล่างด้วยวิธีนี้มีการตรวจสอบการมีอยู่ของ Google Maps ก่อนที่จะเริ่มเจตนา
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);
}
การอ้างอิง: https://developers.google.com/maps/documentation/android-api/intents
หากต้องการไปยังตำแหน่งที่มี PIN อยู่ให้ใช้:
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);
สำหรับไม่มีขาให้ใช้สิ่งนี้ใน uri:
String uri = "geo:" + destinationLatitude + "," + destinationLongitude;
ฉันมีแอปตัวอย่างที่ฉันเตรียมความพร้อมและเพิ่งผ่าน CITY_NAME เพื่อแสดงกิจกรรมของตัวทำเครื่องหมายแผนที่ซึ่งในที่สุดจะคำนวณลองจิจูดและละติจูดโดย Geocoder โดยใช้ CITY_NAME
ด้านล่างนี้เป็นข้อมูลโค้ดของการเริ่มต้นกิจกรรมของตัวทำเครื่องหมายแผนที่และ MapsMarkerActivity ที่สมบูรณ์
@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);
}
}
}
ลิงก์หมดอายุดังนั้นฉันจึงวางโค้ดที่สมบูรณ์ด้านบน แต่ในกรณีที่คุณต้องการเห็นโค้ดที่สมบูรณ์ก็มีให้ที่: https://github.com/gosaliajigar/CSC519/tree/master/CSC519_HW4_89753
สิ่งนี้เขียนขึ้นใน Kotlin มันจะเปิดแอปแผนที่หากพบและวางจุดและให้คุณเริ่มต้นการเดินทาง:
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)
}
แทนที่ด้วยrequireActivity()
Context
lat: 59.915494, lng: 30.409456
มันจะส่งคืนตำแหน่งที่ผิด