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 - 


구글 애드센스는 광고를 자동으로 등록해주고 있지만 자신의 블로그에 적합하지 않거나 개인적으로 노출하기 싫은 광고도 노출이 되기 때문에 직접 선택적으로 차단해야 합니다.


google adsense logo

 

1. 일반 카테고리를 이용 차단

 

애드센스에 로그인을 합니다.


좌측 메뉴에서

차단관리 > 모든 사이트를 선택 합니다.



그러면 우측에 탭 메뉴가 나오고 여기서

일반 카테고리를 선택 합니다.


설명을 위해 하나를 선택해 보겠습니다.

금융과 관련 카테고리를 선택합니다.

허용됨으로 체크 되어있는 금융(52)를 클릭 합니다.



하부 카테고리 리스트에 추가적인 카테고리가 있는 경우 ▶ 표시가 있습니다.

이번엔 융자 대출을 클릭해 봅니다.



한번 차단을 해볼까요?

차단 하려는 광고 좌측 체크박스를 클릭하면 바로 적용이 됩니다.


하나씩 클기하며 차단을 적용 합니다.

상위 카테고리로 이동 하려면 위에 있는

네비게이션을 사용하면 됩니다.




2. 민감한 카테고리 이용 차단

 

일반 카테고리를 이용한 차단은 종류가 많아서 관리가 어렵다면

손쉽게 전체를 관리 할 수 있는 기능이 민감한 카테고리입니다.



~욱 한번 아래로 훌터보면 감이 잡히죠?

 

위에서부터 하나씩 보면서 맘에 들지 않는 광고 단어들을

좌측 체크박스를 클릭하면 바로 차단이 됩니다.



 

지금까지 5개월동안 1달러도 못번 블로그의 팁이었습니다. ㅋㅋ


2019년 황금 돼지해에는 꼭 원달라” “원달라


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


GitHub에 프로젝트를 upload 하고 필요 없거나 잘못 올린 경우

프로젝트를 삭제해야 하는 상황이 발생 합니다.

삭제는 버튼만 몇번 클릭하면 완료 됩니다.


git repository delete


GitHub에서 삭제할 repository를 선택 합니다.

그러면 파일이 있는 페이지로 이동 됩니다.



상단에 [Settings]를 선택 합니다.

 

이동된 페이지에 여러 가지 기능이 나오는데 아래로 쭈~욱 스크롤 합니다.

그럼 맨 마지막에 Danger Zone이 나옵니다.



[Delete this repository] 버튼을 클릭 합니다.

 

여러가지 경고 문구가 있는 팝업 창이 나옵니다.



삭제 하려는 repository명칭을 확인 하고

하단에 있는 긴 [I understand the conse….] 버튼을 클릭 합니다.

 

그러면 한번 더 취소할 수 있는 기회로 비번을 입력하라고 합니다.

여기서 비번을 입력 하고



[Confirm password] 버튼을 클릭하면 Repository 삭제가 완료 됩니다.

 

다시 GitHub 메인 페이지로 돌아오면



완전히 삭제되었음을 확인 할 수 있습니다.


- copy coding -


1···949596979899100···119

+ Recent posts