0

I found a Question on stackoverflow from Nov 2015 here is the link.

The apk should retrieve all Restaurants nearby of the users position and Show them on Google maps.

I copied all the fixed codes from the Question into my Android Studio and changed the "out to date" parts.

When i start the app it Shows only a blank map without any markers and there are also no warnings/Errors.

Does anyone know why it wont work and wont show me the CurrentPosition and the restaurants nearby?

My Code does look like this now:

MapsActivity.java

package androfenix.onlymapsactivity;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
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.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import org.json.JSONArray;
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.ArrayList;
import java.util.HashMap;
import java.util.List;

//get user location: https://stackoverflow.com/questions/30253123/blue-dot-and-circle-is-not-shown-on-mylocation-using-android-fused-location-api/30255219#30255219

//Important resource for making this work:
//1. https://stackoverflow.com/questions/33971717/mapactivity-query-for-nearest-hospital-hospital-not-working
//2. https://stackoverflow.com/questions/31011216/request-denied-with-google-places-api-key-for-server-web-used-in-an-android-appl/31014444#31014444
//3. https://stackoverflow.com/questions/30253123/blue-dot-and-circle-is-not-shown-on-mylocation-using-android-fused-location-api/30255219#30255219


public class MapsActivity extends AppCompatActivity implements
        GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,
        LocationListener,
        OnMapReadyCallback {
    private GoogleMap mGoogleMap;
    SupportMapFragment mapFrag;
    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;
    LatLng latLng;
    double mLatitude = 0;
    double mLongitude = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_maps);

        mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFrag.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

        mGoogleMap = googleMap;
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        mGoogleMap.setMyLocationEnabled(true);
        buildGoogleApiClient();
        mGoogleApiClient.connect();
        String sbValue = sbMethod();
        PlacesTask placesTask = new PlacesTask();
        placesTask.execute(sbValue);
    }

    @Override
    public void onPause()
    {
        super.onPause();
        //Unregister for location callbacks:
        if (mGoogleApiClient != null)
        {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
    }

    protected synchronized void buildGoogleApiClient()
    {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    @Override
    public void onConnected(Bundle bundle) throws SecurityException
    {
        Toast.makeText(this,"Connected",Toast.LENGTH_SHORT).show();
        // Get LocationManager object from System Service LOCATION_SERVICE
        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        // Create a criteria object to retrieve provider
        Criteria criteria = new Criteria();
        // Get the name of the best provider
        String provider = locationManager.getBestProvider(criteria, true);
        // Get Current Location
        Location myLocation = locationManager.getLastKnownLocation(provider);
        // Get latitude of the current location
        double latitude = myLocation.getLatitude();
        // Get longitude of the current location
        double longitude = myLocation.getLongitude();
        // Create a LatLng object for the current location
        latLng = new LatLng(latitude, longitude);

        //mGoogleMap.clear();
        //latLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(latLng);
        markerOptions.title("Current Position");
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
        Marker m = mGoogleMap.addMarker(markerOptions);
        m.showInfoWindow();
        mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
        mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(11));
        Toast.makeText(this,"Touch the Pink Markers to view the details of that Hospital",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onConnectionSuspended(int i) {
        Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onLocationChanged(Location location) {

    }

    public String sbMethod() throws SecurityException
    {
        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        String provider = locationManager.getBestProvider(criteria, true);
        Location myLocation = locationManager.getLastKnownLocation(provider);
        mLatitude=myLocation.getLatitude();
        mLongitude=myLocation.getLongitude();

        String sb = ("https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
        sb += ("location=" + mLatitude + "," + mLongitude);
        sb += ("&radius=20000");
        sb +=("&types=" + "hospital|doctor");
        sb +=("&sensor=true");

        sb +=("&key=AIzaSyAdxtG72Sr7Ytv8mWUOdcbDLS9071ZI3Og");

        Log.d("Map", "url: " + sb);

        return sb;
    }

    private class PlacesTask extends AsyncTask<String, Integer, String>
    {

        String data = null;

        // Invoked by execute() method of this object
        @Override
        protected String doInBackground(String... url) {
            try {
                data = downloadUrl(url[0]);
            } catch (Exception e) {
                Log.d("Background Task", e.toString());
            }
            return data;
        }

        // Executed after the complete execution of doInBackground() method
        @Override
        protected void onPostExecute(String result) {
            ParserTask parserTask = new ParserTask();

            // Start parsing the Google places in JSON format
            // Invokes the "doInBackground()" method of the class ParserTask
            parserTask.execute(result);
        }
    }

    private String downloadUrl(String strUrl) throws IOException
    {
        String data = "";
        InputStream iStream = null;
        HttpURLConnection urlConnection = null;
        try {
            URL url = new URL(strUrl);

            // Creating an http connection to communicate with url
            urlConnection = (HttpURLConnection) url.openConnection();

            // Connecting to url
            urlConnection.connect();

            // Reading data from url
            iStream = urlConnection.getInputStream();

            BufferedReader br = new BufferedReader(new InputStreamReader(iStream));

            String sb = new String();

            String line = "";
            while ((line = br.readLine()) != null) {
                sb += (line);
            }

            data = sb;

            br.close();

        } catch (Exception e) {
            Log.d("Exception", e.toString());
//        } finally {
//            iStream.close();
//            urlConnection.disconnect();
        }
        return data;
    }

    private class ParserTask extends AsyncTask<String, Integer, List<HashMap<String, String>>> {

        JSONObject jObject;

        // Invoked by execute() method of this object
        @Override
        protected List<HashMap<String, String>> doInBackground(String... jsonData) {

            List<HashMap<String, String>> places = null;
            Place_JSON placeJson = new Place_JSON();

            try {
                jObject = new JSONObject(jsonData[0]);

                places = placeJson.parse(jObject);

            } catch (Exception e) {
                Log.d("Exception", e.toString());
            }
            return places;
        }

        // Executed after the complete execution of doInBackground() method
        @Override
        protected void onPostExecute(List<HashMap<String, String>> list) {

            Log.d("Map", "list size: " + list.size());
            // Clears all the existing markers;
            //mGoogleMap.clear();

            for (int i = 0; i < list.size(); i++) {

                // Creating a marker
                MarkerOptions markerOptions = new MarkerOptions();

                // Getting a place from the places list
                HashMap<String, String> hmPlace = list.get(i);


                // Getting latitude of the place
                double lat = Double.parseDouble(hmPlace.get("lat"));

                // Getting longitude of the place
                double lng = Double.parseDouble(hmPlace.get("lng"));

                // Getting name
                String name = hmPlace.get("place_name");

                Log.d("Map", "place: " + name);

                // Getting vicinity
                String vicinity = hmPlace.get("vicinity");

                latLng = new LatLng(lat, lng);

                // Setting the position for the marker
                markerOptions.position(latLng);

                markerOptions.title(name + " : " + vicinity);

                markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));

                // Placing a marker on the touched position
                Marker m = mGoogleMap.addMarker(markerOptions);
            }
        }
    }
    public class Place_JSON {

        /**
         * Receives a JSONObject and returns a list
         */
        public List<HashMap<String, String>> parse(JSONObject jObject) {

            JSONArray jPlaces = null;
            try {
                /** Retrieves all the elements in the 'places' array */
                jPlaces = jObject.getJSONArray("results");
            } catch (JSONException e) {
                e.printStackTrace();
            }
            /** Invoking getPlaces with the array of json object
             * where each json object represent a place
             */
            return getPlaces(jPlaces);
        }

        private List<HashMap<String, String>> getPlaces(JSONArray jPlaces) {
            int placesCount = jPlaces.length();
            List<HashMap<String, String>> placesList = new ArrayList<HashMap<String, String>>();
            HashMap<String, String> place = null;

            /** Taking each place, parses and adds to list object */
            for (int i = 0; i < placesCount; i++) {
                try {
                    /** Call getPlace with place JSON object to parse the place */
                    place = getPlace((JSONObject) jPlaces.get(i));
                    placesList.add(place);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
            return placesList;
        }

        /**
         * Parsing the Place JSON object
         */
        private HashMap<String, String> getPlace(JSONObject jPlace)
        {

            HashMap<String, String> place = new HashMap<String, String>();
            String placeName = "-NA-";
            String vicinity = "-NA-";
            String latitude = "";
            String longitude = "";
            String reference = "";

            try {
                // Extracting Place name, if available
                if (!jPlace.isNull("name")) {
                    placeName = jPlace.getString("name");
                }

                // Extracting Place Vicinity, if available
                if (!jPlace.isNull("vicinity")) {
                    vicinity = jPlace.getString("vicinity");
                }

                latitude = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lat");
                longitude = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lng");
                reference = jPlace.getString("reference");

                place.put("place_name", placeName);
                place.put("vicinity", vicinity);
                place.put("lat", latitude);
                place.put("lng", longitude);
                place.put("reference", reference);

            } catch (JSONException e) {
                e.printStackTrace();
            }
            return place;
        }
    }

}

activity_maps.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:map="http://schemas.android.com/apk/res-auto"
        android:layout_width="match_parent"`enter code here`
        android:layout_height="match_parent"
        android:id="@+id/map"
        tools:context="com.iotaconcepts.aurum.MapsActivity2"
        android:name="com.google.android.gms.maps.SupportMapFragment"/>

</LinearLayout>

Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="androfenix.onlymapsactivity">


    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">


        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="@string/google_maps_key" />

        <activity
            android:name=".MapsActivity"
            android:label="@string/title_activity_maps">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

LogCat Output

06-06 21:47:12.750 2747-2747/? I/art: Not late-enabling -Xcheck:jni (already on)
06-06 21:47:12.773 2747-2753/? I/art: Debugger is no longer active
06-06 21:47:12.857 2747-2747/? W/art: Failed execv(/system/bin/dex2oat --runtime-arg -classpath --runtime-arg  --instruction-set=x86 --instruction-set-features=smp,ssse3,-sse4.1,-sse4.2,-avx,-avx2 --runtime-arg -Xrelocate --boot-image=/system/framework/boot.art --runtime-arg -Xms64m --runtime-arg -Xmx512m --instruction-set-variant=x86 --instruction-set-features=default --dex-file=/data/app/androfenix.onlymapsoffiziell-2/base.apk --oat-file=/data/dalvik-cache/x86/data@app@androfenix.onlymapsoffiziell-2@base.apk@classes.dex) because non-0 exit status
06-06 21:47:13.075 2747-2747/? W/System: ClassLoader referenced unknown path: /data/app/androfenix.onlymapsoffiziell-2/lib/x86
06-06 21:47:13.106 2747-2747/? I/GMPM: App measurement is starting up, version: 8487
06-06 21:47:13.106 2747-2747/? I/GMPM: To enable debug logging run: adb shell setprop log.tag.GMPM VERBOSE
06-06 21:47:13.246 2747-2747/? I/zzad: Making Creator dynamically
06-06 21:47:13.249 2747-2747/? W/System: ClassLoader referenced unknown path: /system/priv-app/PrebuiltGmsCore/lib/x86
06-06 21:47:13.300 2747-2747/? D/ChimeraCfgMgr: Reading stored module config
06-06 21:47:13.303 2747-2747/? D/ChimeraCfgMgr: Loading module com.google.android.gms.maps from APK /data/user/0/com.google.android.gms/app_chimera/chimera-module-root/module-a3e4fba11e705727c59ff3116ef21fa4834b9f56/MapsModule.apk
06-06 21:47:13.303 2747-2747/? D/ChimeraModuleLdr: Loading module APK /data/user/0/com.google.android.gms/app_chimera/chimera-module-root/module-a3e4fba11e705727c59ff3116ef21fa4834b9f56/MapsModule.apk
06-06 21:47:13.316 2747-2757/? W/art: Suspending all threads took: 6.290ms
06-06 21:47:13.317 2747-2757/? I/art: Background partial concurrent mark sweep GC freed 746(60KB) AllocSpace objects, 0(0B) LOS objects, 39% free, 3MB/5MB, paused 6.754ms total 15.550ms
06-06 21:47:13.317 2747-2747/? D/ChimeraFileApk: Primary ABI of requesting process is x86
06-06 21:47:13.317 2747-2747/? D/ChimeraFileApk: Classloading successful. Optimized code found.
06-06 21:47:13.318 2747-2747/? W/System: ClassLoader referenced unknown path: /data/user/0/com.google.android.gms/app_chimera/chimera-module-root/module-a3e4fba11e705727c59ff3116ef21fa4834b9f56/native-libs/x86
06-06 21:47:13.342 2747-2747/? I/Google Maps Android API: Google Play services client version: 8487000
06-06 21:47:13.349 2747-2747/? I/Google Maps Android API: Google Play services package version: 8489470
06-06 21:47:13.619 2747-2747/? I/e: Token loaded from file. Expires in: 355092112 ms.
06-06 21:47:13.619 2747-2747/? I/e: Scheduling next attempt in 354792 seconds.
06-06 21:47:13.855 2747-2825/androfenix.onlymapsoffiziell D/OpenGLRenderer: Use EGL_SWAP_BEHAVIOR_PRESERVED: true
06-06 21:47:13.933 2747-2825/androfenix.onlymapsoffiziell I/OpenGLRenderer: Initialized EGL, version 1.4
06-06 21:47:13.970 2747-2825/androfenix.onlymapsoffiziell W/EGL_emulation: eglSurfaceAttrib not implemented
06-06 21:47:13.970 2747-2825/androfenix.onlymapsoffiziell W/OpenGLRenderer: Failed to set EGL_SWAP_BEHAVIOR on surface 0xaf913c60, error=EGL_SUCCESS
06-06 21:47:14.055 2747-2747/androfenix.onlymapsoffiziell W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
06-06 21:47:23.837 2747-2787/androfenix.onlymapsoffiziell I/GMPM: Tag Manager is not found and thus will not be used
Community
  • 1
  • 1
Martin
  • 13
  • 4
  • you need an API key using a release SHA-1 of you development machine – Mina Gabriel Jun 04 '16 at 03:22
  • @string/google_maps_key I bet this key is the debug one – Mina Gabriel Jun 04 '16 at 03:23
  • I did use the SHA-1 Key, still doesnt work – Martin Jun 04 '16 at 12:02
  • is this is the key you generate using your- Build-> Generate signed APK- Key store or the debug key store? you should end up having two google_maps_api.xml one for release and another for debuging – Mina Gabriel Jun 04 '16 at 12:57
  • Y you were right. The debug key ist the @string/google_maps_key. I generated now with "Build -> Generate signed APK" a "app-release.apk". What do i have to do with the generated file? And what do you mean with "i need to have two google_maps_api.xml"? – Martin Jun 04 '16 at 14:38
  • @Mina Gabriel could you maybe test it in your android studio? =D – Martin Jun 04 '16 at 21:05

2 Answers2

0

After creating the .jks Key store you need to use it to generate your SHA-1 key using the following command

keytool -exportcert -alias alias_goes_here -keystore /location/of/Keystore.jks  -list -v 

go to google developer console and generate a new API key using the release key store SHA-1, your project should have two google_maps_api.xml one for debugging and another one for release.

enter image description here

Mina Gabriel
  • 23,150
  • 26
  • 96
  • 124
  • Yes, this is 100% tested and working, when you created the signed APK it will ask you for the key store alias... this is what you want. – Mina Gabriel Jun 05 '16 at 21:33
  • Okey i got the release SH-1 code and generated a second API Key for the google_maps_api.xml release file – Martin Jun 06 '16 at 00:24
  • I added the release api code into the "google_maps_api.xml" file and "run" the app. Still doesnt work =/ also tested it on mobile phone! – Martin Jun 06 '16 at 00:31
  • what errors are you getting can you post the logcat "errors" – Mina Gabriel Jun 06 '16 at 14:42
  • I posted the whole logcat in the top answer. I updated the logcat today again. – Martin Jun 06 '16 at 21:52
0

I fixed the problem with a friend and we changed the code a little.

I dont know what the reason was, but in the new version we are using only the debug API and Server API code and it also works haha

You can find the new version of the code here. I opened a new question because the new code has some other problems <.<

Community
  • 1
  • 1
Martin
  • 13
  • 4