0

다음 서비스를 사용하여 연속 위치 업데이트를위한 백그라운드 서비스가 생성되어 사용자 위치를 지속적으로 업데이트합니다. 앱이 백그라운드에서 실행 중이거나 기기가 유휴 상태이거나 화면이 꺼져 있거나 최근 목록에서 애플리케이션이 삭제/삭제 된 경우에도 사용자의 위치를 ​​추적해야합니다.fusedlocationAPI

하지만 어떻게 든이 코드는 작동하지 않습니다. 몇 시간 후에 자동으로 위치 업데이트가 중단되고 일부 기기에서는 작동하지 않아도 작동하지 않아서 이유를 이해할 수 없으며 모든 것을 파란색에서 보라색으로 바꿨습니다.

은 Gradle을 : 2.3.3 플레이 서비스와지도 혼란 스럽다 : 11.0.4 컴파일 SDK 버전 : 25

##하지만 안드로이드에이 응용 프로그램을 실행하고하는 것은 6.0.1 산들

은 밖으로 제발 도와주세요 이. 미리 감사드립니다.

public class ServiceLocationNew extends Service implements 
    GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { 

private static final long INTERVAL = 10000; 
private static final long FASTEST_INTERVAL = 10000; 
private static final long FUSED_DISTANCE = 5; 
LocationRequest mLocationRequest; 
GoogleApiClient mGoogleApiClient; 
Location mCurrentLocation; 
String mLastUpdateTime; 
Location mLastLocation; 

@Override 
public void onCreate() { 
    super.onCreate(); 
    buildApiClient(); 
} 

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

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    super.onStartCommand(intent, flags, startId); 
    if (mGoogleApiClient == null) { 
     buildApiClient(); 
    } 
    if (!isGooglePlayServicesAvailable()) { 
     stopSelf(); 
    } 
    createLocationRequest(); 
    return START_STICKY; 
} 

public void buildApiClient() { 
    if (mGoogleApiClient == null) { 
     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
     mGoogleApiClient.connect(); 
    } 
} 

private boolean isGooglePlayServicesAvailable() { 
    int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); 
    if (ConnectionResult.SUCCESS == status) { 
     return true; 
    } else { 
     return false; 
    } 
} 

protected void createLocationRequest() { 
    mLocationRequest = new LocationRequest(); 
    mLocationRequest.setInterval(INTERVAL); 
    mLocationRequest.setSmallestDisplacement(FUSED_DISTANCE); 
    mLocationRequest.setFastestInterval(FASTEST_INTERVAL); 
    mLocationRequest.setSmallestDisplacement(FUSED_DISTANCE); 
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    startLocationUpdates(); 
} 

protected void startLocationUpdates() { 
    if (ActivityCompat.checkSelfPermission(this,   Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
     // TODO: Consider calling 
     // ActivityCompat#requestPermissions 
     // here to request the missing permissions, and then overriding 
     // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
     //           int[] grantResults) 
     // to handle the case where the user grants the permission. See the documentation 
     // for ActivityCompat#requestPermissions for more details. 
     return; 
    } 

    LocationServices.FusedLocationApi.requestLocationUpdates(
      mGoogleApiClient, mLocationRequest, this); 
} 

protected void stopLocationUpdates() { 
    if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) { 
     LocationServices.FusedLocationApi.removeLocationUpdates(
       mGoogleApiClient, this); 
    } 
} 

@Override 
public void onConnected(Bundle bundle) { 
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
     // TODO: Consider calling 
     // ActivityCompat#requestPermissions 
     // here to request the missing permissions, and then overriding 
     // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
     //           int[] grantResults) 
     // to handle the case where the user grants the permission. See the documentation 
     // for ActivityCompat#requestPermissions for more details. 
     return; 
    } 
    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
    if (mLastLocation != null) { 
     updateUI(); 
    } 
    if (mGoogleApiClient.isConnected()) { 
     if (mLocationRequest != null) { 
      startLocationUpdates(); 
     } else { 
      createLocationRequest(); 
     } 
    } 
} 
@Override 
public void onConnectionSuspended(int i) { 

} 
@Override 
public void onConnectionFailed(ConnectionResult connectionResult) { 
    updateUI(); 
} 
@Override 
public void onLocationChanged(Location location) { 
    mCurrentLocation = location; 
    mLastUpdateTime = DateFormat.getTimeInstance().format(new Date()); 
    updateUI(); 
} 

public static float distFrom(double lat1, double lng1, double lat2, double lng2) { 
    double earthRadius = 6371000; //meters 
    double dLat = Math.toRadians(lat2 - lat1); 
    double dLng = Math.toRadians(lng2 - lng1); 
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
      Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * 
        Math.sin(dLng/2) * Math.sin(dLng/2); 
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 
    float dist = (float) (earthRadius * c); 

    return dist; 
} 


private void updateUI() { 
     if (mCurrentLocation != null) { 
//calculate distance between current and last location   

     double dLon = (Double.parseDouble(mLastLocation.getLongitude) - mCurrentLocation.getLongitude()); 
     double y = Math.sin(dLon) * Math.cos(Double.parseDouble(mLastLocation.getLatitude)); 
     double x = Math.cos(mCurrentLocation.getLatitude()) * Math.sin(Double.parseDouble(mLastLocation.getLatitude)) - Math.sin(mCurrentLocation.getLatitude()) * Math.cos(Double.parseDouble(mLastLocation.getLatitude)) * Math.cos(dLon); 
     double brng = Math.toDegrees((Math.atan2(y, x))); 
     brng = (360 - ((brng + 360) % 360)); 

     double earthRadius = 6371000; //meters 
    double dLat = Math.toRadians(mCurrentLocation.getLatitude() - mLastLocation.getLatitude()); 
    double dLng = Math.toRadians(mCurrentLocation.getLongitude() - mLastLocation.getLongitude()); 
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) + 
      Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * 
        Math.sin(dLng/2) * Math.sin(dLng/2); 
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); 
    float distance = (float) (earthRadius * c); 



     if (distance >= CV.LOCATION_DISTANCE) { 
         Tblname.Insert(mCurrentLocation); 
     } 
    } 

} 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 
     stopLocationUpdates(); 
    } 
} 
+0

정기적 인 서비스는 에너지를 저장하거나 자원을 확보하기 위해 시스템에 의해 파괴 될 수있다. 아마도 포 그라운드 서비스로 실행해야 할 것입니다. – Lukasz

+0

@ 루카스 전경 서비스를 원하지 않는다. 배경 서비스가 필요하다. – jil123

+1

왜? 그 위치를 왜 사용하고 있습니까? 안드로이드는 배경 [https://developer.android.com/about/versions/oreo/background-location-limits.html]에서 할 수있는 일에 점점 더 많은 제약을 가하고 있습니다. 아마도 느슨한 전투에 맞설 것입니다. – Lukasz

답변

0

Android Oreo를 실행하는 기기에서는이 기능을 사용할 수 없습니다. 그러나 다른 사람을 위해 당신은 당신의 매니페스트 파일에

<service 
      android:name=".YourLocationService" 
      android:exported="false" 
      android:process=":YourLocationService" 
      android:stopWithTask="false" /> 

을 설정하여이를 달성 할 수있다. stopWithTask="false"이 여기에 핵심입니다.

@Override 
    public void onTaskRemoved(Intent rootIntent) { 

     Intent restartService = new Intent(getApplicationContext(), this.getClass()); 
     PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 1, restartService, PendingIntent.FLAG_ONE_SHOT); 
     AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); 
     alarmManager.set(AlarmManager.ELAPSED_REALTIME, 5000, pendingIntent); 


    }