Запустите GPS-слушатель в фоновом режиме на Android - PullRequest
7 голосов
/ 12 сентября 2011

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

Ответы [ 4 ]

5 голосов
/ 24 июня 2013

Вам необходимо использовать 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 важных момента

  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>
1 голос
/ 24 июня 2013

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

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

0 голосов
/ 12 сентября 2011

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

0 голосов
/ 12 сентября 2011

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

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

...