AppMed
Moderator: julianmartinez16
- JuanDGiraldoM
- Posts: 31
- Joined: Mon Jan 22, 2018 11:23 am
Re: AppMed
¿Qué se ha hecho?
Estamos continuando la migración del proyecto
¿Qué se va a hacer?
Esperamos terminar la migración del proyecto en estos dos Sprints
¿Qué dificultades tuvimos?
Ninguna
Estamos continuando la migración del proyecto
¿Qué se va a hacer?
Esperamos terminar la migración del proyecto en estos dos Sprints
¿Qué dificultades tuvimos?
Ninguna
- JuanDGiraldoM
- Posts: 31
- Joined: Mon Jan 22, 2018 11:23 am
Re: AppMed
Sprint 10 (Abr 12 - Abr 19)
Velocidad: 1
Esfuerzo: 8
Burndown

¿Qué se ha hecho?
Continuamos migrando la aplicación
Evidencias
Mapa Funcional
¿Qué se va a hacer?
Esperamos terminar la migración el siguiente Sprint
¿Qué dificultades tuvimos?
Compatibilidades con las versiones de Gradle de algunas SDK
Velocidad: 1
Esfuerzo: 8
Burndown

¿Qué se ha hecho?
Continuamos migrando la aplicación
Evidencias
Mapa Funcional
Code: Select all
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.OnConnectionFailedListener {
private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
private static final String COURSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION;
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
private static final float DEFAULT_ZOOM = 14f;
private static final LatLngBounds LAT_LNG_BOUNDS = new LatLngBounds(new LatLng(6.094316999999999, -75.63334700000001), new LatLng(6.150559, -75.61681999999996));
private static int PLACE_PICKER_REQUEST = 1;
private FusedLocationProviderClient mFusedLocationProviderClient;
private boolean mLocationPermissionsGranted = false;
private GoogleMap mMap;
private PlaceAutoCompleteAdapter mPlaceAutoCompleteAdapter;
private GoogleApiClient mGoogleApiClient;
private PlaceInfo mPlace;
private Marker mMarker;
private AutoCompleteTextView mSearchText;
private ImageView mGps, mInfo, mPlacePicker;
private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback = new ResultCallback<PlaceBuffer>() {
@Override
public void onResult(@NonNull PlaceBuffer places) {
if (!places.getStatus().isSuccess()) {
places.release();
return;
}
final Place place = places.get(0);
try {
mPlace = new PlaceInfo();
mPlace.setId(place.getId());
mPlace.setNombre(place.getName().toString());
mPlace.setDireccion(place.getAddress().toString());
mPlace.setLatLng(place.getLatLng());
mPlace.setRating(place.getRating());
mPlace.setWebsiteUri(place.getWebsiteUri());
mPlace.setTelefono(place.getPhoneNumber().toString());
mPlace.setAttributions(place.getAttributions().toString());
} catch (Exception e) {
}
moveCamera(new LatLng(place.getViewport().getCenter().latitude, place.getViewport().getCenter().longitude), DEFAULT_ZOOM, mPlace);
places.release();
}
};
private AdapterView.OnItemClickListener mAutoCompleteListener = new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
hideSoftKeyBoard();
final AutocompletePrediction item = mPlaceAutoCompleteAdapter.getItem(i);
final String placeId = item.getPlaceId();
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
.getPlaceById(mGoogleApiClient, placeId);
placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
getLocationPermission();
mSearchText = findViewById(R.id.input_search);
mGps = findViewById(R.id.ic_gps);
mInfo = findViewById(R.id.place_info);
mPlacePicker = findViewById(R.id.ic_map);
}
private void init() {
mGoogleApiClient = new GoogleApiClient
.Builder(this)
.addApi(Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.enableAutoManage(this, this)
.build();
mSearchText.setOnItemClickListener(mAutoCompleteListener);
mPlaceAutoCompleteAdapter = new PlaceAutoCompleteAdapter(this, mGoogleApiClient, LAT_LNG_BOUNDS, null);
mSearchText.setAdapter(mPlaceAutoCompleteAdapter);
mSearchText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {
if (i == EditorInfo.IME_ACTION_SEARCH
| i == EditorInfo.IME_ACTION_DONE
| keyEvent.getAction() == KeyEvent.ACTION_DOWN
| keyEvent.getAction() == KeyEvent.KEYCODE_ENTER) {
geoLocate();
}
return false;
}
});
mGps.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
getDeviceLocation();
}
});
mInfo.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
try {
if (mMarker.isInfoWindowShown()) {
mMarker.hideInfoWindow();
} else {
mMarker.showInfoWindow();
}
} catch (NullPointerException e) {
}
}
});
mPlacePicker.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
PlacePicker.IntentBuilder builder = new PlacePicker.IntentBuilder();
try {
startActivityForResult(builder.build(MapsActivity.this), PLACE_PICKER_REQUEST);
} catch (Exception e) {
Utilities.showAlert(MapsActivity.this, "Ha ocurrido un error con el Selector de Mapa");
}
}
});
hideSoftKeyBoard();
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PLACE_PICKER_REQUEST) {
if (resultCode == RESULT_OK) {
Place place = PlacePicker.getPlace(this, data);
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
.getPlaceById(mGoogleApiClient, place.getId());
placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
}
}
}
private void geoLocate() {
String searchString = mSearchText.getText().toString();
Geocoder geocoder = new Geocoder(MapsActivity.this);
List<Address> addresses = new ArrayList<>();
try {
addresses = geocoder.getFromLocationName(searchString, 1);
} catch (IOException e) {
Utilities.showAlert(this, "Ha ocurrido un error con la búsqueda");
}
if (addresses.size() > 0) {
Address address = addresses.get(0);
moveCamera(new LatLng(address.getLatitude(), address.getLongitude()), DEFAULT_ZOOM, address.getAddressLine(0));
}
}
private void initMap() {
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (mLocationPermissionsGranted) {
getDeviceLocation();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
init();
}
// Add a marker in Sydney and move the camera
//LatLng sydney = new LatLng(-34, 151);
//mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
//mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
private void getLocationPermission() {
String[] permissions = {FINE_LOCATION, COURSE_LOCATION};
if (ContextCompat.checkSelfPermission(this.getApplicationContext(), FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this.getApplicationContext(), COURSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionsGranted = true;
initMap();
} else {
ActivityCompat.requestPermissions(this, permissions, LOCATION_PERMISSION_REQUEST_CODE);
}
} else {
ActivityCompat.requestPermissions(this, permissions, LOCATION_PERMISSION_REQUEST_CODE);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
mLocationPermissionsGranted = false;
switch (requestCode) {
case LOCATION_PERMISSION_REQUEST_CODE: {
if (grantResults.length > 0) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] != PackageManager.PERMISSION_GRANTED)
mLocationPermissionsGranted = false;
return;
}
mLocationPermissionsGranted = true;
initMap();
}
}
}
}
private void getDeviceLocation() {
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
try {
if (mLocationPermissionsGranted) {
Task location = mFusedLocationProviderClient.getLastLocation();
location.addOnCompleteListener(new OnCompleteListener() {
@Override
public void onComplete(@NonNull Task task) {
if (task.isSuccessful()) {
Location currentLocation = (Location) task.getResult();
Utilities.posicion_actual = new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude());
moveCamera(Utilities.posicion_actual, DEFAULT_ZOOM, "My Location");
} else {
Utilities.showAlert(MapsActivity.this, "Ubicación no disponible");
}
}
});
}
} catch (SecurityException e) {
Utilities.showAlert(this, "Ha ocurrido una excepción de seguridad");
}
}
private void moveCamera(LatLng latLng, float zoom, String title) {
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoom));
if (!title.equals("My Location")) {
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title(title);
mMap.addMarker(options);
}
hideSoftKeyBoard();
}
private void moveCamera(LatLng latLng, float zoom, PlaceInfo placeInfo) {
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoom));
mMap.clear();
mMap.setInfoWindowAdapter(new InfoWindowAdapter(MapsActivity.this));
if (placeInfo != null) {
try {
String snippet = "Dirección: " + placeInfo.getDireccion() + "\n" +
"Teléfono: " + placeInfo.getTelefono() + "\n" +
"Website: " + placeInfo.getWebsiteUri() + "\n" +
"Rating: " + placeInfo.getRating() + "\n";
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title(placeInfo.getNombre())
.snippet(snippet);
mMarker = mMap.addMarker(options);
} catch (Exception e) {
Utilities.showAlert(this, "Ha ocurrido un error con el marcador");
}
} else {
mMap.addMarker(new MarkerOptions().position((latLng)));
}
hideSoftKeyBoard();
}
private void hideSoftKeyBoard() {
this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
}
Esperamos terminar la migración el siguiente Sprint
¿Qué dificultades tuvimos?
Compatibilidades con las versiones de Gradle de algunas SDK
Last edited by JuanDGiraldoM on Mon May 21, 2018 9:04 am, edited 1 time in total.
- JuanDGiraldoM
- Posts: 31
- Joined: Mon Jan 22, 2018 11:23 am
Re: AppMed
¿Qué se ha hecho?
Continuamos con la migración del proyecto
¿Qué se va a hacer?
Vamos a hacer la pruebas respectivas del correcto funcionamiento
¿Qué dificultades se han tenido?
Carga académica
Continuamos con la migración del proyecto
¿Qué se va a hacer?
Vamos a hacer la pruebas respectivas del correcto funcionamiento
¿Qué dificultades se han tenido?
Carga académica
Last edited by JuanDGiraldoM on Thu May 03, 2018 10:28 am, edited 1 time in total.
- JuanDGiraldoM
- Posts: 31
- Joined: Mon Jan 22, 2018 11:23 am
Re: AppMed
Sprint 11 (Abril 20 - Abril 26)
Velocidad: 0
Esfuerzo: 8
Burndown

¿Qué se ha hecho?
Investigación de la implementación de Uber
Evidencias

¿Qué se va a hacer?
Corregir compatibilidades del Gradle
Continuar con la migración
Qué dificultades tuvimos?
Carga académica
Velocidad: 0
Esfuerzo: 8
Burndown

¿Qué se ha hecho?
Investigación de la implementación de Uber
Evidencias

¿Qué se va a hacer?
Corregir compatibilidades del Gradle
Continuar con la migración
Qué dificultades tuvimos?
Carga académica
Last edited by JuanDGiraldoM on Mon May 21, 2018 9:04 am, edited 3 times in total.
- JuanDGiraldoM
- Posts: 31
- Joined: Mon Jan 22, 2018 11:23 am
Re: AppMed
¿Qué se ha hecho?
Ya se corrigieron las compatibilidades con Gradle
¿Qué se va a hacer?
Continuar con la investigación e implementación de Uber API
¿Qué dificultades se tuvo?
Ninguna
Ya se corrigieron las compatibilidades con Gradle
¿Qué se va a hacer?
Continuar con la investigación e implementación de Uber API
¿Qué dificultades se tuvo?
Ninguna
Last edited by JuanDGiraldoM on Thu May 17, 2018 8:38 am, edited 1 time in total.
- JuanDGiraldoM
- Posts: 31
- Joined: Mon Jan 22, 2018 11:23 am
Re: AppMed
Sprint 12 (Abril 27 - Mayo 3)
Velocidad: 0
Esfuerzo: 6
Burndown

¿Qué se ha hecho?
Investigación de la implementación de Uber
Evidencias
¿Qué se va a hacer?
Iniciar la implementación de Uber
Continuar con la migración
Qué dificultades tuvimos?
Carga académica
Velocidad: 0
Esfuerzo: 6
Burndown

¿Qué se ha hecho?
Investigación de la implementación de Uber
Evidencias
¿Qué se va a hacer?
Iniciar la implementación de Uber
Continuar con la migración
Qué dificultades tuvimos?
Carga académica
Last edited by JuanDGiraldoM on Mon May 21, 2018 9:05 am, edited 4 times in total.
- JuanDGiraldoM
- Posts: 31
- Joined: Mon Jan 22, 2018 11:23 am
Re: AppMed
¿Qué se ha hecho?
Se inició la implementación de Uber API
¿Qué se va a hacer?
Vamos a continuar con la investigación
Se va a optimizar el código
¿Qué dificultades se tuvieron?
Ninguna
Se inició la implementación de Uber API
Code: Select all
/**
* Método constructor de la actividad
*
* @param savedInstanceState savedInstanceState
*/
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
DrawerLayout drawer = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
/**
* Creacion de sesión para usar api de uber
*/
SessionConfiguration configuration = new SessionConfiguration.Builder()
.setClientId("YqJj9xgQdj6bBh8519ENo7n_Q5tUQKE8")
.setServerToken("_ibbEf36cjMQ6bOS6dTdDeTWSjugfqz3kPnpuvK8")
.setScopes(Arrays.asList(Scope.RIDE_WIDGETS))
.setEnvironment(SessionConfiguration.Environment.PRODUCTION)
.build();
UberSdk.initialize(configuration);
RideRequestButton requestButton = new RideRequestButton(MainActivity.this);
RelativeLayout layout = new RelativeLayout(this);
layout.addView(requestButton);
}
Vamos a continuar con la investigación
Se va a optimizar el código
¿Qué dificultades se tuvieron?
Ninguna
Last edited by JuanDGiraldoM on Thu May 17, 2018 8:45 am, edited 1 time in total.
- JuanDGiraldoM
- Posts: 31
- Joined: Mon Jan 22, 2018 11:23 am
Re: AppMed
Sprint 13 (Mayo 4 - Mayo 10)
Velocidad: 2
Esfuerzo: 7
Burndown

¿Qué se ha hecho?
Investigación de la implementación de Uber
Puliendo las funcionalidades en InstantApp
Evidencias

¿Qué se va a hacer?
Iniciar investigación de Geofence
Qué dificultades tuvimos?
Carga académica
Velocidad: 2
Esfuerzo: 7
Burndown

¿Qué se ha hecho?
Investigación de la implementación de Uber
Puliendo las funcionalidades en InstantApp
Evidencias

¿Qué se va a hacer?
Iniciar investigación de Geofence
Qué dificultades tuvimos?
Carga académica
Last edited by JuanDGiraldoM on Mon May 21, 2018 9:05 am, edited 2 times in total.
- JuanDGiraldoM
- Posts: 31
- Joined: Mon Jan 22, 2018 11:23 am
Re: AppMed
¿Qué se ha hecho?
Iniciar investigación de Geofence
Continuar investigación de Uber API
¿Qué se va a hacer?
Continuar la implementación de Uber API
¿Qué dificultades ha tenido?
Carga académica
Iniciar investigación de Geofence
Continuar investigación de Uber API
¿Qué se va a hacer?
Continuar la implementación de Uber API
¿Qué dificultades ha tenido?
Carga académica
- JuanDGiraldoM
- Posts: 31
- Joined: Mon Jan 22, 2018 11:23 am
Re: AppMed
Último Sprint -> 14 (Mayo 11 - Mayo 20)
Velocidad: 4
Esfuerzo: 10
Velocidad promedio del proyecto: 4
Velocidad acumulada del proyecto: 53
Esfuerzo promedio del proyecto: 6
Esfuerzo acumulado del proyecto: 85
Burndown

¿Qué se ha hecho?
Se agregaron las clases necesarias para el funcionamiento de Google Places
Se actualizaron los diagramas de clases
Se actualizaron las API de Gradle
Evidencias

build.gradle(Module: feature)
build.gradle(Module: base)
build.gradle(Module: app)
PlaceAutoCompleteAdapter
InfoWindowAdapter
¿Qué dificultades se han tenido?
El plugin de 'com.google.gms.google-services' no funciona dentro de la Instant App y no hemos encontrado una solución.
Por lo tanto, no hemos podido avanzar con la migración (Específicamente con todo lo que tiene que ver con Firebase, Google Maps y Google Places)

Información del error
Velocidad: 4
Esfuerzo: 10
Velocidad promedio del proyecto: 4
Velocidad acumulada del proyecto: 53
Esfuerzo promedio del proyecto: 6
Esfuerzo acumulado del proyecto: 85
Burndown

¿Qué se ha hecho?
Se agregaron las clases necesarias para el funcionamiento de Google Places
Se actualizaron los diagramas de clases
Se actualizaron las API de Gradle
Evidencias

build.gradle(Module: feature)
Code: Select all
apply plugin: 'com.android.feature'
android {
compileSdkVersion 27
defaultConfig {
minSdkVersion 23
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation project(':base')
testImplementation 'junit:junit:4.12'
//androidTestImplementation 'com.android.support.test:runner:1.0.1'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation 'com.uber.sdk:rides-android:0.5.3'
implementation 'com.facebook.android:facebook-android-sdk:4.32.0'
implementation 'com.google.firebase:firebase-core:15.0.2'
implementation 'com.google.firebase:firebase-database:15.0.1'
implementation 'com.firebaseui:firebase-ui-database:1.0.0'
implementation 'com.google.firebase:firebase-auth:15.1.0'
implementation 'com.google.android.gms:play-services-maps:15.0.1'
}
Code: Select all
apply plugin: 'com.android.feature'
android {
compileSdkVersion 27
baseFeature true
defaultConfig {
minSdkVersion 23
targetSdkVersion 27
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
//noinspection GradleCompatible
api 'com.android.support:appcompat-v7:27.1.1'
api 'com.android.support:support-v4:27.1.1'
api 'com.android.support:design:27.1.1'
api 'com.android.support.constraint:constraint-layout:1.1.0'
application project(':app')
feature project(':feature')
}
Code: Select all
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "co.edu.upb.appmed.app"
minSdkVersion 23
targetSdkVersion 27
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation project(':feature')
implementation project(':base')
}
apply plugin: 'com.google.gms.google-services'
Code: Select all
package co.edu.upb.appmed.feature.Data;
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.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 ArrayAdapter#ArrayAdapter(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;
}
}
Code: Select all
package co.edu.upb.appmed.feature.Data;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TextView;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.model.Marker;
public class InfoWindowAdapter implements GoogleMap.InfoWindowAdapter {
private final View mWindow;
private Context context;
public InfoWindowAdapter(Context context) {
this.mWindow = LayoutInflater.from(context).inflate(R.layout.custom_info_window, null);
this.context = context;
}
private void renderizarWindowText(Marker marker, View view) {
String title = marker.getTitle();
TextView txtTitle = view.findViewById(R.id.title);
if (!title.equals("")) {
txtTitle.setText(title);
}
String snippet = marker.getSnippet();
TextView txtSnippet = view.findViewById(R.id.snippet);
if (!snippet.equals("")) {
txtSnippet.setText(snippet);
}
}
@Override
public View getInfoWindow(Marker marker) {
renderizarWindowText(marker, mWindow);
return mWindow;
}
@Override
public View getInfoContents(Marker marker) {
renderizarWindowText(marker, mWindow);
return mWindow;
}
}
El plugin de 'com.google.gms.google-services' no funciona dentro de la Instant App y no hemos encontrado una solución.
Por lo tanto, no hemos podido avanzar con la migración (Específicamente con todo lo que tiene que ver con Firebase, Google Maps y Google Places)

Información del error
Code: Select all
More than one variant of project :feature matches the consumer attributes:
- Configuration ':feature:debugApiElements' variant android-aidl:
- Found artifactType 'android-aidl' but wasn't required.
- Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
- Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
- Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
- Required org.gradle.usage 'java-api' and found compatible value 'java-api'.
- Configuration ':feature:debugApiElements' variant android-classes:
- Found artifactType 'android-classes' but wasn't required.
- Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
- Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
- Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
- Required org.gradle.usage 'java-api' and found compatible value 'java-api'.
- Configuration ':feature:debugApiElements' variant android-manifest:
- Found artifactType 'android-manifest' but wasn't required.
- Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
- Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
- Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
- Required org.gradle.usage 'java-api' and found compatible value 'java-api'.
- Configuration ':feature:debugApiElements' variant android-renderscript:
- Found artifactType 'android-renderscript' but wasn't required.
- Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
- Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
- Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
- Required org.gradle.usage 'java-api' and found compatible value 'java-api'.
- Configuration ':feature:debugApiElements' variant jar:
- Found artifactType 'jar' but wasn't required.
- Required com.android.build.api.attributes.BuildTypeAttr 'debug' and found compatible value 'debug'.
- Found com.android.build.api.attributes.VariantAttr 'debug' but wasn't required.
- Required com.android.build.gradle.internal.dependency.AndroidTypeAttr 'Aar' and found compatible value 'Aar'.
- Required org.gradle.usage 'java-api' and found compatible value 'java-api'.