在 Android 上在后台运行 GPS 侦听器

发布于 2024-12-04 01:31:32 字数 49 浏览 2 评论 0原文

我想知道当Android应用程序在后台时如何接收GPS。有没有完整的教程来解释一下?

I would like to know how to receive GPS when the Android app is in the background. Is there a complete tutorial to explain it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

小糖芽 2024-12-11 01:31:32

您需要使用 AlarmManager 激活待处理的意图(通过广播接收器)以启动后台服务。

为您提供的一些示例代码

在您的 MainActivity

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);
  }
}

后台服务。这里你会注意到两个重要的点:

  1. WakeLock,以确保你的设备唤醒并在后台使用网络
  2. 。LocationManager 工作的一个 hack。我不得不调试这个大约两周,相信我,你需要这个。 requestLocationUpdates 和 getLastKnownLocation 不会在您需要时提供您的位置。因此,AlarmManager(它比 java TimerTask 运行得更好)。

所有这些都可以在 Play 商店的生产应用程序中进行。

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>

You need to use a AlarmManager to activate a pending intent (via a broadcast receiver) to launch a background service.

Some sample code for you

In your MainActivity

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 class

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();
        }
    }
}

The 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);
  }
}

The background Service. Here you will notice 2 important points

  1. WakeLock, to ensure that your device wakes up and uses the network in the background
  2. A hack for LocationManager to work. I had to debug this for about 2 weeks, trust me, you need this. requestLocationUpdates and getLastKnownLocation will just not give your location when you want. Hence the AlarmManager (which runs much better than a java TimerTask thing).

All this works in a production app on the 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
}

}

Lastly, don't forget your manifest thing.

 <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>
漫漫岁月 2024-12-11 01:31:32

您将在 Activity 中执行的操作也可以在服务中完成...在 Service 的 onStart() 中...

The thing which you will do in Activity can be done in service also..in the onStart() of Service....

迷路的信 2024-12-11 01:31:32

您可以使用始终在后台运行的服务。在后台服务中,您可以获得当前的纬度和经度,并且可以使用 Android 地理编码器类进一步将这些纬度和经度转换为正确的位置...
检查以下链接:

http://www.codeproject.com/KB/android/GPSLocator。 ASPX

You can use a Service which always runs in the background..and in the background service you can get the current latitude and longitude and you can further convert these lats and longs into proper location using the Android geocoder class...
check the follwing link:

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文