Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed .idea/caches/build_file_checksums.ser
Binary file not shown.
15 changes: 8 additions & 7 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 12 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,17 @@ dependencies {

// Circle ImageView
implementation 'de.hdodenhof:circleimageview:2.2.0'

// Google marker cluster
implementation'com.google.maps.android:android-maps-utils:0.5+'

//Google directions
implementation 'com.google.maps:google-maps-services:0.9.0'
implementation 'org.slf4j:slf4j-simple:1.7.25'

//Google services
implementation 'com.google.android.gms:play-services-maps:15.0.1'
implementation 'com.google.android.gms:play-services-places:15.0.1'
implementation 'com.google.android.gms:play-services-location:15.0.1'
}
apply plugin: 'com.google.gms.google-services'
42 changes: 42 additions & 0 deletions app/google-services.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
{
"project_info": {
"project_number": "999529025534",
"firebase_url": "https://maps-2018-a3040.firebaseio.com",
"project_id": "maps-2018-a3040",
"storage_bucket": "maps-2018-a3040.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:999529025534:android:a1d1ce9b8c3681aa",
"android_client_info": {
"package_name": "com.codingwithmitch.googlemaps2018"
}
},
"oauth_client": [
{
"client_id": "999529025534-phqa0i38lbvdan5ur18ii05lhopd0431.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyCYuRqkzUIhxXRBSHWTh87a0rRFq227M9M"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 1,
"other_platform_oauth_client": []
},
"ads_service": {
"status": 2
}
}
}
],
"configuration_version": "1"
}
22 changes: 22 additions & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.codingwithmitch.googlemaps2018">

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

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

<uses-feature
android:glEsVersion="0x00020000"
android:required="true"/>

<application
android:name=".UserClient"
android:allowBackup="true"
Expand All @@ -24,6 +34,18 @@
<activity android:name=".ui.ChatroomActivity" />
<activity android:name=".ui.ProfileActivity"/>

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

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

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

</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,8 @@
public class Constants {

public static final int ERROR_DIALOG_REQUEST = 9001;
public static final int PERMISSIONS_REQUEST_ENABLE_GPS = 9002;
public static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 9003;
public static final String MAPVIEW_BUNDLE_KEY = "MapViewBundleKey";

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,244 @@
package com.codingwithmitch.googlemaps2018;
/*
/*
* Copyright (C) 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/


import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.common.data.DataBufferUtils;
import com.google.android.gms.location.places.AutocompleteFilter;
import com.google.android.gms.location.places.AutocompletePrediction;
import com.google.android.gms.location.places.AutocompletePredictionBuffer;
import com.google.android.gms.location.places.Places;
import com.google.android.gms.maps.model.LatLngBounds;


import android.content.Context;
import android.graphics.Typeface;
import android.text.style.CharacterStyle;
import android.text.style.StyleSpan;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;

/**
* Adapter that handles Autocomplete requests from the Places Geo Data API.
* {@link AutocompletePrediction} results from the API are frozen and stored directly in this
* adapter. (See {@link AutocompletePrediction#freeze()}.)
* <p>
* Note that this adapter requires a valid {@link com.google.android.gms.common.api.GoogleApiClient}.
* The API client must be maintained in the encapsulating Activity, including all lifecycle and
* connection states. The API client must be connected with the {@link Places#GEO_DATA_API} API.
*/
public class PlaceAutocompleteAdapter
extends ArrayAdapter<AutocompletePrediction> implements Filterable {

private static final String TAG = "PlaceAutoCompleteAd";
private static final CharacterStyle STYLE_BOLD = new StyleSpan(Typeface.BOLD);
/**
* Current results returned by this adapter.
*/
private ArrayList<AutocompletePrediction> mResultList;

/**
* Handles autocomplete requests.
*/
private GoogleApiClient mGoogleApiClient;

/**
* The bounds used for Places Geo Data autocomplete API requests.
*/
private LatLngBounds mBounds;

/**
* The autocomplete filter used to restrict queries to a specific set of place types.
*/
private AutocompleteFilter mPlaceFilter;

/**
* Initializes with a resource for text rows and autocomplete query bounds.
*
* @see android.widget.ArrayAdapter#ArrayAdapter(android.content.Context, int)
*/
public PlaceAutocompleteAdapter(Context context, GoogleApiClient googleApiClient,
LatLngBounds bounds, AutocompleteFilter filter) {
super(context, android.R.layout.simple_expandable_list_item_2, android.R.id.text1);
mGoogleApiClient = googleApiClient;
mBounds = bounds;
mPlaceFilter = filter;
}

/**
* Sets the bounds for all subsequent queries.
*/
public void setBounds(LatLngBounds bounds) {
mBounds = bounds;
}

/**
* Returns the number of results received in the last autocomplete query.
*/
@Override
public int getCount() {
return mResultList.size();
}

/**
* Returns an item from the last autocomplete query.
*/
@Override
public AutocompletePrediction getItem(int position) {
return mResultList.get(position);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);

// Sets the primary and secondary text for a row.
// Note that getPrimaryText() and getSecondaryText() return a CharSequence that may contain
// styling based on the given CharacterStyle.

AutocompletePrediction item = getItem(position);

TextView textView1 = (TextView) row.findViewById(android.R.id.text1);
TextView textView2 = (TextView) row.findViewById(android.R.id.text2);
textView1.setText(item.getPrimaryText(STYLE_BOLD));
textView2.setText(item.getSecondaryText(STYLE_BOLD));

return row;
}

/**
* Returns the filter for the current set of autocomplete results.
*/
@Override
public Filter getFilter() {
return new Filter() {
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();

// We need a separate list to store the results, since
// this is run asynchronously.
ArrayList<AutocompletePrediction> filterData = new ArrayList<>();

// Skip the autocomplete query if no constraints are given.
if (constraint != null) {
// Query the autocomplete API for the (constraint) search string.
filterData = getAutocomplete(constraint);
}

results.values = filterData;
if (filterData != null) {
results.count = filterData.size();
} else {
results.count = 0;
}

return results;
}

@Override
protected void publishResults(CharSequence constraint, FilterResults results) {

if (results != null && results.count > 0) {
// The API returned at least one result, update the data.
mResultList = (ArrayList<AutocompletePrediction>) results.values;
notifyDataSetChanged();
} else {
// The API did not return any results, invalidate the data set.
notifyDataSetInvalidated();
}
}

@Override
public CharSequence convertResultToString(Object resultValue) {
// Override this method to display a readable result in the AutocompleteTextView
// when clicked.
if (resultValue instanceof AutocompletePrediction) {
return ((AutocompletePrediction) resultValue).getFullText(null);
} else {
return super.convertResultToString(resultValue);
}
}
};
}

/**
* Submits an autocomplete query to the Places Geo Data Autocomplete API.
* Results are returned as frozen AutocompletePrediction objects, ready to be cached.
* objects to store the Place ID and description that the API returns.
* Returns an empty list if no results were found.
* Returns null if the API client is not available or the query did not complete
* successfully.
* This method MUST be called off the main UI thread, as it will block until data is returned
* from the API, which may include a network request.
*
* @param constraint Autocomplete query string
* @return Results from the autocomplete API or null if the query was not successful.
* @see Places#GEO_DATA_API#getAutocomplete(CharSequence)
* @see AutocompletePrediction#freeze()
*/
private ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
Log.i(TAG, "Starting autocomplete query for: " + constraint);

// Submit the query to the autocomplete API and retrieve a PendingResult that will
// contain the results when the query completes.
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
mBounds, mPlaceFilter);

// This method should have been called off the main UI thread. Block and wait for at most 60s
// for a result from the API.
AutocompletePredictionBuffer autocompletePredictions = results
.await(60, TimeUnit.SECONDS);

// Confirm that the query completed successfully, otherwise return null
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
Toast.makeText(getContext(), "Error contacting API: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e(TAG, "Error getting autocomplete prediction API call: " + status.toString());
autocompletePredictions.release();
return null;
}

Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
+ " predictions.");

// Freeze the results immutable representation that can be stored safely.
return DataBufferUtils.freezeAndClose(autocompletePredictions);
}
Log.e(TAG, "Google API client is not connected for autocomplete query.");
return null;
}


}
Loading