수색…


소개

Android 위치 API는 사용자 위치 찾기, 사용자가 일반 영역을 벗어 났을 때 알림 (지오 펜싱) 및 사용자 활동 (걷기, 달리기, 운전 등)을 해석하는 것과 같은 다양한 용도로 다양한 앱에서 사용됩니다.

그러나 Android 위치 API 만 사용자 위치를 획득하는 수단이 아닙니다. 다음은 Android의 LocationManager 및 기타 일반 위치 라이브러리 사용 방법에 대한 예제를 제공합니다.

비고

Android에서 위치 인식 앱을 제작하는 데는 두 가지 경로가 있습니다.

LocationManager

찬성

  • 보다 세부적인 제어
  • 모든 기기에서 사용 가능
  • Android 프레임 워크의 일부

단점

  • 제대로 관리하지 않으면 배터리 소모가 문제입니다.
  • 장치가 위치를 찾을 수없는 경우 위치 공급자를 전환하는 논리가 필요합니다 (예 : 건물 내부의 가난한 GPS)

풍모

  • NMEA 리스너
  • GPS 상태 수신기
  • 제공 업체 상태 변경 내용을 듣습니다 (예 : 사용자가 GPS를 사용 중지 한 경우).
  • 위치 소스를 선택할 공급자 목록

제공 업체

GPS

  • 필요한 사용 권한 :
  • 정확도 : 10m - 100m
  • 전원 요구 사항 : 높음
  • 가용성 : 전 세계 (하늘을 시야에서 볼 수 있음)
  • 참고 사항 :
    • 위치 업데이트는 일반적으로 1 초에 한 번씩 발생하지만 GPS를 사용하지 않고 A-GPS 를 사용할 수없는 경우 위치 수신에 몇 분이 걸립니다.
    • 명확한 하늘의 시야가 가려진 경우 GPS 점이 잘 분류되지 않고 (위치 점이 점프) 정확도가 " Urban Canyon "효과로 인해 특정 지역에서 오도 할 수 있습니다.

회로망

  • 필요한 사용 권한 :
  • 정확도 : 100m - 1000m +
  • 전원 요구 사항 : 낮음 - 보통
  • 가용성 : 셀 타워 또는 무선 신호 범위 내
  • 노트:
    • 위치 업데이트가 GPS보다 자주 발생하지 않음
    • 위치 업데이트는 일반적으로 잘 클러스터되지 않으며 (위치 점 "점프") 정확도는 다양한 요소 (Wi-Fi 신호 수, 신호 강도, 셀 타워 유형 등)의 수에 따라 달라질 수 있습니다.

수동태

  • 필요한 사용 권한 :
  • 정확도 : 10m - 1000m +
  • 전원 요구 사항 : NONE
  • 가용성 : 다른 앱이 GPS 또는 네트워크에서 위치 정보를 수신 한 경우에만
  • 노트:
    • 지속적인 업데이트를 제공하기 위해이 정보에 의존하지 마십시오. 이것은 위치 요청을하는 다른 앱에 수동적으로 귀 기울이고 그 위치를 다시 전달합니다.
    • 생성 된 점을 FusedLocationProviderApi로 반환하지 않으며 생성 된 점만 생성합니다.

FusedLocationProviderApi

찬성

  • 배터리 소모를 줄여주는 "out of the box"
  • 가난한 GPS를 잘 처리합니다.
  • 정기적으로 업데이트를 가져옵니다.

단점

  • GPS를 통한 덜 세분화 된 제어
  • 모든 기기 또는 특정 국가에서 사용 가능하지 않을 수 있습니다.
  • 타사 라이브러리 의존성 필요

풍모

  • 최적의 배트 저축을 위해 위치 공급자의 잘 관리 된 사용
  • 일반적으로 네트워크 위치 공급자보다 정확한 지점을 생성합니다.
  • 도서관의 빈번한 업데이트로 개선 가능
  • 사용할 공급자 유형을 지정할 필요가 없습니다.

LocationRequest 우선 순위 수준

PRIORITY_HIGH_ACCURACY

  • 필요한 사용 권한 :
  • 정확도 : 10m - 100m
  • 전원 요구 사항 : 높음
  • 제공 여부 : Google Play 서비스를 이용할 수있는 곳이면 어디에서나 사용할 수 있습니다.
  • 노트:
    • ACCESS_FINE_LOCATION 사용하지 않으면 위치 업데이트를 생성하는 데 GPS가 사용되지 않지만 올바른 조건에서 상당히 정확한 지점을 찾습니다.
    • ACCESS_FINE_LOCATION 이 (가) 사용되면 환경 조건에 따라 현재 GPS가 기기를 얼마나 정확하게 추적 할 수 있는지에 따라 GPS를 사용하여 위치 지점을 생성 할 수도 있고 사용하지 않을 수도 있습니다.
    • 이것은 다른 설정보다 더 정확한 위치 업데이트를보고 할 수 있지만, 여전히 " Urban Canyon "효과를 내기 쉽습니다.

PRIORITY_BALANCED_POWER_ACCURACY

  • 필요한 사용 권한 :
  • 정확도 : 100m - 1000m +
  • 전원 요구 사항 : MEDIUM
  • 제공 여부 : Google Play 서비스를 이용할 수있는 곳이면 어디에서나 사용할 수 있습니다.
  • 노트:
    • PRIORITY_HIGH_ACCURACY 와 같은 메모
    • 가능성은 낮지 만이 설정은 GPS를 사용하여 위치를 생성 할 수 있습니다.

PRIORITY_LOW_POWER

  • 필요한 사용 권한 :
  • 정확도 : 100m - 1000m +
  • 전원 요구 사항 : 낮음
  • 제공 여부 : Google Play 서비스를 이용할 수있는 곳이면 어디에서나 사용할 수 있습니다.
  • 노트:
    • GPS를 사용하지는 않았지만 지금까지는 테스트되지 않았습니다.
    • 업데이트는 일반적으로 정확하지 않습니다.
    • 위치의 중요한 변화를 감지하는 데 일반적으로 사용됩니다.

PRIORITY_NO_POWER

  • 필요한 사용 권한 :
  • 정확도 : 10m - 1000m +
  • 전원 요구 사항 : NONE
  • 제공 여부 : Google Play 서비스를 이용할 수있는 곳이면 어디에서나 사용할 수 있습니다.
  • 노트:
    • LocationManager PASSIVE_PROVIDER 거의 동일하게 기능 PASSIVE_PROVIDER
    • 수신시 Google Play 서비스 업데이트를 다시보고 PASSIVE_PROVIDER . PASSIVE_PROVIDER 는 사용 된 기본 위치 업데이트를보고 PASSIVE_PROVIDER

문제 해결

호출되지 않은 OnLocationChanged ()

이것은 Android 위치 정보를 얻는 데있어 공통적 인 문제인 것으로 보이므로 일반적인 수정 사항에 대한 빠른 점검 목록을 작성합니다.


  1. 매니페스트를 확인하십시오!

    가장 일반적인 문제 중 하나는 올바른 사용 권한이 부여되지 않았다는 것입니다. GPS를 사용하거나 네트워크를 사용하지 않는 경우 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/> 사용하고 그렇지 않으면 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> . Google의 FusedLocationApi에는 ACCESS_FINE_LOCATION 가) 필요합니다.


  1. (Android 6 이상) 런타임 권한을 확인하십시오 !

    확인하고 권한을 요청하십시오! 권한을 부여받지 못하면 충돌로 끝나거나 모든 예외를 포착하는 경우 악화됩니다. 아무 것도 표시하지 않습니다. 사용자가 앱 시작시 권한을 부여했는지 여부는 중요하지 않습니다. 항상 모든 통화에 대한 권한이 있는지 확인하십시오. 사용자는 쉽게 자신의 설정으로 이동하여 취소 할 수 있습니다.


  1. 코드를 다시 확인하십시오!

    올바른 청취자를 보내시겠습니까? BroadcastReceiver 또는 IntentService 를 매니페스트에 추가 했습니까? BroadcastReceiver 클래스에서 PendingIntent.getService() 를 사용하거나 IntentService 클래스에서 IntentService getBroadcast() 를 사용하고 있습니까? 요청한 즉시 청취자를 코드의 다른 곳에서 등록 해제하지 않습니까?


  1. 장치 설정을 확인하십시오!

    분명히 위치 서비스가 켜져 있는지 확인하십시오.

    여기에 이미지 설명을 입력하십시오.

    네트워크 서비스를 사용하는 경우 "항상 검색 가능"으로 설정 했습니까? 위치 모드를 "최고"( "정확도") 또는 "배터리 절약"( "네트워크 전용")으로 설정 했습니까?

    여기에 이미지 설명을 입력하십시오.

    GPS를 사용하는 경우 위치 모드에서 '최고'( '높은 정확도') 또는 '기기 전용'을 사용하도록 설정 했습니까?

    여기에 이미지 설명을 입력하십시오.


  1. 코드를 다시 확인하십시오!

    예, 여기가 두 번 있습니다. PendingIntent 대신 LocationListener 를 사용해 보았는가, 또는 그 반대로, 실제로 LocationManager 를 실제로 구현 했는가? 발생할 것으로 예상되지 않은 활동 또는 서비스 수명주기의 일부에서 위치 요청이 제거되지 않았습니까?


  1. 주변을 확인하십시오!

    샌프란시스코 한가운데있는 건물 1 층에서 GPS를 테스트하고 있습니까? 중간에 네트워크 위치를 테스트하고 있습니까? 당신은 왜 당신의 장치가 위치를 알 수 없는지 궁금해 모든 무선 신호의 비밀 지하 지하 벙커에서 일하고 있습니까? 위치 문제를 해결할 때 항상 주변을 두 번 확인하십시오!


위치가 작동하지 않는 다른 덜 분명한 이유가있을 수 있지만, 이러한 난해한 문제를 검색하기 전에이 빠른 점검 목록을 실행하십시오.

통합 위치 API

LocationRequest를 사용하는 예제 사용

/*
 * This example is useful if you only want to receive updates in this 
 * activity only, and have no use for location anywhere else.
 */
public class LocationActivity extends AppCompatActivity implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {

    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

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

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        mLocationRequest = new LocationRequest()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) //GPS quality location points
                .setInterval(2000) //At least once every 2 seconds
                .setFastestInterval(1000); //At most once a second
    }

    @Override
    protected void onStart(){
        super.onStart();
        mGoogleApiClient.connect();
    }
    
    @Override
    protected void onResume(){
        super.onResume();
        //Permission check for Android 6.0+
        if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if(mGoogleApiClient.isConnected()) {
                LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
            }
        }
    }
    
    @Override
    protected void onPause(){
        super.onPause();
        //Permission check for Android 6.0+
        if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if(mGoogleApiClient.isConnected()) {
                LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
            }
        }
    }
    
    @Override
    protected void onStop(){
        super.onStop();
        mGoogleApiClient.disconnect();
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
    }

    @Override
    public void onLocationChanged(Location location) {
        //Handle your location update code here
    }
}

PendingIntent 및 BroadcastReceiver를 사용하는 서비스의 예

예제 액티비티

추천 도서 : LocalBroadcastManager

/*
 * This example is useful if you have many different classes that should be 
 * receiving location updates, but want more granular control over which ones
 * listen to the updates.
 * 
 * For example, this activity will stop getting updates when it is not visible, but a database
 * class with a registered local receiver will continue to receive updates, until "stopUpdates()" is called here.
 *
 */
public class ExampleActivity extends AppCompatActivity {

    private InternalLocationReceiver mInternalLocationReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        
        //Create internal receiver object in this method only.
        mInternalLocationReceiver = new InternalLocationReceiver(this);
    }

    @Override
    protected void onResume(){
        super.onResume();
        
        //Register to receive updates in activity only when activity is visible
        LocalBroadcastManager.getInstance(this).registerReceiver(mInternalLocationReceiver, new IntentFilter("googleLocation"));
    }

    @Override
    protected void onPause(){
        super.onPause();
        
        //Unregister to stop receiving updates in activity when it is not visible.
        //NOTE: You will still receive updates even if this activity is killed.
        LocalBroadcastManager.getInstance(this).unregisterReceiver(mInternalLocationReceiver);
    }

    //Helper method to get updates
    private void requestUpdates(){
        startService(new Intent(this, LocationService.class).putExtra("request", true));
    }

    //Helper method to stop updates
    private void stopUpdates(){
        startService(new Intent(this, LocationService.class).putExtra("remove", true));
    }

    /*
     * Internal receiver used to get location updates for this activity.
     * 
     * This receiver and any receiver registered with LocalBroadcastManager does
     * not need to be registered in the Manifest.
     *
     */
    private static class InternalLocationReceiver extends BroadcastReceiver{

        private ExampleActivity mActivity;

        InternalLocationReceiver(ExampleActivity activity){
            mActivity = activity;
        }

        @Override
        public void onReceive(Context context, Intent intent) {
            final ExampleActivity activity = mActivity;
            if(activity != null) {
                LocationResult result = intent.getParcelableExtra("result");
                //Handle location update here
            }
        }
    }
}

LocationService

참고 : 매니페스트에이 서비스를 등록하는 것을 잊지 마십시오!

public class LocationService extends Service implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

    @Override
    public void onCreate(){
        super.onCreate();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();

        mLocationRequest = new LocationRequest()
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY) //GPS quality location points
                .setInterval(2000) //At least once every 2 seconds
                .setFastestInterval(1000); //At most once a second
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId){
        super.onStartCommand(intent, flags, startId);
        //Permission check for Android 6.0+
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            if (intent.getBooleanExtra("request", false)) {
                if (mGoogleApiClient.isConnected()) {
                    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, getPendingIntent());
                } else {
                    mGoogleApiClient.connect();
                }
            }
            else if(intent.getBooleanExtra("remove", false)){
                stopSelf();
            }
        }

        return START_STICKY;
    }

    @Override
    public void onDestroy(){
        super.onDestroy();
        if(mGoogleApiClient.isConnected()){
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, getPendingIntent());
            mGoogleApiClient.disconnect();
        }
    }
    
    private PendingIntent getPendingIntent(){
        
        //Example for IntentService
        //return PendingIntent.getService(this, 0, new Intent(this, **YOUR_INTENT_SERVICE_CLASS_HERE**), PendingIntent.FLAG_UPDATE_CURRENT);
        
        //Example for BroadcastReceiver
        return PendingIntent.getBroadcast(this, 0, new Intent(this, LocationReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
    }

    @Override
    public void onConnected(@Nullable Bundle bundle) {
        //Permission check for Android 6.0+
        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, getPendingIntent());
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

LocationReceiver

참고 : 매니페스트에이 수신기를 등록하는 것을 잊지 마십시오!

public class LocationReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        if(LocationResult.hasResult(intent)){
            LocationResult locationResult = LocationResult.extractResult(intent);
            LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("googleLocation").putExtra("result", locationResult));
        }
    }
}

LocationManager를 사용하여 위치 업데이트 요청

항상 그렇듯이 필요한 권한이 있는지 확인해야합니다.

public class MainActivity extends AppCompatActivity implements LocationListener{

    private LocationManager mLocationManager = null;

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

        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    }


    @Override
    protected void onResume() {
        super.onResume();

        try {
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
        }
        catch(SecurityException e){
            // The app doesn't have the correct permissions
        }
    }


    @Override
    protected void onPause() {
        try{
            mLocationManager.removeUpdates(this);
        }
        catch (SecurityException e){
            // The app doesn't have the correct permissions
        }

        super.onPause();
    }




    @Override
    public void onLocationChanged(Location location) {
        // We received a location update!
        Log.i("onLocationChanged", location.toString());
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
}

LocationManager를 사용하여 별도의 스레드에서 위치 업데이트 요청

항상 그렇듯이 필요한 권한이 있는지 확인해야합니다.

public class MainActivity extends AppCompatActivity implements LocationListener{

    private LocationManager mLocationManager = null;
    HandlerThread mLocationHandlerThread = null;
    Looper mLocationHandlerLooper = null;


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

        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        mLocationHandlerThread = new HandlerThread("locationHandlerThread");
    }


    @Override
    protected void onResume() {
        super.onResume();

        mLocationHandlerThread.start();
        mLocationHandlerLooper = mLocationHandlerThread.getLooper();

        try {
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this, mLocationHandlerLooper);
        }
        catch(SecurityException e){
            // The app doesn't have the correct permissions
        }
    }


    @Override
    protected void onPause() {
        try{
            mLocationManager.removeUpdates(this);
        }
        catch (SecurityException e){
            // The app doesn't have the correct permissions
        }

        mLocationHandlerLooper = null;

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2)
            mLocationHandlerThread.quitSafely();
        else
            mLocationHandlerThread.quit();

        mLocationHandlerThread = null;


        super.onPause();
    }




    @Override
    public void onLocationChanged(Location location) {
        // We received a location update on a separate thread!
        Log.i("onLocationChanged", location.toString());

        // You can verify which thread you're on by something like this:
        // Log.d("Which thread?", Thread.currentThread() == Looper.getMainLooper().getThread() ? "UI Thread" : "New thread");
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }
}

지오 펜스 등록

GeoFenceObserversationService 싱글 톤 클래스를 만들었습니다.

GeoFenceObserversationService.java :

public class GeoFenceObserversationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, ResultCallback<Status> {

    protected static final String TAG = "GeoFenceObserversationService";
    protected GoogleApiClient mGoogleApiClient;
    protected ArrayList<Geofence> mGeofenceList;
    private boolean mGeofencesAdded;
    private SharedPreferences mSharedPreferences;
    private static GeoFenceObserversationService mInstant;
    public static GeoFenceObserversationService getInstant(){
        return mInstant;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mInstant = this;
        mGeofenceList = new ArrayList<Geofence>();
        mSharedPreferences = getSharedPreferences(AppConstants.SHARED_PREFERENCES_NAME, MODE_PRIVATE);
        mGeofencesAdded = mSharedPreferences.getBoolean(AppConstants.GEOFENCES_ADDED_KEY, false);

        buildGoogleApiClient();
    }


    @Override
    public void onDestroy() {
        mGoogleApiClient.disconnect();
        super.onDestroy();
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_STICKY;
    }

    protected void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnected(Bundle connectionHint) {
    }

    @Override
    public void onConnectionFailed(ConnectionResult result) {
    }

    @Override
    public void onConnectionSuspended(int cause) {

    }

    private GeofencingRequest getGeofencingRequest() {

        GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
        builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
        builder.addGeofences(mGeofenceList);
        return builder.build();
    }


    public void addGeofences() {
            if (!mGoogleApiClient.isConnected()) {
                Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
                return;
            }

        populateGeofenceList();
        if(!mGeofenceList.isEmpty()){
            try {
                LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, getGeofencingRequest(), getGeofencePendingIntent()).setResultCallback(this);
            } catch (SecurityException securityException) {
                securityException.printStackTrace();
            }
        }

        }

    public void removeGeofences() {
        if (!mGoogleApiClient.isConnected()) {
            Toast.makeText(this, getString(R.string.not_connected), Toast.LENGTH_SHORT).show();
            return;
        }
        try {
            LocationServices.GeofencingApi.removeGeofences(mGoogleApiClient,getGeofencePendingIntent()).setResultCallback(this);
        } catch (SecurityException securityException) {
            securityException.printStackTrace();
        }
    }


    public void onResult(Status status) {

        if (status.isSuccess()) {
            mGeofencesAdded = !mGeofencesAdded;
            SharedPreferences.Editor editor = mSharedPreferences.edit();
            editor.putBoolean(AppConstants.GEOFENCES_ADDED_KEY, mGeofencesAdded);
            editor.apply();
        } else {
            String errorMessage = AppConstants.getErrorString(this,status.getStatusCode());
            Log.i("Geofence", errorMessage);
        }
    }

    private PendingIntent getGeofencePendingIntent() {
        Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
        return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private void populateGeofenceList() {
        mGeofenceList.clear();
        List<GeoFencingResponce> geoFenceList = getGeofencesList;
        if(geoFenceList!=null&&!geoFenceList.isEmpty()){
            for (GeoFencingResponce obj : geoFenceList){
                mGeofenceList.add(obj.getGeofence());
                Log.i(TAG,"Registered Geofences : " + obj.Id+"-"+obj.Name+"-"+obj.Lattitude+"-"+obj.Longitude);
            }
        }
    }
}

AppConstant :

   public static final String SHARED_PREFERENCES_NAME = PACKAGE_NAME + ".SHARED_PREFERENCES_NAME";
    public static final String GEOFENCES_ADDED_KEY = PACKAGE_NAME + ".GEOFENCES_ADDED_KEY";
    public static final String DETECTED_GEOFENCES = "detected_geofences";
    public static final String DETECTED_BEACONS = "detected_beacons";

    public static String getErrorString(Context context, int errorCode) {
        Resources mResources = context.getResources();
        switch (errorCode) {
            case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
                return mResources.getString(R.string.geofence_not_available);
            case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
                return mResources.getString(R.string.geofence_too_many_geofences);
            case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
                return mResources.getString(R.string.geofence_too_many_pending_intents);
            default:
                return mResources.getString(R.string.unknown_geofence_error);
        }
    }

서비스를 시작한 곳은 어디입니까? 응용 프로그램 클래스에서

  • startService(new Intent(getApplicationContext(),GeoFenceObserversationService.class));

지오 펜스를 어떻게 등록 했습니까?

  • GeoFenceObserversationService.getInstant().addGeofences();

Geocoder를 사용하여 위치에서 주소 가져 오기

FusedAPI 에서 Location 객체를 얻은 후에는 해당 객체에서 Address 정보를 쉽게 얻을 수 있습니다.

private Address getCountryInfo(Location location) {
    Address address = null;
    Geocoder geocoder = new Geocoder(getActivity(), Locale.getDefault());
    String errorMessage;
    List<Address> addresses = null;
    try {
        addresses = geocoder.getFromLocation(
                location.getLatitude(),
                location.getLongitude(),
                // In this sample, get just a single address.
                1);
    } catch (IOException ioException) {
        // Catch network or other I/O problems.
        errorMessage = "IOException>>" + ioException.getMessage();
    } catch (IllegalArgumentException illegalArgumentException) {
        // Catch invalid latitude or longitude values.
        errorMessage = "IllegalArgumentException>>" + illegalArgumentException.getMessage();
    }
    if (addresses != null && !addresses.isEmpty()) {
        address = addresses.get(0);
    }
    return country;
}

BroadcastReceiver에서 위치 업데이트 받기

먼저 수신 위치 업데이트를 처리 할 BroadcastReceiver 클래스를 만듭니다.

public class LocationReceiver extends BroadcastReceiver implements Constants {

    @Override
     public void onReceive(Context context, Intent intent) {

        if (LocationResult.hasResult(intent)) {
            LocationResult locationResult = LocationResult.extractResult(intent);
            Location location = locationResult.getLastLocation();
            if (location != null) {
                // Do something with your location
            } else {
                Log.d(LocationReceiver.class.getSimpleName(), "*** location object is null ***");
            }
        }
    }
}

그런 다음 onConnected 콜백에서 GoogleApiClient에 연결할 때 :

@Override
public void onConnected(Bundle connectionHint) {
    Intent backgroundIntent = new Intent(this, LocationReceiver.class);
    mBackgroundPendingIntent = backgroundPendingIntent.getBroadcast(getApplicationContext(), LOCATION_REUEST_CODE, backgroundIntent, PendingIntent.FLAG_CANCEL_CURRENT);
    mFusedLocationProviderApi.requestLocationUpdates(mLocationClient, mLocationRequest, backgroundPendingIntent);
}

해당 라이프 사이클 콜백에서 위치 업데이트 인 텐트를 제거하는 것을 잊지 마십시오.

@Override
public void onDestroy() {
    if (servicesAvailable && mLocationClient != null) {
        if (mLocationClient.isConnected()) {
            fusedLocationProviderApi.removeLocationUpdates(mLocationClient, backgroundPendingIntent);
            // Destroy the current location client
            mLocationClient = null;
        } else {
            mLocationClient.unregisterConnectionCallbacks(this);
            mLocationClient = null;
        }
    }
    super.onDestroy();
}


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow