构建X:Y格式的Uri

我正在尝试构建一个Uri,这是一种用于查询地图上某个位置的最正确方法。 在地图意图的文档中,指出Uris应采用以下forms: geo:0,0?q=my+street+address 。 我尝试使用Uri.Builder但没有find指定uri"0,0"部分的方法,因为Uri.Builder没有指定路径的function而没有预先设置’/’。 目前我使用以下代码:

 uri = new Uri.Builder() .scheme(URL_SCHEME_MAP) .encodedOpaquePart("0,0?q=" + query) .build(); 

哪个好,但不如我想要的好。 所以我想知道是否有人知道更好/更好的方法来做到这一点。

您可以通过结合使用parsebuildUpon方法来实现此buildUpon

 Uri geoLocation = Uri.parse("geo:0,0?").buildUpon() .appendQueryParameter("q", location) .build(); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(geoLocation); 

我从Udacity类“开发Android应用程序”中学到了这种方法,尽管他们没有完全解释它。

只是建立@providencemac答案并提供更多背景信息:

Java区分分层和不透明URI。 你在这里想要创建的是一个不透明的URI。 这种URI由三部分组成:方案,不透明部分和片段。 不透明部分基本上是方案分隔符(:)和片段分隔符( # )之间的所有内容。 那么buildUpon实际上在不透明URI的引擎下做了以下几点:

 return new Builder() .scheme(getScheme()) .opaquePart(getSsp()) .fragment(getFragmentPart()); 

getSchemeparse的字符串集中获取所有内容,直到:getSspSSP意味着特定方案的部分 )获取所有内容:和可能的#getFragmentPart获取#之后的所有内容。

所以@ providencemac的回答不使用parsebuiltUpon看起来如下:

 uri = new Uri.Builder() .scheme(URL_SCHEME_MAP) .encodedOpaquePart("0,0") .appendQueryParameter("q", query) .build(); 

遗憾的是,尽管在消息来源中对此进行了一些研究,但我注意到了这个以及原始答案的缺陷(因此可能存在提到的Udacity课程的问题)。 从SDK 23rev3开始, appendQueryParameter的前两行如下所示:

 // This URI will be hierarchical. this.opaquePart = null; 

因此,我们以前不透明的URI被转换为分层的URI,而不是实际上是分层的,因为它既不是相对的,也不包含"://"部分。 所以结果看起来像"geo:?q=1600+Amphitheatre+Parkway%2C+CA" ,当没有给出具体的经度和纬度时它会起作用。 虽然如果您尝试从这样的文档创建第二个示例

 uri = new Uri.Builder() .scheme("geo") .encodedOpaquePart("47.6,-122.3") .appendQueryParameter("z", "11") .build(); 

你最终会得到"geo:?z=zoom" ,这显然会导致显示当前设备的位置。

长话短说:我认为你应该坚持你最初在你的问题中提出的方式,因为它确实产生了你想要的东西。 虽然你应该使用Uri.encode(query)

正如@providencemac所指出的,Udacity Android开发课程展示了如何做到这一点,但它现在实际上使用了Uri.Builder 。 但是,他们的代码是错误的:

 Uri.Builder builder = new Uri.Builder(); builder.scheme("geo") .path("0,0") .query(streetAddr); Uri uri = builder.build(); 

如果您使用Google的地址作为查询位置,模拟器仍会继续使用,因为这是默认设置。 但是没有位置标记,其他地址也不起作用。 相反,它应该是这样的:

 Uri.Builder builder = new Uri.Builder(); builder.scheme("geo") .appendPath("0,0") .appendQueryParameter("q", addressString); Uri addressUri = builder.build(); 

对于那些仍然有这个问题的人。 我认为这是最接近Udacity课程的:

 builder.scheme("geo") .encodedPath("0,0") .appendQueryParameter("q",streetAddress); 

您只需将Path()更改为encodedPath()

我阅读文档并尝试所有答案,所以我的。 正如您在文档中看到的那样,有4个数据uri模式可以在地图上显示位置。

  1. 简单
  2. 放大
  3. 标签
  4. 地址

这是我对所有选项的建议:

 private Uri getGeoUri(double lat, double log) { return Uri.parse("geo:" + lat + "," + log); } private Uri getGeoUri(double lat, double log, int zoom) { return Uri.parse("geo:" + lat + "," + log + "?z=" + zoom); } private Uri getGeoUri(double lat, double log, String lable) { return Uri.parse("geo:0,0?q=" + lat + "," + log + "(" + lable + ")"); } private Uri getGeoUri(String address) { return Uri.parse("geo:0,0?q=" + address); } 

这是如何使用:

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Uri geoLocation = getGeoUri(47.6,-122.3); //1. simple //Uri geoLocation = getGeoUri(47.6,-122.3, 11); //2. zoom //Uri geoLocation = getGeoUri(34.99,-106.61, "Treasure"); //3. label Uri geoLocation = getGeoUri("1600 Amphitheatre Parkway ,CA"); //4. address openMap(geoLocation); } private void openMap(Uri geoLocation) { Intent i = new Intent(Intent.ACTION_VIEW); i.setData(geoLocation); if (i.resolveActivity(getPackageManager()) != null) { startActivity(i); } } 

一体化MainActivity。

 public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //Uri geoLocation = getGeoUri(47.6,-122.3); //1. simple //Uri geoLocation = getGeoUri(47.6,-122.3, 11); //2. zoom //Uri geoLocation = getGeoUri(34.99,-106.61, "Treasure"); //3. label Uri geoLocation = getGeoUri("1600 Amphitheatre Parkway ,CA"); //4. address openMap(geoLocation); } private void openMap(Uri geoLocation) { Intent i = new Intent(Intent.ACTION_VIEW); i.setData(geoLocation); if (i.resolveActivity(getPackageManager()) != null) { startActivity(i); } } private Uri getGeoUri(double lat, double log) { return Uri.parse("geo:" + lat + "," + log); } private Uri getGeoUri(double lat, double log, int zoom) { return Uri.parse("geo:" + lat + "," + log + "?z=" + zoom); } private Uri getGeoUri(double lat, double log, String lable) { return Uri.parse("geo:0,0?q=" + lat + "," + log + "(" + lable + ")"); } private Uri getGeoUri(String address) { return Uri.parse("geo:0,0?q=" + address); } } 

好好享受。