FusedLocationApi 返回 null

Posted

技术标签:

【中文标题】FusedLocationApi 返回 null【英文标题】:FusedLocationApi returns null 【发布时间】:2017-01-26 05:48:08 【问题描述】:

我正在开发一个 android 应用程序,它有一个广播接收器来广播来自某个数量的传入短信。如果消息来自该号码并且采用特定格式,应用程序会回复用户当前的经度和纬度。

但是当生成回复消息时,位置总是为空。我正在使用 GoogleApiClient 对象和 FusedLocationApi。

mLastLocation = LocationServices.FusedLocationApi.getLastLocation(googleAPIClient);

总是返回 null 并且我的消息在经度和纬度的位置包含 null 值。 这是广播接收器在请求位置的消息时调用的服务。

公共类ReplyWithLocationService 扩展Service 实现GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedList,LocationListener

private BroadcastReceiver senderBroadcastReceiver, deliverBroadcastReceiver;
private String SENT = "SMS_SENT";
private String DELIVERED = "SMS_DELIVERED";
private String latitude, longitude;
private LocationRequest locationRequest;
private LocationManager locationManager;
private ConnectivityManager connectivityManager;
private GoogleApiClient googleAPIClient;
private boolean isConnected;
private Location mLastLocation;
private NetworkInfo activeNetwork;
private boolean isConnectedInternet;
private boolean connectivity = true;

@Nullable
@Override
public IBinder onBind(Intent intent) 
    return null;


@Override
public void onCreate() 
    super.onCreate();

    setUpGoogleAPIClient();
    setUpLocationRequest();
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    connectivityManager = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);

    senderBroadcastReceiver = new BroadcastReceiver() 
        @Override
        public void onReceive(Context context, Intent intent) 
            switch (getResultCode()) 
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "SMS Sent", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
                    Toast.makeText(getBaseContext(), "Generic failure", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_NO_SERVICE:
                    Toast.makeText(getBaseContext(), "No service", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_NULL_PDU:
                    Toast.makeText(getBaseContext(), "Null PDU", Toast.LENGTH_SHORT).show();
                    break;
                case SmsManager.RESULT_ERROR_RADIO_OFF:
                    Toast.makeText(getBaseContext(), "Radio off", Toast.LENGTH_SHORT).show();
                    break;
            

        
    ;

    deliverBroadcastReceiver = new BroadcastReceiver() 
        @Override
        public void onReceive(Context context, Intent intent) 
            switch (getResultCode()) 
                case Activity.RESULT_OK:
                    Toast.makeText(getBaseContext(), "SMS Delivered", Toast.LENGTH_SHORT).show();
                    break;
                case Activity.RESULT_CANCELED:
                    Toast.makeText(getBaseContext(), "SMS not delivered", Toast.LENGTH_SHORT).show();
                    break;
            
        
    ;

    registerReceiver(senderBroadcastReceiver, new IntentFilter(SENT));
    registerReceiver(deliverBroadcastReceiver, new IntentFilter(DELIVERED));

    //setUpGoogleAPIClient();
    //setUpLocationRequest();


private void setUpGoogleAPIClient() 
    Log.e("APIClient", String.valueOf(googleAPIClient));
    if (googleAPIClient == null) 
        this.googleAPIClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API).build();
    
    Log.d("APIClient", String.valueOf(googleAPIClient));


private void setUpLocationRequest() 
    locationRequest = LocationRequest.create().setInterval(1000).setFastestInterval(1000).setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);



@Override
public int onStartCommand(Intent intent, int flags, int startId) 
    //setUpGoogleAPIClient();
    activeNetwork = connectivityManager.getActiveNetworkInfo();
    if (activeNetwork != null && activeNetwork.isConnectedOrConnecting()) 
        isConnectedInternet = true;
    

    connectivity = checkConnectivity();

    if (connectivity) 
        if (!googleAPIClient.isConnected() || !googleAPIClient.isConnecting()) 
            googleAPIClient.connect();
            Log.e("APICLient", "Connect");
        
        if (googleAPIClient.isConnected()) 
            isConnected = true;
            Log.e("APICLient", "Connected");
        

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            //return TODO;
        
        mLastLocation = LocationServices.FusedLocationApi.getLastLocation(googleAPIClient);
        Log.d("LastLocation", String.valueOf(mLastLocation));
        if (mLastLocation != null) 
            latitude = String.valueOf(mLastLocation.getLatitude());
            longitude = String.valueOf(mLastLocation.getLongitude());
            Log.e("Latitude", latitude);
            Log.e("Longitude", longitude);
            mLastLocation = null;
        
     else 
        TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
        CellLocation cellLocation = tm.getCellLocation();
        GsmCellLocation gsmLocation = (GsmCellLocation) cellLocation;
    

    if (intent.getStringExtra("Pin1") != null && intent.getStringExtra("Pin2") != null) 
        String pin1 = intent.getStringExtra("Pin1");
        String pin2 = intent.getStringExtra("Pin2");
        Log.e("PIN1", pin1);
        Log.e("PIN2", pin2);

        sendLocationSMS(pin1, pin2);
    
    return START_STICKY;


private boolean checkConnectivity() 
    if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !isConnectedInternet) 
        connectivity = false;
     else if (!isConnectedInternet) 
        connectivity = false;
     else if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) 
        connectivity = false;
    
    return connectivity;


private void sendLocationSMS(String pin1, String pin2) 
    String message = "FIND Location:" + pin1 + ":" + latitude + ":" + longitude + ":" + pin2;
    Log.e("LocationMessage", message);
    String number = "77131";

    PendingIntent sentPI = PendingIntent.getBroadcast(this, 0, new Intent(SENT), 0);
    PendingIntent deliveredPI = PendingIntent.getBroadcast(this, 0, new Intent(DELIVERED), 0);
    SmsManager sms = SmsManager.getDefault();
    sms.sendTextMessage(number, null, message, sentPI, deliveredPI);


@Override
public void onDestroy() 
    super.onDestroy();
    unregisterReceiver(senderBroadcastReceiver);
    unregisterReceiver(deliverBroadcastReceiver);
    googleAPIClient.disconnect();


@Override
public void onConnected(@Nullable Bundle bundle) 
    locationRequest = LocationRequest.create().setInterval(1000).setFastestInterval(1000).setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    Log.e("LocationRequest", String.valueOf(locationRequest));


@Override
public void onConnectionSuspended(int i) 



@Override
public void onLocationChanged(Location location) 



@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) 


【问题讨论】:

【参考方案1】:

无法保证getLastLocation() 方法将返回实际的Location (see Google Documentation)。 当您需要第一个位置时,通常会尽快调用该方法,但是在这种特定的上下文中,FusedLocation 提供程序仅在至少有一个客户端连接到它时才会在后台维护一些位置(即不会有任何 @ 987654326@在客户端第一次连接时可用)。您应该订阅位置更新调用requestLocationUpdates,而不是等待第一次调用回调,然后删除位置更新。

您可以在here 和Android Developers 上找到更多信息

【讨论】:

以上是关于FusedLocationApi 返回 null的主要内容,如果未能解决你的问题,请参考以下文章

Android 的 FusedLocationApi 不激活 GPS 并返回非常旧的日期

在Android中使用FusedLocationApi时如何获取Location的模式

UserModel 不可分配给 Document | 类型的参数nulll [带有 Typescript 的猫鼬]

thinkphp连接MySQL数据库后,显示nulLL怎么解决

C# mvc+jquery post 提交 后台 action 获取不到值 值为nulll

Key为nulll时Kafka如何选择分区(Partition)