Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีดึงข้อมูลเมืองจาก Network Provider ใน Android

ภาพรวม

บทความนี้สาธิตการดึงชื่อเมือง (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_PROVIDERGPS_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 โดยตรง