在自定义侦听器的服务中使用活动上下文

Posted

技术标签:

【中文标题】在自定义侦听器的服务中使用活动上下文【英文标题】:Use ActivityContext in service for Custom Listner 【发布时间】:2018-11-07 15:59:54 【问题描述】:

PrimaryDashBoard 我使用 LocatinListener 并从服务中检索位置

public class PrimaryDashboard extends AppCompatActivity implements LocationListener 
public LatLng myLatLng=new LatLng(0.0,0.0);

@Override
protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_primary_dashboard);

        try 
           Intent i = new Intent(this, LocationManager.class);

            startService(i);

         catch (Exception e) 
            e.printStackTrace();
        


@Override
public void onLocationChanged(Location location) 
    myLatLng=new LatLng(location.getLatitude(),location.getLongitude());



@Override
public void GPSDisabled(String errorMessage) 



@Override
public void GPSEnabled() 

 

这里是 LocationListner

    public interface LocationListener 
   public void onLocationChanged(Location location);

public  void GPSDisabled(String errorMessage);

public void GPSEnabled();
  

这是我的服务,我想在其中初始化 LocationListner 并想从列表中更新位置值

   public class LocationManager extends IntentService 
private static final String TAG = LocationManager.class.getSimpleName();
// Registered callbacks
public LocationListener locationUpdate;
public static final int REQUEST_CHECK_SETTINGS = 0x1;
private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
        UPDATE_INTERVAL_IN_MILLISECONDS / 2;

private FusedLocationProviderClient mFusedLocationClient;
private SettingsClient mSettingsClient;
private LocationRequest mLocationRequest;
private LocationSettingsRequest mLocationSettingsRequest;
private LocationCallback mLocationCallback;
private Location mCurrentLocation;
private Boolean mRequestingLocationUpdates = false;

@SuppressLint("ServiceCast")
@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) 
        this.locationUpdate = (LocationListener)  getApplicationContext();

    mRequestingLocationUpdates = false;
    mFusedLocationClient = LocationServices.getFusedLocationProviderClient(getApplicationContext());
    mSettingsClient = LocationServices.getSettingsClient(getApplicationContext());

    createLocationCallback();
    createLocationRequest();
    buildLocationSettingsRequest();

    if (!mRequestingLocationUpdates) 
        mRequestingLocationUpdates = true;
        startLocationUpdates();
    

    return START_STICKY;


@Override
protected void onHandleIntent(@Nullable Intent intent) 



@SuppressLint("ServiceCast")
@Override
public void onCreate() 

    super.onCreate();


public LocationManager() 
    super("locationManager");



private void createLocationRequest() 
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
    mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);


/**
 * Creates a callback for receiving location events.
 */
private void createLocationCallback() 
    mLocationCallback = new LocationCallback() 
        @Override
        public void onLocationResult(LocationResult locationResult) 
            super.onLocationResult(locationResult);
            mCurrentLocation = locationResult.getLastLocation();
            PrefManager.getInstance(getApplicationContext()).setLastLatLng(Double.valueOf(locationResult.getLastLocation().getLatitude()), Double.valueOf(locationResult.getLastLocation().getLongitude()));
            if (locationUpdate != null)
                locationUpdate.onLocationChanged(locationResult.getLastLocation());
        
    ;



private void buildLocationSettingsRequest() 
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
    builder.addLocationRequest(mLocationRequest);
    mLocationSettingsRequest = builder.build();



private void startLocationUpdates() 

    // Begin by checking if the device has the necessary location settings.
    mSettingsClient.checkLocationSettings(mLocationSettingsRequest)
            .addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() 
                @SuppressLint("MissingPermission")
                @Override
                public void onSuccess(LocationSettingsResponse locationSettingsResponse) 

                    LogCat.show("All location settings are satisfied.");
                    if (locationUpdate != null)
                        locationUpdate.GPSEnabled();
                    mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
                
            )
            .addOnFailureListener(new OnFailureListener() 
                @Override
                public void onFailure(@NonNull Exception e) 

                    int statusCode = ((ApiException) e).getStatusCode();
                    switch (statusCode) 
                        case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                            if (locationUpdate != null)
                                locationUpdate.GPSDisabled("Location settings are not satisfied. Attempting to upgrade location settings ");
                            LogCat.show("Location settings are not satisfied. Attempting to upgrade location settings ");
                            try 
                                // Show the dialog by calling startResolutionForResult(), and check the
                                // result in onActivityResult().
                                ResolvableApiException rae = (ResolvableApiException) e;
                                rae.startResolutionForResult((Activity) getApplicationContext(), REQUEST_CHECK_SETTINGS);
                             catch (IntentSender.SendIntentException sie) 
                                Log.i(TAG, "PendingIntent unable to execute request.");
                            
                            break;
                        case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                            String errorMessage = "Location settings are inadequate, and cannot be " +
                                    "fixed here. Fix in Settings.";
                            LogCat.show(errorMessage);
                            if (locationUpdate != null)
                                locationUpdate.GPSDisabled(errorMessage);
                            Toast.makeText(getApplicationContext(), errorMessage, Toast.LENGTH_LONG).show();
                            mRequestingLocationUpdates = false;
                    


                
            );





这行代码给我带来了一个问题,因为它需要 Activity 上下文,当它不是服务并且我传递 Activity 上下文时它可以完美运行。

this.locationUpdate = (LocationListener) getApplicationContext();

 Caused by: java.lang.ClassCastException: android.app.Application cannot be cast to driver.com.driver.LocationComponents.LocationListener

java.lang.RuntimeException: Unable to create service driver.com.driver.LocationComponents.LocationManager: java.lang.ClassCastException: android.app.Application cannot be cast to driver.com.driver.LocationComponents.LocationListener

【问题讨论】:

【参考方案1】:

首先,您的应用程序类未实现 LocationListener 接口,因此您收到此错误。您无法在 Intent 服务中获取 Activity 实例,因为 1)它可能不再处于活动状态 2)可以从其他服务或广播接收器启动 Intent 服务。为了将LocationListener 方法与您的活动通信,您需要使用LocalBroadcastManager。

【讨论】:

是的,但如果应用程序关闭,我想要位置 如果我通过 PrimaryDashboard 的静态引用,它可以工作

以上是关于在自定义侦听器的服务中使用活动上下文的主要内容,如果未能解决你的问题,请参考以下文章

什么方法可以捕获在自定义视图(布局)中选择的上下文菜单项?

如何在自定义用户控件中为 ListBox ItemTemplate 属性设置适当的上下文

获取服务中前台活动的上下文

在自主机模式下获取当前的 owin 上下文

何时在自定义 UIVIew 中添加 CAAnimation?

在自定义 serviceWorker 中调度 redux 操作