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

Cách lấy tên quốc gia hiện tại từ Network Provider Android

Giới thiệu

Hướng dẫn này trình bày cách lấy tên quốc gia (country name) của vị trí hiện tại sử dụng Network Provider (mạng di động/WiFi) kết hợp 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) {
                updateCountryName();
            }
        }
    }

    @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) {
            updateCountryName();
        }
    }

    private void updateCountryName() {
        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 countryName = address.getCountryName(); textView.setText("Quốc gia: " + (countryName != null ? countryName : "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>
                

Network Provider - Đặc điểm và lưu ý

Ưu điểm

  • Nhanh: Trả về vị trí gần như tức thì (giây).
  • Tiết kiệm pin: Không dùng GPS hardware.
  • Hoạt động tốt trong nhà, thành phố đông dân cư.
  • Chỉ cần quyền ACCESS_COARSE_LOCATION (ít rườm rà hơn FINE).

Nhược điểm

  • Độ chính xác thấp: ~100m - vài km (dựa trên trạm BTS/WiFi).
  • Không hoạt động tốt vùng vắng, đường cao tốc, biển.
  • Phụ thuộc cơ sở dữ liệu Google về vị trí BTS/WiFi.
  • Cần Internet để Geocoder chuyển tọa độ thành tên quốc gia.

So sánh các Provider

ProviderQuyền cầnĐộ chính xácTốc độPinTrong nhà
NETWORK_PROVIDERCOARSE~100m-1kmNhanhThấpTốt
GPS_PROVIDERFINE~5-50mChậmCaoKém
PASSIVE_PROVIDERCOARSE/FINETheo app khácNhanh nhấtRất thấpTùy app khác
FUSED (Google Play Services)FINETốt nhấtNhanhTối ưuTốt

Cách lấy tên quốc gia TIẾNG VIỆT

Sử dụng Locale phù hợp khi tạo Geocoder:

// Tiếng Việt
Geocoder geocoderVN = new Geocoder(this, new Locale("vi", "VN"));
// -> "Việt Nam"

// Tiếng Anh
Geocoder geocoderEN = new Geocoder(this, Locale.ENGLISH);
// -> "Vietnam"

// Locale mặc định thiết bị
Geocoder geocoderDefault = new Geocoder(this, Locale.getDefault());
// -> Tùy ngôn ngữ hệ thống

Xử lý trường hợp đặc biệt

  • Vị trí biển/quốc tế: getCountryName() trả về null hoặc "International Waters".
  • Biên giới: Có thể trả về quốc gia láng giềng do độ chính xác Network Provider.
  • Không có Internet: Geocoder ném IOException - cần try-catch.
  • Android 10+: Cần quyền ACCESS_BACKGROUND_LOCATION cho vị trí nền.