Giới thiệu
Hướng dẫn này trình bày cách thay đổi mã quốc gia (country code) trong đối tượng Address thông qua Geocoder. Tương tự như thay đổi tên quốc gia, thao tác này chỉ ảnh hưởng đến đối tượng Address trong bộ nhớ.
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) {
updateCountryCode();
}
}
}
@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) {
updateCountryCode();
}
}
private void updateCountryCode() {
if (location == null) {
textView.setText("Không lấy được vị trí");
return;
}
try {
List addresses = geocoder.getFromLocation(
location.getLatitude(), location.getLongitude(), 1);
if (addresses != null && !addresses.isEmpty()) {
Address address = addresses.get(0);
// THAY ĐỔI MÃ QUỐC GIA (ISO 3166-1 alpha-2)
address.setCountryCode("VN"); // Vietnam
// address.setCountryCode("US"); // United States
// address.setCountryCode("KR"); // Korea (như code gốc)
// address.setCountryCode("JP"); // Japan
textView.setText("Mã quốc gia (đã sửa): " + address.getCountryCode());
textView.append("\nTên quốc gia: " + address.getCountryName());
}
} catch (IOException e) {
e.printStackTrace();
textView.setText("Lỗi: " + 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 quan trọng
address.setCountryCode() làm gì?
- Chỉ thay đổi trường
countryCode(mã ISO 3166-1 alpha-2) trong đối tượngAddresscục bộ. - KHÔNG thay đổi cài đặt vùng (region) của thiết bị, không ảnh hưởng Google Play Store, không đổi ngôn ngữ.
- Mã quốc gia phải tuân thủ chuẩn ISO 3166-1 alpha-2 (2 chữ cái in hoa: VN, US, JP, KR, CN, DE, FR...).
Phân biệt Country Code vs Region/Locale
| Khái niệm | Mô tả | Ví dụ |
|---|---|---|
| Country Code (ISO 3166) | Mã 2 chữ cái quốc gia | VN, US, JP, KR |
| Locale (Language + Region) | Ngôn ngữ + vùng văn hóa | vi_VN, en_US, ja_JP, ko_KR |
| Region Setting (Android) | Cài đặt vùng của hệ thống | Anh hưởng format ngày/giờ, tiền tệ |
| MCC/MNC (SIM) | Mã mạng di động | 452 02 (Viettel VN) |
Cách THỰC SỰ thay đổi region/locale ứng dụng
// Thay đổi locale trong app (API 24+)
public void setAppLocale(String languageCode, String countryCode) {
Locale locale = new Locale(languageCode, countryCode);
Locale.setDefault(locale);
Configuration config = getResources().getConfiguration();
config.setLocale(locale);
getResources().updateConfiguration(config, getResources().getDisplayMetrics());
// Cần recreate() Activity để áp dụng
recreate();
}
Lưu ý
- Geocoder cần Internet, kết quả phụ thuộc dữ liệu Google Maps.
- setCountryCode() không validate mã nhập vào - nhập sai vẫn được nhưng không có ý nghĩa.
- Để lấy MCC/MNC (mã nhà mạng thực tế từ SIM):
TelephonyManager.getNetworkOperator().