【问题标题】:Send location updates to IntentService向 IntentService 发送位置更新
【发布时间】:2015-07-20 10:05:26
【问题描述】:

如何将位置更新直接发送到 Intent Service?以下方法不起作用。 OnConnected 函数被调用,但服务中从未收到意图:

...
    private PendingIntent getLocationPendingIntent(boolean shouldCreate) {
        Intent broadcast = new Intent(m_context,LocationUpdateService.class);
        int flags = shouldCreate ? 0 : PendingIntent.FLAG_NO_CREATE;
        return PendingIntent.getService(m_context, 0, broadcast, flags);
    }



    @Override
    public void onConnected(Bundle arg0) {
        PendingIntent locationPendingIntent = getLocationPendingIntent(true);        
        LocationRequest locationRequest = new LocationRequest();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(LOCATION_UPDATE_INTERVAL);
        locationRequest.setFastestInterval(LOCATION_FASTEST_UPDATE_INTERVAL);
        LocationServices.FusedLocationApi.requestLocationUpdates(m_googleApiClient, locationRequest,locationPendingIntent);
}
...

意向服务:

import android.app.IntentService;
import android.content.Intent;
import android.util.Log;

public class LocationUpdateService extends IntentService {

    public LocationUpdateService() {
        super(LocationUpdateService.class.getName());
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startID) {
        super.onStartCommand(intent, flags, startID);
        Log.d("LocationUpdateService","Location received");
        return START_REDELIVER_INTENT;
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        Log.d("LocationUpdateService","Intent received");

    }   
}

清单文件:

...
<service  android:name=".LocationUpdateService" />
...

【问题讨论】:

标签: android intentservice google-api-client


【解决方案1】:

根据找到的代码here,这是成功将 IntentService 设置为用于位置更新的 PendingIntent 中包含的 Intent 的接收器的工作和测试代码。

首先,IntentService:

import android.app.IntentService;
import android.content.Intent;
import android.location.Location;
import android.util.Log;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationResult;

public class LocationUpdateService extends IntentService {

    private final String TAG = "LocationUpdateService";
    Location location;

    public LocationUpdateService() {

        super("LocationUpdateService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (LocationResult.hasResult(intent)) {
            LocationResult locationResult = LocationResult.extractResult(intent);
            Location location = locationResult.getLastLocation();
            if (location != null) {
                 Log.d("locationtesting", "accuracy: " + location.getAccuracy() + " lat: " + location.getLatitude() + " lon: " + location.getLongitude());
            }
        }
    }
}

这是使用PendingIntent 注册位置更新的活动代码,该代码发送到IntentService:

import android.app.PendingIntent;
import android.os.Bundle;
import android.content.Intent;
import android.app.Activity;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

public class MainActivity extends Activity implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {

    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    PendingIntent mRequestLocationUpdatesPendingIntent;

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

        buildGoogleApiClient();
        mGoogleApiClient.connect();
    }

    @Override
    protected void onPause(){
        super.onPause();
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, mRequestLocationUpdatesPendingIntent);
        }
    }

    protected synchronized void buildGoogleApiClient() {
        Toast.makeText(this,"buildGoogleApiClient",Toast.LENGTH_SHORT).show();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    @Override
    public void onConnected(Bundle bundle) {
        Toast.makeText(this,"onConnected",Toast.LENGTH_SHORT).show();

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10);
        mLocationRequest.setFastestInterval(10);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        //mLocationRequest.setSmallestDisplacement(0.1F);

        // create the Intent to use WebViewActivity to handle results
        Intent mRequestLocationUpdatesIntent = new Intent(this, LocationUpdateService.class);

        // create a PendingIntent
        mRequestLocationUpdatesPendingIntent = PendingIntent.getService(getApplicationContext(), 0,
                mRequestLocationUpdatesIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

        // request location updates
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
                mLocationRequest,
                mRequestLocationUpdatesPendingIntent);
    }

    @Override
    public void onConnectionSuspended(int i) {
        Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show();
    }
}

结果日志:

 D/locationtesting﹕ accuracy: 10.0 lat: 37.779702 lon: -122.3931595
 D/locationtesting﹕ accuracy: 10.0 lat: 37.7797023 lon: -122.3931594
 D/locationtesting﹕ accuracy: 10.0 lat: 37.7797022 lon: -122.3931596
 D/locationtesting﹕ accuracy: 10.0 lat: 37.7797021 lon: -122.3931597
 D/locationtesting﹕ accuracy: 10.0 lat: 37.7797021 lon: -122.3931596
 D/locationtesting﹕ accuracy: 10.0 lat: 37.7797019 lon: -122.3931597
 D/locationtesting﹕ accuracy: 10.0 lat: 37.7797019 lon: -122.3931597

【讨论】:

  • 我不知道为什么这对我不起作用。 requestLocationUpdates 被调用,但 onHandleIntent 未被调用。
【解决方案2】:

您不能直接执行此操作 - 我的意思是 requestLocationUpdates 并在 IntentService 中获取这些更新。

您可以做的是在后台有一个Service,它通过requestLocationUpdates 请求这些更新,并且一直在运行(请记住设备进入睡眠状态的情况)。然后从Service 那里收到位置更新时向IntentService 开火并在那里处理。

【讨论】:

    【解决方案3】:

    Intent 服务本质上用于终端任务,例如从调用活动或片段接收 Intent,在单独的线程上启动某些任务,然后静默完成,而不通知任何实体它的终止。还有一个注释文档指出不应为 Intent 服务 ([IntentService][1]) 覆盖 onStartCommand。我的猜测是,您的服务会在您期望它还活着时自行完成,因此,意图没有正确传递。

    绑定服务将是一个更合适的选择,因为它们允许不同的组件附加到自己并执行所需的通信。

    【讨论】:

    • 我的想法是在 Intent 服务中处理位置更新,然后终止它,直到下一次更新到来 - 对我来说,它看起来完全可以接受 Intent 服务的使用,如果我错了,请纠正我。也不知道你的意思是什么:“完成自己”,在这种情况下,我是否应该从我的服务方法中看到任何日志记录?
    • 我明白了,那么是的,Intent Service 非常适合这种目的。在这种情况下,您只需要覆盖 onHandleIntent 并在那里处理所有位置更新逻辑。尝试消除 onStartCommand,将您的日志语句放在 onHandleIntent 中,看看是否调用了 onHandleIntent。
    • 不一样,我真的对这个问题感到困惑。我应该从哪里开始调试?
    • 能否请您发布以下部分的更新代码:启动服务的活动或片段、服务本身以及声明服务的清单。调试服务的一个很好的起点是打开 Android 设备监视器,观察您的进程线程(通过 applicationId)并查看您的服务是否实际运行。
    【解决方案4】:

    您可以使用 pendingIntent 的 getService() 方法,在服务的 onStartCommand() 中可以得到对应的意图。 getBroadcast() 发送一个广播,您需要注册一个广播接收器来收听该广播。希望这会有所帮助。

    【讨论】:

    • 我已经根据您的帖子更新了我的代码,但是,我仍然无法在我的 Intent Service 中获取位置更新。请在编辑后的问题中查看我更新的代码。
    • 检查 onConnected() 是否被调用
    • 是的,但在那之后什么也没有发生。有什么想法可以调试吗?
    猜你喜欢
    • 2015-08-31
    • 2013-08-08
    • 2018-03-26
    • 1970-01-01
    • 2022-01-10
    • 2017-12-10
    • 2016-12-31
    • 2012-01-31
    • 2020-11-08
    相关资源
    最近更新 更多