Android服务在应用程序关闭时不起作用。

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

Android service not working when app is closed

问题

public class LocationService extends Service {
    private LocationCallback locationCallback = new LocationCallback() {
        @Override
        public void onLocationResult(LocationResult locationResult) {
            super.onLocationResult(locationResult);
            if (locationResult != null && locationResult.getLastLocation() != null) {
                double latitude = locationResult.getLastLocation().getLatitude();
                double longitude = locationResult.getLastLocation().getLongitude();
                Log.d("LOCATION_UPDATE", latitude + ", " + longitude);
                stopLocationService();
            }
        }
    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        throw new UnsupportedOperationException("Not yet implemented");
    }

    public void startLocationService() {
        String channelId = "location_notification_channel";
        NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        Intent resultIntent = new Intent();
        PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
        NotificationCompat.Builder builder = new NotificationCompat.Builder(
                getApplicationContext(),
                channelId
        );
        builder.setSmallIcon(R.drawable.ic_app);
        builder.setContentTitle("Location Service");
        builder.setDefaults(NotificationCompat.DEFAULT_ALL);
        builder.setContentText("Running");
        builder.setContentIntent(pendingIntent);
        builder.setAutoCancel(false);
        builder.setPriority(NotificationCompat.PRIORITY_MAX);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            if (notificationManager != null && notificationManager.getNotificationChannel(channelId) == null) {
                NotificationChannel notificationChannel = new NotificationChannel(
                        channelId, "Location Service", NotificationManager.IMPORTANCE_HIGH
                );
                notificationChannel.setDescription("This channel is used by location service");
                notificationManager.createNotificationChannel(notificationChannel);
            }
        }

        LocationRequest locationRequest = new LocationRequest();
        locationRequest.setInterval(8000);
        locationRequest.setFastestInterval(5000);
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        LocationServices.getFusedLocationProviderClient(this)
                .requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
        startForeground(Constants.LOCATION_SERVICE_ID, builder.build());
    }

    private void stopLocationService(){
        LocationServices.getFusedLocationProviderClient(this)
                .removeLocationUpdates(locationCallback);
        stopForeground(true);
        stopSelf();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if(intent != null){
            String action = intent.getAction();
            if(action != null){
                if(action.equals(Constants.ACTION_START_LOCATION_SERVICE)){
                    startLocationService();
                }
            }
        }
        return super.onStartCommand(intent, flags, startId);
    }
}
英文:

I'm having trouble with an android service that I'm doing. The service is about to get the location of the user every 5 minutes. All seems to go well except when i kill the app, the service won't do nothing. In the code you will ses its checking every 60 seconds I think, but this will change to 5 minutes.

Minimum Target Version: API 23

Target Version: API 29

Android Manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.venomapps.meets">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application
android:name=".Utils.App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".Activities.RegisterActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Activities.MainActivity" />
<activity android:name=".Activities.LoginActivity">
</activity>
<service android:name=".Services.LocationService"
android:enabled="true"
android:exported="true"/>
</application>

</manifest>

Code that executes the service:

AlarmManager am=(AlarmManager)getApplicationContext().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(getApplicationContext(), LocationService.class);                            intent.setAction(Constants.ACTION_START_LOCATION_SERVICE);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), Constants.LOCATION_SERVICE_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT);
am.setRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), 60000, pendingIntent);

Service:

public class LocationService extends Service {
private LocationCallback locationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
super.onLocationResult(locationResult);
if (locationResult != null &amp;&amp; locationResult.getLastLocation() != null) {
double latitude = locationResult.getLastLocation().getLatitude();
double longitude = locationResult.getLastLocation().getLongitude();
Log.d(&quot;LOCATION_UPDATE&quot;, latitude + &quot;, &quot; + longitude);
stopLocationService();
}
}
};
@Nullable
@Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException(&quot;Not yet implemented&quot;);
}
public void startLocationService() {
String channelId = &quot;location_notification_channel&quot;;
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent resultIntent = new Intent();
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(
getApplicationContext(),
channelId
);
builder.setSmallIcon(R.drawable.ic_app);
builder.setContentTitle(&quot;Location Service&quot;);
builder.setDefaults(NotificationCompat.DEFAULT_ALL);
builder.setContentText(&quot;Running&quot;);
builder.setContentIntent(pendingIntent);
builder.setAutoCancel(false);
builder.setPriority(NotificationCompat.PRIORITY_MAX);
if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O) {
if (notificationManager != null &amp;&amp; notificationManager.getNotificationChannel(channelId) == null) {
NotificationChannel notificationChannel = new NotificationChannel(
channelId, &quot;Location Service&quot;, NotificationManager.IMPORTANCE_HIGH
);
notificationChannel.setDescription(&quot;This channel is used by location service&quot;);
notificationManager.createNotificationChannel(notificationChannel);
}
}
LocationRequest locationRequest = new LocationRequest();
locationRequest.setInterval(8000);
locationRequest.setFastestInterval(5000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &amp;&amp; ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.getFusedLocationProviderClient(this)
.requestLocationUpdates(locationRequest, locationCallback, Looper.getMainLooper());
startForeground(Constants.LOCATION_SERVICE_ID, builder.build());
}
private void stopLocationService(){
LocationServices.getFusedLocationProviderClient(this)
.removeLocationUpdates(locationCallback);
stopForeground(true);
stopSelf();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent != null){
String action = intent.getAction();
if(action != null){
if(action.equals(Constants.ACTION_START_LOCATION_SERVICE)){
startLocationService();
}
}
}
return super.onStartCommand(intent, flags, startId);
}

}

答案1

得分: 2

AlarmManager 如果用于该目的已被弃用。请查看WorkManager

英文:

AlarmManager is deprecated if used for that purpose. Have a look at WorkManager.

huangapple
  • 本文由 发表于 2020年9月4日 19:02:35
  • 转载请务必保留本文链接:https://go.coder-hub.com/63739902.html
匿名

发表评论

匿名网友

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

确定