Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Android

Cách lấy khu vực hành chính (tỉnh/thành) từ Network Provider Android

Giới thiệu

Hướng dẫn này trình bày cách lấy thông tin khu vực hành chính cấp tỉnh/thành phố (Administrative Area - State/Province) từ vị trí Network Provider sử dụng Geocoder trên Android.

Các bước thực hiện

Bước 1: Tạo dự án mới

Tạo dự án Android Studio: File → New Project.

Bước 2: Layout activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:gravity="center"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/text"
        android:textSize="30sp"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>

Bước 3: MainActivity.java

package com.example.myapplication;

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.widget.TextView;
import java.io.IOException;
import java.util.List;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {

    TextView textView;
    Location location;
    Geocoder geocoder;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.text);

        LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
                != PackageManager.PERMISSION_GRANTED 
                && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) 
                != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, 
                new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 101);
            return;
        }

        location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        geocoder = new Geocoder(this, Locale.getDefault());
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 101) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                updateAdminArea();
            }
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
                == PackageManager.PERMISSION_GRANTED 
                || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) 
                == PackageManager.PERMISSION_GRANTED) {
            updateAdminArea();
        }
    }

    private void updateAdminArea() {
        if (location == null) {
            textView.setText("Không lấy được vị trí từ Network Provider");
            return;
        }
        
        try {
            List
addresses = geocoder.getFromLocation( location.getLatitude(), location.getLongitude(), 1); if (addresses != null && !addresses.isEmpty()) { Address address = addresses.get(0); String adminArea = address.getAdminArea(); textView.setText("Khu vực hành chính: " + (adminArea != null ? adminArea : "Không xác định")); } else { textView.setText("Không tìm thấy địa chỉ từ vị trí này"); } } catch (IOException e) { e.printStackTrace(); textView.setText("Lỗi Geocoder: " + e.getMessage()); } } }

Bước 4: AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.example.myapplication">

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                

Giải thích getAdminArea()

Admin Area là gì?

Address.getAdminArea() trả về tên đơn vị hành chính cấp 1 (State/Province/Region) - tương đương Tỉnh/Thành phố trực thuộc Trung ương tại Việt Nam.

Ví dụ tại Việt Nam

Vị trígetAdminArea()getLocality() (City)getSubLocality() (District)
Quận 1, TP.HCMHồ Chí MinhHồ Chí MinhQuận 1
Quận Ba Đình, Hà NộiHà NộiHà NộiBa Đình
TP. Đà NẵngĐà NẵngĐà NẵngHải Châu
TP. Cần ThơCần ThơCần ThơNinh Kiều
Tỉnh Bình DươngBình DươngThủ Dầu MộtThủ Dầu Một

Ví dụ quốc tế

  • California, USA → AdminArea: "California", Locality: "Los Angeles"
  • Tokyo, Japan → AdminArea: "Tokyo", Locality: "Tokyo" (Tokyo là cả prefecture lẫn city)
  • London, UK → AdminArea: "England", Locality: "London"
  • Sydney, Australia → AdminArea: "New South Wales", Locality: "Sydney"

Cấu trúc địa chỉ đầy đủ (Address components)

Address address = addresses.get(0);

String countryName   = address.getCountryName();     // Quốc gia: "Vietnam"
String countryCode   = address.getCountryCode();     // Mã quốc gia: "VN"
String adminArea     = address.getAdminArea();       // Tỉnh/Thành: "Hồ Chí Minh"
String subAdminArea  = address.getSubAdminArea();    // Huyện/Quận cấp 2: "Quận 1" (ít dùng)
String locality      = address.getLocality();        // Thành phố: "Hồ Chí Minh"
String subLocality   = address.getSubLocality();     // Quận/Huyện: "Quận 1"
String thoroughfare  = address.getThoroughfare();    // Đường: "Nguyễn Huệ"
String subThoroughfare = address.getSubThoroughfare(); // Số nhà: "123"
String postalCode    = address.getPostalCode();      // Mã bưu chính: "700000"
String featureName   = address.getFeatureName();     // Tên địa điểm: "Bến Thành Market"

Độ chính xác Network Provider cho Admin Area

Khu vựcĐộ chính xác Admin AreaGhi chú
Thành phố lớn (HN, HCM, ĐN)Cao (>90%)Mật độ BTS/WiFi cao
Tỉnh thành vùng đồng bằngTrung bình (70-85%)Phụ thuộc infrastructure
Vùng núi, vùng sâuThấp (<50%)BTS thưa, có thể ra tỉnh láng giềng
Biên giới quốc giaRất thấpDễ nhầm lẫn quốc gia

Lưu ý quan trọng

  • Geocoder cần Internet, kết quả phụ thuộc dữ liệu Google.
  • Network Provider không chính xác bằng GPS - chỉ dùng khi không cần độ chính xác cao.
  • Cân nhắc FusedLocationProviderClient (Google Play Services) cho kết quả tốt hơn.
  • Xử lý null cho tất cả các trường Address - nhiều trường có thể null.
  • Từ Android 10+, cần ACCESS_BACKGROUND_LOCATION cho vị trí nền.