Monday 9 August 2021

Can not get places data from google map in android

I want to show the list of nearby hospitals, but I cannot get the data from Google Maps. (But when I use the API key of the user from where I have learned to display the map in android, I am able to get the data.)

Things I have already done:

  1. Enable Map API and place API from google cloud console
  2. Setup billing account

Code XML file

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/white"
    android:orientation="vertical"
    android:weightSum="10">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="@color/colorPrimaryDark"
        app:layout_constraintTop_toTopOf="parent">

        <ImageView
            android:id="@+id/imageDrawer"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:contentDescription="@string/app_name"
            android:gravity="center_vertical"
            android:src="@drawable/back_arrows" />

        <TextView
            android:id="@+id/textTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="@dimen/_24sdp"
            android:background="@drawable/title_stroke"
            android:fontFamily="@font/ubuntu_bold"
            android:gravity="center_vertical"
            android:paddingStart="@dimen/_8sdp"
            android:paddingTop="@dimen/_2sdp"
            android:paddingEnd="@dimen/_8sdp"
            android:paddingBottom="@dimen/_2sdp"
            android:text="@string/nearby"
            android:textColor="@color/white"
            android:textSize="@dimen/_16ssp" />
    </androidx.appcompat.widget.Toolbar>

    <fragment
        android:id="@+id/googleMap"
        android:name="com.google.android.gms.maps.SupportMapFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="5"
        tools:ignore="FragmentTagUsage" />

    <ListView
        android:id="@+id/centersListView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="5" />

</LinearLayout>

Java Class

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.widget.ListView;
import android.widget.Toast;

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

import com.aaienafit.R;
import com.aaienafit.databinding.ActivityDoctorBinding;
import com.aaienafit.utils.ProgressDialog;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
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.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;


public class DoctorActivity extends FragmentActivity implements OnMapReadyCallback {

    ActivityDoctorBinding binding;

    StringBuffer stringBuffer;
    ListView centersListView;
    double latitude, longitude;
    LocationManager locationManager;
    Location location;
    private GoogleMap mMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivityDoctorBinding.inflate(LayoutInflater.from(this));
        setContentView(binding.getRoot());

        stringBuffer = new StringBuffer();
        centersListView = findViewById(R.id.centersListView);

        centersListView.setOnItemClickListener((adapterView, view, i, l) -> new AlertDialog.Builder(DoctorActivity.this).setCancelable(true).setTitle(LocationController.detailArrayList.get(i).getHospitalName()).setMessage(LocationController.detailArrayList.get(i).getAddress()).setIcon(R.drawable.marker).show());

        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.googleMap);
        if (mapFragment != null) {
            mapFragment.getMapAsync(this);

        }
        getList();


    }


    @Override
    public void onMapReady(@NonNull GoogleMap googleMap) {
        mMap = googleMap;

        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            mMap.setMyLocationEnabled(true);
            setUpCameraAndMarkers();
            LatLng latLng = new LatLng(latitude, longitude);
            mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 11f));
            Objects.requireNonNull(mMap.addMarker(new MarkerOptions().position(latLng))).setIcon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE));

        }

    }

    public void updateLoc() {
        locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
        if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            throw new IllegalArgumentException("No GPS");
        } else if (!isGooglePlayServicesAvailable(this)) {
            throw new IllegalArgumentException("No Google Play Services Available");
        } else getLocation();

    }

    public boolean isGooglePlayServicesAvailable(Context context) {
        GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
        int resultCode = googleApiAvailability.isGooglePlayServicesAvailable(context);
        return resultCode == ConnectionResult.SUCCESS;
    }

    void getLocation() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
            try {
                location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

                if (location != null) {
                    Log.d("latitude=>", location.getLatitude() + ", longitude=> " + location.getLongitude());
                    latitude = location.getLatitude();
                    longitude = location.getLongitude();

                }

            } catch (Exception e) {
                Log.d("LOCATION_UPDATE", "getLocation: ");
            }


        }


    }

    protected void fillList() {
        ArrayList<String> placeName = new ArrayList<>();
        for (int i = 0; i < LocationController.detailArrayList.size(); i++) {
            placeName.add(LocationController.detailArrayList.get(i).getHospitalName());
        }


        ArrayList<String> address = new ArrayList<>();
        for (int i = 0; i < LocationController.detailArrayList.size(); i++) {
            address.add(LocationController.detailArrayList.get(i).getAddress());
        }

        PlacesListAdapter placesListAdapter = new PlacesListAdapter(this, placeName, address);
        centersListView.setAdapter(placesListAdapter);
    }

    void loadLocation() {
        try {
            RetrieveFeedTask();
            new Thread(() -> {
                while (stringBuffer.length() == 0) Log.d("Message", "buffer reading");
                LocationController.manipulateData(stringBuffer);
            }).start();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    void RetrieveFeedTask() {

        ExecutorService executor = Executors.newSingleThreadExecutor();
        executor.execute(() -> {

            try {
                String string =
                        "https://maps.googleapis.com/maps/api/place/search/json?rankby=distance&keyword=hospital&location=" +
                                latitude +
                                "," +
                                longitude +
                                "&key=" + getString(R.string.google_api_key) + "&libraries=places";
               

                URL url = new URL(string);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                InputStream inputStream = connection.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                StringBuffer buffer = new StringBuffer();

                String n;
                while ((n = bufferedReader.readLine()) != null) {
                    buffer.append(n);
                }

                stringBuffer = buffer;
            } catch (Exception e) {
                Toast.makeText(DoctorActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
            }

        });
    }

    void getList() {
        try {
            updateLoc();
            LocationController.loading = true;
            loadLocation();
            while (LocationController.loading) {
                Log.d("GeometryResponse", "Waiting for response");
            }
            fillList();
        } catch (IllegalArgumentException e) {
            Toast.makeText(DoctorActivity.this, e.getMessage(), Toast.LENGTH_LONG).show();
        }
        if (ProgressDialog.isProgressShowing()) {
            ProgressDialog.dismissProgressDialog();
        }
    }

    void setUpCameraAndMarkers() {
        LatLng latLng;
        for (int i = 0; i < LocationController.detailArrayList.size(); i++) {
            latLng = new LatLng(LocationController.detailArrayList.get(i).getGeometry()[0], LocationController.detailArrayList.get(i).getGeometry()[1]);
            mMap.addMarker(new MarkerOptions().position(latLng).title(LocationController.detailArrayList.get(i).getHospitalName()));
            mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        }


    }


}

PlacesListAdapter Class

import android.annotation.SuppressLint;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;

import com.aaienafit.R;

import java.util.ArrayList;

public class PlacesListAdapter extends BaseAdapter {


    private final Context context;
    private final ArrayList<String> placeName;
    private final ArrayList<String> openNowText;


    public PlacesListAdapter(Context context, ArrayList<String> placeName, ArrayList<String> openNowText) {
        this.context = context;
        this.placeName = placeName;
        this.openNowText = openNowText;
    }


    @Override
    public int getCount() {
        return placeName.size();
    }

    @Override
    public Object getItem(int i) {
        return placeName.get(i);
    }

    @Override
    public long getItemId(int i) {
        return 3232;
    }

    @SuppressLint("SetTextI18n")
    @Override
    public View getView(int i, View view, ViewGroup viewGroup) {

        if (view == null) view = View.inflate(context, R.layout.doctor_list_item, null);

        TextView placeTextView = view.findViewById(R.id.textDoctorName);
        TextView address = view.findViewById(R.id.textAddress);

        placeTextView.setText(placeName.get(i));
        address.setText(openNowText.get(i));

        return view;
    }
}

HospitalModel Class

import androidx.annotation.NonNull;

import java.util.Arrays;

public class HospitalModel {

    private String hospitalName;
    private String rating;
    private String openingHours;
    private String address;
    private double[] geometry;

    public String getHospitalName() {
        return hospitalName;
    }

    public void setHospitalName(String hospitalName) {
        this.hospitalName = hospitalName;
    }

    public String getRating() {
        return rating;
    }

    public void setRating(String rating) {
        this.rating = rating;
    }

    public String getOpeningHours() {
        return openingHours;
    }

    public void setOpeningHours(String openingHours) {
        this.openingHours = openingHours;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public double[] getGeometry() {
        return geometry;
    }

    public void setGeometry(double[] geometry) {
        this.geometry = geometry;
    }

    @NonNull
    @Override
    public String toString() {
        return "NearbyHospitalsDetail{" +
                ", hospitalName='" + hospitalName + '\'' +
                ", rating=" + rating +
                ", openingHours='" + openingHours + '\'' +
                ", address='" + address + '\'' +
                ", geometry=" + Arrays.toString(geometry) +
                '}';
    }
}

LocationController class

import android.util.Log;

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

import java.util.ArrayList;


public class LocationController {

    public static boolean loading;
    public static ArrayList<HospitalModel> detailArrayList = new ArrayList<>();

    public static void manipulateData(StringBuffer buffer) {
        loading = true;
        try {
            detailArrayList.clear();
            JSONObject object = new JSONObject(buffer.toString());
            JSONArray array = object.getJSONArray("results");
            for (int i = 0; i < array.length(); i++) {
                try {
                    JSONObject jsonObject = array.getJSONObject(i);
                    HospitalModel hospitalsDetail = new HospitalModel();

                    jsonObject.getString("name");
                    hospitalsDetail.setHospitalName(jsonObject.getString("name"));

                    try {
                        hospitalsDetail.setRating(String.valueOf(jsonObject.getDouble("rating")));
                    } catch (Exception e) {
                        hospitalsDetail.setRating("Not Available");
                    }
                    try {
                        if (jsonObject.getJSONObject("opening_hours").getBoolean("open_now"))
                            hospitalsDetail.setOpeningHours("Opened");
                        else hospitalsDetail.setOpeningHours("closed");
                    } catch (Exception e) {
                        hospitalsDetail.setOpeningHours("Not Available");
                    }

                    hospitalsDetail.setAddress(jsonObject.getString("vicinity"));
                    hospitalsDetail.setGeometry(new double[]{jsonObject.getJSONObject("geometry").getJSONObject("location").getDouble("lat"),
                            jsonObject.getJSONObject("geometry").getJSONObject("location").getDouble("lng")});

                    detailArrayList.add(hospitalsDetail);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        loading = false;
        Log.d("Array Loaded with size ", "Size of " + detailArrayList.size());
    }
}

Manifest file

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example">
    <!--
         The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
         Google Maps Android API v2, but you must specify either coarse or fine
         location permissions for the "MyLocation" functionality.
    -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission
        android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />
    <uses-permission
        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />
    <uses-permission android:name="android.permission.CAMERA" />

    <uses-feature
        android:name="android.hardware.camera"
        android:required="true" />

    <queries>
        <intent>
            <action android:name="com.google.android.youtube.api.service.START" />
        </intent>
    </queries>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:requestLegacyExternalStorage="true"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AaienaFit"
        android:usesCleartextTraffic="true"
        tools:ignore="AllowBackup"
        tools:targetApi="m">
        <activity
            android:name=".activities.youtubePlayer.YoutubePlayerActivity"
            android:configChanges="orientation|screenSize"
            android:noHistory="true" />

        <uses-library
            android:name="org.apache.http.legacy"
            android:required="false" />

        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_api_key" />
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <activity android:name=".activities.doctor.DoctorActivity" />
        <activity
            android:name=".utils.SplashScreen"
            android:noHistory="true"
            android:theme="@style/Splash"
            tools:ignore="IntentFilterExportedReceiver">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".activities.authentication.AuthenticationActivity" />
        <activity android:name=".activities.main.MainActivity" />

        <receiver
            android:name=".broadcasts.NotificationBroadcast"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="button_click" />
            </intent-filter>
        </receiver>
    </application>

</manifest>


from Can not get places data from google map in android

No comments:

Post a Comment