안드로이드 스튜디오에서 앱을 만들고 테스트를 하기 위해 AVD Manager로 새로운 virtual device를 생성 했는데 에뮬레이터가 나타나지 않고 Emulator: emulator: ERROR: x86 emulation currently requires hardware acceleration! 오류가 발생하는 경우가 있습니다.


android emulation error


emulator에서 Nexus 6P API 28을 선택하고 [OK] 버튼을 틀릭 합니다.


잠시 후 하단과 같은 오류가 나타나고 작업이 중단 됩니다.



오류 내용은

Emulator: emulator: ERROR: x86 emulation currently requires hardware acceleration!

입니다.


해결 방법



1. Intel x86 Emulator Accelerator (HAXM installer) 설치


settings 팝업 창에서 작업을 하는데 팝업 창을 여는 방법은 2가지가 있습니다.

첫째는 상단메뉴 에서 Tool을 찾습니다.


Tools > SDK Manager



SDK Manager 메뉴를 선택 하면 Settings 팝업이 나옵니다.

 

두번째는 상단 메뉴에서 File을 찾습니다.


File > Settings


두가지 방법 모두 아래 Default Settings 팝업을 띄웁니다.

그림을 보면 알 수 있겠지만 다음을 선택


Appearance & Behavior > System Settings > Android SDK


하면 우측에 3개의 탭이 나오는데 그중에 SDK Tools를 선택 합니다.



 

설치가 안되어 있으면 설치를 합니다.

저는 이미 설치된 상태 인데도 emulator가 작동을 하지 않는 경우 입니다.

 

2. 프로그램 수동 실행


프로그램이 설치된 위치로 이동하여 수동으로 실행 시켜 줍니다.

위치는 개인별로 다를 텐데 기본 설치를 했다면 컴퓨터이름만 자신의 컴퓨터 이름으로 변경 합니다.


C:\Users\컴퓨터이름\AppData\Local\Android\Sdk\extras\intel\Hardware_Accelerated_Execution_Manager

 

못칮겠나요?

그럼 위의 사진에 Android SDK Location을 보시면 기본 디렉토리가 있습니다.

거기에 다음 위치를 연결하면 찾을 수 있습니다.

\extras\intel\Hardware_Accelerated_Execution_Manager

 

디렉토리에 파일들이 나옵니다.

이중에서 intelhaxm-android.exe 파일을 실행 합니다.



 

설치 과정은 단순하게 활성화 되어있는 버튼을 클릭하면 됩니다.



[Install] 버튼 클릭





[Finish] 버튼 클릭




이제 다시 emulator를 실행해 봅니다.



잘 실행이 되는 군요.




3. Windows 하이퍼바이저 플랫폼


Windows 하이퍼바이저 플랫폼을 체크해 주어야 한다는 이야기도 있는데 컴퓨터 마다 설정이 달라서 인듯 합니다.

저는 Windows 하이퍼바이저 플랫폼이 체크 안되어 있어도 잘되는 군요.

 

Windows 하이퍼바이저 플랫폼 설정 방법은

제어판에서 Windows 기능 켜기/끄기를 검색합니다. Windows를 한글로 쓰면 안됨.



팝업에서 Windows 하아퍼바이저 플랫폼을 체크 합니다.



 

Windows 7에서는 하이퍼바이저 오류는 없는것 같습니다.

한글 영문 검색을 해도 안나오는 군요.

 


 

따라 하기를 해도 나만 안될 때 참 비참한데...

그럴 때! 한번 더! 힘을 내시길 바랍니다.


- copy coding -


1. 프로젝트 생성

 

1.1 프로젝트 만들기

 

전에 google map을 사용할 수 있는 API key를 생성했는데요.


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


이제 키가 잘 작동 하는지 테스트를 해보겠습니다.

안드로이드 프로젝트를 하나 생성 합니다.


MapTest 이라는 이름으로 생성을 하겠습니다.


프로젝트 명을 입력하는 화면 하단에 Package name이 있습니다.

com.example.컴퓨터이름.프로젝트명 이런식으로 나타나는데 [Edit] 버튼을 누르면 편집이 가능 합니다.



필요하면 편집을 하고 [Done] 버튼을 누르면 반영이 됩니다.



com.android.google.maptest 이렇게 변경을 해 보았습니다.



Android 4.0으로 선택을 했는데 각자 알아서 선택을 하면 됩니다.



Empty Activity를 선택 합니다.



모두 기본으로 놓았는데 변경이 필요하면 수정 합니다.

이제 [Finish] 버튼을 눌러 프로젝트를 생성 합니다.

 

수정한 Package name으로 생성이 되었는지 확인해 볼까요?



잘 되어 있군요.

 

1.2 패키지 이름 등록

 

새로 만든 프로젝트에서 구글 맵을 사용 하려면 패키지 이름을 API 키에 등록해야 합니다.

google에 로그인을 하고 https://console.developers.google.com 에 접속 합니다.



사용자 인증 정보 만들기에서 API1을 선택 합니다. 등록할 때 이름을 변경 했다면 다른 이름이겠죠.

 

라디오 버튼 중 Android 앱을 선택합니다.

[+ 패키지 이름 및 지문 추가]를 선택하면 패키지 이름과 SHA-1 인증서 지문이 하나 추가 됩니다.



신규 생성한 내용을 추가 합니다.

빨간색 박스가 이번에 만든 패키지인증서 지문 입니다.

[저장] 버튼을 선택 하면 패키지 이름으로 생성된 프로젝트 에서 지도를 사용할 수 있습니다.

 


2. 프로젝트 개발

 

2.1 API 키 등록

 

구글 맵을 사용하기 위한 키를 등록 해야 권한을 이용 하여 앱에 지도가 표시 됩니다.


AndroidMainifest.xml


<meta-data
   
android:name="com.google.android.geo.API_KEY"
   
android:value="생성된 API 키 입력" />


2.2 Layout 작성

 

activity_main.xml


지도를 표시할 fragment 를 추가합니다.

그런데 빨간색으로 오류가 나오는 군요.

map 관련 class가 없어서 발생 하니 추가해야 합니다.



build.gradle

implementation 'com.google.android.gms:play-services:10.0.1'


를 추가 합니다.

그러면 상단에 Sync를 맞추라고 합니다. [Sync Now]를 클릭 합니다.



다시 activity_main.xml에 가봅니다.



빨간색이 없어졌습니다.



2.3 지도 사용

 

이제 지도를 그려 보겠습니다.

MainActivity.java implements OnMapReadyCallback를 이용해 보겠습니다.

 

onCreate()함수에 Fragment를 추가 하고


FragmentManager fragmentManager = getFragmentManager();
MapFragment mapFragment = (MapFragment)fragmentManager
        .findFragmentById(R.id.
map);
mapFragment.getMapAsync(this);


onMapReady() 함수에 지도를 그려줍니다OnMapReadyCallback이걸 추가하면 map 기능이 추가되어서 onMapReady() 함수에서 작업하면 됩니다.  이 함수에서 정거장 위치, 약속장소등을 어떻게 표시하는지 기회가 되면 설명 드리겠습니다.


@Override
public void onMapReady(final GoogleMap map) {

    LatLng SEOUL =
new LatLng(37.56, 126.97);

   
MarkerOptions markerOptions = new MarkerOptions();
   
markerOptions.position(SEOUL);
   
markerOptions.title("서울");
   
markerOptions.snippet("한국 수도");

   
map.addMarker(markerOptions);
   
map.moveCamera(CameraUpdateFactory.newLatLng(SEOUL));
   
map.animateCamera(CameraUpdateFactory.zoomTo(14));
}


실행을 해볼까요?

아직 오류가 발생합니다.

 

Error: Program type already present: android.support.v4.app.BackStackRecord$Op

 

android.support.v4 오류이군요.

gradle에 아래 내용을 추가 합니다.


implementation 'com.android.support:support-v4:27.1.0'


오류가 없어졌습니다.


왔다 갔다. 이것 저것 추가하고 혼란 스러운가요?


하단에 추가한 전체 소스가 그리 길지 않습니다.


전체 소스를 보면서 읽으면 별거 없습니다.



2.4  결과


android google map

 

이제 잘 나오는 군요.

지도의 좌표를 임의로 설정해서 나온 결과 입니다.

다음 번에는 핸드폰의 위치를 지도에 표시 해보도록 하겠습니다.

 

 

3. Source Code

 

3.1 AndroidManifest.xml


개인이 발급 받은 API 키 값을 넣으세요.

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

    <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="AIzxxxxx API 키 값xxxxxxxxxx_L8" />


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


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

    <fragment
        android:id="@+id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.MapFragment" />

</android.support.constraint.ConstraintLayout>

3.3 build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.android.google.maptest"
        minSdkVersion 14
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.google.android.gms:play-services:10.0.1'
    implementation 'com.android.support:support-v4:27.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}


3.4 MainActivity.java

package com.android.google.maptest;

import android.app.FragmentManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;

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

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {

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

        FragmentManager fragmentManager = getFragmentManager();
        MapFragment mapFragment = (MapFragment)fragmentManager
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

    }

    @Override
    public void onMapReady(final GoogleMap map) {

        LatLng SEOUL = new LatLng(37.56, 126.97);

        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(SEOUL);
        markerOptions.title("서울");
        markerOptions.snippet("한국 수도");

        map.addMarker(markerOptions);
        map.moveCamera(CameraUpdateFactory.newLatLng(SEOUL));
        map.animateCamera(CameraUpdateFactory.zoomTo(14));
    }

}

- copy coding -


구글 맵이 유료로 변경되면서 뭔가 새로운 변화가 있나 확인도 할겸 google map 서비스를 다시 사용해 봅니다.

처음부터 프로젝트를 만들고 키 값을 설정하는 부분 까지만 진행 하고 실제 안드로이드에서 맵을 사용 하는 부분은 따로 작업을 하도록 하겠습니다.

키 값을 생성 하기 위해 프로젝트를 생성 하려면 로그인을 해야 하기 때문에 회원 가입이 되어 있어야 합니다.

 


1. 프로젝트 생성

 

1.1 프로젝트 명 만들기


Google Developers Console 사이트 (https://console.developers.google.com )에 접속합니다.

현재 신규 아이디로 로그인만 하고 아무것도 생성되지 않은 상태 입니다.


android api key


이제 처음부터 시작을 하기 위해 [프로젝트 만들기] 버튼을 클릭 합니다.



대시보드에서 [만들기] 버튼을 클릭 합니다.

사용할 프로젝트 이름을 생성하는 화면 입니다.



프로젝트 이름은 편한대로 생성 하는데 성격은 포함되도록

MyMapProj

저는 이렇게 하고 [만들기] 버튼을 클릭합니다.

 

잠시 기다리면 다시 프로젝트가 생성 되고 첫 화면으로 돌아 갑니다.

화면이 처음과 비슷해서 아무 일도 안 일어난것 같지만 상단에 보면 신규 프로젝트가 생성되어 있습니다.


첫 화면과 비교해 볼까요?

상단 조직 없음에서 프로젝트 이름 MyMapProj 로 변경이 되어 있습니다.




 

한번 뭐가 있나 MyMapProj를 눌러 봅니다.

 


별거 없군요. 누를 필요 없겠습니다.



1.2 구글 맵 서비스 등록

 

이제 생성된 프로젝트에서 사용할 API를 등록해야 합니다.

그러기 위해서는 서비스를 등록 해야 하겠지요.



[API 및 서비스 사용 설정]을 선택 합니다.


 

종류가 많으므로 검색 키워드를 입력 합니다.

map만 입력하면 너무 많이 나오니까 map android를 입력하고 검색 합니다.

 


안드로이드 앱 개발을 테스르 하기 위해 처음에 있는 Maps SDK for Android를 선택 합니다.



 

이제 [사용 설정] 버튼을 클릭합니다.

 

~~~~~! 지겨워 한 페이지에서 다 선택 하게 하면 좋을 텐데 페이지가 너무 많네요.



화면이 다시 메인으로 넘어 오는데 예전에 못보던 할당량 이라는 메뉴가 들어 있습니다.

이게 유료화와 관련이 있나? 한번 눌러 봤습니다.



일단 여기까지. 자세한건 나중에 천천히 보고 지금 해야 하는건 사용자 인증 정보를 만드는 것입니다.

 


2. 사용자 인증 정보

 

2.1 인증 키 생성


할당량 옆에 있는 [사용자 인증 정보]를 선택 합니다.



[사용자 인증 정보 만들기]를 선택 합니다.

 

몇가지 선택 할 수 있는 메뉴가 나옵니다.




goole map을 사용하기 위한 키를 생성하는 것이니

[API ] 를 선택 합니다.


잠시 생성중... 하다가 키를 하나 만들어서 보여 줍니다.


여기까지가 구글 맵을 사용하기 위한 키값 생성하는 작업 입니다.




? 필요 없으시다 구요?



그럼 [사용중지]나 쓰레기통을 클릭하세요.


계속 진행 하려면 [API] 또는 연필 아이콘을 클릭 합니다.

 

2.2 앱과 개발 장비 등록 화면

 

여기서 잠깐!

이 글을 찾아서 보시는 분이라면 처음 사용하는 분이라 생각됩니다.

여기에 있는 키가 안드로이드 스튜디오에서 구글 맵을 추가할 때 사용하는 인증 키 입니다.

아래에서 설명 하는 내용은 이 키 값을 가지고 만들게 되는 앱과 컴퓨터 정보를 등록하는 부분입니다.


 

자신의 용도에 맞게 라디오 버튼을 선택 하고 [저장] 버튼을 클릭 합니다.

 

Android 앱에서 사용하려고 하는 거라 Android 라디오 버튼을 누르면 하단에 지문 추가 항목이 나타납니다.


 

패키지 이름은 자신이 만들려는 앱의 패키지 이름입니다.

SHA-1 인증서 지문은 앱 개발을 하는 컴퓨터의 인증서 지문을 말합니다.

, 안드로이드 스튜디오로 생성할 프로젝트를 등록하고 컴퓨터에서 생성한 인증서도 등록 합니다.

 

여기서 부터는 잠시 웹을 중단하고 자신의 컴퓨터에서 작업을 시작 합니다.

잠시 휴식...


2.3 SHA-1 인증서 지문 생성


keytool 명령을 사용해서 인증서를 생성 하는데 안된다면 keytool이 어디 있는지 확인 합니다.

java를 어디에 설치 했는가에 따라 다르겠지만

C:\Java\jdk1.8.0_131\bin 이곳에 있습니다.

console창의 위치를 이동 하거나 path를 잡아서 명령을 실행 합니다.


콘솔 창을 하나 열어서 키를 생성 해 보도록 합니다.


c:\>keytool -list -v -keystore "%USERPROFILE%\.android\debug.keystore" -alias androiddebugkey -storepass android -keypass android



그림의  SHA1이 인증서 지문 입니다.


 

2.4 패키지 이름 생성

 

이젠 안드로이드 프로젝트를 하나 생성 합니다.

MapTest 이라는 이름으로 생성을 하겠습니다.

프로젝트 명을 입력하는 화면 하단에 Package name이 있습니다.

com.example.컴퓨터이름.프로젝트명 이런식으로 나타나는데 [Edit] 버튼을 누르면 편집이 가능 합니다.



필요하면 편집을 하고 [Done] 버튼을 누르면 반영이 됩니다.



패키지 이름을 변경하려고 합니다.

com.android.google.maptest 이렇게 변경을 해 보았습니다.



2.4 API 키에 패키지 이름 및 인증서 지문 등록

 

패키지 이름과 SHA-1 인증서 지문이 모두 준비 되었습니다.

이제 웹 작업을 마무리 할 때가 되었습니다.

 


다시 웹 페이지로 돌아 갑니다.

깜짝 놀랄 수도 있지만 이해를 돕고자 예전에 만들어 놓은 인증정보를 가지고 설명을 하겠습니다.



인증서 지문이 다양하게 있죠?

일부는 노트북에서 인증서 지문을 만들고 앱을 개발한 내용이고

일부는 데스크 탑에서 인증서 지문을 만들고 앱을 개발한 내용입니다.


컴퓨터 마다 또는 생성 할 때 마다 다르게 만들어집니다.

 

빨간색 박스가 이번에 만든 패키지와 인증서 지문 입니다.


API 키는 개인에게 부여된 google map을 사용하기 위한 하나의 키 값이고 컴퓨터 마다 패키지와 인증서 지문을 등록 하는 것 입니다.

그렇다고 프로젝트를 만들 때마다 인증서 지문을 만드는건 아닙니다.

위에서 보듯이 동일한 인증서 지문에 패키지 이름(새로 생성한 프로젝트)을 입력하고 [저장]버튼을 누르면 됩니다.

새로 프로젝트를 만들면 패키지명은 새로 추가되고 인증서지문은 동일한걸 사용하면 됩니다.



요 빨간색 박스의 키가 개인에게 부여된 키이고 위에서 한 작업은 프로젝트와 작업 컴퓨터를 키에 등록한다고 생각하면 됩니다.

 

키 값은 개인에게 부여된 값이기 때문에 구글 맵 사용이 유료화가 되었으니 중요도가 더 높아졌습니다.

잘 보관하여 사용 하세요.

 

다음에는 키 값을 가지고 구글 맵을 한번 생성해 보겠습니다.


- copy coding -

 

인터넷에서 다운받거나 개인이 생성한 material icon을 사용하는 방법을 소개 합니다.

src 경로만 잡아주면 좋을텐데 귀찮은 몇가지 설정을 해야 합니다.

 

1. icon 준비


인터넷에서 무료 아이콘을 다운로드 받거나 직접 제작한 icon을 준비 합니다.

준비된 아이콘을 프로젝트의 assets 디렉토리에 저장 합니다.


angular customer_icon

 

/src/assets/images/ alarm_on-24px.svg


저는 이렇게 저장이 되어 있습니다.


 

2. 설정 및 등록

 

웹에서 사용자 정의 아이템을 사용 할 수 있도록 설정을 하고 아이콘을 등록하는 작업을 수행 합니다.

 

/src/app/app.module.ts


파일을 열고 사용자 정의 모듈을 import 합니다.


import { HttpClientModule } from '@angular/common/http';


  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MatFormFieldModule,
    MatInputModule,
    MatButtonModule,
    MatIconModule,
    HttpClientModule
  ],

 

/src/app/material-test/material-test.component.ts


파일을 열고 아이콘을 등록 합니다.

아이콘 path는 보안을 위해 DomSanitizer를 이용 합니다.


import { DomSanitizer } from '@angular/platform-browser';


import { MatIconRegistry } from '@angular/material';


constructor(iconRegistry: MatIconRegistry, sanitizer: DomSanitizer) {
    iconRegistry.addSvgIcon(
        'alarm_on',
        sanitizer.bypassSecurityTrustResourceUrl('assets/images/alarm_on-24px.svg'));
}


설정은 이렇게 하면 끝입니다.

 


3. icon 출력


이제 아이콘을 사용하여 화면에 표시만 하면 됩니다.


/src/app/material-test/material-test.component.html


파일을 열고 아이콘을 사용합니다.


<mat-icon svgIcon="alarm_on"></mat-icon>



출력을 해봅니다.



이런식으로 사용 하면 됩니다.



4. Source Code

 

기존 icon code에 추가했습니다.

 

/src/app/app.module.ts


import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { CompanyVisionComponent } from './company-vision/company-vision.component';

// Material - animation
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { MatFormFieldModule } from '@angular/material/form-field';
import { MatInputModule } from '@angular/material';
import { MatButtonModule } from '@angular/material/button';
import { MatIconModule } from '@angular/material/icon';
import { MaterialTestComponent } from './material-test/material-test.component';

import { HttpClientModule } from '@angular/common/http';

@NgModule({
  declarations: [
    AppComponent,
    CompanyVisionComponent,
    MaterialTestComponent
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    MatFormFieldModule,
    MatInputModule,
    MatButtonModule,
    MatIconModule,
    HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent, MaterialTestComponent]
})
export class AppModule { }

 

/src/app/material-test/material-test.component.ts


import { Component, OnInit } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { MatIconRegistry } from '@angular/material';


@Component({
  selector: 'app-material-test',
  templateUrl: './material-test.component.html',
  styleUrls: ['./material-test.component.css']
})
export class MaterialTestComponent implements OnInit {

  constructor(iconRegistry: MatIconRegistry, sanitizer: DomSanitizer) {
    iconRegistry.addSvgIcon(
        'alarm_on',
        sanitizer.bypassSecurityTrustResourceUrl('assets/images/alarm_on-24px.svg'));
  }


  ngOnInit() {
  }
}


/src/app/material-test/material-test.component.html


<mat-icon svgIcon="alarm_on"></mat-icon>


- copy coding -


1···105106107108109110111···118

+ Recent posts