Android 使用腾讯地图定位地点

Android 利用和风天气API显示实时天气 - 拾一贰叁 - 博客园 (cnblogs.com)

之前使用和风天气的SDK在Android App上显示了实时天气情况,但是显示的地点信息是提前设置好的

因此需要借助腾讯地图的SDK实现手动设定地点,如图:

在一个Activity的Fragment中点击"获取位置"

打开地图,跳转到如图所示的Activity,可以选择地点,然后点击确定(这个Activity本质上是一个WebView加一个Button,也就是下文的MappingActivity)

可以看出原来的Activity/Fragment得到了选定的地理位置,并将控件Button的Text文字修改成了这个地理位置。

使用腾讯位置服务的SDK还可以获得选择地点的其他信息,如经纬度之类的,在和风天气中通过经纬度显示当地天气。

关于如何获取腾讯位置服务可以参考官方文档,也可以参考之前和风天气的服务获取过程,基本上都差不多

Android定位SDK | 腾讯位置服务 (qq.com)

Key名称:随便取一个

描述:随便填一下

地图SDK:下边填的那个是应用程序的包名,com.xxx.xxx的那种

WebServiceAPI:不知道这个有啥用,之前死活加载不出来,一直显示获取消息列表失败,把这个选项勾选上后诡异地成功了,于是一直勾选着它了

 

接下来是对自己的工程文件操作了

在AndroidManifest.xml里配置刚刚在平台上获取的Key(就是那一长串字符)

<application>
    ...
    <meta-data android:name="TencentMapSDK" android:value="您申请的Key" />
</application>

然后给予一堆权限

<!-- 通过GPS得到精确位置 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<!-- 通过网络得到粗略位置 -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- 访问网络,某些位置信息需要从网络服务器获取 -->
<uses-permission android:name="android.permission.INTERNET"/>
<!-- 访问WiFi状态,需要WiFi信息用于网络定位 -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<!-- 修改WiFi状态,发起WiFi扫描, 需要WiFi信息用于网络定位 -->
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<!-- 访问网络状态, 检测网络的可用性,需要网络运营商相关信息用于网络定位 -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- 访问网络的变化, 需要某些信息用于网络定位 -->
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<!-- 蓝牙扫描权限 -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!-- 前台service权限 -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<!-- 后台定位权限 -->
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<!-- A-GPS辅助定位权限,方便GPS快速准确定位 -->
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/>

在build.gradle(Module:app)里添加依赖

implementation 'com.tencent.map.geolocation:TencentLocationSdk-openplatform:7.4.9'

(官方文档里写了多种方法,比较简单的做法就是直接在build.gradle里添上这一行就行了)

创建一个MappingActivity

布局文件为

activity_mapping.xml
 <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MappingActivity">

    <WebView
            android:id="@+id/web_map"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_marginBottom="56dp"
            app:layout_constraintBottom_toTopOf="@+id/btn_map"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent">
    </WebView>

    <Button
            android:id="@+id/btn_map"
            android:layout_width="match_parent"
            android:layout_height="40dp"
            android:layout_marginStart="16dp"
            android:layout_marginEnd="16dp"
            android:layout_marginBottom="8dp"
            android:background="@drawable/loginbuttonbackground"
            android:gravity="center"
            android:text="确定"
            android:textColor="@color/white"
            app:layout_constraintBottom_toBottomOf="parent"
            tools:layout_editor_absoluteX="16dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

效果

MappingActivity的java代码为:

package com.xxx.xxx;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.util.Log;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;

import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.text.DecimalFormat;

public class MappingActivity extends Activity {
    private WebView mWebView;
    private Button btn_map;
    private String positionname;//位置名
    private String rcity="";//城市
    private String address="未获取到位置";//详细地址
    private String latng="";//经纬度,纬度在前
    private String lat="";//纬度
    private String lng="";//经度
    private Uri uri;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_mapping);


        mWebView=findViewById(R.id.web_map);
        btn_map=findViewById(R.id.btn_map);
        String mUrl = "https://apis.map.qq.com/tools/locpicker?search=1&type=0&backurl=http://callback&key=【Key值】&referer=【应用名】";
        WebSettings settings = mWebView.getSettings();
        settings.setRenderPriority(WebSettings.RenderPriority.HIGH);
        settings.setSupportMultipleWindows(true);
        settings.setJavaScriptEnabled(true);
        settings.setSavePassword(false);
        settings.setJavaScriptCanOpenWindowsAutomatically(true);
        settings.setMinimumFontSize(settings.getMinimumFontSize() + 8);
        settings.setAllowFileAccess(false);
        settings.setTextSize(WebSettings.TextSize.NORMAL);
        mWebView.setVerticalScrollbarOverlay(true);
        mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, String url) {
                if (!url.startsWith("http://callback")) {
                    view.loadUrl(url);
                } else {
                    try {
                        //转utf-8编码
                        String decode = URLDecoder.decode(url, "UTF-8");
                        // LogUtil.i(decode);

                        //转uri,然后根据key取值
                        uri = Uri.parse(decode);
                        Log.e("address",uri.toString());
                        latng = uri.getQueryParameter("latng");//纬度在前,经度在后,以逗号分隔
                        String[] split = latng.split(",");
                        DecimalFormat decimalFormat=new DecimalFormat(".00");
                        lat=decimalFormat.format(Float.parseFloat(split[0]));//纬度
                        lng=decimalFormat.format(Float.parseFloat(split[1]));//经度
                        rcity = uri.getQueryParameter("city");//城市
                        address = uri.getQueryParameter("addr");//地理位置
                        positionname=uri.getQueryParameter("name");//地址名
                        //name是地址名,addr是详细地址,city是城市,latng是经纬度(不过纬度在前边)
                    } catch (UnsupportedEncodingException e) {
                        e.printStackTrace();
                    }
                }
                return true;
            }
        });
        mWebView.loadUrl(mUrl);

        /**最下边那个button的作用是点击后直接返回上一个activity
        与此同时将选定的位置数据传递给那个Activity
        */
        btn_map.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(MappingActivity.this,address.toString()+latng.toString(),Toast.LENGTH_LONG).show();
                System.out.println("信息:"+uri.toString());
                Intent intent = getIntent();

                intent.putExtra("name", positionname);
                intent.putExtra("city", rcity);
                intent.putExtra("address", address);
                intent.putExtra("lat", lat);
                intent.putExtra("lng", lng);
                MappingActivity.this.setResult(0,intent);//resultCode被设为0了,这个视实际情况而定,涉及到通过Intent在Activity间传递数据的知识
                MappingActivity.this.finish();
            }
        });
    }
}

在之前的和风天气中有这样一个接口 

QWeather.getWeatherNow(Context context, String location, Lang lang, Unit unit,QWeather.OnResultWeatherNowListener listener) ;

在这个接口里String location决定了查询天气的地点信息,这个变量可以是城市代码,比如“CN101180101”(郑州的城市代码),

也可以是经纬度,例如“113.66245,34.78181”(郑州的经纬度)(注意这个是经度在前,纬度在后)

将刚才从腾讯地图中获取的经纬度传递进去,就可以实现不同的地点显示不同的天气情况了。

 

补充:Fragment里接收来自MappingActivity信息的代码
//一个Fragment向另外一个Activity(MappingActivity)跳转,写在OnCreateView()里
btn_presetting_getposition.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(getActivity(),MappingActivity.class);
                startActivityForResult(intent,0);//请求码设为0
            }
        });

//-----写在OnCreateView外边
//该方法以回调方式来获取指定Activity返回的结果
    @Override
    public void onActivityResult(int requestCode,int resultCode,Intent intent){
        //核实请求码和答复码
        if(requestCode==0&&resultCode==0){
            //Toast.makeText(getActivity(),"回传成功",Toast.LENGTH_LONG).show();
            try{
                Bundle bundle=intent.getExtras();
                //iv_portrait.setImageResource(bundle.getInt("imageid"));
                btn_presetting_getposition.setText(bundle.getString("address"));
                position=bundle.getString("name");
                city=bundle.getString("city");
                address=bundle.getString("address");
                lat=bundle.getString("lat");
                lng=bundle.getString("lng");
            }catch(java.lang.RuntimeException e){
                Toast.makeText(getActivity(),"获取信息失败",Toast.LENGTH_SHORT).show();
            }
        }
    }

 

posted @ 2023-02-04 19:34  拾一贰叁  阅读(1057)  评论(0编辑  收藏  举报