안드로이드) 서비스 내 무한루프 때문에 타 클래스로 onResume() 되었을 때 stopService()가 작동하지 않습니다. 혹시 해결법 아시는 분 계실까요?

조회수 1309회

안녕하세요, 위치 확인 어플리케이션을 개발하고 있는데 궁금증이 생겨 문의드리게 되었습니다.

현재, 서비스 기능이 활성화 되었을 때 지속적으로 디바이스의 gps 위치 정보 값을 불러오기 위해 while문을 활용해 무한 루프를 걸어놓은 상황입니다.

하지만, 이로 인해 앱이 백그라운드로 넘어갈 경우 서비스 실행에 따른 무한 루프가 발생하게 되어 다시 포그라운드로 돌아왔을 때 onResume() 메소드 내 stopService() 메소드가 작동되지 않습니다.

앱이 포그라운드로 돌아왔을 때 서비스 클래스의 while 문에 break를 걸어줘야 할 것 같은데 '앱이 포그라운드로 돌아왔다는' 것을 코드로 표현할 수 있는 방법을 몰라 헤매고 있습니다.

혹시 아시는 분 계실까요? 감사합니다 :)

코드는 다음과 같습니다.

  • 서비스 클래스

    public class ServiceGoogleMap extends Service implements LocationListener {
    // 위도, 경도
    Double latitude = 0.0;
    Double longitude = 0.0;
    
    // 내 uid
    String myUid;
    
    // 위치 입력하기 위한 변수 설정
    LocationManager locationManager;
    
    // start
    @Override
    public void onCreate() {
        super.onCreate();
    }
    
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        // 내 uid 불러오기
        myUid = FirebaseAuth.getInstance().getCurrentUser().getUid();
        System.out.println("service uid 확인: " + myUid);
        System.out.println("service 확인: onStartCommand 접근 완료");
    
        // 스레드 활용
        new Thread(new Runnable() {
            @Override
            public void run() {
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        while (true) {
                            // locationManager 설정
                            locationManager = (LocationManager) ServiceGoogleMap.this.getSystemService(Context.LOCATION_SERVICE);
    
                            // 허가 확인을 하지 않으면 해당 메소드들을 사용할 수 없습니다.
                            if (ContextCompat.checkSelfPermission(ServiceGoogleMap.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                                    && ContextCompat.checkSelfPermission(ServiceGoogleMap.this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                                // 어떤 방식으로 위치를 불러올지, 시간 간격, 몇 미터마다 갱신할 것인지, 리스너를 파라미터로 받습니다,
                                // 어디에 연결되었니? GPS || NETWORD
                                if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
                                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, ServiceGoogleMap.this);
    
                                    // 위치 변경 시 호출
                                    onLocationChanged(locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER));
                                    System.out.println("service 확인 gps 위치: " + locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER));;
                                }
                                // 네트워크 방식을 통한 위치 호출은 정확도가 급격히 떨어진다는 단점이 존재합니다.
                                else {
                                    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, ServiceGoogleMap.this);
    
                                    // 위치 변경 시 호출
                                    onLocationChanged(locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER));
                                    System.out.println("service 확인 기지국 위치: " + locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER));
                                }
                            } else {
                                Toast.makeText(ServiceGoogleMap.this, "권한이 필요합니다.", Toast.LENGTH_SHORT).show();
                            }
                        }
                    }
                });
            }
        }).start();
    
        return START_STICKY;
    }
    
    // 서비스 제거
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
    
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    
    // 위치 변경 시
    @Override
    public void onLocationChanged(Location location) {
        System.out.println("service 확인: onLocationChangerd 메소드 접근 완료");
    
        // 현재 위도와 경도 값을 받아옵니다.
        latitude = location.getLatitude();
        longitude = location.getLongitude();
    
        // 데이터 모델에 맞게 포맷합니다.
        final LocationModel locationModel = new LocationModel();
        locationModel.latitude = latitude;
        locationModel.longitude = longitude;
        locationModel.uid = myUid;
        locationModel.timestamp = ServerValue.TIMESTAMP;
    
        // 위치 데이터를 입력합니다.
        FirebaseDatabase.getInstance().getReference().child("locations").child(myUid)
                .setValue(locationModel)
                .addOnCompleteListener(new OnCompleteListener<Void>() {
                    @Override
                    public void onComplete(@NonNull Task<Void> task) {
                        //
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Toast.makeText(ServiceGoogleMap.this, "위치 입력에 실패했습니다.", Toast.LENGTH_SHORT).show();
                    }
                });
    }
    
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    
    }
    
    @Override
    public void onProviderEnabled(String provider) {
    
    }
    
    @Override
    public void onProviderDisabled(String provider) {
    
    }
    }
    
  • onResume() 메소드가 실행되는 클래스

    @Override
    protected void onPause() {
        super.onPause();
        // 서비스 매칭
        Intent serviceIntent = new Intent(this, ServiceGoogleMap.class);
        // 서비스 시작
        startService(serviceIntent);
        System.out.println("service 확인: 서비스 시작");
    }
    
    @Override
    protected void onResume() {
        System.out.println("resume 확인");
        super.onResume();
        // 서비스 매칭
        Intent serviceIntent = new Intent(this, ServiceGoogleMap.class);
        stopService(serviceIntent);
        System.out.println("service 확인: 서비스 종료");
    }
    

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)