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

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

개요

이 튜토리얼에서는 Android에서 네트워크 공급자(Network Provider)가 제공하는 위치 정보를 활용해 현재 도시 이름을 가져오는 방법을 단계별로 살펴봅니다. 네트워크 공급자는 Wi-Fi나 이동통신 기지국을 기반으로 위치를 파악하기 때문에 GPS보다 빠르게 응답하며, 실내 환경에서도 동작한다는 장점이 있습니다.

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.getLocality());
            } 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.getLocality());
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

핵심 로직 정리

  • LocationManagerNETWORK_PROVIDER를 통해 마지막으로 알려진 위치를 가져옵니다.
  • 위치 권한(ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION)이 부여되지 않은 경우 요청 코드 101로 권한을 요청하고, 결과는 onRequestPermissionsResult()에서 처리합니다.
  • Geocoder.getFromLocation() 메서드로 위도·경도 값을 주소 목록으로 변환한 뒤, 첫 번째 주소의 getLocality()를 호출해 도시 이름을 추출하여 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>

매니페스트에는 대략적 위치 권한인 ACCESS_COARSE_LOCATION, Geocoder 사용 시 필요한 INTERNET, 그리고 READ_PHONE_STATE 권한을 선언했습니다.

실행 결과 확인

이제 애플리케이션을 실행해 보겠습니다. 실제 Android 기기가 컴퓨터에 연결되어 있다고 가정합니다. Android Studio에서 프로젝트의 액티비티 파일 중 하나를 연 뒤 툴바의 실행(Run)Android에서 네트워크 공급자(Network Provider)로 현재 도시 정보 가져오는 방법 아이콘을 클릭하세요. 실행 기기 목록에서 자신의 모바일 기기를 선택하면, 기기 화면에 아래와 같이 현재 도시 정보가 표시됩니다.

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