728x90

앱을 만들다보면 앱을 실행하면서 현재 위치 좌표값만 획득하고 싶을 경우가 있다.


AndroidManifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<!-- Android 10 이상 백그라운드 위치 액세스 요청 --> 


앱 build.gradle

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'androidx.constraintlayout:constraintlayout:1.1.3'

    implementation 'gun0912.ted:tedpermission:2.0.0'
    implementation 'com.google.android.gms:play-services-location:17.0.0'
    implementation 'com.naver.maps:map-sdk:3.7.1' // 네이버 지도 SDK

}


SplashActivity.java

public class SplashActivity extends AppCompatActivity {
    private final String TAG = this.getClass().getSimpleName();
    Context mContext;

    private final int GPS_ENABLE_REQUEST_CODE = 2001;
    private final long UPDATE_INTERVAL_MS = 1000 * 60 * 15;
    private final long FASTEST_UPDATE_INTERVAL_MS = 1000 * 30 ; // 30초 단위로 화면 갱신

    private FusedLocationProviderClient mFusedLocationProviderClient;
    private LocationRequest locationRequest;
    private double longitude, latitude;

    PermissionListener permissionlistener = new PermissionListener() {
        @Override
        public void onPermissionGranted() {
            initView();
        }

        @Override
        public void onPermissionDenied(ArrayList<String> deniedPermissions) {
            Toast.makeText(SplashActivity.this, "권한 허용을 하지 않으면 서비스를 이용할 수 없습니다.", Toast.LENGTH_SHORT).show();
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_splash);
        mContext = SplashActivity.this;
        PrefsHelper.init(getApplicationContext()); // 한번만 실행하면 된다.

        checkPermissions();
    }

    private void checkPermissions() {

        if(Build.VERSION.SDK_INT >= 26){ // 출처를 알 수 없는 앱 설정 화면 띄우기
            PackageManager pm = mContext.getPackageManager();
            if (!pm.canRequestPackageInstalls()){
                startActivity(new Intent(android.provider.Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
                        Uri.parse("package:" + getPackageName())));
            }
        }

        if (Build.VERSION.SDK_INT >= 23) { // 마시멜로(안드로이드 6.0) 이상 권한 체크
            TedPermission.with(mContext)
                    .setPermissionListener(permissionlistener)
                    .setRationaleMessage("앱을 이용하기 위해서는 접근 권한이 필요합니다")
                    .setDeniedMessage("앱에서 요구하는 권한설정이 필요합니다...\n [설정] > [권한] 에서 사용으로 활성화해주세요.")
                    .setPermissions(new String[]{
                            android.Manifest.permission.ACCESS_FINE_LOCATION,
                            android.Manifest.permission.ACCESS_COARSE_LOCATION
                            //android.Manifest.permission.ACCESS_BACKGROUND_LOCATION
                            //앱이 Android 10 이상 앱이 백그라운드에 있는 동안 정기 위치 업데이트를 받을 시
                    })
                    .check();

        } else {
            initView();
        }
    }

    private void initView() {
        checkLocationSetting();
    }

    @SuppressLint("MissingPermission")
    private void checkLocationSetting() {
        // https://developer.android.com/training/location/change-location-settings 읽어라.
        // 위치 요청 설정
        locationRequest = LocationRequest.create();
        locationRequest.setInterval(UPDATE_INTERVAL_MS); // 위치가 Update 되는 주기
        locationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_MS); // 위치 획득후 업데이트되는 주기
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        // 현재 위치 설정 받기
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder().addLocationRequest(locationRequest);
        SettingsClient settingsClient = LocationServices.getSettingsClient(this);
        settingsClient.checkLocationSettings(builder.build())
                .addOnSuccessListener(this, locationSettingsResponse -> {
                    mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(SplashActivity.this);
                    mFusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, null);
                })
                .addOnFailureListener(SplashActivity.this, e -> {
                    int statusCode = ((ApiException) e).getStatusCode();
                    switch (statusCode) {
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            try {
                                ResolvableApiException rae = (ResolvableApiException) e;
                                rae.startResolutionForResult(SplashActivity.this, GPS_ENABLE_REQUEST_CODE);
                            } catch (IntentSender.SendIntentException sie) {
                                Log.e(TAG, "unable to start resolution for result due to " + sie.getLocalizedMessage());
                            }
                            break;
                        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            Log.e(TAG, "Fix in Settings.");
                    }
                });
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == GPS_ENABLE_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                checkLocationSetting();
            } else {
                finish();
            }
        }
    }

    private LocationCallback locationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            super.onLocationResult(locationResult);
            longitude = locationResult.getLastLocation().getLongitude();
            latitude = locationResult.getLastLocation().getLatitude();
            mFusedLocationProviderClient.removeLocationUpdates(locationCallback);

            Log.e(TAG, "latitude:"+latitude+" , longitude:"+longitude);
            PrefsHelper.write("latitude", String.valueOf(latitude));
            PrefsHelper.write("longitude", String.valueOf(longitude));

            Intent intent = new Intent(SplashActivity.this, MainActivity.class);
            startActivity(intent);
            finish();
        }

        @Override
        public void onLocationAvailability(LocationAvailability locationAvailability) {
            super.onLocationAvailability(locationAvailability);
            Log.i(TAG, "onLocationAvailability - " + locationAvailability);
        }
    };

}
 


PrefsHelper.java

public class PrefsHelper {
    public static final String PREFERENCE_NAME="pref";
    private Context mContext;
    private static SharedPreferences prefs;
    private static SharedPreferences.Editor prefsEditor;
    private static PrefsHelper instance;

    public static synchronized PrefsHelper init(Context context){
        if(instance == null)
            instance = new PrefsHelper(context);
        return instance;
    }

    private PrefsHelper(Context context) {
        mContext = context;
        prefs = mContext.getSharedPreferences(PREFERENCE_NAME, Context.MODE_PRIVATE );
        prefsEditor = prefs.edit();
    }

    public static String read(String key, String defValue) {
        return prefs.getString(key, defValue);
    }

    public static void write(String key, String value) {
        prefsEditor.putString(key, value);
        prefsEditor.commit();
        // double 변수 값은 string으로 감싸서 데이터를 넘기면 된다.
    }

    public static Integer read(String key, int defValue) {
        return prefs.getInt(key, defValue); // 32비트
    }

    public static void write(String key, Integer value) {
        prefsEditor.putInt(key, value).commit();
    }

    public static long read(String key, Long defValue) {
        return prefs.getLong(key, defValue); // 64비트
    }

    public static void write(String key, Long value) {
        prefsEditor.putLong(key, value).commit();
    }

    public static boolean read(String key, boolean defValue) {
        return prefs.getBoolean(key, defValue);
    }

    public static void write(String key, boolean value) {
        prefsEditor.putBoolean(key, value);
        prefsEditor.commit();
    }
}


지도를 띄우지 않은 상태에서 현재 위치 좌표만 얻어지는 걸 확인할 수 있다.


참고하면 좋은 게시글

https://medium.com/@droidbyme/android-turn-on-gps-programmatically-d585cf29c1ef



728x90
블로그 이미지

Link2Me

,