Aks*_*hay 3 android android-geofence android-service-binding android-8.0-oreo
我正在使用Intent Service来监控Geofence过渡.为此,我正在使用Sticky Service的跟随电话.
LocationServices.GeofencingApi.addGeofences(
mGoogleApiClient,
getGeofencingRequest(),
getGeofencePendingIntent()
)
Run Code Online (Sandbox Code Playgroud)
Pending Intent调用Transition Service(IntentService),如下所示.
private PendingIntent getGeofencePendingIntent() {
Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
// We use FLAG_UPDATE_CURRENT so that we get the
//same pending intent back when calling addgeoFences()
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
Run Code Online (Sandbox Code Playgroud)
这工作很好Pre Oreo.但是,我必须将我的粘性服务转换为JobScheduler,我需要将GeofenceTransitionsIntentService哪个是intentService 转换为JobIntentService.
说过我不知道如何返回为JobIntentService创建一个PendingIntent,因为我需要为JobIntentService调用enqueueWork.
任何建议/指针将不胜感激.
从Android Oreo +设备迁移IntentService到JobIntentServiceAndroid 时,我遇到了同样的问题.
我发现的所有指南和片段都不完整,它们忽略了迁移对使用的重大变化PendingIntent.getServce.
特别是,此迁移会破坏Alarm计划启动服务的任何计划,AlarmManager并Actions添加任何Notification已启动服务的服务.
替换
PendingIntent.getService为PendingIntent.getBroadcast开始aBroastcastReceiver.然后该接收器开始
JobIntentService使用enqueueWork.
迁移多个服务时,这可能是重复的,并且容易出错.
为了使这更容易和服务无关,我创建了一个通用的StartJobIntentServiceReceiver,它带有一个工作ID和一个Intent意图JobIntentService.
当接收器启动时,它将JobIntentService以作业ID 启动最初的预期,并实际将Intent原始内容转发到幕后服务.
/**
* A receiver that acts as a pass-through for enqueueing work to a {@link android.support.v4.app.JobIntentService}.
*/
public class StartJobIntentServiceReceiver extends BroadcastReceiver {
public static final String EXTRA_SERVICE_CLASS = "com.sg57.tesladashboard.extra_service_class";
public static final String EXTRA_JOB_ID = "com.sg57.tesladashboard.extra_job_id";
/**
* @param intent an Intent meant for a {@link android.support.v4.app.JobIntentService}
* @return a new Intent intended for use by this receiver based off the passed intent
*/
public static Intent getIntent(Context context, Intent intent, int job_id) {
ComponentName component = intent.getComponent();
if (component == null)
throw new RuntimeException("Missing intent component");
Intent new_intent = new Intent(intent)
.putExtra(EXTRA_SERVICE_CLASS, component.getClassName())
.putExtra(EXTRA_JOB_ID, job_id);
new_intent.setClass(context, StartJobIntentServiceReceiver.class);
return new_intent;
}
@Override
public void onReceive(Context context, Intent intent) {
try {
if (intent.getExtras() == null)
throw new Exception("No extras found");
// change intent's class to its intended service's class
String service_class_name = intent.getStringExtra(EXTRA_SERVICE_CLASS);
if (service_class_name == null)
throw new Exception("No service class found in extras");
Class service_class = Class.forName(service_class_name);
if (!JobIntentService.class.isAssignableFrom(service_class))
throw new Exception("Service class found is not a JobIntentService: " + service_class.getName());
intent.setClass(context, service_class);
// get job id
if (!intent.getExtras().containsKey(EXTRA_JOB_ID))
throw new Exception("No job ID found in extras");
int job_id = intent.getIntExtra(EXTRA_JOB_ID, 0);
// start the service
JobIntentService.enqueueWork(context, service_class, job_id, intent);
} catch (Exception e) {
System.err.println("Error starting service from receiver: " + e.getMessage());
}
}
}
Run Code Online (Sandbox Code Playgroud)
您需要用自己的名称替换包名称,并BroadcastReceiver在以下情况下按常规注册AndroidManifest.xml:
<receiver android:name=".path.to.receiver.here.StartJobIntentServiceReceiver"/>
Run Code Online (Sandbox Code Playgroud)
您现在可以安全使用Context.sendBroadcast或PendingIntent.getBroadcast在任何地方使用,只需将Intent您希望交付的内容包装JobIntentService在接收器的静态方法中,StartJobIntentServiceReceiver.getIntent.
您可以通过以下方式JobIntentService立即启动接收器,并通过扩展您:
Context.sendBroadcast(StartJobIntentServiceReceiver.getIntent(context, intent, job_id));
Run Code Online (Sandbox Code Playgroud)
如果您没有立即启动服务,则必须使用a PendingIntent,例如在Alarms使用s AlarmManager或向Actions 添加s时Notification:
PendingIntent.getBroadcast(context.getApplicationContext(),
request_code,
StartJobIntentServiceReceiver.getIntent(context, intent, job_id),
PendingIntent.FLAG_UPDATE_CURRENT);
Run Code Online (Sandbox Code Playgroud)
Aks*_*hay -1
正如 @andrei_zaitcev 所建议的,我实现了自定义的 BroadCastReceiver 和enqueueWork()服务调用,效果非常好。
| 归档时间: |
|
| 查看次数: |
6367 次 |
| 最近记录: |