获取用户当前所在城市
Posted
技术标签:
【中文标题】获取用户当前所在城市【英文标题】:Get the user's current city 【发布时间】:2017-01-03 14:14:46 【问题描述】:您好,我不久前发布了一个关于同一主题的问题,在听从您的建议后,我觉得我已经接近解决我的问题了。当我在监视器中单击带有以下错误消息的按钮时,应用程序现在正在崩溃:
FATAL EXCEPTION: main
Process: com.example.apple.myapp1, PID: 10081
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.example.apple.myapp1.MainActivity$1.onClick(MainActivity.java:62)
MainActivity.java
package com.example.apple.myapp1;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Locale;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONObject;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.telephony.gsm.GsmCellLocation;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.view.View.OnClickListener;
public class MainActivity extends Activity
double lats, lons;
Geocoder geocoder;
double lat = lats;
double lon = lons;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button btnGetLocation = (Button) findViewById(R.id.button1);
btnGetLocation.setOnClickListener(new OnClickListener()
@Override
public void onClick(View v)
ProgressDialog mProgressDialog = new ProgressDialog(MainActivity.this);
mProgressDialog.setMessage("Fetching location...");
mProgressDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressDialog.show();
geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
List<Address> addresses = null;
try
addresses = geocoder.getFromLocation(lat, lon, 1);
catch (IOException e)
e.printStackTrace();
if (addresses != null)
String address = addresses.get(0).getAddressLine(0);
String city = addresses.get(0).getLocality();
String state = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
String postalCode = addresses.get(0).getPostalCode();
String knownName = addresses.get(0).getFeatureName();
mProgressDialog.dismiss();
TextView cellText = (TextView) findViewById(R.id.cellText);
cellText.setText(address);
else
mProgressDialog.dismiss();
TextView cellText = (TextView) findViewById(R.id.cellText);
cellText.setText("Error");
);
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_
android:layout_
android:orientation="vertical" >
<TextView
android:layout_
android:layout_
android:text="Please click the button below to get your location" />
<Button
android:id="@+id/button1"
android:layout_
android:layout_
android:text="Click Me" />
<TextView
android:id="@+id/cellText"
android:layout_
android:layout_
android:text="" />
<TextView
android:id="@+id/lacationText"
android:layout_
android:layout_
android:text="" />
</LinearLayout>
【问题讨论】:
看起来地址是一个空数组。您必须仔细检查 geocoder.getFromLocation(lat, lon, 1); 同时测试空而不是空。 在您发布的代码中,lats
和 lons
变量未初始化。结果你的lat
和lon
也没有被初始化。
@GuyBouallet 那么我还能为地址赋予什么其他价值?
@DavidBradley 谈论经纬度?还是地址?
【参考方案1】:
在if (addresses != null)
条件下,您还应该检查地址的长度,因为可能有 0。
if (addresses != null && addresses.size() > 0)
String address = addresses.get(0).getAddressLine(0);
String city = addresses.get(0).getLocality();
String state = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
String postalCode = addresses.get(0).getPostalCode();
String knownName = addresses.get(0).getFeatureName();
mProgressDialog.dismiss();
TextView cellText = (TextView) findViewById(R.id.cellText);
cellText.setText(address);
else
mProgressDialog.dismiss();
TextView cellText = (TextView) findViewById(R.id.cellText);
cellText.setText("Error");
如果它无法找到至少一个地址,您应该考虑向用户显示一个空状态。
您似乎在调用 addresses = geocoder.getFromLocation(lat, lon, 1);
之前忘记初始化您的纬度和经度
要正确初始化它,请执行以下操作:
Location location = intent.getParcelableExtra(__YOUR_PACKAGE_NAME__ + ".LOCATION_DATA_EXTRA");
lat = location.getLatitude();
lon = location.getLongitude();
如果您需要更多帮助,请查看此page from android。它应该包含您需要的所有信息。
编辑:
我有点假设您我们在此过程中更进一步,但您似乎只是尝试获取您从未获得过的 latLong 位置的位置。要获得地址,您必须首先获得用户的位置。
同样,上述页面应说明获取位置所需的一切,但请确保以下内容:
1.有权访问用户的位置(Android 6+ 使用Runtime permissions)
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.android.gms.location.sample.locationupdates" >
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
</manifest>
2。获取 GoogleApi 的实例并让您的活动实现一些回调
对于回调
public class YourActivity extends AppCompatActivity implements
ConnectionCallbacks, OnConnectionFailedListener
然后在您的OnCreate()
中创建一个 GoogleApiClient 实例。
protected GoogleApiClient mGoogleApiClient;
public void onCreate(Bundle savedInstanceState)
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mGoogleApiClient.connect();
3.从 GoogleApiClient 获取位置 通过正确实现回调来做到这一点。
/**
* Represents a geographical location.
*/
protected Location mLastLocation;
@Override
public void onConnected(Bundle connectionHint)
// Gets the best and most recent location currently available, which may be null
// in rare cases when a location is not available.
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mLastLocation != null)
// Determine whether a Geocoder is available.
if (!Geocoder.isPresent())
Toast.makeText(this, "no geocoder available", Toast.LENGTH_LONG).show();
return;
4.现在获取 lat long 并尝试获取之前尝试的地址。
lat = mLastLocation.getLatitude();
lon = mLastLocation.getLongitude();
geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
List<Address> addresses = null;
try
addresses = geocoder.getFromLocation(lat, lon, 1);
catch (IOException e)
e.printStackTrace();
这应该足以获取设备的实际地址并向地理编码器询问地址。我稍微改变了这个例子来简化这个问题。谷歌的例子处理获取地址更干净一些。请注意,在停止活动等时,您还必须断开 GoogleApi 的连接。我再次建议阅读整个Tutorial page。您可以找到他们的实施示例on this page on GitHub
【讨论】:
我一直看到显示“错误” 是的,这可能意味着地理编码器无法找到给定纬度和经度的地址。你给的是偏远地区的latlong吗?检查 API 以了解在找不到地址时应该做什么 如何检查我是否在偏远地区提供 lat 和 ling?以及如何从 API 设置在这种情况下应该做什么,我在 AndroidStudio 世界里有点新。 :) 看来你还没有初始化你的纬度和经度。我更新了我的答案,这应该可以解决问题 无法解析 LOCATION_DATA_EXTRA,好像我们越来越近了!! :)以上是关于获取用户当前所在城市的主要内容,如果未能解决你的问题,请参考以下文章