Android의 위치 리스너가있는 백그라운드 서비스
자체 프로세스에서 실행되는 백그라운드 서비스를 만들고 있습니다. 장치 위치가 변경된 경우들을 수 있어야합니다. UI에 알리기 전에 이동 거리와 같은 기준을 변경할 수 있어야합니다.
어떻게해야하나요? 서비스 및 LocationListener구현에 대해 약간의 지식이 있습니다 . 인터넷에 대한 모든 자습서를 주시면 감사하겠습니다.
스택 오버플로에서 하나의 백 링크 를 얻었 지만 그다지 이해하지 못했습니다.
먼저 Service. 그것 Service에서 확장하는 클래스를 만듭니다 LocationListener. 이를 위해 다음 코드 스 니펫을 사용하십시오 Service.
public class LocationService extends Service {
public static final String BROADCAST_ACTION = "Hello World";
private static final int TWO_MINUTES = 1000 * 60 * 2;
public LocationManager locationManager;
public MyLocationListener listener;
public Location previousBestLocation = null;
Intent intent;
int counter = 0;
@Override
public void onCreate() {
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
}
@Override
public void onStart(Intent intent, int startId) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
listener = new MyLocationListener();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 4000, 0, (LocationListener) listener);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener);
}
@Override
public IBinder onBind(Intent intent)
{
return null;
}
protected boolean isBetterLocation(Location location, Location currentBestLocation) {
if (currentBestLocation == null) {
// A new location is always better than no location
return true;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use the new location
// because the user has likely moved
if (isSignificantlyNewer) {
return true;
// If the new location is more than two minutes older, it must be worse
} else if (isSignificantlyOlder) {
return false;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are from the same provider
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and accuracy
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
return true;
}
return false;
}
/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
@Override
public void onDestroy() {
// handler.removeCallbacks(sendUpdatesToUI);
super.onDestroy();
Log.v("STOP_SERVICE", "DONE");
locationManager.removeUpdates(listener);
}
public static Thread performOnBackgroundThread(final Runnable runnable) {
final Thread t = new Thread() {
@Override
public void run() {
try {
runnable.run();
} finally {
}
}
};
t.start();
return t;
}
public class MyLocationListener implements LocationListener
{
public void onLocationChanged(final Location loc)
{
Log.i("*****", "Location changed");
if(isBetterLocation(loc, previousBestLocation)) {
loc.getLatitude();
loc.getLongitude();
intent.putExtra("Latitude", loc.getLatitude());
intent.putExtra("Longitude", loc.getLongitude());
intent.putExtra("Provider", loc.getProvider());
sendBroadcast(intent);
}
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
public void onProviderDisabled(String provider)
{
Toast.makeText( getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT ).show();
}
public void onProviderEnabled(String provider)
{
Toast.makeText( getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
}
}
이 추가 Service언제 어디 프로젝트에서, 당신이 원하는 방식으로! :)
이 답변을 조금 늦게 게시하고 있음을 알고 있지만 Google의 퓨즈 위치 공급자 서비스를 사용하여 현재 위치를 알아볼 가치가 있다고 느꼈습니다.
이 API의 주요 기능은 다음과 같습니다.
1. 간단한 API : 전력 소비량뿐만 아니라 정확도 수준을 선택할 수 있습니다.
2. 즉시 사용 가능 : 앱이 가장 최근의 위치에 즉시 액세스 할 수 있도록합니다.
3. 전력 효율성 : 전력 소비가 적은 위치를 찾는 가장 효율적인 방법을 선택합니다.
4. 다양성 : 매우 정확한 위치가 필요한 전경 사용부터 무시할 수있는 전력 영향으로주기적인 위치 업데이트가 필요한 배경 사용에 이르기까지 다양한 요구 사항을 충족합니다.
위치에서 업데이트하는 동안 유연합니다. 앱이 시작될 때만 현재 위치를 원한다면 getLastLocation(GoogleApiClient)방법 을 사용할 수 있습니다 .
지속적으로 위치를 업데이트하려면 다음을 사용할 수 있습니다. requestLocationUpdates(GoogleApiClient,LocationRequest, LocationListener)
여기에서 퓨즈 위치에 대한 매우 멋진 블로그를 찾을 수 있으며 퓨즈 위치에 대한 Google 문서도 여기 에서 찾을 수 있습니다 .
최신 정보
Android O에서 시작하는 개발자 문서에 따르면 백그라운드 위치에 대한 새로운 제한이 추가되었습니다.
앱이 백그라운드에서 실행중인 경우 위치 시스템 서비스는 앱의 새 위치를 매시간 몇 번만 계산합니다. 앱이 더 자주 위치 업데이트를 요청하는 경우에도 마찬가지입니다. 그러나 앱이 포 그라운드에서 실행되는 경우 Android 7.1.1 (API 레벨 25)과 비교하여 위치 샘플링 비율에 변화가 없습니다.
백그라운드 위치 서비스. 앱을 종료 한 후에도 다시 시작됩니다.
MainActivity.java
public class MainActivity extends AppCompatActivity {
AlarmManager alarmManager;
Button stop;
PendingIntent pendingIntent;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (alarmManager == null) {
alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceive.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 30000,
pendingIntent);
}
}
}
BookingTrackingService.java
public class BookingTrackingService extends Service implements LocationListener {
private static final String TAG = "BookingTrackingService";
private Context context;
boolean isGPSEnable = false;
boolean isNetworkEnable = false;
double latitude, longitude;
LocationManager locationManager;
Location location;
private Handler mHandler = new Handler();
private Timer mTimer = null;
long notify_interval = 30000;
public double track_lat = 0.0;
public double track_lng = 0.0;
public static String str_receiver = "servicetutorial.service.receiver";
Intent intent;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
mTimer = new Timer();
mTimer.schedule(new TimerTaskToGetLocation(), 5, notify_interval);
intent = new Intent(str_receiver);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.context = this;
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
Log.e(TAG, "onDestroy <<");
if (mTimer != null) {
mTimer.cancel();
}
}
private void trackLocation() {
Log.e(TAG, "trackLocation");
String TAG_TRACK_LOCATION = "trackLocation";
Map<String, String> params = new HashMap<>();
params.put("latitude", "" + track_lat);
params.put("longitude", "" + track_lng);
Log.e(TAG, "param_track_location >> " + params.toString());
stopSelf();
mTimer.cancel();
}
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
/******************************/
private void fn_getlocation() {
locationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
isGPSEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnable && !isNetworkEnable) {
Log.e(TAG, "CAN'T GET LOCATION");
stopSelf();
} else {
if (isNetworkEnable) {
location = null;
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
Log.e(TAG, "isNetworkEnable latitude" + location.getLatitude() + "\nlongitude" + location.getLongitude() + "");
latitude = location.getLatitude();
longitude = location.getLongitude();
track_lat = latitude;
track_lng = longitude;
// fn_update(location);
}
}
}
if (isGPSEnable) {
location = null;
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
Log.e(TAG, "isGPSEnable latitude" + location.getLatitude() + "\nlongitude" + location.getLongitude() + "");
latitude = location.getLatitude();
longitude = location.getLongitude();
track_lat = latitude;
track_lng = longitude;
// fn_update(location);
}
}
}
Log.e(TAG, "START SERVICE");
trackLocation();
}
}
private class TimerTaskToGetLocation extends TimerTask {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
fn_getlocation();
}
});
}
}
// private void fn_update(Location location) {
//
// intent.putExtra("latutide", location.getLatitude() + "");
// intent.putExtra("longitude", location.getLongitude() + "");
// sendBroadcast(intent);
// }
}
AlarmReceive.java (BroadcastReceiver)
public class AlarmReceive extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.e("Service_call_" , "You are in AlarmReceive class.");
Intent background = new Intent(context, BookingTrackingService.class);
// Intent background = new Intent(context, GoogleService.class);
Log.e("AlarmReceive ","testing called broadcast called");
context.startService(background);
}
}
AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<service
android:name=".ServiceAndBroadcast.BookingTrackingService"
android:enabled="true" />
<receiver
android:name=".ServiceAndBroadcast.AlarmReceive"
android:exported="false">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
매우 쉽게 클래스를 만들 필요가 없습니다 LocationListener 1- Variable
private LocationManager mLocationManager;
private LocationListener mLocationListener;
private static double currentLat =0;
private static double currentLon =0;
2- onStartService ()
@Override public void onStartService() {
addListenerLocation();
}
3- 메소드 addListenerLocation ()
private void addListenerLocation() {
mLocationManager = (LocationManager)
getSystemService(Context.LOCATION_SERVICE);
mLocationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
currentLat = location.getLatitude();
currentLon = location.getLongitude();
Toast.makeText(getBaseContext(),currentLat+"-"+currentLon, Toast.LENGTH_SHORT).show();
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
Location lastKnownLocation = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if(lastKnownLocation!=null){
currentLat = lastKnownLocation.getLatitude();
currentLon = lastKnownLocation.getLongitude();
}
}
@Override
public void onProviderDisabled(String provider) {
}
};
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, 500, 10, mLocationListener);
}
4- onDestroy ()
@Override
public void onDestroy() {
super.onDestroy();
mLocationManager.removeUpdates(mLocationListener);
}
참고 URL : https://stackoverflow.com/questions/14478179/background-service-with-location-listener-in-android
'Nice programing' 카테고리의 다른 글
| 데이터 주석의 Asp.Net Mvc 숨겨진 필드 (0) | 2020.10.29 |
|---|---|
| NuGet.exe를 소스 제어에 추가 할 필요 방지 (0) | 2020.10.29 |
| C #을 Oracle 데이터베이스에 연결하는 데 필요한 최소 클라이언트 풋 프린트는 얼마입니까? (0) | 2020.10.29 |
| 클라우드 컴퓨팅과 그리드 컴퓨팅의 차이점은 무엇입니까? (0) | 2020.10.29 |
| 파이썬 문자열의 최대 길이는 얼마입니까? (0) | 2020.10.29 |