在不使用gps或互联网的情况下获取用户的当前位置名称,但在android中使用Network_Provider

时间:2015-04-05 13:10:00

标签: java android location locationmanager

此问题与" Android: get current location of user without using gps or internet"中的相同主流stackoverflow问题直接相关。接受的答案实际上没有回答问题。

我应该能够通过网络提供商而不是GPS或互联网获取设备的当前位置名称(例如:城市名称,村庄名称)。 以下是该问题的公认答案。 (以下代码部分应包含在onCreate()方法中)

// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
    public void onLocationChanged(Location location) {
      // Called when a new location is found by the network location provider.
      makeUseOfNewLocation(location);
    }

    public void onStatusChanged(String provider, int status, Bundle extras) {}

    public void onProviderEnabled(String provider) {}

    public void onProviderDisabled(String provider) {}
  };

// Register the listener with the Location Manager to receive location updates
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);

我更改了链接答案中给出的上述代码,但没有成功。

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final TextView txtView = (TextView) findViewById(R.id.tv1);
    txtView.setText("ayyo samitha");
    ////

    // Acquire a reference to the system Location Manager
    LocationManager locationManager;
   locationManager= (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

    // Define a listener that responds to location updates
    LocationListener locationListener = new LocationListener() {
        public void onLocationChanged(Location location) {
            // Called when a new location is found by the network location provider.
            makeUseOfNewLocation(location);

        }

        private void makeUseOfNewLocation(Location location) {
            txtView.setText("sam came in");
            txtView.append(location.toString());
        }

        public void onStatusChanged(String provider, int status, Bundle extras) {}

        public void onProviderEnabled(String provider) {
           // makeUseOfNewLocation(location);
        }

        public void onProviderDisabled(String provider) {}
    };

    // Register the listener with the Location Manager to receive location updates
    if (locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener);
    }

}

如何通过纠正上述代码或任何其他方法来实现我想要的目标?请注意,我想获取位置名称,但不是经度和纬度。有人可以帮助我。

5 个答案:

答案 0 :(得分:4)

您在此处所指的内容(在旧手机上显示位置名称)是使用“小区广播”(或“CB”)完成的。这与Location API或其中的任何变体完全无关。

手机信号塔可以发送可以被设备接收的广播信息(类似“一对多短信”)。一些运营商使用Cell Broadcast来广播蜂窝塔所在位置的名称。一些运营商已经使用小区广播来广播小区塔的位置(纬度/经度)。一些运营商使用Cell Broadcast发送广告代码。 CB广播消息中包含的信息没有标准,每个移动运营商都可以选择是否使用此信息。

由于大多数运营商不发送这些消息,因此在尝试接收和解码它们时,任何时候投入都没有意义。但是,如果您想尝试,可以注册BroadcastReceiver收听此Intent操作:android.provider.Telephony.SMS_CB_RECEIVED。有关Intent

中包含哪些数据的详细信息,请参阅the documentation

答案 1 :(得分:1)

问题在于您尝试的代码确实有效,可能不如您所愿。例如,三星Galaxy S3上提供的这种方法的准确度是2000m,这意味着实际位置是在2公里半径范围内的任何位置。此外,在您的应用程序被告知位置更改之前,可能需要进行相当大的位置更改,因为错误幅度非常大。

需要GPS或LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY(如果使用Google Play服务)才能获得相当不错的位置。这确实需要android.permission.ACCESS_FINE_LOCATION,但除非您只需要公里级精度,否则此权限是必须的。

最后请注意,使用带有LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY的Google Play服务,我可以在没有打开GPS的情况下获得精确到10米的位置数据,因此这仍然可以满足您的要求。

以下是一个完整的例子:

<强>的AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<强> MainActivity.java

import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.widget.TextView;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

public class MainActivity extends Activity implements
        com.google.android.gms.location.LocationListener, ConnectionCallbacks,
        OnConnectionFailedListener {
    private final FusedLocationProviderApi fusedLocationProviderApi = LocationServices.FusedLocationApi;
    private GoogleApiClient mGoogleAPIClient;

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

        mGoogleAPIClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API).addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this).build();
    }

    @Override
    protected void onResume() {
        super.onResume();

        mGoogleAPIClient.connect();
    }

    @Override
    protected void onPause() {
        super.onPause();

        if (mGoogleAPIClient != null) {
        mGoogleAPIClient.disconnect();
        }
    }

    @Override
    public void onConnected(Bundle arg0) {
        final LocationRequest locationRequest = LocationRequest.create();
        locationRequest
                .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        locationRequest.setInterval(30 * 1000);
        locationRequest.setFastestInterval(5 * 1000);
        fusedLocationProviderApi.requestLocationUpdates(mGoogleAPIClient,
                locationRequest, this);
    }

    @Override
    public void onConnectionSuspended(int arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onConnectionFailed(ConnectionResult arg0) {
        // TODO Auto-generated method stub

    }

    @Override
    public void onLocationChanged(Location location) {
        // the location is no more than 10 min old, and with reasonable
        // accurarcy (50m), done
        if (System.currentTimeMillis() < location.getTime() + 10 * 60 * 1000
                && location.getAccuracy() < 50) {
            mGoogleAPIClient.disconnect();
            mGoogleAPIClient = null;
            ((TextView) findViewById(R.id.test)).setText(location.toString());
        }
    }
}

答案 2 :(得分:1)

您可以尝试使用Locale对象或使用Telephony服务获取国家/地区级别的准确度。无需互联网或GPS。

从Locale获取国家/地区代码:

String locale = context.getResources().getConfiguration().locale.getCountry();

从Android的Telephony服务获取国家/地区代码:

TelephonyManager tm = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
// Will work on all networks. Only provide the SIM card's country
String countryCode = tm.getSimCountryIso();

// Might not work well on CDMA networks. Will provide the country code
// for the country the device is currently in.
String currentCountryCode = tm.getNetworkCountryIso();

更好的代码示例和讨论here

答案 3 :(得分:0)

试试这段代码..

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;

public class AppLocationService extends Service implements LocationListener         {

protected LocationManager locationManager;
Location location;

private static final long MIN_DISTANCE_FOR_UPDATE = 10;
private static final long MIN_TIME_FOR_UPDATE = 1000 * 60 * 2;

public AppLocationService(Context context) {
    locationManager = (LocationManager) context
            .getSystemService(LOCATION_SERVICE);
}

public Location getLocation(String provider) {
    if (locationManager.isProviderEnabled(provider)) {
        locationManager.requestLocationUpdates(provider,
                MIN_TIME_FOR_UPDATE, MIN_DISTANCE_FOR_UPDATE, this);
        if (locationManager != null) {
            location = locationManager.getLastKnownLocation(provider);
            return location;
        }
    }
    return null;
}

@Override
public void onLocationChanged(Location location) {
}

@Override
public void onProviderDisabled(String provider) {
}

@Override
public void onProviderEnabled(String provider) {
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}

@Override
public IBinder onBind(Intent arg0) {
    return null;
}

}

和下一堂课是

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.provider.Settings;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

public class AndroidLocationActivity extends Activity {

Button btnGPSShowLocation;
Button btnNWShowLocation;

AppLocationService appLocationService;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    appLocationService = new AppLocationService(
            AndroidLocationActivity.this);

    btnGPSShowLocation = (Button) findViewById(R.id.btnGPSShowLocation);
    btnGPSShowLocation.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {

            Location gpsLocation = appLocationService
                    .getLocation(LocationManager.GPS_PROVIDER);

            if (gpsLocation != null) {
                double latitude = gpsLocation.getLatitude();
                double longitude = gpsLocation.getLongitude();
                Toast.makeText(
                        getApplicationContext(),
                        "Mobile Location (GPS): \nLatitude: " + latitude
                                + "\nLongitude: " + longitude,
                        Toast.LENGTH_LONG).show();
            } else {
                showSettingsAlert("GPS");
            }

        }
    });

    btnNWShowLocation = (Button) findViewById(R.id.btnNWShowLocation);
    btnNWShowLocation.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {

            Location nwLocation = appLocationService
                    .getLocation(LocationManager.NETWORK_PROVIDER);

            if (nwLocation != null) {
                double latitude = nwLocation.getLatitude();
                double longitude = nwLocation.getLongitude();
                Toast.makeText(
                        getApplicationContext(),
                        "Mobile Location (NW): \nLatitude: " + latitude
                                + "\nLongitude: " + longitude,
                        Toast.LENGTH_LONG).show();
            } else {
                showSettingsAlert("NETWORK");
            }

        }
    });

}

public void showSettingsAlert(String provider) {
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(
            AndroidLocationActivity.this);

    alertDialog.setTitle(provider + " SETTINGS");

    alertDialog
            .setMessage(provider + " is not enabled! Want to go to settings menu?");

    alertDialog.setPositiveButton("Settings",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    Intent intent = new Intent(
                            Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    AndroidLocationActivity.this.startActivity(intent);
                }
            });

    alertDialog.setNegativeButton("Cancel",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });

    alertDialog.show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

} 和此用户权限

<!-- to get location using GPS -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<!-- to get location using NetworkProvider -->
<uses-permission android:name="android.permission.INTERNET" />

答案 4 :(得分:0)

祝你好运。它被称为地理编码器。或者更具体地说,反向地理编码以将坐标转换为人类可读输出。我相当确定谷歌提供的是付费服务,但你可以免费获得一堆。因此,请尽可能计划缓存结果并使用缓存结果。

List<Address> list = geoCoder.getFromLocation(location
            .getLatitude(), location.getLongitude(), 1);
    if (list != null & list.size() > 0) {
        Address address = list.get(0);
        result = address.getLocality();
        return result;

https://developer.android.com/training/location/display-address.html

How to get city name from latitude and longitude coordinates in Google Maps?