Yêu cầu quyền truy cập thông tin vị trí dựa trên phiên bằng nút vị trí

Nút vị trí trên Android là một phần tử trên giao diện người dùng hệ thống có thể tuỳ chỉnh, được thiết kế để đơn giản hoá cách bạn yêu cầu quyền truy cập thông tin vị trí chính xác ở phạm vi phiên. Bằng cách bắt đầu các yêu cầu vị trí thông qua hành động trực tiếp của người dùng, nút này giúp cải thiện quyền riêng tư của người dùng và giảm bớt sự phiền hà của các hộp thoại cấp quyền lặp đi lặp lại thường gặp khi cấp quyền tạm thời "Chỉ lần này".

Nếu ứng dụng của bạn nhắm đến Android 17 (cấp độ API 37) trở lên và chỉ chứa các tính năng yêu cầu quyền truy cập thông tin vị trí dựa trên phiên để hoạt động, thì chính sách của Google Play yêu cầu bạn phải sử dụng nút vị trí. Để biết thêm chi tiết, hãy xem chính sách về nút vị trí.

Ảnh minh hoạ luồng trong ứng dụng của nút vị trí
Hình 1. Minh hoạ luồng người dùng của nút vị trí.

Thời điểm sử dụng nút vị trí

Hãy sử dụng nút vị trí cho các tính năng yêu cầu quyền truy cập thông tin vị trí chính xác theo phiên và tức thời. Đây là lựa chọn lý tưởng cho những ứng dụng không yêu cầu quyền truy cập thông tin vị trí liên tục và nhằm mục đích giảm bớt lời nhắc cấp quyền "Chỉ lần này" lặp đi lặp lại.

Các trường hợp sử dụng phổ biến bao gồm:

  • Các chức năng "Tìm kiếm gần tôi": Tìm khách sạn, cửa hàng hoặc nhà hàng ở gần.
  • Chia sẻ vị trí: Chia sẻ vị trí hiện tại của bạn một lần với bạn bè hoặc gia đình.
  • Mạng xã hội: Đăng ký hoặc gắn thẻ vị trí.
  • Thương mại điện tử: Tự động điền địa chỉ giao hàng.

Tuỳ chỉnh giao diện người dùng

Để đảm bảo nút này phù hợp với tính thẩm mỹ của ứng dụng mà vẫn dễ nhận biết, bạn có thể sửa đổi các phần tử hình ảnh sau:

  • Bảng phối màu nền và biểu tượng.
  • Kiểu, kích thước và hình dạng đường viền.
  • Nhãn văn bản trong danh sách được xác định trước (ví dụ: "Sử dụng vị trí chính xác", "Chia sẻ vị trí chính xác").
Nút Vị trí minh hoạ các lựa chọn tuỳ chỉnh
Hình 2. Ví dụ về các lựa chọn tuỳ chỉnh nút vị trí.

Triển khai nút vị trí

Để tích hợp nút vị trí, hãy sử dụng Thư viện Jetpack. Thư viện này giúp đơn giản hoá quá trình thiết lập, xử lý quá trình kết xuất an toàn trên các nền tảng mới hơn và cung cấp giải pháp dự phòng cho các ứng dụng nhắm đến Android 16 trở xuống.

Bước 1: Khai báo quyền trong Tệp kê khai Android

Bạn phải khai báo các quyền vị trí tiêu chuẩn cùng với quyền USE_LOCATION_BUTTON dành riêng mà dịch vụ kết xuất từ xa của hệ thống yêu cầu.

<?xml version="1.0" encoding="utf-8"?>
<!--
     Copyright 2026 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          https://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android">

    <!-- 1. Standard Coarse and Fine Location Permissions -->
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <!-- Optional: If your app is only using the location button to access 
    location, you should add the "onlyForLocationButton" flag shown below to
    your ACCESS_FINE_LOCATION declaration.

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" 
    android:usesPermissionFlags="onlyForLocationButton"/>

    Note: Adding this flag restricts your app from accessing the precise 
    location permission via the broader permission, and that users will be 
    required to use the location button in order to share precise location with 
    the app. This is designed to improve user privacy & trust when granting location access.
    -->

    <!-- 2. CRITICAL: Required system permission for rendering the LocationButton -->
    <uses-permission android:name="android.permission.USE_LOCATION_BUTTON" />

    <application
        android:icon="@mipmap/ic_launcher"
        android:label="LocationButtonSample"
        android:theme="@style/Theme.PinPoint">
        <activity
            android:name=".MainActivity"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Bước 2: Triển khai thành phần kết hợp Kotlin

Sau đây là ví dụ về cách triển khai nút vị trí, bao gồm cả ví dụ về cách sử dụng các lựa chọn tuỳ chỉnh hiện có mà bạn có thể dùng để làm cho giao diện người dùng phù hợp với phần còn lại của ứng dụng.

import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
import androidx.core.locationbutton.compose.LocationButton
import androidx.core.locationbutton.compose.LocationButtonTextType

@Composable
fun LocationPermissionScreen(onPermissionGranted: () -> Unit, onPermissionDenied: () -> Unit) {
    // Renders the secure system-trusted Location Button composable
    LocationButton(
        // Callback triggered when the user taps the secure button and makes a decision on the permission dialog
        onPermissionResult = { isGranted ->
            if (isGranted) {
                onPermissionGranted()
            } else {
                onPermissionDenied()
            }
        },
        /* ============================================================================
         * VISUAL CUSTOMIZATIONS
         * Un-comment any of the parameters below to customize the button's aesthetics.
         * If omitted, the button falls back to secure, high-contrast system defaults.
         * ============================================================================ */
        /*
        // LABEL TEXT TYPE:
        // Predefined system strings rendered inside the secure process.
        // Options: PreciseLocation, UsePreciseLocation, SharePreciseLocation,
        // NearMyPreciseLocation, or None (for an icon-only button).
        textType = LocationButtonTextType.UsePreciseLocation,

        // COLOR PALETTE:
        // Customize the container background, text label, and icon tint colors.
        backgroundColor = Color(0xFF00796B), // e.g., Material Teal
        textColor = Color.White,
        iconTint = Color(0xFFFFC107),        // e.g., Amber icon tint

        // CORNER RADIUS & SHAPE:
        // Define the resting corner radius and the morphed radius when pressed.
        cornerRadius = 24.dp,        // Rounded capsule shape
        pressedCornerRadius = 12.dp, // Morphs to sharper corners on tap

        // OUTLINE STROKE (BORDERS):
        // Add a contrasting outline stroke around the button bounds.
        strokeColor = Color(0xFF004D40),
        strokeWidth = 2.dp,

        // INTERACTIVE TOUCH PADDING:
        // Defines the secure clickable touch target boundary.
        // Coerced securely by the system between 4.dp and 8.dp.
        clickablePadding = PaddingValues(6.dp)
        */
    )
}

Bước 3: Xử lý khả năng tương thích ngược

Thư viện Jetpack tự động xử lý khả năng tương thích ngược trên các phiên bản Android thấp hơn. Trên các thiết bị chạy Android 16 trở xuống, thư viện sẽ quay lại một thành phần được kết xuất cục bộ giúp giữ nguyên bố cục trực quan đã tuỳ chỉnh nhưng quay lại kích hoạt lời nhắc cấp quyền truy cập thông tin vị trí tiêu chuẩn.

Khi sử dụng phương pháp này, bạn có thể tận dụng các lợi ích của việc áp dụng nút vị trí mà không cần duy trì một giải pháp song song cho các thiết bị chạy Android 16 trở xuống.