728x90
반응형
일단 위 페이지에서처럼 google map api를 사용했고 기본적인 코딩을 했다.
1. build.gradle (:app)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
...
dependencies {
implementation 'androidx.appcompat:appcompat:1.3.1'
implementation 'com.google.android.material:material:1.4.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
implementation 'org.jetbrains:annotations:15.0'
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'com.google.android.gms:play-services-maps:17.0.0'
implementation 'com.google.android.gms:play-services-location:17.0.0'
implementation 'gun0912.ted:tedpermission:2.0.0'
}
|
cs |
11~12 - googleMapApi를 사용하기 위한 라이브러리
14 - 권한 허가를 위한 라이브러리
2. gradle.properties
1
2
3
|
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
android.useAndroidX=true
android.enableJetifier=true
|
cs |
3 - 라이브러리를 추가함으로써 생기는 에러를 해결하기 위해서 위 열을 추가해준다. (추가한 라이브러리를 androidx를 형태로 변환하는 듯하다.)
3. 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
|
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.googlemapapplication">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<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/Theme.GoogleMapApplication">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="~~~~~~~~~~~~~~~~~~~~~~"/>
</application>
</manifest>
|
cs |
4~5 - gps로 사용자의 위치를 불러오기 위해서 추가해준다.
20~22 - googleMapApi를 사용하기 위해서 metaData를 추가해준다.
4. activity_main.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
51
|
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
tools:context=".MainActivity"
android:orientation="vertical"
android:id="@+id/rootLayout"
android:background="#000000">
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/googleMap"
class="com.google.android.gms.maps.MapFragment"/>
<Button
android:id="@+id/btn_toMyLocation"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp"
android:layout_marginRight="16dp"
android:text="현위치"
app:layout_constraintEnd_toEndOf="@id/googleMap"
app:layout_constraintTop_toTopOf="parent" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintTop_toTopOf="parent"
android:id="@+id/linearLayout"
android:layout_marginTop="100dp"
android:background="#FFFFFF"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Name"
android:textSize="30sp"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="ex) name"
android:id="@+id/et_name"/>
<Button
android:layout_marginTop="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="생성"
android:id="@+id/btnForApply"/>
</LinearLayout>
</RelativeLayout>
|
cs |
11~15 - googleMap을 위한 fragment이다.
16~25 - 현위치로 시점을 움직이는 버튼이다.
26~50 - LinearLayout으로 marker에 대한 정보를 등록하거나 수정할 수 있는 위젯들이 담을 viewGroup이다. 드래그를 통해서 아래로 밀어넣었다가 다시 위로 꺼낼 수 있게 할 것이다.
39~43 - marker의 title을 입력받을 editText 위젯이다.
44~49 - 입력한 것을 적용하기 위한 버튼이다. 상황에 따라서 text를 바꿀 것이다.
5. 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
|
package com.example.googlemapapplication;
import ...
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback { //implements 중요
private FragmentManager fragmentManager; //googleMap을 띄우기 위한 것
private MapFragment mapFragment;
private Thread thread;
private LocationManager locationManager; //현위치를 가져오기 위한 것
Location location;
double lattitude;
double longitude;
private Boolean isFine = false;
private RelativeLayout rootLayout; //여러 view들을 연결해주기 위한 것
private LinearLayout linearLayout;
private Button btn_toMyLocation;
private EditText et_name;
private Button btnForApply;
private boolean isForApply = true; //btnForApply를 위한 boolean
private LatLng latLngForMarker; //marker을 만들 때 사용할 것
GoogleMap map; //googleMap에 대한 것들을 저장할 것
private boolean onMarker = true; //현위치에 시점을 고정하는 것에 대한 boolean
Marker marker;
Marker markerForRetouch;
private final static String TAG = "MainActivity.java";
private final static int UPDATELOCATION = 0;
private int mpHeight; //linearLayout을 움직이게 하기 위한 변수
private int lastY, curY;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TedPermission.with(this) //권한을 얻기 위한 코드이다.
.setPermissionListener(permission)
.setRationaleMessage("위치 확인를 위하여 권한을 허용해주세요.")
.setDeniedMessage("권한이 거부되었습니다. 설정 > 권한에서 허용할 수 있습니다.")
.setPermissions(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION)
.check();
fragmentManager = getFragmentManager();
mapFragment = (MapFragment) fragmentManager.findFragmentById(R.id.googleMap);
mapFragment.getMapAsync(this); //googleMap을 사용하기 위한 것
rootLayout = (RelativeLayout)findViewById(R.id.rootLayout);
linearLayout = (LinearLayout)findViewById(R.id.linearLayout);
et_name = (EditText)findViewById(R.id.et_name);
btnForApply = (Button)findViewById(R.id.btnForApply);
btnForApply.setOnClickListener(v -> {
if (isForApply) {
if (et_name.getText().toString() == "") { //입력된 것이 없을 때의 부분
Toast.makeText(getApplicationContext(), "이름을 입력해주세요.", Toast.LENGTH_SHORT).show();
} else {
MarkerOptions markerOptions = new MarkerOptions(); //marker를 등록하기 위한 부분
markerOptions.title(et_name.getText().toString());
markerOptions.position(latLngForMarker);
map.addMarker(markerOptions);
isForApply = false;
btnForApply.setText("수정");
}
} else {//marker을 수정하기 위한 부분
markerForRetouch.setTitle(et_name.getText().toString());
}
});
btn_toMyLocation = (Button)findViewById(R.id.btn_toMyLocation);
btn_toMyLocation.setOnClickListener(v -> { //버튼으로 현위치로 시점을 움직이기 위한 부분
onMarker = true; //시점을 현위치에 고정
btn_toMyLocation.setVisibility(View.INVISIBLE); //버튼을 보이지 않게
Log.d(TAG, ("onClickListener : onMarker = " + onMarker));
LatLng location = new LatLng(lattitude, longitude);
map.moveCamera(CameraUpdateFactory.newLatLng(location));
});
thread = new Thread() { //계속 위치를 받아오기 위한 thread
@SuppressLint("MissingPermission")
@Override
public void run() {
while (true) {
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (isFine) { //관련 허가를 받았는지 확인해주는 부분
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
lattitude = location.getLatitude(); //gps로 얻은 위치로 좌표를 받아와서 저장한다.
longitude = location.getLongitude();
}
handler.sendEmptyMessage(UPDATELOCATION); // mainThread에서 실행해야할 부분을 실행
Log.d(TAG, "run : threadIsRunning");
}
}
};
thread.start();
linearLayout.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) { // linearLayout을 드레그로 움직일 수 있게 한다.
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) linearLayout.getLayoutParams();
int action = event.getAction();
if(action == MotionEvent.ACTION_DOWN){
lastY = (int)event.getY() + layoutParams.topMargin;
} else if (action == MotionEvent.ACTION_MOVE && Math.abs(lastY - layoutParams.topMargin) < 100 && lastY < (mpHeight - 200) && lastY > 100) {
curY = (int)event.getY() + layoutParams.topMargin;
layoutParams.setMargins(0, (layoutParams.topMargin +curY-lastY), 0, 0);
linearLayout.setLayoutParams(layoutParams);
lastY = curY;
}
return true;
}
});
}
@Override
public void onMapReady(@NonNull @org.jetbrains.annotations.NotNull GoogleMap googleMap) {
LatLng location = new LatLng(0, 0); //지도에 marker을 만들기 위한 좌표
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.title("현위치");
markerOptions.draggable(true);
markerOptions.position(location);
marker = googleMap.addMarker(markerOptions); //위에서 설정한 marker을 적용
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(location, 16)); //marker 위치로 camera를 이동하고 줌함
googleMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
@Override
public void onCameraMove() {
Log.d(TAG, "onCameraMove : TouchLinstenerIsRunning");
if (Math.abs(map.getCameraPosition().target.latitude - lattitude) < 0.0005 && Math.abs(map.getCameraPosition().target.longitude - longitude) < 0.0005) {
onMarker = true; //시점이 현위치에 주변에 가면 고정한다.
btn_toMyLocation.setVisibility(View.INVISIBLE);
Log.d(TAG, ("onCameraMove : onMarker = " + onMarker));
} else {
onMarker = false; //시점이 현위치를 벗어나면 고정을 푼다.
btn_toMyLocation.setVisibility(View.VISIBLE);
Log.d(TAG, ("onCameraMove : onMarker = " + onMarker));
}
}
});
googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
if (marker.getTitle().toString() != "현위치"){ //marker을 클릭했을 때 그 marker을 수정할 수 있게 준비한다.
markerForRetouch = marker;
et_name.setText(marker.getTitle());
} else {
onMarker = true;
btn_toMyLocation.setVisibility(View.INVISIBLE);
}
googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(marker.getPosition().latitude, marker.getPosition().longitude)));
return true;
}
});
googleMap.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() { //오래 터치했을 때 marker을 생성할 준비를 한다.
@Override
public void onMapLongClick(LatLng latLng) {
googleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) linearLayout.getLayoutParams();
isForApply = true;
btnForApply.setText("생성");
layoutParams.setMargins(0, mpHeight/2+100, 0, 0); //정보를 입력받기 위한 linearLayout을 적당한 높이로 띄운다.
linearLayout.setLayoutParams(layoutParams);
btn_toMyLocation.setVisibility(View.VISIBLE);
onMarker = false;
latLngForMarker = latLng;
}
});
map = googleMap;
}
PermissionListener permission = new PermissionListener() {
@Override
public void onPermissionGranted() {
Toast.makeText(MainActivity.this, "권한 허가", Toast.LENGTH_SHORT);
locationManager = (LocationManager)getSystemService(LOCATION_SERVICE);
isFine = true; //허가를 받았을 때 그 정보를 저장
}
@Override
public void onPermissionDenied(ArrayList<String> deniedPermissions) {
Toast.makeText(MainActivity.this, "권한 거부", Toast.LENGTH_SHORT);
}
};
private Handler handler = new Handler() { //thread에서 사용될 부분을 정의
@Override
public void handleMessage(@NonNull Message msg) {
if (msg.what == UPDATELOCATION){
LatLng location = new LatLng(lattitude, longitude);
marker.setPosition(location);
Log.d(TAG, ("handleMessage: onMarker = " + onMarker));
if (onMarker) map.moveCamera(CameraUpdateFactory.newLatLng(location));//현위치에 시점이 고정되어있을 때 시점을 marker로 이동
}
}
};
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
mpHeight = rootLayout.getHeight(); //현재 화면의 세로 방향의 px를 저장함
}
}
|
cs |
6. 결과
728x90
반응형
'Android App' 카테고리의 다른 글
Google login in Android Studio (0) | 2021.11.08 |
---|---|
selector로 버튼 꾸미기 in Android Studio (0) | 2021.10.02 |
startActivityForResult, startActivityResult in Android Studio (0) | 2021.09.18 |
하단 선택바 (bottomNavigation, Fragment 전환) in Android Studio (0) | 2021.09.17 |
외부저장소 동영상 플레이어 in Android Studio (0) | 2021.09.04 |