ภาพรวม
บทความนี้สาธิตการดึงชื่อเมือง (City) จากตำแหน่งที่ตั้งผ่าน Network Provider (Wi-Fi/Cell Tower) โดยใช้ LocationManager และ Geocoder แปลงพิกัดเป็นที่อยู่
Permissions ที่ต้องการ
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.INTERNET"/> <!-- Geocoder ต้องการเน็ต -->
โค้ดหลัก (MainActivity.java)
public class MainActivity extends AppCompatActivity {
private TextView textView;
private Location location;
private 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);
// ขออนุญาต Location
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;
}
// ดึงตำแหน่งจาก Network Provider
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
geocoder = new Geocoder(this);
if (location != null) {
updateCityName();
}
}
private void updateCityName() {
try {
List addresses = geocoder.getFromLocation(
location.getLatitude(), location.getLongitude(), 1);
if (!addresses.isEmpty()) {
Address address = addresses.get(0);
String city = address.getLocality(); // ชื่อเมือง
textView.setText(city != null ? city : "Unknown");
}
} catch (IOException e) {
e.printStackTrace();
textView.setText("Error: " + e.getMessage());
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 101 && grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted - ดึงตำแหน่งใหม่
LocationManager lm = (LocationManager) getSystemService(LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
location = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
updateCityName();
}
}
}
@Override
protected void onResume() {
super.onResume();
if (location != null) updateCityName();
}
}
Network Provider vs GPS Provider
| คุณสมบัติ | NETWORK_PROVIDER | GPS_PROVIDER |
|---|---|---|
| ความแม่นยำ | ประมาณ 100-1000 เมตร | ประมาณ 5-20 เมตร |
| ความเร็ว | รวดเร็ว (ไม่ต้องรอ GPS Lock) | ช้า (ต้อง Lock ดาวเทียม) |
| การใช้พลังงาน | ต่ำ | สูง |
| ทำงานภายในอาคาร | ได้ดี | ไม่ได้/ยาก |
| ต้องการอินเทอร์เน็ต | ใช่ (ส่งข้อมูล Wi-Fi/Cell ID ไป Server) | ไม่จำเป็น |
Geocoder.getFromLocation() พารามิเตอร์
getFromLocation(double latitude, double longitude, int maxResults)
maxResults: จำนวนผลลัพธ์สูงสุด (แนะนำ 1-5)- คืนค่า
Listเรียงตามความน่าจะเป็น - ต้องการอินเทอร์เน็ตเพื่อ Query Server
Address Fields ที่ใช้บ่อย
getLocality()- เมือง/เทศบาลgetSubLocality()- เขต/แขวง/ตำบลgetAdminArea()- จังหวัด/รัฐgetCountryName()- ชื่อประเทศgetPostalCode()- รหัสไปรษณีย์getAddressLine(0)- ที่อยู่เต็มบรรทัดแรก
ข้อจำกัดและแนวทางแก้
- Geocoder อาจล้มเหลวหรือคืนค่าว่าง -> ใช้
Geocoder.isPresent()ตรวจสอบก่อน - มี Rate Limit -> ควร Cache ผลลัพธ์
- Android 10+ ต้องการ Foreground Service สำหรับ Location ในพื้นหลัง
- แนะนำใช้ FusedLocationProviderClient (Google Play Services) แทน LocationManager โดยตรง