Android API弃用的替代方案推荐地点

11

我正在尝试实现地点API。我的代码看起来像这样:

val builder = PlacePicker.IntentBuilder()
startActivityForResult(builder.build(mActivity), PLACE_PICKER_REQUEST)

我的谷歌地图API凭证是正确的,但在调用时出现了以下错误:

您的应用程序似乎没有启用Android Places API。有关更多详细信息,请参见https://developers.google.com/places/android/signup

然而,当我试图启用“Places API for Android”时,我遇到了以下错误。

您没有足够的权限查看此页面。

我尝试退出帐户并重新登录,使用隐身模式、Safari和Chrome,但都无法解决问题,因此我联系了支持人员,他们非常快速(感谢你们!)

当您尝试启用Android Places API时,会收到错误提示,原因是该API已被弃用。现在,启用Places API就可以实现Android上的地点功能。

我询问了我的实施情况,并得到了以下回复。

Place Picker也已被弃用。您可以安装兼容库,以在弃用期结束之前继续使用Place Picker。有关更多信息,请参阅https://developers.google.com/places/android-sdk/client-migration#place_picker

现在我在网上找到的文档有些令人困惑,什么被弃用了,什么没有?请问有人能指点我这种功能的正确方向吗?


Place Picker客户端库兼容性库将于7月29日停止支持。我的理解是,如果您想使用Place API,则必须构建自己的UI/UX。 - Morrison Chang
我也在尝试新的地点API,并且遇到了相同的错误:“Android上的地点API似乎未启用您的应用程序。” 我在现有应用程序中使用Place和Autocomplete Place,那么我是否需要更改所有API? - pradip_android
Google正在追踪对于在此处使用Place Picker小部件的兴趣:(Android)https://issuetracker.google.com/128304810,(iOS)https://issuetracker.google.com/128304760。如果您有兴趣,请填写链接表格并说明您的用例和需求。 - Daffi
4个回答

22

Google Places SDK for Android已经被弃用,所以我们需要迁移到Places API。 要使用新的Places API来实现自动完成位置,请按照以下步骤进行。

首先在开发人员控制台中启用Places API,然后通过更新gradle安装Client Library。

(注意:您只能安装客户端库或兼容性库,无法同时安装两者)

implementation 'com.google.android.libraries.places:places:1.0.0'

现在将以下代码初始化到Oncreate()中:

 // Add an import statement for the client library.
    import com.google.android.libraries.places.api.Places;

    // Initialize Places.
    Places.initialize(getApplicationContext(), "***YOUR API KEY***");

   // Create a new Places client instance.
   PlacesClient placesClient = Places.createClient(this);

新的PlacesAPI已被初始化..

要使用自动完成地点,请使用以下代码(也可以使用AutoComplete Fragment)

// Set the fields to specify which types of place data to return.
List<Place.Field> fields = Arrays.asList(Place.Field.ID, Place.Field.NAME);
// Start the autocomplete intent.
Intent intent = new Autocomplete.IntentBuilder(
        AutocompleteActivityMode.FULLSCREEN, fields)
        .build(this);
startActivityForResult(intent, AUTOCOMPLETE_REQUEST_CODE);

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == AUTOCOMPLETE_REQUEST_CODE) {
        if (resultCode == RESULT_OK) {
            Place place = Autocomplete.getPlaceFromIntent(data);
            Log.i(TAG, "Place: " + place.getName() + ", " + place.getId());
        } else if (resultCode == AutocompleteActivity.RESULT_ERROR) {
            // TODO: Handle the error.
            Status status = Autocomplete.getStatusFromIntent(data);
            Log.i(TAG, status.getStatusMessage());
        } else if (resultCode == RESULT_CANCELED) {
            // The user canceled the operation.
        }
    }
}
  • 确保清单文件中的权限
  • 生成API密钥。
  • 在Dev Console中启用Places API。

REMOVE(如果您已添加)


implementation 'com.google.android.gms:play-services-places:16.0.0'

必要的头文件

import com.google.android.libraries.places.api.Places;
import com.google.android.libraries.places.api.model.Place;
import com.google.android.libraries.places.api.net.PlacesClient;
import com.google.android.libraries.places.widget.Autocomplete;
import com.google.android.libraries.places.widget.AutocompleteActivity;
import com.google.android.libraries.places.widget.model.AutocompleteActivityMode;

希望这可以帮助到您。


3
PlacesClient是一个用户可以在地图上选择一个点的UI(活动)吗?所以当我不需要自动完成时,我可以使用它,对吗? - Denny Weinberg
3
如何使用地点选择器和地图? - divaPrajapati09
请参考以下链接:https://developers.google.com/places/android-sdk/client-migration#place_picker - Navin Kumar
3
其他教程没有提到我需要删除 gms:play-services,这对我很有效。谢谢! - Aakash
此代码未显示默认的MapsActivity以从地图中选择位置。该解决方案仅显示默认的SearchLocationActivity。 - Ahamadullah Saikat
显示剩余2条评论

1
尽管Google为Places SDK提供了新的API,但由于新的计费政策,他们正在放弃对Place Picker的支持,因此有两种处理方式。
  1. 您可以使用新的SDK自己实现此逻辑。

  2. 或者幸运的是,有这个Ping Place Picker库,它模仿了旧的Place Picker的行为。


1
作为Google Place Picker的替代方案,您可以使用Leku。这是一个易于使用的库,适合您的需求。
您只需要添加依赖项:
dependencies {
    implementation 'com.schibstedspain.android:leku:7.0.0'
}

在您的清单文件中声明该活动:

<activity
    android:name="com.schibstedspain.leku.LocationPickerActivity"
    android:label="@string/leku_title_activity_location_picker"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar"
    android:windowSoftInputMode="adjustPan"
    android:parentActivityName=".MainActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEARCH" />
    </intent-filter>
    <meta-data android:name="android.app.searchable"
        android:resource="@xml/leku_searchable" />
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".MainActivity" />
</activity>

在需要的地方启动活动:

val locationPickerIntent = LocationPickerActivity.Builder()
    .build(applicationContext)

startActivityForResult(locationPickerIntent, MAP_BUTTON_REQUEST_CODE)

最后,处理结果:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (resultCode == Activity.RESULT_OK && data != null) {
        Log.d("RESULT****", "OK")
        if (requestCode == 1) {
            val latitude = data.getDoubleExtra(LATITUDE, 0.0)
            Log.d("LATITUDE****", latitude.toString())
            val longitude = data.getDoubleExtra(LONGITUDE, 0.0)
            Log.d("LONGITUDE****", longitude.toString())
            val address = data.getStringExtra(LOCATION_ADDRESS)
            Log.d("ADDRESS****", address.toString())
            val postalcode = data.getStringExtra(ZIPCODE)
            Log.d("POSTALCODE****", postalcode.toString())
            val bundle = data.getBundleExtra(TRANSITION_BUNDLE)
            Log.d("BUNDLE TEXT****", bundle.getString("test"))
            val fullAddress = data.getParcelableExtra<Address>(ADDRESS)
            if (fullAddress != null) {
                Log.d("FULL ADDRESS****", fullAddress.toString())
            }
            val timeZoneId = data.getStringExtra(TIME_ZONE_ID)
            Log.d("TIME ZONE ID****", timeZoneId)
            val timeZoneDisplayName = data.getStringExtra(TIME_ZONE_DISPLAY_NAME)
            Log.d("TIME ZONE NAME****", timeZoneDisplayName)
        } else if (requestCode == 2) {
            val latitude = data.getDoubleExtra(LATITUDE, 0.0)
            Log.d("LATITUDE****", latitude.toString())
            val longitude = data.getDoubleExtra(LONGITUDE, 0.0)
            Log.d("LONGITUDE****", longitude.toString())
            val address = data.getStringExtra(LOCATION_ADDRESS)
            Log.d("ADDRESS****", address.toString())
            val lekuPoi = data.getParcelableExtra<LekuPoi>(LEKU_POI)
            Log.d("LekuPoi****", lekuPoi.toString())
        }
    }
    if (resultCode == Activity.RESULT_CANCELED) {
        Log.d("RESULT****", "CANCELLED")
    }
}

并且你已经准备好了。 ;)

看起来很棒! - TomCB
这个库看起来很棒!但是,从安全角度考虑,将谷歌API密钥传递给第三方库是否安全? - Suneesh Ambatt

0

Google Play Services版本的Android Places SDK(在Google Play Services 16.0.0中)已于2019年1月29日停用,并将于2019年7月29日关闭。如果您在Google API控制台下检查,只有PLACES API,没有PLACES SDK FOR ANDROID。

迁移指南到新的Places SDK客户端库可以在这里找到

或者在我的repo中找到自定义实现 => NewGooglePlacesSDK


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接