구글에서 제공하는 안드로이드 용 지도 앱(단순히 정해준 위치의 지도를 보여주는 기능) 사용하기 예제를 이용하여 테스트 하고 사용 방법을 익혀 봅니다아주 단순하고 간단하게 만들어 볼 수 있습니다. 웹 주소는

https://developers.google.com/maps/documentation/android-sdk/start


이곳으로 여기에 가면 소스를 그대로 복사해서 테스트 해 볼 수 있습니다웹 페이지에 나와있는 순서대로 작업을 해봅니다물론 순서는 편리에 따라 바꾸어도 상관 없습니다.

 

Step 1. Download Android Studio


https://developer.android.com/studio/index.html


android google map sdk


자신의 운영체제에 맞는 패키지를 다운받아 설치 합니다. 현재 3.5버전 이고 다른 버전이라도 설치되어 있으면 패스. 저는 업데이트 했습니다.

 

Step 2. Install the Google Play services SDK


안드로이드 스튜디오 메뉴에서 팝업 창을 열고

Tools > SDK Manager > Appearance & Behavior > System Settings > Android SDK

우측에서 SDK Tools 탭을 선택 합니다.


android google map sdk


Google Play services 를 체크하여 설치 합니다기존에 설치를 했으면 패스.

 

Step 3. Create a Google Maps project


그냥 생각 나는 이름으로 프로젝트를 하나 생성 합니다.

Activityempty를 선택하고 생성 했습니다.


android google map sdk


Package nameAPI 사이트에 등록을 해야 하니 적당하게 입력 합니다저는 copycoding.tistory.mylocation으로 했습니다.


android google map sdk


Step 4. Get a Google Maps API key


구글에서 API를 사용할 수 있는 키를 생성 합니다. 그리고 package name을 이용하여 등록을 합니다.  기존에 생성한 API 키가 있다면 package name만 신규로 등록 합니다키 생성 방법은 검색하면 자세한 설명들이 바글바글 합니다저도 하나 설명한게 있습니다.

[안드로이드] google map 사용을 위한 API 생성(2018.11)


android google map sdk


Step 5. Hello Map! Take a look at the code


이제 프로젝트에 사이트에 있는 소스를 복사해서 붙여 넣기를 합니다사이트에는 두개의 소스가 있습니다.

 

activity_main.xml

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:tools="http://schemas.android.com/tools"
   
android:layout_width="match_parent"
   
android:layout_height="match_parent"
   
android:id="@+id/map"
   
tools:context=".MapsActivity"
   
android:name="com.google.android.gms.maps.SupportMapFragment" />

 

MainActivity.java

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {

   
private GoogleMap mMap;

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
       
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(
this);
    }

   
@Override
   
public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

       
// Add a marker in Sydney, Australia, and move the camera.
       
LatLng sydney = new LatLng(-34, 151);
        mMap.addMarker(
new MarkerOptions().position(sydney).title("Marker in Sydney"));
        mMap.moveCamera(
CameraUpdateFactory.newLatLng(sydney));
    }
}

 

이 두가지로만 하면 오류가 발생 합니다.

사이트에 없지만 추가를 해야 하는 항목이 두개 있습니다간단해서 생략 했을 수도 있습니다.


AndroidManifest.xml

<meta-data
   
android:name="com.google.android.geo.API_KEY"
   
android:value="API 키 값" >
</
meta-data>

Step 4에서 생성한 API 키를 입력 합니다.

 

build.gradle(Module: app)

implementation 'com.google.android.gms:play-services-maps:10.2.0'

라이브러리도 추가 해줍니다.

 

Step 6. Connect an Android device


테스트를 진행하기 위해 가상 디바이스를 생성 하거나 실제 핸드폰을 연결 합니다


android google map sdk


Step 7. Build and run your app


이제 프로그램을 실행 하기만 하면 끝 입니다.


android google map sdk


GPS를 이용 하는게 아니라서 방구석 처밖혀 인터넷만 연결되면 테스트가 가능 합니다.

줌 기능을 추가하지 않아 그냥 세계지도를 보는 느낌이네요.

 

전체 소스

 

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
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">

    <fragment
xmlns:android="http://schemas.android.com/apk/res/android"
       
xmlns:tools="http://schemas.android.com/tools"
       
android:layout_width="match_parent"
       
android:layout_height="match_parent"
       
android:id="@+id/map"
       
tools:context=".MapsActivity"
       
android:name="com.google.android.gms.maps.SupportMapFragment" />

</androidx.constraintlayout.widget.ConstraintLayout>

 

 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
   
package="copycoding.tistory.gpsmap">
    <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">

        <meta-data
           
android:name="com.google.android.geo.API_KEY"
           
android:value="API Key "/>
        <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>

 

 

build.gradle(Module: app)

apply plugin: 'com.android.application'

android {
    compileSdkVersion
29
   
buildToolsVersion '29.0.2'
   
defaultConfig {
        applicationId
"copycoding.tistory.gpsmap"
       
minSdkVersion 16
        
targetSdkVersion 29
       
versionCode 1
       
versionName "1.0"
       
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
   
}
    buildTypes {
        release {
           
minifyEnabled false
           
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
       
}
    }
}

dependencies {
    implementation fileTree(
dir: 'libs', include: ['*.jar'])
    implementation
'androidx.appcompat:appcompat:1.1.0'
   
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
   
implementation 'com.google.android.gms:play-services-maps:10.2.0'
   
testImplementation 'junit:junit:4.12'
   
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
   
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}

 

 

 

 

MainActivity.java

package copycoding.tistory.mylocation;

import
androidx.appcompat.app.AppCompatActivity;
import
androidx.fragment.app.FragmentActivity;

import
android.os.Bundle;

import
com.google.android.gms.maps.CameraUpdateFactory;
import
com.google.android.gms.maps.GoogleMap;
import
com.google.android.gms.maps.OnMapReadyCallback;
import
com.google.android.gms.maps.SupportMapFragment;
import
com.google.android.gms.maps.model.LatLng;
import
com.google.android.gms.maps.model.MarkerOptions;

public class
MainActivity extends FragmentActivity implements OnMapReadyCallback {

   
private GoogleMap mMap;

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
       
setContentView(R.layout.activity_main);

       
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.
map);
       
mapFragment.getMapAsync(this);
   
}

   
@Override
   
public void onMapReady(GoogleMap googleMap) {
       
mMap = googleMap;

       
// Add a marker in Sydney, Australia, and move the camera.
       
LatLng sydney = new LatLng(-34, 151);
       
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
       
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
   
}
}

 

 - copy coding -


Could not find any version that matches com.android.support:appcompat

또는

Failed to resolve: com.android.support:appcompat-v7:29.+


프로젝트를 생성하였더니 위와 같은 오류가 발생하는 경우가 있습니다.

dependencies {
    implementation fileTree(
dir: 'libs', include: ['*.jar'])
   
implementation 'com.android.support:appcompat-v7:29.+'
   
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
   
testImplementation 'junit:junit:4.12'
   
androidTestImplementation 'com.android.support.test:runner:1.0.2'

 

오류가 발생하는 위치는 gradle 설정 부분에 있습니다


android version match error

 

하단에 있는 오류를 텍스트로 다시 보면

Unable to resolve dependency for ':app@debug/compileClasspath': Could not find any version that matches com.android.support:appcompat-v7:29.+.

Open File

Show Details

 

 

Unable to resolve dependency for ':app@debugAndroidTest/compileClasspath': Could not find any version that matches com.android.support:appcompat-v7:29.+.

Open File

Show Details

 

 

Unable to resolve dependency for ':app@debugUnitTest/compileClasspath': Could not find any version that matches com.android.support:appcompat-v7:29.+.

Open File

Show Details

동일한 오류의 반복 입니다.

SDK를 업데이트 해도 잘 해결이 안 되는 경우에는 개발 상황에 따라 조금씩 다르겠지만 설정 값을 조금 수정해야 합니다.

 

1. maven 추가


allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url
"https://maven.google.com"
       
}
    }
}

이런 식으로 maven 주소를 추가하면 해결되는 경우가 있습니다.

 

2. 버전 수정 1


implementation 'com.android.support:appcompat-v7:26.1.0'

이렇게 29를 그 아래 버전으로 수정하면 해결되는 경우도 있습니다.

 

3. 버전 수정 2


implementation 'com.android.support:appcompat-v7:+'

그냥 적합한 버전을 찾도록 합니다.


4. 그 외

 

1+ 2, 1+ 3번 이렇게 두 가지를 섞어서 테스트를 해보았는데 이것도 저에게는 오류가 사라지는 효과를 얻을 수 있었습니다.

 

- copy coding -


예전에 작업해놓은 소스를 수정하거나 참조를 해야 할 때 최신 버전을 사용하면 수정하는 작업이 막막할 때에는 백업해놓은 안드로이드 스튜디오 올드 버전이 있다면 좋겠는데 그렇지 않다면 저작권 문제로 인터넷에서 쉽게 검색으로 다운받기 어려운데요당연히 구글에서 구버전을 다운받을 수 있습니다.

 

Android Studio old version download

예전버전 다운로드 사이트에 접속해서 약관 스크롤을 하단으로 죽 내리면 약관에 동의합니다.라는 문구가 나옵니다.  


android studio old version


이걸 클릭하면 현재는 Android Studio 2.3.2 부터 Android Studio 3.3 Canary 13  까지의 old version을 볼 수 있습니다.


android studio old version



android studio old version


그중에 필요한 버전을 클릭 하고


android studio old version


자신의  OS에 맞는 파일을 다운받아 설치 하면 됩니다.

 

- copy coding -


Serverandroid app간에 데이터를 주고 받는 작업이 필요하여 간단하게 샘플 작업을 해보았습니다인터넷에 많은 예제가 널려 있는데 하나 더 던져 봅니다.  IPPC에 설정된 것으로 사용을 하기 위해 PC에 설정된(자동으로 잡히도록 되어 있으므로 다음에는 변할 수 있지만) 값을 찾아 봅니다.  ipconfig/all 명령으로 찾으면 됩니다.


andriod eclipse socket


 

1. Eclipse Server

 

서버에서는 IP는 사용하지 않고 port 번호만으로 접속 대기 상황을 만들면 됩니다그리고 client에서 연결 요청과 데이터가 들어오면 다시 보내주는 작업을 진행 합니다.

 

//client 접속 대기

Socket client = serverSocket.accept();

//client data 수신

BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));

String str = in.readLine();

//client 다시 전송

PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true);

out.println("Server Received : '" + str + "'");

 

2. Android Client

 

Client 에서는 화면작업이 좀 있습니다그리고 문자를 입력 받아 서버에 보내주고 다시 받아오는 작업을 진행 합니다.

 

//소켓 생성
InetAddress serverAddr = InetAddress.getByName(ip);
 
socket =  new Socket(serverAddr,port);
//입력 메시지
String sndMsg = et.getText().toString();
//데이터 전송
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
out.println(sndMsg);
//데이터 수신
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String read = input.readLine();

 

그리고 인터넷을 사용하므로 Manifest.xml에 권한 설정을 해주면 됩니다.

 

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

 

  

3. 결과 화면

 

안드로이드 클라이언트 화면입니다문자 입력과 전송버튼 그리고 서버로 부터 받은 데이터를 화면에 출력하는 기능이 있습니다.


andriod eclipse socket


이런... Connet 버튼은 테스트하려고 만들었는데 사용하지 않습니다삭제 안했네요.

 

서버쪽은 클라이언트에서 보내온 데이터를 콘솔에 출력만 합니다.


andriod eclipse socket


소스가 간단해서 설명도 간단 하네요.

 

4. 전체 소스

 

4.1 Eclipse Server

 

package egovframework.admin.chart.web;

 

import java.io.BufferedReader;

import java.io.BufferedWriter;

import java.io.InputStreamReader;

import java.io.ObjectOutputStream;

import java.io.OutputStreamWriter;

import java.io.PrintWriter;

import java.net.ServerSocket;

import java.net.Socket;

 

public class TCPServer implements Runnable {

 

             public static final int ServerPort = 9999;

//    public static final String ServerIP = "192.168.0.6";

 

             @Override

             public void run() {

                           try {

            System.out.println("Connecting...");

            ServerSocket serverSocket = new ServerSocket(ServerPort);

 

            while (true) {

                     //client 접속 대기

                Socket client = serverSocket.accept();

                System.out.println("Receiving...");

                try {

                   //client data 수신

                    BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));

                    String str = in.readLine();

                    System.out.println("Received: '" + str + "'");

                    //client에 다시 전송

                    PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(client.getOutputStream())), true);

                    out.println("Server Received : '" + str + "'");

                   

                } catch (Exception e) {

                    System.out.println("Error");

                    e.printStackTrace();

                } finally {

                    client.close();

                    System.out.println("Done.");

                }

            }

        } catch (Exception e) {

            System.out.println("S: Error");

            e.printStackTrace();

        }

             }

            

             public static void main(String[] args) {

        Thread ServerThread = new Thread(new TCPServer());

        ServerThread.start();

     }

}

 

4.2 안드로이드 Client

 

activity_main.xml

 

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout 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">

    <
TextView
       
android:id="@+id/TextView01"
       
android:layout_width="fill_parent"
       
android:layout_height="wrap_content" />

    <
EditText
       
android:id="@+id/EditText01"
       
android:layout_width="289dp"
       
android:layout_height="wrap_content"
       
android:layout_marginStart="92dp"
       
app:layout_constraintStart_toStartOf="@+id/Button01"
       
tools:layout_editor_absoluteY="0dp" />

    <
Button
       
android:id="@+id/Button01"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:text="Send" />

    <
Button
       
android:id="@+id/button02"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:layout_marginEnd="16dp"
       
android:layout_marginTop="456dp"
       
android:text="Connect"
       
app:layout_constraintEnd_toEndOf="parent"
       
app:layout_constraintTop_toTopOf="parent" />

    <
TextView
       
android:id="@+id/chatTV"
       
android:layout_width="fill_parent"
       
android:layout_height="381dp"
       
android:layout_marginTop="64dp"
       
app:layout_constraintTop_toTopOf="@+id/TextView01"
       
tools:layout_editor_absoluteX="0dp" />
</
android.support.constraint.ConstraintLayout>

 

 

AndroidManifest.xml

 

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    
package="com.example.tcpclient">

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

    <
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>

 

 

MainActivity.java


package com.example.tcpclient;

import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.UnknownHostException;


public class MainActivity extends AppCompatActivity {

   
private Handler mHandler;
    Socket
socket;
   
private String ip = "192.168.0.6"; // IP 주소
   
private int port = 9999; // PORT번호
   
EditText et;
    TextView
msgTV;

   
@Override
   
protected void onStop() {
       
super.onStop();
       
try {
           
socket.close();
        }
catch (IOException e) {
            e.printStackTrace();
        }
    }

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
        setContentView(R.layout.
activity_main);

       
mHandler = new Handler();

       
et = (EditText) findViewById(R.id.EditText01);
        Button btn = (Button) findViewById(R.id.
Button01);
        Button btnCon = (Button)findViewById(R.id.
button02);
       
final TextView tv = (TextView) findViewById(R.id.TextView01);
       
msgTV = (TextView)findViewById(R.id.chatTV);

        btn.setOnClickListener(
new View.OnClickListener() {
           
public void onClick(View v) {
               
if (et.getText().toString() != null || !et.getText().toString().equals("")) {
                    ConnectThread th =
new ConnectThread();
                    th.start();
                }
            }
        });
    }

   
class ConnectThread extends Thread{
       
public void run(){
           
try{
               
//소켓 생성
               
InetAddress serverAddr = InetAddress.getByName(ip);
                
socket new Socket(serverAddr,port);
               
//입력 메시지
               
String sndMsg = et.getText().toString();
                Log.d(
"=============", sndMsg);
               
//데이터 전송
               
PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
                out.println(sndMsg);
               
//데이터 수신
               
BufferedReader input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String read = input.readLine();
               
//화면 출력
               
mHandler.post(new msgUpdate(read));
                Log.d(
"=============", read);
               
socket.close();
            }
catch(Exception e){
                e.printStackTrace();
            }
        }
    }
   
// 받은 메시지 출력
   
class msgUpdate implements Runnable {
       
private String msg;
       
public msgUpdate(String str) {
           
this.msg = str;
        }
       
public void run() {
           
msgTV.setText(msgTV.getText().toString() + msg + "\n");
        }
    };
}

 

- copy coding -


1···78910111213···15

+ Recent posts