Android餐厅配送系统:如何借助Google Maps API计算配送距离与费用
Perfect question—you'll want to use the Google Maps Distance Matrix API for this task. It’s built specifically to calculate travel distances (and durations) between origin and destination points, which is exactly what you need to determine if the delivery falls under your 8km threshold.
Here’s a step-by-step breakdown of how to implement this in your Android app:
1. Enable the API & Secure Your Key
First, set up access to the API via the Google Cloud Console:
- Create a new project (or use your existing one)
- Search for "Distance Matrix API" and enable it
- Generate an API key, then restrict it to your Android app (using your app’s package name and SHA-1 fingerprint) to prevent unauthorized usage.
2. Add Dependencies
We’ll use OkHttp (a lightweight HTTP client) to make the API call. Add this to your module-level build.gradle file:
implementation 'com.squareup.okhttp3:okhttp:4.11.0'
3. Fetch Distance Between Restaurant & User Address
Create a suspend function to call the API (using Kotlin Coroutines for safe background execution):
import okhttp3.OkHttpClient import okhttp3.Request import org.json.JSONObject import java.net.URLEncoder import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext suspend fun getDeliveryDistance( restaurantAddress: String, userAddress: String, apiKey: String ): Double? { return withContext(Dispatchers.IO) { val client = OkHttpClient() // Encode addresses to handle spaces and special characters val encodedOrigin = URLEncoder.encode(restaurantAddress, "UTF-8") val encodedDestination = URLEncoder.encode(userAddress, "UTF-8") val apiUrl = "https://maps.googleapis.com/maps/api/distancematrix/json" + "?origins=$encodedOrigin" + "&destinations=$encodedDestination" + "&mode=driving" // Use driving route for delivery "&units=metric" // Returns distance in kilometers/meters "&key=$apiKey" val request = Request.Builder().url(apiUrl).build() try { client.newCall(request).execute().use { response -> if (!response.isSuccessful) throw Exception("API call failed: ${response.code}") val jsonResponse = JSONObject(response.body?.string() ?: "") val rows = jsonResponse.getJSONArray("rows") // Validate response structure if (rows.length() == 0) return@withContext null val elements = rows.getJSONObject(0).getJSONArray("elements") if (elements.length() == 0) return@withContext null val element = elements.getJSONObject(0) val status = element.getString("status") if (status != "OK") { // Handle cases like NO_ROUTE or NOT_FOUND return@withContext null } // Convert meters to kilometers val distanceObj = element.getJSONObject("distance") val distanceInMeters = distanceObj.getInt("value") distanceInMeters / 1000.0 } } catch (e: Exception) { e.printStackTrace() null } } }
4. Calculate Delivery Fee Using the Distance
Call the function from your activity/fragment (using lifecycleScope to tie coroutines to the UI lifecycle):
lifecycleScope.launch { val apiKey = BuildConfig.MAPS_API_KEY // Store key in local.properties, access via BuildConfig val restaurantAddress = "123 Main St, Your City" // Replace with your restaurant's address val userAddress = userDeliveryAddressInput.text.toString() // Get user's address from input val distanceKm = getDeliveryDistance(restaurantAddress, userAddress, apiKey) distanceKm?.let { val deliveryFee = if (it <= 8.0) { // Your 8km-or-under fee (e.g., $5.00) 5.00 } else { // Your over-8km fee (e.g., $10.00) 10.00 } // Update UI to show the calculated fee deliveryFeeTextView.text = "Delivery Fee: $$deliveryFee" } ?: run { // Handle error: show message to user if distance can't be calculated deliveryFeeTextView.text = "Unable to calculate delivery fee" } }
Key Tips
- API Key Security: Never hardcode your key directly in code. Add it to
local.properties(e.g.,MAPS_API_KEY=your_key_here) and reference it inbuild.gradleto generate it inBuildConfig. - Billing: The Distance Matrix API is a paid service—monitor your usage in the Google Cloud Console to avoid unexpected charges.
- Error Handling: Account for edge cases like unreachable addresses or invalid inputs to keep your app user-friendly.
内容的提问来源于stack exchange,提问作者Aman Patnayak




