Запуск прослушивателя GPS в фоновом режиме на Android

Я хотел бы знать, как получать GPS, когда приложение Android работает в фоновом режиме. Есть ли полный учебник, чтобы объяснить это?


person Dev    schedule 12.09.2011    source источник


Ответы (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();
        }
    }
}

Радиовещательный приемник

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 важных момента

  1. WakeLock, чтобы ваше устройство просыпалось и использовало сеть в фоновом режиме.
  2. Хак для работы LocationManager. Мне пришлось отлаживать это около 2 недель, поверьте мне, вам это нужно. requestLocationUpdates и getLastKnownLocation просто не дадут ваше местоположение, когда вы этого захотите. Следовательно, AlarmManager (который работает намного лучше, чем java TimerTask).

Все это работает в рабочем приложении в магазине игр.

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>
person Siddharth    schedule 24.06.2013
comment
Что такое класс HomeScreen? - person ChArAnJiT; 09.10.2016

Вам нужно использовать концепцию службы вместо активности. http://developer.android.com/guide/components/services.html

Вот хороший пример: Фоновой службе необходимо отправить местоположение GPS на сервер

person Jehy    schedule 24.06.2013

То, что вы будете делать в Activity, можно сделать и в сервисе... в onStart() сервиса....

person Karan_Rana    schedule 12.09.2011

Вы можете использовать службу, которая всегда работает в фоновом режиме... и в фоновой службе вы можете получить текущую широту и долготу, и вы можете дополнительно преобразовать эти широты и долготы в правильное местоположение, используя класс геокодера Android... проверьте следующую ссылку :

http://www.codeproject.com/KB/android/GPSLocator.aspx

person Karan_Rana    schedule 12.09.2011
comment
Спасибо, но этот код для активности, как я могу использовать сервис. - person Dev; 12.09.2011