대략적인 개념이기 때문에 실제 사용할 수 있는 나침반을 만들려면 다른 변수들도 반영니 되야 겠지만 가속도 센서(TYPE_ACCELEROMETER)자기장 센서(TYPE_MAGNETIC_FIELD)를 이용하여 단순한compass를 만들어보겠습니다구현 방법은 구글에서 이미 함수를 만들어서 제공을 하기 때문에 그걸 그대로 사용합니다. 사용되는 함수는 getRotationMatrix() getOrientation() 입니다.



1. 함수

 

1.1 getRotationMatrix


 public static boolean getRotationMatrix (float[] R,

                float[] I,

                float[] gravity,

                float[] geomagnetic)


Type

 Parameter

 설명

 float[9]

 R

 회전 매트릭스 (Rotation matrix)

 float[9]

 I

 경사도 매트릭스 (Inclination matrix)

 float[3]

 gravity

 장치 좌표계의 gravity vector(TYPE_ACCELEROMETER)

 float[3]

 geomagnetic

 장치 좌표계의 geomagnetic vector(TYPE_MAGNETIC_FIELD)


getRotationMatrix()는 경사도와 회전 매트릭스를 구하는 함수로 지구에 대한 세계 좌표계(World Coordinate System)를 기준으로 핸드폰 장치의 좌표계의 변화하는 값을 구합니다세계 좌표계에서 서로 직교하는 3개의 축은

x : 지표면에 접하는 동쪽 방향의 벡터

y : 지표면에 접하는 북극 방향의 벡터

z : 지표면과 직각을 이루는 상공을 향하는 벡터

으로 설명 할 수 있습니다구글에서 설명하는 그림을 참고하면 아래와 같습니다.


android_compass


나침반을 만들 때에는 경사도 매트릭스를 사용하지 않습니다.


2.2 getOrientation


getOrientation() 함수는 rotation matrix를 이용하여 장치의 방향을 구하는 함수입니다. getRotationMatrix() 함수를 통해 구한 첫 번째 값인 회전 매트릭스를 사용해서 방향을 구할 수 있습니다.


public static float[] getOrientation (float[] R,

                float[] values)


Parameter

 설명

 R

 otation matrix : getRotationMatrix(float[], float[], float[], float[])

 values

 float[3] :

values[0]: Azimuth. z축에 대한 회전 방위각으로 이게 필요하죠.

values[1]: Pitch. x축에 대한 회전 방위각

values[2]: Roll. y축에 대한 회전 방위각


설명에도 기술 하였지만 getRotationMatrix()에서 회전 매트릭스 (Rotation matrix)를 구하여 getOrientation()에 입력하면 values[0] (Azimuth : z축에 대한 회전 방위각) 구하게 됩니다 값이 바로 북을 향하는 각도가 됩니다.

 

 

2. 프로젝트 생성

 

CompassTest 라는 이름으로 프로젝트를 생성 합니다.


android_compass


Activityempty로 선택합니다.


android_compass


나머지는 그냥 기본 설정 값으로 놓고 Next 버튼을 클릭 합니다.


3. 코딩

 

3.1 layout

 

구해진 회전각을 출력 할 수 있는 TextView를 하나 생성하고 나침반 이미지를 위해서 ImageView를 추가 합니다.


<TextView
    android:id="@+id/DegreeTV"
    android:layout_width="wrap_content"
    android:layout_height="18dp"
    android:layout_marginBottom="8dp"
    android:layout_marginTop="8dp"
    android:text="Heading : 0.0"
    app:layout_constraintBottom_toTopOf="@+id/pointer"
    app:layout_constraintTop_toTopOf="parent"
    app:layout_constraintVertical_bias="0.027"
    tools:layout_editor_absoluteX="127dp" />

<ImageView
    android:id="@+id/pointer"
    android:layout_width="match_parent"
    android:layout_height="437dp"
    android:src="@drawable/compass_icon"
    tools:layout_editor_absoluteX="0dp"
    tools:layout_editor_absoluteY="56dp" />


이미지는 인터넷에서 무료 이미지를 하나 줏어왔습니다. 배경이 투명이 아니라 돌아갈때 커다란네모가 돌면서 글씨를 가리는 군요전에 작업한 투명이미지 만들기를 보면서 수정했습니다.


[Pixlr] Adobe Photoshop 없이 무료 투명 배경 이미지 만들기


android_compass


3.2 방위각 구하기


getRotationMatrix() 함수를 이용하여 회전 매트릭스(mR)를 구합니다.


SensorManager.getRotationMatrix(mR, null, mLastAccelerometer, mLastMagnetometer);


mR을 이용하여 getOrientation()에서 방위각을 구합니다.


SensorManager.getOrientation(mR, mOrientation);


3.3 이미지 회전


z 축의 회전각으로 RotateAnimation()을 이용하여 이미지를 회전 시킵니다.

RotateAnimation ra = new RotateAnimation(
mCurrentDegree,
-azimuthinDegress,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f
);

이미지 회전 설명은 [Android] 안드로이드 RotateAnimation 함수 이용 이미지 회전 을 참조 하세요.



3. 결과


android_compass


 

4. 전체 소스

 

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/DegreeTV"
        android:layout_width="wrap_content"
        android:layout_height="18dp"
        android:layout_marginBottom="8dp"
        android:layout_marginTop="8dp"
        android:text="Heading : 0.0"
        app:layout_constraintBottom_toTopOf="@+id/pointer"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.027"
        tools:layout_editor_absoluteX="127dp" />

    <ImageView
        android:id="@+id/pointer"
        android:layout_width="match_parent"
        android:layout_height="437dp"
        android:src="@drawable/compass_icon"
        tools:layout_editor_absoluteX="0dp"
        tools:layout_editor_absoluteY="56dp" />
</android.support.constraint.ConstraintLayout>


MainActivity.java


package copycoding.tistory.com.compasstest;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements SensorEventListener {

    private ImageView mPointer;
    private SensorManager mSensorManager;
    private Sensor mAccelerometer;
    private Sensor mMagnetometer;
    private float[] mLastAccelerometer = new float[3];
    private float[] mLastMagnetometer = new float[3];
    private boolean mLastAccelerometerSet = false;
    private boolean mLastMagnetometerSet = false;
    private float[] mR = new float[9];
    private float[] mOrientation = new float[3];
    private float mCurrentDegree = 0f;
    TextView DegreeTV;

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

        mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        mMagnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        mPointer = (ImageView)findViewById(R.id.pointer);
        DegreeTV = (TextView)findViewById(R.id.DegreeTV);

    }

    @Override
    protected void onResume() {
        super.onResume();
        mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
        mSensorManager.registerListener(this, mMagnetometer, SensorManager.SENSOR_DELAY_GAME);
    }

    @Override
    protected void onPause() {
        super.onPause();
        mSensorManager.unregisterListener(this, mAccelerometer);
        mSensorManager.unregisterListener(this, mMagnetometer);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        if(event.sensor == mAccelerometer) {
            System.arraycopy(event.values, 0, mLastAccelerometer, 0, event.values.length);
            mLastAccelerometerSet = true;
        } else if(event.sensor == mMagnetometer) {
            System.arraycopy(event.values, 0, mLastMagnetometer, 0, event.values.length);
            mLastMagnetometerSet = true;
        }
        if(mLastAccelerometerSet && mLastMagnetometerSet) {
            SensorManager.getRotationMatrix(mR, null, mLastAccelerometer, mLastMagnetometer);
            float azimuthinDegress  = (int) ( Math.toDegrees( SensorManager.getOrientation( mR, mOrientation)[0] ) + 360 ) % 360;
            DegreeTV.setText("Heading : " + Float.toString(azimuthinDegress) + " degrees");
            RotateAnimation ra = new RotateAnimation(
                    mCurrentDegree,
                    -azimuthinDegress,
                    Animation.RELATIVE_TO_SELF, 0.5f,
                    Animation.RELATIVE_TO_SELF, 0.5f
            );
            ra.setDuration(250);
            ra.setFillAfter(true);
            mPointer.startAnimation(ra);
            mCurrentDegree = -azimuthinDegress;
        }
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {

    }

}



이미지를 회전시키기 위한 RotateAnimation() 함수 입니다.  parameter2, 4개 또는 6개를 포함한 함수를 제공 하는데 회전 중심을 어디로 어떻게 설정 하는가에 따라 선택해서 사용 합니다.  



1. RotateAnimation() 함수

 

여기서는 중앙을 중심으로 회전을 시키는 parameter 6개의 함수를 사용 합니다.

 

public RotateAnimation (float fromDegrees,

                float toDegrees,

                int pivotXType,

                float pivotXValue,

                int pivotYType,

                float pivotYValue)


Type

 Parameter

 설명

 float

 fromDegrees

 회전을 시작하는 각도

 float

 toDegrees

 회전을 종료하는 각도

 int

 pivotXType

 x축 설정

Animation.ABSOLUTE,

Animation.RELATIVE_TO_SELF,

Animation.RELATIVE_TO_PARENT

 float

 pivotXValue

 x축 위치. 0은 좌측 끝, 1.0은 우측 끝, 0.5는 중앙

 int

 pivotYType

 y축 설정.

Animation.ABSOLUTE,

Animation.RELATIVE_TO_SELF,

Animation.RELATIVE_TO_PARENT.

 float

 pivotYValue

 y축 위치. 0은 상단 끝, 1.0은 하단 끝, 0.5는 중앙



2. layout

 

회전에 사용할 이미지를 대충 잘라서 res/drawable에 추가해 줍니다.


RotateAnimation


왼쪽 회전, 오른쪽 회전을 위한 버튼 2개를 추가하고 회전시킬 이미지를 하단에 추가 합니다.

<Button
    android:id="@+id/btn_left"
    android:text="left"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="10dp"
    android:layout_marginTop="10dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<Button
    android:id="@+id/btn_right"
    android:text="right"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginLeft="250dp"
    android:layout_marginTop="10dp"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<ImageView
    android:id="@+id/rotImage"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:src="@drawable/rotateimage"
    android:layout_marginTop="100dp"
    app:layout_constraintTop_toTopOf="parent"/>

이런 모양이 되겠죠?


RotateAnimation



3. 구현

 

3.1 버튼 기능 구현


이미지 정의와 버튼 클릭 이벤트를 이용하여 기능을 구현 합니다. 버튼을 클릭 하면 10도씩 시계방향, 반시계 방향으로 회전 하도록 testRotation() 함수를 호출하여 줍니다.

Button btnLeft = (Button)findViewById(R.id.btn_left);
Button btnRight = (Button)findViewById(R.id.btn_right);

mImageView =  (ImageView)findViewById(R.id.rotImage);

btnLeft.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        testRotation(nBefore - 10);
        Toast.makeText(MainActivity.this, "Left", Toast.LENGTH_SHORT).show();
    }
});

btnRight.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        testRotation(nBefore + 10);
        Toast.makeText(MainActivity.this, "Right", Toast.LENGTH_SHORT).show();
    }
});

3.2 이미지 회전

 

받아온 값을 RotateAnimation()에 대입하여 이미지를 회전 시켜 줍니다.

public void testRotation(int i) {
    RotateAnimation ra = new RotateAnimation(
            nBefore,
            i,
            Animation.RELATIVE_TO_SELF, 0.5f,
            Animation.RELATIVE_TO_SELF, 0.5f
    );
    ra.setDuration(250);
    ra.setFillAfter(true);
    mImageView.startAnimation(ra);
    nBefore = i;
}


4. 프로젝트 생성


4.1 프로젝트 만들기

 

RotateAnimation 으로 프로젝트를 생성합니다.


RotateAnimation


Activityempty를 선택해 줍니다.


RotateAnimation

 

나머지는 그냥 Next를 눌러줍니다.

 

 

4.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">

    <Button
        android:id="@+id/btn_left"
        android:text="left"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="10dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/btn_right"
        android:text="right"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="250dp"
        android:layout_marginTop="10dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <ImageView
        android:id="@+id/rotImage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:src="@drawable/rotateimage"
        android:layout_marginTop="100dp"
        app:layout_constraintTop_toTopOf="parent"/>

</android.support.constraint.ConstraintLayout>


- MainActivity.java

package copycoding.tistory.com.rotateanimation;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private ImageView mImageView;
    private int nBefore = 0;

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

        Button btnLeft = (Button)findViewById(R.id.btn_left);
        Button btnRight = (Button)findViewById(R.id.btn_right);

        mImageView =  (ImageView)findViewById(R.id.rotImage);

        btnLeft.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                testRotation(nBefore - 10);
                Toast.makeText(MainActivity.this, "Left", Toast.LENGTH_SHORT).show();
            }
        });

        btnRight.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                testRotation(nBefore + 10);
                Toast.makeText(MainActivity.this, "Right", Toast.LENGTH_SHORT).show();
            }
        });

    }

    public void testRotation(int i) {
        RotateAnimation ra = new RotateAnimation(
                nBefore,
                i,
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF, 0.5f
        );
        ra.setDuration(250);
        ra.setFillAfter(true);
        mImageView.startAnimation(ra);
        nBefore = i;
    }
}


5. 결과

 

상단에 있는 Left, Right 버튼을 누르면 이미지가 10도씩 회전합니다.


RotateAnimation



Google Maps Platform 사이트에 가면 구글에서 제공하는 현재 위치 표시 소스가 있습니다.

이걸 이용해서 핸드폰에 현재 위치를 표시해 보도록 하겠습니다.

 

순서

1. 프로젝트 생성

2. Source Code 작성

2.1 AndroidManifest.xml

2.2 activity_main.xml

2.3 custom_info_contents.xml

2.4 current_place_menu.xml

2.5 strings.xml

2.6 build.gradle (Project)

2.7 build.gradle (Module)

2.8 MainActivity.java

3. 결과

4. APK

5. 전체 Source Code

5.1 AndroidManifest.xml

5.2 activity_main.xml

5.3 custom_info_contents.xml

5.4 current_place_menu.xml

5.5 strings.xml

5.6 build.gradle (Project)

5.7 build.gradle (Module)

5.8 MainActivity.java

 

 

사이트 주소

https://developers.google.com/maps/documentation/android-sdk/current-place-tutorial

에 접속하면 Source code와 함께 자세한 설명이 나와있습니다.



< > Show/Hide the Java code for the map activity.

이글을 클릭하면 소스 전체 보기가 펼쳐 집니다.

이 소스를 이용하여 프로젝트를 생성해 보겠습니다.


최종 결과는 현재 위치 표시와 근처 가계 정보가 나옵니다.


구글맵 현재 위치 표시


 

 

1. 프로젝트 생성

 

제목을 제외하고는 모두 기본 설정을 사용 했습니다.





package명을 이용하여



Google map API키에 등록 합니다.



API Key 생성과 등록에 대한 설명이 필요하면



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


[안드로이드] google map 테스트


기존 설명을 참고 하세요.



2. Source Code 작성


google 에서 제공하는 위치 정보에는 현재 위치에 대한 지역정보를 보여주도록 되어있어서 불필요한 설정들이 있습니다.

, 지역정보가 필요 없다면 생략해도 되는 소스들이 많이 있어 Resource 설정부분이 좀 복잡합니다.

일단은 모두 기록를 하였으니 필요없는 부분은 생략해서 사용하세요.

 

2.1 AndroidManifest.xml


권한 설정을 추가 합니다.

 

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

 

API 키도 추가해 줍니다.

 

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

 

<meta-data
   
android:name="com.google.android.gms.version"
   
android:value="@integer/google_play_services_version" />

 

 

2.2 activity_main.xml

 

layoutfragment를 추가 합니다.

 

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

 

2.3 custom_info_contents.xml


res>layout에 현재 위치의 지역정보를 보여주는 레이아웃 정보를 추가 합니다.

필요가 없다면 생략해도 됩니다.

 

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
   
android:layout_width="wrap_content"
   
android:layout_height="wrap_content"
   
android:layoutDirection="locale"
   
android:orientation="vertical">
    <TextView
       
android:id="@+id/title"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:layout_gravity="center_horizontal"
       
android:textColor="#ff000000"
       
android:textStyle="bold" />

    <TextView
       
android:id="@+id/snippet"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:textColor="#ff7f7f7f" />
</LinearLayout>

 

2.4 current_place_menu.xml


res>menu에 추가 합니다.

현재 위치의 지역정보를 보여주기 위한 메뉴입니다.

필요 없다면 생략 합니다.

 

<?xml version="1.0" encoding="utf-8"?><!--
     Copyright (C) 2016 The Android Open Source Project
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
          http://www.apache.org/licenses/LICENSE-2.0
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
       
android:id="@+id/option_get_place"
       
android:title="@string/option_get_place"
       
app:showAsAction="always"/>
</menu>

 

2.5 strings.xml


메뉴등 텍스트 정보를 추가 합니다.

그냥 layout에 하드코딩 해도 됩니다.

<resources>
    <string
name="app_name">MyLocation</string>
    <string
name="default_info_title">Default Location</string>
    <string
name="default_info_snippet">No places found, because location permission is disabled.</string>
    <string
name="option_get_place">Get place</string>
    <string
name="pick_place">Choose a place</string>
</resources>

 

2.6 build.gradle (Project)


gms 추가

classpath 'com.google.gms:google-services:3.1.0'

 

2.7 build.gradle (Module)


gms 추가

 

implementation 'com.android.support:support-v4:27.1.1'
implementation 'com.google.android.gms:play-services-maps:15.0.0'
implementation 'com.google.android.gms:play-services-location:15.0.0'
implementation 'com.google.android.gms:play-services-places:15.0.0'

 

 

2.8 MainActivity.java


google 사이트 소스를 복사 합니다.

 

작성된 코드는 원본과 세곳이 다릅니다.

 

class 명이 기본 값이라 TAG 생성시 MainActivity를 사용했습니다.

private static final String TAG = MainActivity.class.getSimpleName();

기본 좌표를 한국으로 변경했습니다.

private final LatLng mDefaultLocation = new LatLng(37.56, 126.97);

layout도 기본설정이라 activity_main으로 사용합니다.

setContentView(R.layout.activity_main);

 

 

3. 결과


주말에 돌아다니다 캡처를 해봤습니다.

우측 상단 GET PLACE를 클릭하면 주변 정보를 보여줍니다.



 

4. APK

 

소스코드 작업이 귀찮을때는 다운받아 테스트 해보세요.


MyLocation.apk




5. 전체 Source Code


android mylocation

 

5.1 AndroidManifest.xml


 

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

    <uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
    <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">

        <meta-data
           
android:name="com.google.android.gms.version"
           
android:value="@integer/google_play_services_version" />

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

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

 

5.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
xmlns:android="http://schemas.android.com/apk/res/android"
       
xmlns:tools="http://schemas.android.com/tools"
       
android:id="@+id/map"
       
android:name="com.google.android.gms.maps.SupportMapFragment"
       
android:layout_width="match_parent"
       
android:layout_height="match_parent"
        
tools:context="com.example.currentplacedetailsonmap.MapsActivityCurrentPlace" />

</android.support.constraint.ConstraintLayout>

 

5.3 custom_info_contents.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
   
android:layout_width="wrap_content"
   
android:layout_height="wrap_content"
   
android:layoutDirection="locale"
   
android:orientation="vertical">
    <TextView
       
android:id="@+id/title"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:layout_gravity="center_horizontal"
       
android:textColor="#ff000000"
       
android:textStyle="bold" />

    <TextView
       
android:id="@+id/snippet"
       
android:layout_width="wrap_content"
       
android:layout_height="wrap_content"
       
android:textColor="#ff7f7f7f" />
</LinearLayout>

 

5.4 current_place_menu.xml


<?xml version="1.0" encoding="utf-8"?><!--
     Copyright (C) 2016 The Android Open Source Project
     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at
          http://www.apache.org/licenses/LICENSE-2.0
     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android"
   
xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
       
android:id="@+id/option_get_place"
       
android:title="@string/option_get_place"
       
app:showAsAction="always"/>
</menu>

 

5.5 strings.xml


<resources>
    <string
name="app_name">MyLocation</string>
    <string
name="default_info_title">Default Location</string>
    <string
name="default_info_snippet">No places found, because location permission is disabled.</string>
    <string
name="option_get_place">Get place</string>
    <string
name="pick_place">Choose a place</string>
</resources>

 

5.6 build.gradle (Project)


// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
   
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath
'com.android.tools.build:gradle:3.2.1'

       
classpath 'com.google.gms:google-services:3.1.0'
       

       
// NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
   
}
}

allprojects {
    repositories {
        google()
        jcenter()
    }
}

task clean(
type: Delete) {
    delete
rootProject.buildDir
}

 

5.7 build.gradle (Module)


apply plugin: 'com.android.application'

android {
    compileSdkVersion
28
   
defaultConfig {
       
applicationId "copycoding.tistory.mylocation"
       
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:support-v4:27.1.1'
   
implementation 'com.google.android.gms:play-services-maps:15.0.0'
   
implementation 'com.google.android.gms:play-services-location:15.0.0'
   
implementation 'com.google.android.gms:play-services-places:15.0.0'
   
   
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
   
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'
}

 

5.8 MainActivity.java

 

package copycoding.tistory.mylocation;

import
android.content.DialogInterface;
import
android.content.pm.PackageManager;
import
android.location.Location;
import
android.os.Bundle;
import
android.support.annotation.NonNull;
import
android.support.v4.app.ActivityCompat;
import
android.support.v4.content.ContextCompat;
import
android.support.v7.app.AlertDialog;
import
android.support.v7.app.AppCompatActivity;
import
android.util.Log;
import
android.view.Menu;
import
android.view.MenuItem;
import
android.view.View;
import
android.widget.FrameLayout;
import
android.widget.TextView;

import
com.google.android.gms.location.FusedLocationProviderClient;
import
com.google.android.gms.location.LocationServices;
import
com.google.android.gms.location.places.GeoDataClient;
import
com.google.android.gms.location.places.PlaceDetectionClient;
import
com.google.android.gms.location.places.PlaceLikelihood;
import
com.google.android.gms.location.places.PlaceLikelihoodBufferResponse;
import
com.google.android.gms.location.places.Places;
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.CameraPosition;
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.google.android.gms.tasks.OnCompleteListener;
import
com.google.android.gms.tasks.Task;

import
java.util.Locale;

public class
MainActivity extends AppCompatActivity implements OnMapReadyCallback {

   
private static final String TAG = MainActivity.class.getSimpleName();
    private
GoogleMap mMap;
    private
CameraPosition mCameraPosition;

   
// The entry points to the Places API.
   
private GeoDataClient mGeoDataClient;
    private
PlaceDetectionClient mPlaceDetectionClient;

   
// The entry point to the Fused Location Provider.
   
private FusedLocationProviderClient mFusedLocationProviderClient;
   
// A default location (Sydney, Australia) and default zoom to use when location permission is
    // not granted.
   
private final LatLng mDefaultLocation = new LatLng(37.56, 126.97);
    private static final int
DEFAULT_ZOOM = 15;
    private static final int
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
    private boolean
mLocationPermissionGranted;

    private
Location mLastKnownLocation;

   
// Keys for storing activity state.
   
private static final String KEY_CAMERA_POSITION = "camera_position";
    private static final
String KEY_LOCATION = "location";

   
// Used for selecting the current place.
   
private static final int M_MAX_ENTRIES = 5;
    private
String[] mLikelyPlaceNames;
    private
String[] mLikelyPlaceAddresses;
    private
String[] mLikelyPlaceAttributions;
    private
LatLng[] mLikelyPlaceLatLngs;

   
@Override
   
protected void onCreate(Bundle savedInstanceState) {
       
super.onCreate(savedInstanceState);
       
// Retrieve location and camera position from saved instance state.
       
if (savedInstanceState != null) {
           
mLastKnownLocation = savedInstanceState.getParcelable(KEY_LOCATION);
           
mCameraPosition = savedInstanceState.getParcelable(KEY_CAMERA_POSITION);
       
}
        setContentView(R.layout.
activity_main);

       
mGeoDataClient = Places.getGeoDataClient(this, null);
       
mPlaceDetectionClient = Places.getPlaceDetectionClient(this, null);
       
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);

       

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

   
/**
     * Saves the state of the map when the activity is paused.
     */
   
@Override
   
protected void onSaveInstanceState(Bundle outState) {
       
if (mMap != null) {
            outState.putParcelable(
KEY_CAMERA_POSITION, mMap.getCameraPosition());
            
outState.putParcelable(KEY_LOCATION, mLastKnownLocation);
            super
.onSaveInstanceState(outState);
       
}
    }

   
/**
     * Sets up the options menu.
     * @param
menu The options menu.
     * @return Boolean.
     */
   
@Override
   
public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.
current_place_menu, menu);
        return true;
   
}

   
/**
     * Handles a click on the menu option to get a place.
     * @param
item The menu item to handle.
     * @return Boolean.
     */
   
@Override
   
public boolean onOptionsItemSelected(MenuItem item) {
       
if (item.getItemId() == R.id.option_get_place) {
            showCurrentPlace()
;
       
}
       
return true;
   
}

   
/**
     * Manipulates the map when it's available.
     * This callback is triggered when the map is ready to be used.
     */
   
@Override
   
public void onMapReady(GoogleMap map) {
       
mMap = map;

       
// Use a custom info window adapter to handle multiple lines of text in the
        // info window contents.
       
mMap.setInfoWindowAdapter(new GoogleMap.InfoWindowAdapter() {

           
@Override
           
// Return null here, so that getInfoContents() is called next.
           
public View getInfoWindow(Marker arg0) {
               
return null;
           
}

           
@Override
           
public View getInfoContents(Marker marker) {
               
// Inflate the layouts for the info window, title and snippet.
               
View infoWindow = getLayoutInflater().inflate(R.layout.custom_info_contents,
                       
(FrameLayout) findViewById(R.id.map), false);

               
TextView title = ((TextView) infoWindow.findViewById(R.id.title));
               
title.setText(marker.getTitle());

               
TextView snippet = ((TextView) infoWindow.findViewById(R.id.snippet));
               
snippet.setText(marker.getSnippet());

                return
infoWindow;
           
}
        })
;

       
// Prompt the user for permission.
        
getLocationPermission();

       
// Turn on the My Location layer and the related control on the map.
       
updateLocationUI();

       
// Get the current location of the device and set the position of the map.
       
getDeviceLocation();
   
}

    
/**
     * Gets the current location of the device, and positions the map's camera.
     */
   
private void getDeviceLocation() {
       
/*
         * Get the best and most recent location of the device, which may be null in rare
         * cases when a location is not available.
         */
       
try {
           
if (mLocationPermissionGranted) {
                Task<Location> locationResult =
mFusedLocationProviderClient.getLastLocation();
               
locationResult.addOnCompleteListener(this, new OnCompleteListener<Location>() {
                   
@Override
                   
public void onComplete(@NonNull Task<Location> task) {
                       
if (task.isSuccessful()) {
                           
// Set the map's camera position to the current location of the device.
                           
mLastKnownLocation = task.getResult();
                           
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(
                                   
new LatLng(mLastKnownLocation.getLatitude(),
                                           
mLastKnownLocation.getLongitude()), DEFAULT_ZOOM));
                       
} else {
                            Log.d(
TAG, "Current location is null. Using defaults.");
                           
Log.e(TAG, "Exception: %s", task.getException());
                           
mMap.moveCamera(CameraUpdateFactory
                                    .newLatLngZoom(
mDefaultLocation, DEFAULT_ZOOM));
                           
mMap.getUiSettings().setMyLocationButtonEnabled(false);
                       
}
                    }
                })
;
           
}
        }
catch (SecurityException e)  {
            Log.e(
"Exception: %s", e.getMessage());
       
}
    }


   
/**
     * Prompts the user for permission to use the device location.
     */
   
private void getLocationPermission() {
       
/*
         * Request location permission, so that we can get the location of the
         * device. The result of the permission request is handled by a callback,
         * onRequestPermissionsResult.
         */
       
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
               
android.Manifest.permission.ACCESS_FINE_LOCATION)
                == PackageManager.
PERMISSION_GRANTED) {
           
mLocationPermissionGranted = true;
       
} else {
            ActivityCompat.requestPermissions(
this,
                    new
String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
                   
PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
       
}
    }

   
/**
     * Handles the result of the request for location permissions.
     */
   
@Override
   
public void onRequestPermissionsResult(int requestCode,
                                          
@NonNull String permissions[],
                                           
@NonNull int[] grantResults) {
       
mLocationPermissionGranted = false;
        switch
(requestCode) {
           
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
               
// If request is cancelled, the result arrays are empty.
               
if (grantResults.length > 0
                       
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                   
mLocationPermissionGranted = true;
               
}
            }
        }
        updateLocationUI()
;
   
}

   
/**
     * Prompts the user to select the current place from a list of likely places, and shows the
     * current place on the map - provided the user has granted location permission.
     */
   
private void showCurrentPlace() {
       
if (mMap == null) {
           
return;
       
}

       
if (mLocationPermissionGranted) {
           
// Get the likely places - that is, the businesses and other points of interest that
            // are the best match for the device's current location.
           
@SuppressWarnings("MissingPermission") final
           
Task<PlaceLikelihoodBufferResponse> placeResult =
                   
mPlaceDetectionClient.getCurrentPlace(null);
           
placeResult.addOnCompleteListener
                    (
new OnCompleteListener<PlaceLikelihoodBufferResponse>() {
                       
@Override
                       
public void onComplete(@NonNull Task<PlaceLikelihoodBufferResponse> task) {
                           
if (task.isSuccessful() && task.getResult() != null) {
                                PlaceLikelihoodBufferResponse likelyPlaces = task.getResult()
;

                               
// Set the count, handling cases where less than 5 entries are returned.
                                
int count;
                                if
(likelyPlaces.getCount() < M_MAX_ENTRIES) {
                                    count = likelyPlaces.getCount()
;
                               
} else {
                                    count =
M_MAX_ENTRIES;
                               
}

                               
int i = 0;
                               
mLikelyPlaceNames = new String[count];
                               
mLikelyPlaceAddresses = new String[count];
                                
mLikelyPlaceAttributions = new String[count];
                               
mLikelyPlaceLatLngs = new LatLng[count];

                                for
(PlaceLikelihood placeLikelihood : likelyPlaces) {
                                   
// Build a list of likely places to show the user.
                                   
mLikelyPlaceNames[i] = (String) placeLikelihood.getPlace().getName();
                                   
mLikelyPlaceAddresses[i] = (String) placeLikelihood.getPlace()
                                            .getAddress()
;
                                   
mLikelyPlaceAttributions[i] = (String) placeLikelihood.getPlace()
                                            .getAttributions()
;
                                    
mLikelyPlaceLatLngs[i] = placeLikelihood.getPlace().getLatLng();

                                   
i++;
                                    if
(i > (count - 1)) {
                                       
break;
                                   
}
                                }

                               
// Release the place likelihood buffer, to avoid memory leaks.
                               
likelyPlaces.release();

                               
// Show a dialog offering the user the list of likely places, and add a
                                // marker at the selected place.
                               
openPlacesDialog();

                           
} else {
                                Log.e(
TAG, "Exception: %s", task.getException());
                           
}
                        }
                    })
;
       
} else {
           
// The user has not granted permission.
           
Log.i(TAG, "The user did not grant location permission.");

           
// Add a default marker, because the user hasn't selected a place.
           
mMap.addMarker(new MarkerOptions()
                    .title(getString(R.string.
default_info_title))
                    .position(
mDefaultLocation)
                    .snippet(getString(R.string.
default_info_snippet)));

           
// Prompt the user for permission.
           
getLocationPermission();
       
}
    }

   
/**
     * Displays a form allowing the user to select a place from a list of likely places.
     */
   
private void openPlacesDialog() {
       
// Ask the user to choose the place where they are now.
       
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
           
@Override
           
public void onClick(DialogInterface dialog, int which) {
               
// The "which" argument contains the position of the selected item.
               
LatLng markerLatLng = mLikelyPlaceLatLngs[which];
               
String markerSnippet = mLikelyPlaceAddresses[which];
                if
(mLikelyPlaceAttributions[which] != null) {
                    markerSnippet = markerSnippet +
"\n" + mLikelyPlaceAttributions[which];
               
}

               
// Add a marker for the selected place, with an info window
                // showing information about that place.
               
mMap.addMarker(new MarkerOptions()
                        .title(
mLikelyPlaceNames[which])
                        .position(markerLatLng)
                        .snippet(markerSnippet))
;

               
// Position the map's camera at the location of the marker.
               
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(markerLatLng,
                       
DEFAULT_ZOOM));
           
}
        }
;

       
// Display the dialog.
       
AlertDialog dialog = new AlertDialog.Builder(this)
                .setTitle(R.string.
pick_place)
                .setItems(
mLikelyPlaceNames, listener)
                .show()
;
   
}

   
/**
     * Updates the map's UI settings based on whether the user has granted location permission.
     */
   
private void updateLocationUI() {
       
if (mMap == null) {
           
return;
       
}
       
try {
           
if (mLocationPermissionGranted) {
               
mMap.setMyLocationEnabled(true);
               
mMap.getUiSettings().setMyLocationButtonEnabled(true);
           
} else {
               
mMap.setMyLocationEnabled(false);
               
mMap.getUiSettings().setMyLocationButtonEnabled(false);
               
mLastKnownLocation = null;
               
getLocationPermission();
           
}
        }
catch (SecurityException e)  {
            Log.e(
"Exception: %s", e.getMessage());
       
}
    }
}

 

- copy coding - 


android에서 사용하는 여러 저장 방법 중 간단하게 사용할 수 있는 기능 입니다.

개발에 필요한 크지 않은 변수와 값들을 내부에 저장하기에 적당합니다.

key-value 형식으로 저장이 됩니다.

 


1. SharedPreferences

 

SharedPreferences에서 사용하는 상수와  Method들 입니다.

그냥 이런게 있구나 하고 보시고 필요시 사용하면 됩니다.

 

1.1 Constants


SharedPreference Constants


Type

Constant

Description

int

MODE_APPEND

기존 preferences 신규 preferences 추가

int

MODE_MULTI_PROCESS

이미 호출되어 사용 중인지 체크

int

MODE_PRIVATE

생성한 application에서만 사용 가능

int

MODE_WORLD_READABLE

다른 application에서 읽을 있음

int

MODE_WORLD_WRITEABLE

다른 application에서 기록할 있음

 


1.2 Methods


SharedPreference Methods

 

Type

Method

abstract boolean

contains(String key)

- 키 값이 들어있는지 체크

abstract SharedPreferences.Editor

edit()

- 신규 Editor를 생성

abstract Map

getAll()

- 저장된 모든 값을 검색

abstract boolean

getBoolean(String key, boolean defValue)

- 키에 해당하는 boolean 값 검색

abstract float

getFloat(String key, float defValue)

- 키에 해당하는 float 값 검색

abstract int

getInt(String key, int defValue)

- 키에 해당하는 int 값 검색

abstract long

getLong(String key, long defValue)

- 키에 해당하는 long 값 검색

abstract String

getString(String key, String defValue)

- 키에 해당하는 set 형태의 string 값 검색

abstract Set

getStringSet(String key, Set defValues)

- 키에 해당하는 boolean 값 검색


1.3 Editor Methods


SharedPreference.Editor Methods

 

Type

Method

abstract void

apply()

- 비동기 적으로 값을 저장 한다

abstract SharedPreferences.Editor

clear()

- 모든 값을 삭제 한다.

abstract boolean

commit()

- 동기 적으로 값을 저장 하고 결과를 리턴 한다

abstract SharedPreferences.Editor

putBoolean(String key, boolean value)

- bool 값을 설정 한다

abstract SharedPreferences.Editor

putFloat(String key, float value)

- float 값을 설정 한다

abstract SharedPreferences.Editor

putInt(String key, int value)

- int 값을 설정 한다

abstract SharedPreferences.Editor

putLong(String key, long value)

- long 값을 설정 한다

abstract SharedPreferences.Editor

putString(String key, String value)

- string 값을 설정 한다

abstract SharedPreferences.Editor

putStringSet(String key, Set values)

- set  값을 설정 한다

abstract SharedPreferences.Editor

remove(String key)

- key 해당하는 값을 삭제 한다

 

* putxxx() 작업은 반영을 위해 commit() 또는 apply()를 호출해야 합니다.

* remove()는 반영을 위해 commit()을 호출 해야 합니다.



2. 프로그램 설명

 

간단히 사용하는 저장 공간이기 때문에 설치하는 것도 없고

핸들만 얻어서 사용하면 됩니다.

 

2.1 Handle 얻기


getSharedPreferences() : 여러개의 Shared Preference 파일들을 사용 하는 경우

getPreferences() : 한개의 Shared Preference 파일을 사용하는 경우.

 

여기서는 첫번째 getSharedPreferences()를 사용 합니다.

정의는

public abstract SharedPreferences getSharedPreferences (String name, int mode)

이렇게 되어 있고


사용은

SharedPreferences sharePref = getSharedPreferences("SHARE_PREF", MODE_PRIVATE);

이렇게 합니다.


SHARE_PREF라는 이름의 저장소를 생성한 application에서만

사용가능 모드로 사용하기 위해 생성합니다.

만일 SHARE_PREF 라는파일이 없으면 신규로 생성 합니다.


 버튼을 클릭하면 작업을 하고 바로 리스트를 가져오도록 되어있습니다.

 

2.2 Data 저장


Editor를 이용하여 저장 합니다.

SharedPreferences.Editor editor = sharePref.edit();

각각의 데이터 타입별로 저장해 보았습니다.

public void saveData() {
    editor.putBoolean("isShare", true);
    editor.putFloat("fRate", 1.33f);
    editor.putInt("nValue", 100);
    editor.putString("name", "copycoding");
    editor.apply();

}

2.3 Data 수정


저장과 같은 방식으로 값만 변경하면 됩니다.

public void updateData() {
    editor.putBoolean("isShare", false);
    editor.putFloat("fRate", 3.33f);
    editor.putInt("nValue", 5000);
    editor.putString("name", "copycoding.tistory");
    editor.apply();
}

2.4 Data 삭제


remove()key값을 적어주면 됩니다.

public void deleteData() {
    editor.remove("nValue");
    editor.commit();
}

2.5 불러오기


최초 생성한 핸들(여기서는 sharePref)을 이용해서 불러옵니다.

public void listData() {
    String dataList = "";
    Map totalValue = sharePref.getAll();
    for(Map.Entry entry : totalValue.entrySet()) {
        dataList += entry.getKey().toString()+ ": " + entry.getValue().toString() + "\r\n";
        Log.d("share : ", entry.getKey() + ": " + entry.getValue());
    }
    tvList.setText(dataList);
}


저는 자동으로 출력하려고 만든거고 하나씩 가져오려면

sharePref.getString(“name”, “”);

이렇게 하면 됩니다.

뒤에 “”이건 default 값을 적어주는 것입니다.

 

 

3. Source Code

 

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

    <Button
        android:id="@+id/btn_onclick1"
        android:text="Save"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginTop="50dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:onClick="btnClick"/`
    <Button
        android:id="@+id/btn_onclick2"
        android:text="Update"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="100dp"
        android:layout_marginTop="50dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:onClick="btnClick"/>
    <Button
        android:id="@+id/btn_onclick3"
        android:text="Delete"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="190dp"
        android:layout_marginTop="50dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:onClick="btnClick"/>
    <Button
        android:id="@+id/btn_onclick4"
        android:text="Clear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="280dp"
        android:layout_marginTop="50dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        android:onClick="btnClick"/>

    <TextView
        android:id="@+id/tvList"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="SharedPreferences Test"
        android:layout_marginTop="100dp"
        android:textSize="25dp"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>


3.2 MainActivity.java


package copycoding.android.app.sharedprefer;

import android.content.SharedPreferences;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

import java.util.Map;

public class MainActivity extends AppCompatActivity {

    static private String SHARE_NAME = "SHARE_PREF";
    static SharedPreferences sharePref = null;
    static SharedPreferences.Editor editor = null;
    TextView tvList;

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

        tvList = (TextView)findViewById(R.id.tvList);

        sharePref = getSharedPreferences(SHARE_NAME, MODE_PRIVATE);
        editor = sharePref.edit();
    }

    public void btnClick(View view) {
        if(view.getId() == R.id.btn_onclick1) {  // Buttoon의 ID를 찾아서 실행이 된다.
            saveData();
        } else if(view.getId() == R.id.btn_onclick2) {
            updateData();
        } else if(view.getId() == R.id.btn_onclick3) {
            deleteData();
        } else if(view.getId() == R.id.btn_onclick4) {
            editor.clear();
            editor.commit();
        }
        listData();
    }

    public void saveData() {
        editor.putBoolean("isShare", true);
        editor.putFloat("fRate", 1.33f);
        editor.putInt("nValue", 100);
        editor.putString("name", "copycoding");
        editor.apply();

    }

    public void updateData() {
        editor.putBoolean("isShare", false);
        editor.putFloat("fRate", 3.33f);
        editor.putInt("nValue", 5000);
        editor.putString("name", "copycoding.tistory");
        editor.apply();
    }

    public void deleteData() {
        editor.remove("nValue");
        editor.commit();
    }

    public void listData() {
        String dataList = "";
        Map<String, ?> totalValue = sharePref.getAll();
        for(Map.Entry<String, ?> entry : totalValue.entrySet()) {
            dataList += entry.getKey().toString()+ ": " + entry.getValue().toString() + "\r\n";
            Log.d("share : ", entry.getKey() + ": " + entry.getValue());
        }
        tvList.setText(dataList);
    }
}


4. 결과


각각의 버튼에 대한 화면 입니다.

버튼을 클릭하면 기능을 수행하고 바로 결과에 대한 리스트를 출력합니다.



android data sharedpreferences



5. APK


다운받아 테스트를 해봅니다.


SharePref.apk


- copy coding -


1···78910111213···17

+ Recent posts