ANDROID STUDIO - 如何将标记添加到当前位置?

Posted

技术标签:

【中文标题】ANDROID STUDIO - 如何将标记添加到当前位置?【英文标题】:ANDROID STUDIO - How to add marker to current location? 【发布时间】:2021-09-03 08:15:53 【问题描述】:

我是 android Studio 的新手,我正在尝试一件事。当我用地图加载我的片段时,我想显示我的位置(这不起作用 - 市场没有出现,相机也没有放大),当我点击按钮时,它会搜索附近的麦当劳。我在 youtube 上找到了它,但我不想让滚动条来选择一个位置,我只想要一个位置,我认为这就是问题所在。

MapActivity.java

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.Button;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.List;

public class MapActivity extends AppCompatActivity 

    Button btFind;
    SupportMapFragment supportMapFragment;
    GoogleMap googleMap;
    FusedLocationProviderClient fusedLocationProviderClient;
    double currentLat = 0, currentLong = 0;

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

        btFind = findViewById(R.id.bt_find);
        supportMapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.google_map);

        String[] placeNameList = "McDonald's";
        String[] placeTypeList = "McDonald's";

        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);

        if (ActivityCompat.checkSelfPermission(MapActivity.this
                , Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) 
            getCurrentLocation();
        

        btFind.setOnClickListener(v -> 
            String url = "https://maps.google.com/maps/api/place/nearbysearch/json" +
                    "?location=" + currentLat + "," + currentLong +
                    "&radius=15000" +
                    "&types=" + placeTypeList +
                    "&sensor=true" +
                    "&key=" + "AIzaSyB-c4k2RXcThSgX9YxeK56QDbzsqK5xPu8";

            new PlaceTask().execute(url);
        );
    

    private void getCurrentLocation() 
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
            return;
        
        Task<Location> task = fusedLocationProviderClient.getLastLocation();
        task.addOnSuccessListener(new OnSuccessListener<Location>() 
            @Override
            public void onSuccess(Location location) 
                if (location != null) 
                    currentLat = location.getLatitude();
                    currentLong = location.getLongitude();
                    supportMapFragment.getMapAsync(new OnMapReadyCallback() 
                        @Override
                        public void onMapReady(GoogleMap googleMap) 
                            GoogleMap map = googleMap;
                            map.animateCamera(CameraUpdateFactory.newLatLngZoom(
                                    new LatLng(currentLong, currentLong), 15.5f), 4000, null
                            );
                        
                    );
                
            
        );
    

    private class PlaceTask extends AsyncTask<String, Integer, String> 

        @Override
        protected String doInBackground(String... strings) 
            String data = null;
            try 
                data = downloadUrl(strings[0]);
             catch (IOException e) 
                e.printStackTrace();
            
            return data;
        

        @Override
        protected void onPostExecute(String s) 
            new ParserTask().execute(s);
        

        private String downloadUrl(String string) throws IOException 
            URL url = new URL(string);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.connect();
            InputStream stream = connection.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
            StringBuilder builder = new StringBuilder();
            String line = "";
            while ((line = reader.readLine()) != null) 
                builder.append(line);
            
            String data = builder.toString();
            reader.close();
            return data;
        

        private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String, String>>> 
            @Override
            protected List<HashMap<String, String>> doInBackground(String... strings) 
                JsonParser jsonParser = new JsonParser();
                List<HashMap<String, String>> mapList = null;
                JSONObject object = null;
                try 
                    object = new JSONObject(strings[0]);
                    mapList = jsonParser.parseResult(object);
                 catch (JSONException e) 
                    e.printStackTrace();
                
                return mapList;
            

            @Override
            protected void onPostExecute(List<HashMap<String, String>> hashMaps) 
                googleMap.clear();
                for (int i = 0; i < hashMaps.size(); i++) 
                    HashMap<String, String> hashMapList = hashMaps.get(i);
                    double lat = Double.parseDouble(hashMapList.get("lat"));
                    double lng = Double.parseDouble(hashMapList.get("lng"));
                    String name = hashMapList.get("name");
                    LatLng latLng = new LatLng(lat, lng);
                    MarkerOptions options = new MarkerOptions();
                    options.position(latLng);
                    options.title(name);
                    googleMap.addMarker(options);
                
            
        
    

JsonParser.java

package com.example.mcdonaldscoupons;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ResourceBundle;

public class JsonParser 
    private HashMap<String,String> parseJsonObject(JSONObject JSONObject) 
        HashMap<String, String> dataList = new HashMap<>();
        try 
            JSONArray object = null;
            String name = object.getString(Integer.parseInt("name"));
            String latitude = object.getJSONObject(Integer.parseInt("geometry"))
                    .getJSONObject("location").getString("lat");
            String longitude = object.getJSONObject(Integer.parseInt("geometry"))
                    .getJSONObject("location").getString("lng");
            dataList.put("name", name);
            dataList.put("lat", latitude);
            dataList.put("lng", longitude);
         catch (JSONException e) 
            e.printStackTrace();
        

        return dataList;
    

    private List<HashMap<String, String>> parseJsonArray(JSONArray jsonArray) throws JSONException 
        List<HashMap<String, String>> dataList = new ArrayList<>();
        for (int i = 0; i < jsonArray.length(); i++) 
            HashMap<String, String> data = parseJsonObject((JSONObject) jsonArray.get(i));
            dataList.add(data);
        
        return dataList;
    

    public List<HashMap<String, String>> parseResult(JSONObject object) throws JSONException 
        JSONArray jsonArray = null;
        jsonArray = object.getJSONArray("results");
        return parseJsonArray(jsonArray);
    

fragment_map.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_
    android:layout_
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    tools:context=".MapActivity">

    <LinearLayout
        android:layout_
        android:layout_
        android:orientation="horizontal"
        android:padding="8dp">

        <Button
            android:id="@+id/bt_find"
            android:layout_
            android:layout_
            android:layout_centerInParent="true"
            android:text="Hledej!" />
    </LinearLayout>

    <androidx.fragment.app.FragmentContainerView
        android:layout_
        android:layout_
        android:id="@+id/google_map"
        android:name="com.google.android.gms.maps.SupportMapFragment"/>

</LinearLayout>

【问题讨论】:

你已经输入了你的谷歌密钥,删除这篇文章并创建一个新的。永远不要在 SO 上发布密钥或密码。 你检查了 currentLat,currentLng 在 getCurrentLocation() 中有值吗? @androidLearner 我该怎么做? (我是 android 新手,这段代码来自 youtube) 【参考方案1】:

如果currentLat,currentLng有值,添加标记

     supportMapFragment.getMapAsync(new OnMapReadyCallback() 
                                @Override
                                public void onMapReady(GoogleMap googleMap) 
     //use your global map instance.                               
     googleMap= googleMap;

//check value in "Run" tab .
    log.i("currrentLat",currrentLat);
    log.i("currrentLang",currentLng);

    LatLng latLng = new LatLng(currrentLat, currentLng);
                        MarkerOptions options = new MarkerOptions();
                        options.position(latLng);
                        options.title(name);
                        googleMap.addMarker(options);
                                    googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
                                            new LatLng(currentLong, currentLong), 15.5f), 4000, null
                                    );
                                
                            );

【讨论】:

错误:找不到符号 options.title(name); 你可以给任何你想要的标题。@VojtěchAdam options.title("test");没有错误,但它仍然不起作用:/ 试试这个 onMapReady(GoogleMap map) googleMap= map; @VojtěchAdam 使用 googleMap= map 它没有工作必须做 googleMap= googleMap 但再次......仍然没有工作【参考方案2】:

我看到你这里有一个错字:

new LatLng(currentLong, currentLong),
           ^^^^^^^^^^^

应该是 currentLat

【讨论】:

当前位置和按钮都不起作用 @VojtěchAdam 你确定你知道位置吗?您是否为清单文件添加了适当的权限? @VojtěchAdam 您应该使用 ActivityCompat.requestPermissions 请求权限,请参见此处:developers.google.com/android/guides/permissions 一旦授予权限,将在您可以请求位置的地方调用回调 onRequestPermissionsResult。 是的,我在清单中执行它,在我的 MainActivity 中我有一个对话框(互联网、access_fine_location 和 access_coarse_location) 但是在提供的代码中,一旦检查权限失败,您就不要调用 ActivityCompat.requestPermissions。您的代码应包含 ActivityCompat.requestPermissions【参考方案3】:

更新伙计们! 我尝试了不同的代码来显示我当前的位置,但它仍然不起作用:/

MapActivity.java


import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.fragment.app.FragmentActivity;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;

import org.jetbrains.annotations.NotNull;

public class MapActivity extends FragmentActivity implements OnMapReadyCallback 

    Location currentLocation;
    FusedLocationProviderClient fusedLocationProviderClient;
    private static final int REQUEST_CODE = 101;

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

        fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        fetchLastLocation();
    

    private void fetchLastLocation() 
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) 
            ActivityCompat.requestPermissions(this,new String[]
                    Manifest.permission.ACCESS_FINE_LOCATION, REQUEST_CODE);
            return;
        
        Task<Location> task = fusedLocationProviderClient.getLastLocation();
        task.addOnSuccessListener(location -> 
            if (location != null) 
                currentLocation = location;
                Toast.makeText(getApplicationContext(),currentLocation.getLatitude()
                +""+currentLocation.getLongitude(),Toast.LENGTH_SHORT).show();
                SupportMapFragment supportMapFragment = (SupportMapFragment)
                        getSupportFragmentManager().findFragmentById(R.id.google_map);
                supportMapFragment.getMapAsync(MapActivity.this);
            
        );
    

    @Override
    public void onMapReady(@NonNull @NotNull GoogleMap googleMap) 
        LatLng latLng = new LatLng(currentLocation.getLatitude(),currentLocation.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions().position(latLng)
                .title("Here I am!");
        googleMap.animateCamera(CameraUpdateFactory.newLatLng(latLng));
        googleMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 5));
        googleMap.addMarker(markerOptions);
    

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull @NotNull String[] permissions, @NonNull @NotNull int[] grantResults) 
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) 
            case REQUEST_CODE:
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) 
                    fetchLastLocation();
                
                break;
        
    

fragment_map.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    tools:context=".MapActivity">

    <fragment
        android:id="@+id/google_map"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_
        android:layout_ />

</RelativeLayout>

【讨论】:

以上是关于ANDROID STUDIO - 如何将标记添加到当前位置?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 iPhone 添加到 Android Studio?

如何将图像添加到 Android Studio 中的“drawable”文件夹?

如何将 Android Studio 项目添加到 GitHub [重复]

如何使用 Android Studio 将信息窗口放置在 GoogleMaps 中标记的左侧或右侧

如何将两个集合添加到 Firestore 中的集合 android studio

如何将 Mysql JDBC 驱动程序添加到 android studio