简体   繁体   English

获取用户的当前城市

[英]Get the user's current city

Hi I posted a question concerning the same topic a while ago, after following your advices I can feel that I'm getting closed to solving my problem. 嗨,我不久前发布了一个关于同一主题的问题,在听取了您的建议后,我感到我已经接近解决问题了。 The App does is now crashing as I click on the button with the following error message in the monitor: 当我在监视器上单击带有以下错误消息的按钮时,该应用程序确实崩溃了:

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 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 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Please click the button below to get your location" />

<Button
    android:id="@+id/button1"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Click Me" />

<TextView
    android:id="@+id/cellText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="" />

<TextView
    android:id="@+id/lacationText"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="" />


</LinearLayout>

in the condition if (addresses != null) { } you should also check for the length of the addresses, since there might be 0. 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");
}

if it wasn't able to find at least one address you should consider showing the user an empty state. 如果找不到至少一个地址,则应考虑向用户显示一个空状态。

It also seems like you forgot to initialize your latitude and longitude before calling addresses = geocoder.getFromLocation(lat, lon, 1); 似乎您也忘记了在调用addresses = geocoder.getFromLocation(lat, lon, 1);之前初始化纬度和经度addresses = geocoder.getFromLocation(lat, lon, 1);

To properly initialize this, do the following: 要正确初始化它,请执行以下操作:

Location location = intent.getParcelableExtra(__YOUR_PACKAGE_NAME__ + ".LOCATION_DATA_EXTRA");
lat = location.getLatitude();
lon = location.getLongitude();

If you need any more help check out this page from android . 如果您需要更多帮助,请从android查看此页面 It should hold all information you need. 它应该包含您需要的所有信息。

EDIT: 编辑:

I kind of assumed you we're further in the process, but it seems you have only tried to get the location of a latLong position, which you have never obtained. 我以为您在这个过程中会更进一步,但是似乎您只是在尝试获取latLong位置的位置,而您从未获得过。 To achieve obtaining the address you will have to have the user's lcoation first. 要获得地址,您必须首先拥有用户的商标。

Again, the page mentioned above should explain everything you need to obtain the location, but make sure of the following: 同样,上述页面应解释获取位置所需的一切,但请确保以下几点:

1. Have the permission to access the user's location (for Android 6+ use Runtime permissions ) 1.拥有访问用户位置的权限 (对于Android 6+,请使用运行时权限

<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. Get an instance of the GoogleApi and ave your activity implement some callbacks 2.获取一个GoogleApi实例并让您的活动实现一些回调

For the Callbacks 对于回调

public class YourActivity extends AppCompatActivity implements
        ConnectionCallbacks, OnConnectionFailedListener

Then in your OnCreate() create an instance of GoogleApiClient. 然后在您的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. Obtain the location from the GoogleApiClient Do this by implementing the callbacks properly. 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. Now obtain the lat long and try to obtain the address as attempted before. 4.现在获取经纬度,然后尝试按以前的尝试获取地址。

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();
}

This should be enough to obtain the actual adress of the device and ask the geocoder for the addresses. 这应该足以获取设备的实际地址,并向地址解析器询问地址。 I altered the example a bit to simplify for this question. 我对示例进行了一些改动,以简化此问题。 Google's example handles fetching the address a bit more clean. Google的示例处理了一些更干净的地址获取。 Note that you will also have to disconnect the GoogleApi when stopping your activity and such. 请注意,停止活动等时,您还必须断开Goog​​leApi的连接。 Again I recommend reading the entire Tutorial page . 再次,我建议阅读整个教程页面 You can find en example of their implementation on this page on GitHub 您可以在GitHub的此页面上找到其实现的示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM