메뉴 건너뛰기

조회 수 2436 추천 수 0 댓글 0
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 첨부
?

단축키

Prev이전 문서

Next다음 문서

크게 작게 위로 아래로 댓글로 가기 인쇄 첨부

 

[ 실행화면 설명 ]

1. 최근위치1 텍스트로 가장 최근에 GPS 지점을 화면에 표시해준다. 

마커 이미지 화면표시, 1Km 반경 원표시 기능

2. 인공위성 GPS 연동될 경우에 매초마다 현재 위치가 자동 화면 중앙에 표시된다.

마커와 반경이 자동이동된다.

 

 

 

 

 

[ activity_main.xml ] - xml 디자인구성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
 
    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" android:text="현재위치 확인하기"/>
 
    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
 
    <Button
        android:id="@+id/button2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" android:text="구글지도맵 내위치"/>
 
    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.SupportMapFragment"/>
 
</LinearLayout>
cs

위의 xml 디자인페이지의 핵심은 button2를 클릭할 경우 fragment 형태로 현재 GPS 위치가 실시간으로 화면에 보여준다.

 

[ build.gradle ( Module: app ) ] 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
allprojects {
    repositories {
        maven { url 'https://jitpack.io' }
    }
}
 
dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.1'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
    implementation 'com.github.pedroSG94:AutoPermissions:1.0.3'
    implementation 'com.google.android.gms:play-services-maps:17.0.0'
}
cs

14라인은 AutoPermissions 라이브러리를 이용하여 권한기능을 자동화하기 위해 추가했다.

15라인은 구글 GPS 연동을 위해 꼭 추가했다.

 

또한 구글맵 연동을 위하여 구글 콘솔 페이지에서 구글 API키 발급받도록 하자.

https://console.developers.google.com/

 

 

[ AndroidManifest.xml ] - 안드로이드 환경설정부분

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="wonpa.alwaysweb.com.myloctest">
    <permission android:name="wonpa.alwaysweb.com.myloctest.permission.MAPS_RECEIVE"
        android:protectionLevel="signature" />
 
    <uses-permission android:name="wonpa.alwaysweb.com.myloctest.permission.MAPS_RECEIVE" />
 
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
 
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
 
    <uses-feature
        android:glEsVersion="0x00020000"
        android:required="true"/>
 
    <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">
        <uses-library android:name="com.google.android.maps" />
        <uses-library
            android:name="org.apache.http.legacy"
            android:required="false" />
 
        <meta-data
            android:name="com.google.android.maps.v2.API_KEY"
            android:value="구글계정api키값" />
 
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
 
        <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>
cs

위의 manifest 소스에서 12라인, 13라인이 GPS 연동을 위해 꼭 추가해야 하는 부분이다.

[ 인공위성 GPS 연동 ] - 현재위치가 정확하나, 실내에서는 회신이 잘 되지 않는 단점이 있다.

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

[ 기지국을 통한 GPS 연동 ]

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

 

[ MainActivity.java ]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
package wonpa.alwaysweb.com.myloctest;
 
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
 
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
 
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapsInitializer;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.Circle;
import com.google.android.gms.maps.model.CircleOptions;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import com.pedro.library.AutoPermissions;
import com.pedro.library.AutoPermissionsListener;
 
public class MainActivity extends AppCompatActivity implements AutoPermissionsListener {
    private Button button1, button2;
    private TextView textView1;
    LocationManager manager;
    GPSListener gpsListener;
 
    SupportMapFragment mapFragment;
    GoogleMap map;
 
    Marker myMarker;
    MarkerOptions myLocationMarker;
    Circle circle;
    CircleOptions circle1KM;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        setTitle("GPS 현재위치 확인하기");
 
        button1 = findViewById(R.id.button1);
        button2 = findViewById(R.id.button2);
        textView1 = findViewById(R.id.textView1);
 
        manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        gpsListener = new GPSListener();
 
        try {
            MapsInitializer.initialize(this);
        } catch (Exception e) {
            e.printStackTrace();
        }
 
        mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap googleMap) {
                Log.i("MyLocTest","지도 준비됨");
                map = googleMap;
                map.setMyLocationEnabled(true);
            }
        });
 
        // 최초 지도 숨김
        mapFragment.getView().setVisibility(View.GONE);
 
        button2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
 
                // 지도 보임
                mapFragment.getView().setVisibility(View.VISIBLE);
                startLocationService();
            }
        });
 
        AutoPermissions.Companion.loadAllPermissions(this101);
    }
 
    public void startLocationService() {
        try {
            Location location = null;
 
            long minTime = 0;        // 0초마다 갱신 - 바로바로갱신
            float minDistance = 0;
 
            if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                location = manager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
 
                if (location != null) {
                    double latitude = location.getLatitude();
                    double longitude = location.getLongitude();
                    String message = "최근 위치1 -> Latitude : " + latitude + "\n Longitude : " + longitude;
 
                    textView1.setText(message);
                    showCurrentLocation(latitude, longitude);
                    Log.i("MyLocTest""최근 위치1 호출");
                }
 
                //위치 요청하기
                manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTime, minDistance, gpsListener);
                //manager.removeUpdates(gpsListener);
                Toast.makeText(getApplicationContext(), "내 위치1확인 요청함", Toast.LENGTH_SHORT).show();
                Log.i("MyLocTest""requestLocationUpdates() 내 위치1에서 호출시작 ~~ ");
 
            } else if (manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
 
                location = manager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                if (location != null) {
                    double latitude = location.getLatitude();
                    double longitude = location.getLongitude();
                    String message = "최근 위치2 -> Latitude : " + latitude + "\n Longitude : " + longitude;
 
                    textView1.setText(message);
                    showCurrentLocation(latitude,longitude);
 
                    Log.i("MyLocTest","최근 위치2 호출");
                }
 
 
                //위치 요청하기
                manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, minTime, minDistance, gpsListener);
                //manager.removeUpdates(gpsListener);
                Toast.makeText(getApplicationContext(), "내 위치2확인 요청함", Toast.LENGTH_SHORT).show();
                Log.i("MyLocTest","requestLocationUpdates() 내 위치2에서 호출시작 ~~ ");
            }
 
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }
 
 
    class GPSListener implements LocationListener {
 
        // 위치 확인되었을때 자동으로 호출됨 (일정시간 and 일정거리)
        @Override
        public void onLocationChanged(Location location) {
            double latitude = location.getLatitude();
            double longitude = location.getLongitude();
            String message = "내 위치는 Latitude : " + latitude + "\nLongtitude : " + longitude;
            textView1.setText(message);
 
            showCurrentLocation(latitude,longitude);
            Log.i("MyLocTest","onLocationChanged() 호출되었습니다.");
        }
 
        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
 
        }
 
        @Override
        public void onProviderEnabled(String provider) {
 
        }
 
        @Override
        public void onProviderDisabled(String provider) {
 
        }
    }
 
    @Override
    protected void onResume() {
        super.onResume();
 
        // GPS provider를 이용전에 퍼미션 체크
        if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    Activity#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for Activity#requestPermissions for more details.
            Toast.makeText(getApplicationContext(),"접근 권한이 없습니다.",Toast.LENGTH_SHORT).show();
            return;
        } else {
 
            if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 00, gpsListener);
                //manager.removeUpdates(gpsListener);
            } else if (manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
                manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 00, gpsListener);
                //manager.removeUpdates(gpsListener);
            }
 
            if (map != null) {
                map.setMyLocationEnabled(true);
            }
            Log.i("MyLocTest","onResume에서 requestLocationUpdates() 되었습니다.");
        }
    }
 
    @Override
    protected void onPause() {
        super.onPause();
        manager.removeUpdates(gpsListener);
 
        if (map != null) {
            map.setMyLocationEnabled(false);
        }
        Log.i("MyLocTest","onPause에서 removeUpdates() 되었습니다.");
    }
 
    private void showCurrentLocation(double latitude, double longitude) {
        LatLng curPoint = new LatLng(latitude, longitude);
        map.animateCamera(CameraUpdateFactory.newLatLngZoom(curPoint, 15));
        showMyLocationMarker(curPoint);
    }
 
    private void showMyLocationMarker(LatLng curPoint) {
        if (myLocationMarker == null) {
            myLocationMarker = new MarkerOptions(); // 마커 객체 생성
            myLocationMarker.position(curPoint);
            myLocationMarker.title("최근위치 \n");
            myLocationMarker.snippet("*GPS로 확인한 최근위치");
            myLocationMarker.icon(BitmapDescriptorFactory.fromResource((R.drawable.mylocation)));
            myMarker = map.addMarker(myLocationMarker);
        } else {
            myMarker.remove(); // 마커삭제
            myLocationMarker.position(curPoint);
            myMarker = map.addMarker(myLocationMarker);
        }
 
        // 반경추가
        if (circle1KM == null) {
            circle1KM = new CircleOptions().center(curPoint) // 원점
                    .radius(1000)       // 반지름 단위 : m
                    .strokeWidth(1.0f);    // 선너비 0f : 선없음
            //.fillColor(Color.parseColor("#1AFFFFFF")); // 배경색
            circle = map.addCircle(circle1KM);
 
        } else {
            circle.remove(); // 반경삭제
            circle1KM.center(curPoint);
            circle = map.addCircle(circle1KM);
        }
 
 
    }
 
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        AutoPermissions.Companion.parsePermissions(this, requestCode, permissions, this);
        Toast.makeText(this"requestCode : "+requestCode+"  permissions : "+permissions+"  grantResults :"+grantResults, Toast.LENGTH_SHORT).show();
    }
 
    @Override
    public void onDenied(int requestCode, String[] permissions) {
        Toast.makeText(getApplicationContext(),"permissions denied : " + permissions.length, Toast.LENGTH_SHORT).show();
    }
 
    @Override
    public void onGranted(int requestCode, String[] permissions) {
        Toast.makeText(getApplicationContext(),"permissions granted : " + permissions.length, Toast.LENGTH_SHORT).show();
    }
}
 
cs

일단 AutoPermissionsListener 를 implement 하여 권한기능을 좀더 편하게 할 수 있도록 하였다.

259라인부터 273라인까지의 메소드 오버라이딩하여 구현하였다.

 

59라인에서

LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

LocationManager 객체인 manager 를 구했고, 이를 바탕으로

 

81라인의 button2 를 클릭하면 startLocationService() 함수가 동작한다. 이 메소드 안의 핵심은 115라인

long minTime = 1000; // 1초,

minTime = 0;            //  매초마다

float minDistance = 0; // 0 m 거리이동시마다.

 

manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, minTime, minDistance, gpsListener); 

이부분이다. 

 

gpsListener 는 148라인의 GPSListener 의 객체를 삽입하였다. 

GPSListener 의 152라인에서 onLocationChanged() 함수를 통하여 위치가 확인되고 변경되는 새로운 Location location 값을 콜백받게 되고 이를 통해 매번 새로운 위치값을 받을 수 있다. 

 

또한 236라인처럼

myMarker.remove(); // 마커삭제  

이미 객체가 생성되어 있을 경우에 일단 그 마커를 삭제하고 새롭게 변경된 위치에 마커가 표시될 수 있도록 하였다.

 

마찬가지로 현재위치점에서 1Km 반경에 해당하는 새로운 원이 250라인처럼 

circle.remove(); // 반경삭제 

기존의 반경관련 객체가 있을 경우에 삭제하고 새로운 위치점을 기준으로 새반경이 나타나도록 하였다.

 


List of Articles
번호 제목 날짜 조회 수
197 안드로이드 - 프레임레이아웃 (FrameLayout) file 2021.03.29 507
196 안드로이드 - 랠러티브 레이아웃(Relative Layout) file 2021.03.29 239
195 안드로이드 - 리니어 레이아웃 (Linear Layout) file 2021.03.29 319
194 안드로이드 스튜디오 - 코드 자동 들여쓰기 file 2021.03.29 419
193 안드로이드 스튜디오 - 필수 재정의 함수 자동 코드 추가 file 2021.03.29 194
192 안드로이드 스튜디오 - getter/setter 메소드 자동생성 file 2021.03.29 583
191 안드로이드 스튜디오 - 싱글톤 패턴 (SingleTon Pattenr) 클래스 자동 생성 file 2021.03.29 614
190 안드로이드 unescape /escape [StringEscapeUtils로 해결] file 2021.03.29 344
189 안드로이드 arrayList 를 Json으로 변환 / jsonarry file 2021.03.29 326
188 Apk manager 이용해 Decompile (디컴파일) 하기 file 2021.03.16 1619
187 안드로이드 입문 연습문제 3문항 - CheckBox, RadioButton, EditText, Spinner, 이벤트연습 file 2020.12.14 480
186 안드로이드 앱배포하기 apk 만들기 file 2020.12.14 324
185 초기화면 페이지를 만들어보자. splash 페이지 제작 file 2020.12.14 284
184 ListView 리스트뷰 연습3 - 커스텀 리스트뷰 (Custom ListView) file 2020.12.14 906
183 하이브리드앱 기본 - WebView로 웹페이지 띄우기 file 2020.12.14 1025
182 패키지명을 한꺼번에 변경하기 (Refactor) file 2020.12.14 295
181 안드로이드 스튜디오 actionbar(액션바) 사라짐 file 2020.12.14 604
180 This Handler class should be static or leaks might occur 시 해결법 2020.12.14 240
179 안드로이드에서 url 주소로 이미지 바로 불러오기 (Glide 사용) 2020.12.14 759
» 구글맵으로 GPS 현재위치 실시간 연동하기 file 2020.12.14 2436
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 ... 13 Next
/ 13

하단 정보를 입력할 수 있습니다

© k2s0o1d4e0s2i1g5n. All Rights Reserved