Бих искал да знам как да получавам GPS, когато приложението за Android е на заден план. Има ли пълен урок, който да го обясни?
Стартирайте GPS слушател във фонов режим на Android
Отговори (4)
Трябва да използвате AlarmManager, за да активирате чакащо намерение (чрез излъчващ приемник), за да стартирате фонова услуга.
Примерен код за вас
Във вашата основна дейност
AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
Intent notifyintent = new Intent(this, OnAlarmReceiver.class);
notifyintent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
notifyintent.setAction("android.intent.action.NOTIFY");
PendingIntent notifysender = PendingIntent.getBroadcast(this, 0, notifyintent,
PendingIntent.FLAG_UPDATE_CURRENT);
am.setInexactRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 20 * 1000,
notifysender);
Клас AlarmReceiver
public class OnAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// PullPendingRequests.acquireStaticLock(context)
try {
lock = getLock(context);
lock.acquire();
context.startService(new Intent(context, UpdateCustomerRequests.class));
} finally {
if (lock.isHeld()) {
lock.release();
}
}
}
BroadcastReceiver
private static final String NAME = "com.commonsware.cwac.wakeful.WakefulIntentService";
private static volatile PowerManager.WakeLock lockStatic = null;
private static PowerManager.WakeLock lock;
// Needed since network will to work when device is sleeping.
synchronized private static PowerManager.WakeLock getLock(Context context) {
if (lockStatic == null) {
PowerManager mgr = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, NAME);
lockStatic.setReferenceCounted(true);
}
return (lockStatic);
}
}
Фоновата услуга. Тук ще забележите 2 важни точки
- WakeLock, за да гарантирате, че вашето устройство се събужда и използва мрежата във фонов режим
- Хак за работа на LocationManager. Трябваше да отстранявам грешки в това за около 2 седмици, повярвайте ми, имате нужда от това. requestLocationUpdates и getLastKnownLocation просто няма да дадат вашето местоположение, когато искате. Оттук и AlarmManager (който работи много по-добре от нещо на Java TimerTask).
Всичко това работи в производствено приложение в Play Store.
public class UpdateCustomerRequests extends IntentService implements LocationListener {
private static Context mainContext;
public UpdateCustomerRequests() {
super("UpdateCustomerRequests");
mHandler = new Handler();
me = this;
}
public static UpdateCustomerRequests getService() {
if (me == null)
me = new UpdateCustomerRequests();
return me;
}
@Override
final protected void onHandleIntent(Intent intent) {
mainContext = getApplicationContext();
Location myLocation;
if (HomeScreen.getLocationManager() != null) {
// this is needed to trigger a background location change. Since LocationManager does not work on Samsung phones. Its a hack needed.
HomeScreen.getLocationManager().requestLocationUpdates(
LocationManager.NETWORK_PROVIDER, 0, 0, new LocationListener() {
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
@Override
public void onLocationChanged(final Location location) {
}
});
myLocation = HomeScreen.getLocationManager().getLastKnownLocation(
LocationManager.NETWORK_PROVIDER);
if (myLocation != null)
onLocationChanged(myLocation);
else {
God.notifications.setSpeedNotification();
}
} else
Log.e("Taxeeta:PullPendingRequets", "Not activated");
}
@Override
public void onLocationChanged(final Location location) {
// Do your background stuff
}
}
И накрая, не забравяйте вашето манифестно нещо.
<service
android:name="com.taxeeta.UpdateCustomerRequests"
android:enabled="true"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@android:style/Theme.Light.NoTitleBar" />
<receiver
android:name="com.taxeeta.support.OnAlarmReceiver"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.NOTIFY" />
</intent-filter>
</receiver>
<receiver
android:name="com.taxeeta.HomeScreen$ResponseReceiver"
android:exported="true" >
<intent-filter>
<action android:name="com.taxeeta.intent.action.GET_SCREEN_UPDATES" />
</intent-filter>
</receiver>
Трябва да използвате концепцията за услуга вместо дейност. http://developer.android.com/guide/components/services.html
Ето добър пример: Фоновата услуга трябва да изпраща GPS местоположение на сървър
Нещото, което ще направите в Activity, може да бъде направено и в услугата..в onStart() на услугата....
Можете да използвате услуга, която винаги работи във фонов режим... и във фоновата услуга можете да получите текущата географска ширина и дължина и можете допълнително да конвертирате тези ширини и дължини в правилното местоположение, като използвате класа на геокодер на Android... проверете следната връзка :
http://www.codeproject.com/KB/android/GPSLocator.aspx