我无法使用 Geonames API 从邮政编码中获取城市名称

Posted

技术标签:

【中文标题】我无法使用 Geonames API 从邮政编码中获取城市名称【英文标题】:I am unable to get the City name from postal code using Geonames API 【发布时间】:2020-10-08 10:53:50 【问题描述】:

我正在尝试使用 Geonames API 从 邮政编码 搜索或获取 城市 名称。

但是,我得到一个空值期望。

下面是我获取 邮政编码 的代码,我已将其传递给 AsyncTask 以在后台执行

private void sharedPreferenceCreate(final String userAddress, Double latitude, Double longitude, Intent data) throws Exception 

    final String City;
    final String Country;
    final String State;

    Geocoder gcd = new Geocoder(MainActivity.this, Locale.getDefault());
    List<Address> addresses = null;

    try 
        addresses = gcd.getFromLocation(latitude, longitude, 1);
     catch (IOException e) 
        e.printStackTrace();
    

    if (addresses.size() > 0) 

        City= addresses.get(0).getLocality();
        Country= addresses.get(0).getCountryName();
        State= addresses.get(0).getAdminArea();
        String q=addresses.get(0).getSubLocality();
        String w=addresses.get(0).getFeatureName();
        String e=addresses.get(0).getPostalCode();  //Here I get the Postal code
        String r=addresses.get(0).getSubAdminArea();
        String t=addresses.get(0).getPremises();
        String g= e+"&country=";

        urlBackground background= new urlBackground();

        background.doInBackground(e);
        background.execute();

        Log.i(TAG, "sharedPreferenceCreate: "+city);

        distanceRestaurant(latitude,longitude, City,Country,State);
              ).show();

    
    else 
        Toast.makeText(this, "Unable to fetch your location, try again", Toast.LENGTH_SHORT).show();
    

这是我的 AsyncTask

public class urlBackground extends AsyncTask<String, Void, String> 

    String result;

    public urlBackground() 
    

    @Override
    protected String doInBackground(String... strings) 

        WebService.setUserName("Jack"); // add your username here

        ToponymSearchCriteria searchCriteria = new ToponymSearchCriteria();
        searchCriteria.setQ(String.valueOf(strings));
        ToponymSearchResult searchResult = new ToponymSearchResult();

        try 
            searchResult = WebService.search(searchCriteria);
         catch (Exception e) 
            e.printStackTrace();
        

        for (Toponym toponym : searchResult.getToponyms()) //When I run the Code it skip this line IDK Why?? 
              
            System.out.println(toponym.getName()+" "+ toponym.getCountryName());

            try 
                result= toponym.getAdminCode3();
             catch (InsufficientStyleException e) 
                e.printStackTrace();
            
        

        return result; // I get null Value
    

当我使用网站 Geonames.org 并从邮政编码中搜索城市名称时,我能够得到它。

谁能帮帮我!!这就像我尝试了 2 天,但仍然得到一个空引用

堆栈跟踪

2020-06-18 17:39:08.171 18749-18749/com.chonang.main D/VanillaMapActivity: AddressResultReceiver.onReceiveResult: address: Pilongri Bhavan, Vaikang Road, Rongkhelan, Diphu, Assam 782460, India
2020-06-18 17:39:09.682 18749-19054/com.chonang.main D/FetchAddressIntentService: Addresses >> []
2020-06-18 17:39:09.683 18749-19054/com.chonang.main I/FetchAddressIntentService: Address found
2020-06-18 17:39:09.684 18749-18749/com.chonang.main D/VanillaMapActivity: AddressResultReceiver.onReceiveResult: address: NH329, Assam 782460, India
2020-06-18 17:39:18.957 18749-18749/com.chonang.main W/om.chonang.mai: Got a deoptimization request on un-deoptimizable method java.net.InetAddress[] libcore.io.Linux.android_getaddrinfo(java.lang.String, android.system.StructAddrinfo, int)
2020-06-18 17:39:18.958 18749-18749/com.chonang.main W/System.err: android.os.NetworkOnMainThreadException
2020-06-18 17:39:18.959 18749-18749/com.chonang.main W/System.err:     at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1565)
2020-06-18 17:39:18.960 18749-18749/com.chonang.main W/System.err:     at java.net.Inet6AddressImpl.lookupHostByName(Inet6AddressImpl.java:115)
2020-06-18 17:39:18.961 18749-18749/com.chonang.main W/System.err:     at java.net.Inet6AddressImpl.lookupAllHostAddr(Inet6AddressImpl.java:103)
2020-06-18 17:39:18.962 18749-18749/com.chonang.main W/System.err:     at java.net.InetAddress.getAllByName(InetAddress.java:1152)
2020-06-18 17:39:18.962 18749-18749/com.chonang.main W/System.err:     at com.android.okhttp.Dns$1.lookup(Dns.java:41)
2020-06-18 17:39:18.963 18749-18749/com.chonang.main W/System.err:     at com.android.okhttp.internal.http.RouteSelector.resetNextInetSocketAddress(RouteSelector.java:178)
2020-06-18 17:39:18.964 18749-18749/com.chonang.main W/System.err:     at com.android.okhttp.internal.http.RouteSelector.nextProxy(RouteSelector.java:144)
2020-06-18 17:39:18.965 18749-18749/com.chonang.main W/System.err:     at com.android.okhttp.internal.http.RouteSelector.next(RouteSelector.java:86)
2020-06-18 17:39:18.966 18749-18749/com.chonang.main W/System.err:     at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:176)
2020-06-18 17:39:18.967 18749-18749/com.chonang.main W/System.err:     at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:128)
2020-06-18 17:39:18.968 18749-18749/com.chonang.main W/System.err:     at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:97)
2020-06-18 17:39:18.969 18749-18749/com.chonang.main W/System.err:     at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:289)
2020-06-18 17:39:18.970 18749-18749/com.chonang.main W/System.err:     at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:232)
2020-06-18 17:39:18.971 18749-18749/com.chonang.main W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:465)
2020-06-18 17:39:18.972 18749-18749/com.chonang.main W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:411)
2020-06-18 17:39:18.973 18749-18749/com.chonang.main W/System.err:     at com.android.okhttp.internal.huc.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:248)
2020-06-18 17:39:18.974 18749-18749/com.chonang.main W/System.err:     at org.geonames.WebService.connect(WebService.java:235)
2020-06-18 17:39:18.974 18749-18749/com.chonang.main W/System.err:     at org.geonames.WebService.connectAndParse(WebService.java:302)
2020-06-18 17:39:18.975 18749-18749/com.chonang.main W/System.err:     at org.geonames.WebService.search(WebService.java:1292)
2020-06-18 17:39:18.976 18749-18749/com.chonang.main W/System.err:     at com.chonang.main.MainActivity$urlBackground.doInBackground(MainActivity.java:344)
2020-06-18 17:39:18.977 18749-18749/com.chonang.main W/System.err:     at com.chonang.main.MainActivity.sharedPreferenceCreate(MainActivity.java:283)
2020-06-18 17:39:18.978 18749-18749/com.chonang.main W/System.err:     at com.chonang.main.MainActivity.onActivityResult(MainActivity.java:142)
2020-06-18 17:39:18.978 18749-18749/com.chonang.main W/System.err:     at android.app.Activity.dispatchActivityResult(Activity.java:8135)
2020-06-18 17:39:18.980 18749-18749/com.chonang.main W/System.err:     at android.app.ActivityThread.deliverResults(ActivityThread.java:4955)
2020-06-18 17:39:18.981 18749-18749/com.chonang.main W/System.err:     at android.app.ActivityThread.handleSendResult(ActivityThread.java:5003)
2020-06-18 17:39:18.982 18749-18749/com.chonang.main W/System.err:     at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51)
2020-06-18 17:39:18.983 18749-18749/com.chonang.main W/System.err:     at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
2020-06-18 17:39:18.983 18749-18749/com.chonang.main W/System.err:     at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
2020-06-18 17:39:18.984 18749-18749/com.chonang.main W/System.err:     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2109)
2020-06-18 17:39:18.985 18749-18749/com.chonang.main W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:107)
2020-06-18 17:39:18.985 18749-18749/com.chonang.main W/System.err:     at android.os.Looper.loop(Looper.java:214)
2020-06-18 17:39:18.986 18749-18749/com.chonang.main W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7682)
2020-06-18 17:39:18.986 18749-18749/com.chonang.main W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
2020-06-18 17:39:18.987 18749-18749/com.chonang.main W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:516)
2020-06-18 17:39:18.988 18749-18749/com.chonang.main W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)`

我进行了一些更改,但仍然为空。

这是我更新后的代码

 @Override
    protected String doInBackground(String... strings) 

         StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
        StrictMode.setThreadPolicy(policy);

        SharedPreferences sharedPreferences= getSharedPreferences("POSTAL",MODE_PRIVATE);
        String code= sharedPreferences.getString("postal","");

        WebService.setUserName("jack"); // add your username here

        String result= new String();

        ToponymSearchCriteria searchCriteria= new ToponymSearchCriteria();
        searchCriteria.setQ(code);

        ToponymSearchResult searchResult = new ToponymSearchResult();
        try 
            searchResult = WebService.search(searchCriteria);
         catch (Exception e) 
            e.printStackTrace();
        

        for (Toponym tp: searchResult.getToponyms())

            result= tp.getAdminName3();
            Log.i(TAG, "doInBackground: city name is "+ result);
        

        Log.i(TAG, "doInBackground: postal Admin3 name is"+ result);


        return result;// ignore this value!!
    

但是,当我在网络上搜索结果时,我得到了结果:

【问题讨论】:

在问题中添加完整的错误堆栈跟踪。 @EraftYps 我已经添加了 StackTrace。我不知道为什么我的结果为空 我做了一些更改,但结果仍然为 null。 【参考方案1】:

我要感谢所有尝试给我答案的人。不幸的是,我没有得到答案。然而,经过两天的奋斗,我终于能够得到所需的结果。通过邮政编码,我可以得到城市名称。

上面我添加的内容是正确的,没有任何问题,但由于 Strick 模式,我无法获取它。但仍然有一个问题,我使用了以下代码,而不是 ToponmySearch:

PostalCodeSearchCriteria codeSearchCriteria= new PostalCodeSearchCriteria();
            codeSearchCriteria.setPostalCode("<Past_Your_postal_code_here>");
    List<PostalCode> postalCodes= WebService.postalCodeSearch(codeSearchCriteria);
                String ci= postalCodes.get(0).getAdminName3(); //CityName
                String cq= postalCodes.get(0).getAdminCode1();//StateName
                String cw= postalCodes.get(0).getAdminName2();//DistrictName
                String ce= postalCodes.get(0).getPlaceName();//PlaceName and etc many more you cam call there.```

我希望它可以帮助所有其他想要从邮政编码中获得城市名称的人。但是,您必须在 GEONAMES.ORG 中拥有一个帐户,并且您已经激活了免费服务选项。之后,您将能够从邮政编码中获取所需的值。为此,您必须使用 Geonames API。

谢谢!!

【讨论】:

【参考方案2】:

我打赌它崩溃了,因为您的库(来自 Geonames.org)正在尝试 http 与 https。解决方法(不好!)把它放在你的清单标签下:android:usesCleartextTraffic="true"


这也是错误的。您应该首先执行 (.execute()) 您的 AsyncTask。但实际上你最好不要使用 AsyncTask 并选择 rx 或协程。

        urlBackground background= new urlBackground();

        String city= background.doInBackground(e);

【讨论】:

我在我的 Manifest.xml 文件中添加了该行。android:usersCleartextTraffic="true"。当我尝试在 MainThread 上运行时,我收到一条错误消息,提示我必须在后台运行它。这就是我尝试使用 AsyncTask 的原因。我已附上 StackTrace 您误用了 AsyncTask,这就是错误的原因。如果你想走这条路,可以找一些关于 AsyncTasks 的教程。 我使用AsyncTask的方式不对!!好的。我以为我可以像其他方法一样传递它和值。我必须正确使用 onPostExecute 方法。但是我不知道如何从execute();方法中获取值 好的,我会检查并在这里发布。但请帮我解决它! :) 谢谢 不要期望从 execute() 本身获得价值。您应该在 doInBackground 中调用(调用 execute() 时会调用它)并在 onPostExecute 中处理其结果。

以上是关于我无法使用 Geonames API 从邮政编码中获取城市名称的主要内容,如果未能解决你的问题,请参考以下文章

使用 JSONP 技术从 Geonames API 加载国家标志

邮政编码数据库/地址验证

如何在地理名称和地理编码器 api 中动态生成边界框

从给定的城市谷歌地方 API 检索所有地区和子地区

GeoNames 是不是允许将街道数据下载为文件,而不是通过 Web 服务?

从纬度/经度获取邮政编码 + 4