位置更新接收器未接收到位置更新 android

huangapple go评论117阅读模式
英文:

Location update Receiver not getting location updates android

问题

我已使用PendingIntent启动广播接收器以获取位置更新。应用在之前运行正常,但在过去几个月停止工作。我检查了发现LocationReceiver.kt没有收到任何更新。

LocationReceiver.kt 代码如下:

class LocationReceiver : BroadcastReceiver() {
    private var locationRepository: LocationRepository? = null
    private var lastLocation: Location? = null

    override fun onReceive(context: Context, intent: Intent) {
        val action = intent.action
        if (Utility.currentApiVersion >= Build.VERSION_CODES.O) NotificationHandler.getInstance(context).updateNotification(action)
        Log.d("locationslog", "" + action)
        Utility.appToastShort(context, "onReceive: " + action)

        if (ACTION_LOCATION_UPDATES == action) {
            val result = LocationResult.extractResult(intent)
            if (result != null) {
                val locations = result.locations
                if (locationRepository == null) locationRepository = LocationRepository.getInstance(context.applicationContext, Executors.newSingleThreadExecutor())
                if (locations.size > 0) {
                    if (locations.size == 1 && lastLocation != null && lastLocation!!.latitude == locations[0].latitude && lastLocation!!.latitude == locations[0].longitude) {
                        //already saved location
                    } else {
                        for (i in locations.indices) {
                            if (i == locations.size - 1) lastLocation = locations[i]
                            val curntLoc = locations[i]
                            locationRepository!!.insertLocation(
                                LocationPoint(
                                    curntLoc.latitude,
                                    curntLoc.longitude
                                )
                            )
                        }
                        if (Utility.currentApiVersion >= Build.VERSION_CODES.O) NotificationHandler.getInstance(context).updateNotification(
                            Utils.getLocationText(lastLocation)
                        )
                    }
                }
            }
        }
    }

    companion object {
        const val ACTION_LOCATION_UPDATES = "ACTION_LOCATION_UPDATE"
    }
}

LocationUpdatesService.java 代码如下:

public class LocationUpdatesService extends Service {
    private static final String PACKAGE_NAME = "dk.invoiceportal.mileage";
    public static final String EXTRA_LOCATION = PACKAGE_NAME + ".location";
    public static final String LAST_LOCATION = PACKAGE_NAME + ".lastlocation";
    public static final String STOP_LOCATION = PACKAGE_NAME + ".stop";
    private static final String TAG = LocationUpdatesService.class.getSimpleName();
    private static final String EXTRA_STARTED_FROM_NOTIFICATION = PACKAGE_NAME + ".started_from_notification";
    private static final int NOTIFICATION_ID = 2123;
    private final IBinder mBinder = new LocalBinder();
    private boolean mChangingConfiguration = false, tracking = false;
    private Location mLocation;
    private Context mContext;
    private Activity activity;

    private LocationRepository locationRepository;
    private Thread thread;
    private NotificationHandler notificationHandler = null;

    public LocationUpdatesService() {
    }

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onCreate() {
        getLocationRepository();
        notificationHandler = NotificationHandler.getInstance(this);
    }

    // 其余部分请查看您的代码。
}

LocationHandler.kt 代码如下:

class LocationHandler private constructor(private val context: Context ) {
    private var mLocationRequest: LocationRequest? = null
    private var mFusedLocationClient: FusedLocationProviderClient? = null
    private val _receivingLocationUpdates: MutableLiveData<Boolean> = MutableLiveData<Boolean>(false)

    // 其余部分请查看您的代码。
}

LocationRepository.kt 代码如下:

class LocationRepository private constructor(
    private val myDataBase: MyLocationDatabase,
    private val locationHandler: LocationHandler,
    private val executor: ExecutorService
) {
    // 数据库相关字段/方法

    // 其余部分请查看您的代码。
}

请注意,这只是您提供的代码的部分翻译,而不包括完整的内容。如果需要更多翻译,请提供更多的代码部分。

英文:

i have used pending intent to launch broadcast receiver get location updates.

app was working fine before.

but from last couple of months it stopped working.

i checked and found LocationReceiver.kt is not getting any updates

class LocationReceiver : BroadcastReceiver() {
private var locationRepository: LocationRepository? = null
private var lastLocation: Location? = null
override fun onReceive(context: Context, intent: Intent) {
val action = intent.action
if (Utility.currentApiVersion \&gt;= Build.VERSION_CODES.O) NotificationHandler.getInstance(context).updateNotification(action)
Log.d(&quot;locationslog&quot;,&quot;&quot;+action)
Utility.appToastShort(context, &quot;onReceive: &quot;+action)
if (ACTION_LOCATION_UPDATES == action) {
val result = LocationResult.extractResult(intent)
if (result != null) {
val locations = result.locations
if (locationRepository == null) locationRepository =
LocationRepository.getInstance(context.applicationContext, Executors.newSingleThreadExecutor())
if (locations.size \&gt; 0) {
if (locations.size == 1 &amp;&amp; lastLocation != null &amp;&amp; lastLocation!!.latitude == locations\[0\].latitude &amp;&amp; lastLocation!!.latitude == locations\[0\].longitude) {
//already saved location
} else {
for (i in locations.indices) {
if (i == locations.size - 1) lastLocation = locations\[i\]
val curntLoc = locations\[i\]
//LatLng curntLatLng = new LatLng(curntLoc.getLatitude(), curntLoc.getLongitude());
locationRepository!!.insertLocation(
LocationPoint(
curntLoc.latitude,
curntLoc.longitude
)
)
}
if (Utility.currentApiVersion \&gt;= Build.VERSION_CODES.O) NotificationHandler.getInstance( context).updateNotification(
Utils.getLocationText(lastLocation)
)
}
}
}
}
}

    companion object {
        const val ACTION_LOCATION_UPDATES = &quot;ACTION_LOCATION_UPDATE&quot;
    }

}
public class LocationUpdatesService extends Service {
private static final String PACKAGE_NAME = &quot;dk.invoiceportal.mileage&quot;;
public static final String EXTRA_LOCATION = PACKAGE_NAME + &quot;.location&quot;;
public static final String LAST_LOCATION = PACKAGE_NAME + &quot;.lastlocation&quot;;
public static final String STOP_LOCATION = PACKAGE_NAME + &quot;.stop&quot;;
private static final String TAG = LocationUpdatesService.class.getSimpleName();
private static final String EXTRA_STARTED_FROM_NOTIFICATION = PACKAGE_NAME + &quot;.started_from_notification&quot;;
private static final int NOTIFICATION_ID = 2123;
private final IBinder mBinder = new LocalBinder();
private boolean mChangingConfiguration = false, tracking = false;
private Location mLocation;
private Context mContext;
private Activity activity;
private LocationRepository locationRepository;
private Thread thread;
private NotificationHandler notificationHandler = null;
public LocationUpdatesService() {
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onCreate() {
getLocationRepository();
notificationHandler = NotificationHandler.getInstance(this);
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, &quot;Service started&quot;);
boolean startedFromNotification = false;
if (intent != null)
startedFromNotification = intent.getBooleanExtra(EXTRA_STARTED_FROM_NOTIFICATION,
false);
// We got here because the user decided to remove location updates from the notification.
if (startedFromNotification) {
removeLocationUpdates();
stopSelf();
} else {
getLocationRepository();
if (notificationHandler == null)
notificationHandler = NotificationHandler.getInstance(this);
notificationHandler.activity = activity;
startForeground(NOTIFICATION_ID, notificationHandler.getNotification(Utils.getLocationText(mLocation)));
}
// Tells the system to not try to recreate the service after it has been killed.
return START_STICKY;
}
private void startWorkOnNewThread(GoogleMap mGoogleMap, final int start, final String event) {
if (start == 1)
locationRepository.startLocationUpdates();
else if (start == 0) {
locationRepository.stopLocationUpdates();
tracking = false;
if (notificationHandler != null)
notificationHandler.cancelNotification();
if (event.equalsIgnoreCase(&quot;stopself&quot;))
stopSelf();
} else if (start == 2)
locationRepository.getLastLocation(mGoogleMap, event);
stopThread();
/* thread = new Thread(new Runnable() {
public void run() {
if(start == 1)
locationRepository.startLocationUpdates(getApplicationContext());
else if(start == 0)
{
locationRepository.stopLocationUpdates(getApplicationContext());
if(event.equalsIgnoreCase(&quot;stopself&quot;))
stopSelf();
}
else if(start ==2)
locationRepository.getLastLocation(event);
}
});
thread.start();*/
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public void onTaskRemoved(Intent rootIntent) {
//When remove app from background then start it again
if (tracking)
startForegroundService(new Intent(getApplicationContext(), LocationUpdatesService.class));
super.onTaskRemoved(rootIntent);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mChangingConfiguration = true;
}
@Override
public IBinder onBind(Intent intent) {
// Called when a client (MapActivity in case of this sample) comes to the foreground
// and binds with this service. The service should cease to be a foreground service
// when that happens.
Log.i(TAG, &quot;in onBind()&quot;);
stopForeground(true);
mChangingConfiguration = false;
return mBinder;
}
@Override
public void onRebind(Intent intent) {
// Called when a client (MapActivity in case of this sample) returns to the foreground
// and binds once again with this service. The service should cease to be a foreground
// service when that happens.
Log.i(TAG, &quot;in onRebind()&quot;);
stopForeground(true);
mChangingConfiguration = false;
super.onRebind(intent);
}
@RequiresApi(api = Build.VERSION_CODES.O)
@Override
public boolean onUnbind(Intent intent) {
Log.i(TAG, &quot;Last client unbound from service&quot;);
// Called when the last client (MapActivity in case of this sample) unbinds from this
// service. If this method is called due to a configuration change in MapActivity, we
// do nothing. Otherwise, we make this service a foreground service.
if (!mChangingConfiguration &amp;&amp; Utils.requestingLocationUpdates(this)) {
Log.i(TAG, &quot;Starting foreground service&quot;);
if (notificationHandler == null) {
notificationHandler = NotificationHandler.getInstance(this);
notificationHandler.setNotificationManager();
}
notificationHandler.activity = activity;
startForeground(NOTIFICATION_ID, notificationHandler.getNotification(Utils.getLocationText(mLocation)));
}
return true; // Ensures onRebind() is called when a client re-binds.
}
@RequiresApi(api = Build.VERSION_CODES.O)
public void requestLocationUpdates() {
Log.i(TAG, &quot;Requesting location updates&quot;);
tracking = true;
startForegroundService(new Intent(getApplicationContext(), LocationUpdatesService.class));
try {
startWorkOnNewThread(null, 1, &quot;&quot;);
} catch (SecurityException unlikely) {
Utils.setRequestingLocationUpdates(this, false);
Log.e(TAG, &quot;Lost location permission. Could not request updates. &quot; + unlikely);
}
}
public void getLastLocation(GoogleMap mGoogleMap, String event) {
try {
startWorkOnNewThread(mGoogleMap, 2, event);
} catch (SecurityException unlikely) {
Utils.setRequestingLocationUpdates(this, false);
Log.e(TAG, &quot;Lost location permission. Could not remove updates. &quot; + unlikely);
}
}
public void removeLocationUpdates() {
Log.i(TAG, &quot;Removing location updates&quot;);
try {
startWorkOnNewThread(null, 0, &quot;stopself&quot;);
//stopSelf();
} catch (SecurityException unlikely) {
Utils.setRequestingLocationUpdates(this, true);
Log.e(TAG, &quot;Lost location permission. Could not remove updates. &quot; + unlikely);
}
}
private LocationRepository getLocationRepository() {
if (locationRepository == null)
locationRepository = LocationRepository.Companion.getInstance(getApplicationContext(), Executors.newSingleThreadExecutor());
return locationRepository;
}
private void stopThread() {
if (thread != null)
thread.interrupt();
thread = null;
}
@Override
public void onDestroy() {
Utils.setRequestingLocationUpdates(this, false);
if (notificationHandler != null)
notificationHandler.destroy();
notificationHandler = null;
stopThread();
}
public class LocalBinder extends Binder {
public LocationUpdatesService getService(Context context) {
mContext = context;
activity = (Activity) context;
return LocationUpdatesService.this;
}
}
}
class LocationHandler private constructor(private val context: Context ) {
private var mLocationRequest: LocationRequest? = null
private var mFusedLocationClient: FusedLocationProviderClient? = null
private val _receivingLocationUpdates: MutableLiveData&lt;Boolean&gt; = MutableLiveData&lt;Boolean&gt;(false)
val receivingLocationUpdates: LiveData&lt;Boolean&gt;
get() = _receivingLocationUpdates
@SuppressLint(&quot;MissingPermission&quot;)
fun startLocationUpdates() {
if (!AppPermissions.checkPermissions(context, true)) {
Utility.appToast(context, &quot;Location permission not given or GPS is OFF&quot;)
return
} else {
_receivingLocationUpdates.value = true
if (mLocationRequest == null) createLocationRequest()
Utils.setRequestingLocationUpdates(context, true)
if (mFusedLocationClient == null) mFusedLocationClient =
LocationServices.getFusedLocationProviderClient(
context
)
mFusedLocationClient!!.requestLocationUpdates(mLocationRequest!!, pendingIntent)
Log.d(&quot;locationslog&quot;,&quot;startLocationUpdates&quot;)
Utility.appToastShort(context, &quot;startLocationUpdates&quot;)
}
}
fun stopLocationUpdate() {
if (mLocationRequest == null) createLocationRequest()
if ( mFusedLocationClient != null) {
mFusedLocationClient!!.removeLocationUpdates(pendingIntent)
}
Log.d(&quot;locationslog&quot;,&quot;stopLocationUpdate&quot;)
Utils.setRequestingLocationUpdates(context, false)
_receivingLocationUpdates.value = false
Utility.appToastShort(context, &quot;stopLocationUpdate&quot;)
}
private fun createLocationRequest() {
mLocationRequest = LocationRequest.Builder(
Priority.PRIORITY_HIGH_ACCURACY,
UPDATE_INTERVAL_IN_MILLISECONDS
)
.setMinUpdateDistanceMeters(SMALLEST_DISTANCE_IN_METER)
.setIntervalMillis(UPDATE_INTERVAL_IN_MILLISECONDS)
.setMinUpdateIntervalMillis(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS)
.setMaxUpdateDelayMillis(MAX_WAIT_TIME).setWaitForAccurateLocation(false)
.setPriority(Priority.PRIORITY_HIGH_ACCURACY).build()
displayGpsMessage()
}
// Note: for apps targeting API level 25 (&quot;Nougat&quot;) or lower, either
// PendingIntent.getService() or PendingIntent.getBroadcast() may be used when requesting
// location updates. For apps targeting API level O, only
// PendingIntent.getBroadcast() should be used. This is due to the limits placed on services
// started in the background in &quot;O&quot;.
private val pendingIntent: PendingIntent
get() {
// Note: for apps targeting API level 25 (&quot;Nougat&quot;) or lower, either
// PendingIntent.getService() or PendingIntent.getBroadcast() may be used when requesting
// location updates. For apps targeting API level O, only
// PendingIntent.getBroadcast() should be used. This is due to the limits placed on services
// started in the background in &quot;O&quot;.
val intent = Intent(LocationReceiver.ACTION_LOCATION_UPDATES)
//intent.action = LocationReceiver.ACTION_LOCATION_UPDATES
Utility.appToastShort(context, &quot;intent:&quot;+intent.action)
Log.d(&quot;locationslog&quot;,&quot;&quot;+intent.action)
var p_intent = PendingIntent.getBroadcast(
context,
32,
intent,
PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
p_intent.send();
return p_intent;
}
fun getLastLocation(mGoogleMap: GoogleMap?, event: String) {
try {
if (mLocationRequest == null) createLocationRequest()
if (mFusedLocationClient == null) mFusedLocationClient =
LocationServices.getFusedLocationProviderClient(
context
)
// _receivingLocationUpdates = true;
Utils.setRequestingLocationUpdates(context, true)
mFusedLocationClient!!.lastLocation
.addOnCompleteListener { task -&gt;
if (task.isSuccessful &amp;&amp; task.result != null) {
val mLocation = task.result
if (mLocation != null) {
if (event.equals(
LocationUpdatesService.LAST_LOCATION,
ignoreCase = true
)
) {
if (mGoogleMap != null) Utility.setMapCammera(
mGoogleMap,
LatLng(mLocation.latitude, mLocation.longitude)
)
} else {
val loc = LocationPoint(mLocation.latitude, mLocation.longitude)
LocationRepository.getInstance(
context.applicationContext,
Executors.newSingleThreadExecutor()
).insertLocation(loc)
if (Utility.currentApiVersion &gt;= Build.VERSION_CODES.O) NotificationHandler.getInstance(
context
).updateNotification(Utils.getLocationText(mLocation))
}
stopLocationUpdate()
} else Log.i(&quot;TAG&quot;, &quot;Last location not null&quot;)
} else Log.i(&quot;TAG&quot;, &quot;Last location not received&quot;)
}.addOnFailureListener { e -&gt;
e.printStackTrace()
Log.i(&quot;TAG&quot;, e.message!!)
stopLocationUpdate()
}
} catch (unlikely: SecurityException) {
Log.e(&quot;TAG&quot;, &quot;Lost location permission.$unlikely&quot;)
}
}
fun displayGpsMessage() {
if ( mLocationRequest != null) {
val builder = LocationSettingsRequest.Builder()
builder.addLocationRequest(mLocationRequest!!)
val locationSettingsRequest = builder.build()
val settingsClient = LocationServices.getSettingsClient(context)
settingsClient.checkLocationSettings(locationSettingsRequest).addOnFailureListener(Utility.curentActivity
) { e -&gt;
val statusCode = (e as ApiException).statusCode
when (statusCode) {
LocationSettingsStatusCodes.RESOLUTION_REQUIRED -&gt; try {
// Show the dialog by calling startResolutionForResult(), and check the
// result in onActivityResult().
val rae = e as ResolvableApiException
rae.startResolutionForResult(Utility.curentActivity , 1000)
} catch (sie: SendIntentException) {
Log.i(&quot;location&quot;, &quot;PendingIntent unable to execute request.&quot;)
}
LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE -&gt; {
val errorMessage = &quot;Location settings are inadequate, and cannot be &quot; +
&quot;fixed here. Fix in Settings.&quot;
Log.e(&quot;location&quot;, errorMessage)
}
}
}
}
}
companion object {
private const val SMALLEST_DISTANCE_IN_METER = 5f//35f
private const val UPDATE_INTERVAL_IN_MILLISECONDS = (9 * 1000).toLong()
//private final Context mContext;
private const val FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = (1 * 1000).toLong()
private const val MAX_WAIT_TIME = (6000 * 3).toLong()//(60000 * 3).toLong()
@Volatile private var INSTANCE: LocationHandler? = null
fun getInstance(context: Context): LocationHandler {
return INSTANCE ?: synchronized(this) {
INSTANCE ?: LocationHandler(context).also { INSTANCE = it }
}
}
}
}
class LocationRepository private constructor(
private val myDataBase: MyLocationDatabase,
private val locationHandler: LocationHandler,
private val executor: ExecutorService
) {
// Database related fields/methods:
private val locationDao = myDataBase.locationDao()
fun insertLocation(location: LocationPoint?) {
executor.execute { locationDao.insertLocation(location) }
}
fun fetchAllLocation(): LiveData&lt;List&lt;LocationPoint?&gt;?&gt;? {
return locationDao.fetchAllLocation()
}
fun fetchAllLAddresses(): LiveData&lt;List&lt;SavedAddress?&gt;?&gt;? {
return locationDao.fetchAllLAddresses()
}
fun insertSaveAddress(savedAddress: SavedAddress?) {
executor.execute { locationDao.insertAddress(savedAddress) }
}
val locationsCount: Unit
get() {
executor.execute { locationDao.locationsCount }
}
val savedAddressCount: Unit
get() {
executor.execute { locationDao.savedAddressCount }
}
fun deleteLocation(locationPoint: LocationPoint?) {
executor.execute { locationDao.deleteLocation(locationPoint) }
}
fun deleteSavedAddress(savedAddress: SavedAddress?) {
executor.execute {locationDao.deleteSavedAddress(savedAddress) }
}
fun deleteSavedAddress(id: Int) {
executor.execute { locationDao.deleteSavedAddress(id) }
}
fun deleteSavedAddress(address: String?) {
executor.execute { locationDao.deleteSavedAddress(address) }
}
fun deleteAll() {
executor.execute { locationDao.delete() }
}
fun getLastLocation(mGoogleMap: GoogleMap?, event: String?) { locationHandler.getLastLocation(mGoogleMap, event!!)
}
fun startLocationUpdates() {locationHandler.startLocationUpdates()
}
val receivingLocationUpdates: LiveData&lt;Boolean&gt; = locationHandler.receivingLocationUpdates
@MainThread
fun stopLocationUpdates() {
locationHandler.stopLocationUpdate()
}
companion object {
@Volatile private var INSTANCE: LocationRepository? = null
fun getInstance(context: Context, executor: ExecutorService): LocationRepository {
return INSTANCE ?: synchronized(this) {
INSTANCE ?: LocationRepository(
MyLocationDatabase.getInstance(context),
LocationHandler.getInstance(context),executor)
.also { INSTANCE = it }
}
}
}
}

Manifest file

&lt;service
android:name=&quot;.services.LocationUpdatesService&quot;
android:enabled=&quot;true&quot;
android:exported=&quot;true&quot;
android:foregroundServiceType=&quot;location&quot; /\&gt;
&lt;receiver
android:name=&quot;.services.LocationReceiver&quot;
android:enabled=&quot;true&quot;
android:exported=&quot;true&quot;
android:permission=&quot;android.permission.ACCESS_BACKGROUND_LOCATION&quot;&gt;
&lt;intent-filter&gt;
&lt;action android:name=&quot;ACTION_LOCATION_UPDATE&quot; /&gt;
&lt;/intent-filter&gt;
&lt;/receiver&gt;

i have updated the libraries gradle and target sdk is 33. minumm is 24

答案1

得分: 0

将以下内容翻译为中文:

PendingIntent.getBroadcast(context, 32, intent, PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)

更改为

PendingIntent.getBroadcast(context, 32, intent, PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT)
英文:

changed
<pre>
PendingIntent.getBroadcast(context,32,intent,<b>PendingIntent.FLAG_IMMUTABLE</b> or PendingIntent.FLAG_UPDATE_CURRENT)
</pre>
to
<pre>
PendingIntent.getBroadcast(context,32,intent,<b>PendingIntent.FLAG_MUTABLE</b> or PendingIntent.FLAG_UPDATE_CURRENT)
</pre>

huangapple
  • 本文由 发表于 2023年3月8日 19:10:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/75672246.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定