📌  相关文章
📜  如何在 Android 中实现 Google 的 Places AutocompleteBar?

📅  最后修改于: 2022-05-13 01:55:45.907000             🧑  作者: Mango

如何在 Android 中实现 Google 的 Places AutocompleteBar?

如果您曾经在移动设备上使用过 Google 地图或从桌面访问过,那么您肯定已经在搜索栏中输入了某个位置并选择了其中一个结果。结果可能包含地址、电话号码、评分、时间等字段。此外,如果您曾经在 google.com 上从桌面搜索过某个地点,那么您一定会得到许多搜索结果以及带有上述参数从右侧对齐。下面给出了一个示例 GIF,以了解我们将在本文中做什么。请注意,我们将使用Kotlin语言来实现这个项目。

这两个应用程序都实现了一个 API,公开称为 Places API。自动完成栏是 Places API 的一项功能,它根据用户在搜索栏中键入的词推荐位置列表。借助 Places API,我们将实现 AutocompleteBar 并获取位置信息。

分步实施

第 1 步:在 Android Studio 中创建一个新项目

要在 Android Studio 中创建新项目,请参阅如何在 Android Studio 中创建/启动新项目。我们在 Kotlin 中演示了该应用程序,因此请确保在创建新项目时选择Kotlin作为主要语言。

第 2 步:获取和隐藏 API 密钥



我们的应用程序利用 Google 的 Places API 来实现自动完成栏,因此我们需要从 Google 获取 Places API 密钥。要获取 API 密钥,请参阅生成用于使用任何 Google API 的 API 密钥。隐藏 API 密钥是必不可少的,为此,请参阅如何在 Android Studio 中隐藏 API 和秘密密钥?。

第三步:在build.gradle文件中添加依赖

我们需要导入支持我们的自动完成栏实现的库。由于自动完成栏是 Places API 的一项功能,我们需要在 build.gradle 文件中附加其最新的依赖项。以下是必须添加的依赖项。

第 4 步:在清单文件中添加 Internet 权限

导航到app > manifest 文件夹并记下它的以下权限。

第五步:在activity_main.xml文件中实现Autocomplete Bar片段(前端)

导航到app > res > layout > activity_main.xml并将以下代码添加到该文件中。下面是activity_main.xml文件的代码

XML


  
    
        
    
  
    
  


Kotlin
package org.geeksforgeeks.myapplication
  
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import com.google.android.gms.common.api.Status
import com.google.android.libraries.places.api.Places
import com.google.android.libraries.places.api.model.Place
import com.google.android.libraries.places.widget.AutocompleteSupportFragment
import com.google.android.libraries.places.widget.listener.PlaceSelectionListener
  
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
  
        // Fetching API_KEY which we wrapped
        val ai: ApplicationInfo = applicationContext.packageManager
            .getApplicationInfo(applicationContext.packageName, PackageManager.GET_META_DATA)
        val value = ai.metaData["api_key"]
        val apiKey = value.toString()
  
        // Initializing the Places API 
          // with the help of our API_KEY
        if (!Places.isInitialized()) {
            Places.initialize(applicationContext, apiKey)
        }
  
        // Initialize Autocomplete Fragments 
          // from the main activity layout file
        val autocompleteSupportFragment1 = supportFragmentManager.findFragmentById(R.id.autocomplete_fragment1) as AutocompleteSupportFragment?
  
        // Information that we wish to fetch after typing 
          // the location and clicking on one of the options
        autocompleteSupportFragment1!!.setPlaceFields(
            listOf(
  
                Place.Field.NAME,
                Place.Field.ADDRESS,
                Place.Field.PHONE_NUMBER,
                Place.Field.LAT_LNG,
                Place.Field.OPENING_HOURS,
                Place.Field.RATING,
                Place.Field.USER_RATINGS_TOTAL
  
            )
        )
  
        // Display the fetched information after clicking on one of the options
        autocompleteSupportFragment1.setOnPlaceSelectedListener(object : PlaceSelectionListener {
            override fun onPlaceSelected(place: Place) {
  
                // Text view where we will
                  // append the information that we fetch
                val textView = findViewById(R.id.tv1)
  
                // Information about the place
                val name = place.name
                val address = place.address
                val phone = place.phoneNumber.toString()
                val latlng = place.latLng
                val latitude = latlng?.latitude
                val longitude = latlng?.longitude
  
                val isOpenStatus : String = if(place.isOpen == true){
                    "Open"
                } else {
                    "Closed"
                }
  
                val rating = place.rating
                val userRatings = place.userRatingsTotal
  
                textView.text = "Name: $name \nAddress: $address \nPhone Number: $phone \n" +
                        "Latitude, Longitude: $latitude , $longitude \nIs open: $isOpenStatus \n" +
                        "Rating: $rating \nUser ratings: $userRatings"
            }
  
            override fun onError(status: Status) {
                Toast.makeText(applicationContext,"Some error occurred", Toast.LENGTH_SHORT).show()
            }
        })
  
    }
}


第 6 步:使用 MainActivity.kt(后端)

简而言之,我们所做的是:

  1. 获取我们在步骤 2 中存储的 API 密钥。
  2. 使用 API 密钥初始化 Places API。
  3. 在布局 (activity_main.xml) 中初始化了自动完成片段。
  4. 声明了我们希望从 API 获取的位置参数。
  5. 在选择侦听器事件上声明,当从自动完成栏结果中单击位置时,该事件会在布局的文本视图中发布参数。

onError函数是 select 监听器的一个成员函数,它会在失败时抛出一个 toast 消息“发生了一些错误”。一般原因可能是互联网不可用。下面是MainActivity.kt文件的代码。代码中添加了注释以更详细地理解代码。

科特林

package org.geeksforgeeks.myapplication
  
import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.TextView
import android.widget.Toast
import com.google.android.gms.common.api.Status
import com.google.android.libraries.places.api.Places
import com.google.android.libraries.places.api.model.Place
import com.google.android.libraries.places.widget.AutocompleteSupportFragment
import com.google.android.libraries.places.widget.listener.PlaceSelectionListener
  
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
  
        // Fetching API_KEY which we wrapped
        val ai: ApplicationInfo = applicationContext.packageManager
            .getApplicationInfo(applicationContext.packageName, PackageManager.GET_META_DATA)
        val value = ai.metaData["api_key"]
        val apiKey = value.toString()
  
        // Initializing the Places API 
          // with the help of our API_KEY
        if (!Places.isInitialized()) {
            Places.initialize(applicationContext, apiKey)
        }
  
        // Initialize Autocomplete Fragments 
          // from the main activity layout file
        val autocompleteSupportFragment1 = supportFragmentManager.findFragmentById(R.id.autocomplete_fragment1) as AutocompleteSupportFragment?
  
        // Information that we wish to fetch after typing 
          // the location and clicking on one of the options
        autocompleteSupportFragment1!!.setPlaceFields(
            listOf(
  
                Place.Field.NAME,
                Place.Field.ADDRESS,
                Place.Field.PHONE_NUMBER,
                Place.Field.LAT_LNG,
                Place.Field.OPENING_HOURS,
                Place.Field.RATING,
                Place.Field.USER_RATINGS_TOTAL
  
            )
        )
  
        // Display the fetched information after clicking on one of the options
        autocompleteSupportFragment1.setOnPlaceSelectedListener(object : PlaceSelectionListener {
            override fun onPlaceSelected(place: Place) {
  
                // Text view where we will
                  // append the information that we fetch
                val textView = findViewById(R.id.tv1)
  
                // Information about the place
                val name = place.name
                val address = place.address
                val phone = place.phoneNumber.toString()
                val latlng = place.latLng
                val latitude = latlng?.latitude
                val longitude = latlng?.longitude
  
                val isOpenStatus : String = if(place.isOpen == true){
                    "Open"
                } else {
                    "Closed"
                }
  
                val rating = place.rating
                val userRatings = place.userRatingsTotal
  
                textView.text = "Name: $name \nAddress: $address \nPhone Number: $phone \n" +
                        "Latitude, Longitude: $latitude , $longitude \nIs open: $isOpenStatus \n" +
                        "Rating: $rating \nUser ratings: $userRatings"
            }
  
            override fun onError(status: Status) {
                Toast.makeText(applicationContext,"Some error occurred", Toast.LENGTH_SHORT).show()
            }
        })
  
    }
}

输出:

想要一个更快节奏和更具竞争力的环境来学习 Android 的基础知识吗?
单击此处前往由我们的专家精心策划的指南,旨在让您立即做好行业准备!