Computer >> 컴퓨터 >  >> 프로그래밍 >> Android

Android에서 네트워크 공급자(Network Provider)로 현재 행정 구역 가져오는 방법

이 튜토리얼에서는 Android 앱에서 네트워크 공급자(Network Provider)를 활용해 기기의 현재 위치를 파악하고, 이를 바탕으로 현재 소재 지역(행정 구역)을 화면에 표시하는 방법을 단계별로 알아봅니다.

핵심 원리는 다음과 같습니다. LocationManager의 NETWORK_PROVIDER로 마지막으로 확인된 위치(위도·경도)를 가져온 뒤, Geocoder를 사용해 해당 좌표를 주소 정보로 변환하고 그중 행정 구역(adminArea) 값을 추출하여 TextView에 출력합니다.

1단계 — 새 프로젝트 생성

Android Studio를 실행한 후 File → New Project 메뉴로 이동하여 새 프로젝트를 생성하고, 필요한 모든 세부 정보를 입력해 프로젝트 설정을 완료합니다.

2단계 — activity_main.xml 작성

다음 코드를 res/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>

위 코드에서는 현재 지역 정보를 화면에 보여주기 위한 TextView 하나를 배치했습니다.

3단계 — MainActivity.java 작성

다음 코드를 src/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 android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

import java.io.IOException;
import java.util.List;

public class MainActivity extends AppCompatActivity {
    TextView textView;
    Location location;
    double describeContents;
    List<Address> addresses;
    Geocoder geocoder;

    @RequiresApi(api = Build.VERSION_CODES.P)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        textView = findViewById(R.id.text);
        LocationManager locationManager = (LocationManager) this.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);
        }
        location = locationManager
        .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
        geocoder = new Geocoder(this);
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case 101:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        return;
                    }
                    try {
                        addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 10);
                        Address address = addresses.get(0);
                        textView.setText("" + address.getAdminArea());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                } else {
                    //not granted
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    @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) {
            return;
        }
        try {
            addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 10);
            Address address = addresses.get(0);
            textView.setText("" + address.getAdminArea());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

주요 코드 설명

  • 권한 요청: 위치 권한(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION)이 부여되지 않은 경우 requestPermissions()를 호출해 권한을 요청합니다.
  • 마지막 위치 조회: getLastKnownLocation(LocationManager.NETWORK_PROVIDER)를 통해 네트워크(Wi-Fi, 셀룰러 기지국) 기반의 마지막 알려진 위치를 가져옵니다.
  • 역지오코딩(Geocoding): Geocoder.getFromLocation()에 위도와 경도를 전달하면 해당 좌표에 대응하는 주소 목록을 반환받습니다.
  • 행정 구역 표시: 반환된 첫 번째 Address 객체에서 getAdminArea()를 호출하여 시·도 단위의 행정 구역 이름을 TextView에 출력합니다.

4단계 — AndroidManifest.xml 권한 추가

다음 코드를 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.INTERNET"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <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>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

Geocoder가 온라인 서비스를 통해 좌표를 주소로 변환하므로 INTERNET 권한이 필수이며, 위치 접근을 위해 ACCESS_COARSE_LOCATION 권한도 함께 선언해야 합니다.

앱 실행 및 결과 확인

이제 애플리케이션을 실행해 보겠습니다. 실제 Android 스마트폰이 컴퓨터에 연결되어 있다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤 툴바의 Run(실행) 아이콘을 클릭하세요. 실행 대상 기기 목록에서 본인의 모바일 기기를 선택하면, 앱이 기기에 설치되어 실행됩니다.

앱이 실행되면 위치 권한 허용 여부를 묻는 대화상자가 나타나며, 권한을 허용하면 아래 이미지와 같이 화면에 현재 소재 지역(행정 구역)이 표시됩니다.

Android에서 네트워크 공급자(Network Provider)로 현재 행정 구역 가져오는 방법