martes, agosto 22, 2017

Límites de ejecución en segundo plano de Android Oreo

viernes, julio 21, 2017

Android 2017

Saludos de nuevo. 

Ya hace un tiempo que no escribía, he tenido bastante trabajo y como siempre he estado leyendo y aprendiendo muchas cosas sobre Android. 

Pedro Varela Google I/O 2017
Sundar Pichai Google I/O 2017

Este año tuve la oportunidad de ser seleccionado y asistir a Google IO 2017, fue una experiencia única, estar rodeado por tanta gente con tus mismos intereses, conocer lo nuevo de Android antes que muchas otras personas es fascinante, ver a todos los Googlers hablar con ellos y hacerles preguntas no tiene precio. 

En fin,  a lo que vengo con este post - y no es notica nueva - Kotlin es un lenguaje de programación oficial para Android, por lo que de ahora en adelante estaré publicando tutoriales escritos en kotlin, así como una introducción al mismo.







viernes, abril 14, 2017

Verificar Google Play Services

Para que nuestra aplicación pueda ejecutarse si necesitamos Google Play Services, tenemos que hacer la verificación previa.

Esto lo podemos lograr fácilmente agregando las siguientes líneas de código en nuestra actividad de lanzamiento o Splash Screen si es que la tenemos sino, en la primera actividad de nuestra aplicación.

Creamos el método checkPlayServices() con  el código

errorDialog es una variable global de la actividad.

Dialog errorDialog;

private boolean checkPlayServices() {

    GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();

    int resultCode = googleApiAvailability.isGooglePlayServicesAvailable(this);

    if (resultCode != ConnectionResult.SUCCESS) {
       if (googleApiAvailability.isUserResolvableError(resultCode)) {

       if (errorDialog == null) {
           errorDialog = googleApiAvailability.getErrorDialog(this, resultCode, 2404);
           errorDialog.setCancelable(false);
       }

       if (!errorDialog.isShowing())
           errorDialog.show();
        }
     }

    return resultCode == ConnectionResult.SUCCESS;
}


Y luego, en el método onResume(), hacemos la llamada al método checkPlayServices()

@Override
protected void onResume() {
    super.onResume();
    if (checkPlayServices()) {
        startApp();
    }
}


¿Por qué en onResume() y no en onCreate()? Sencillamente porque en onCreate() la llamada se va a ejecutar una sola vez; onResume() llamará checkPlayServices() hasta que actualicemos Google Play Service o cerremos la aplicación, evitando así que iniciemos nuestra app sin la versión más reciente de estos servicios de Google.

miércoles, febrero 01, 2017

Life of a Certification Student

editText.getText().toString(); #buildbetterapps

Saludos a todos.

En la mayoría de tutoriales , la misma documentación de Android te enseñan a obtener el String de un  EditText de la siguiente manera.

String phoneNumber = mTextInputEditTextPhoneNumber.getText().toString();

Perfecto, eso no tiene ningún error.  El punto está en que en ocasiones se vuelve muy fastidioso y si tenemos muchos EditText on TextInputEditText como en mi caso obtenerlos todos buuuuuff cansa. 

Recordando DataBinding en Apache Flex me dije: ok, si podemos agregar un TextChangeListener para que asignar la variable con getText().toString(), luego hice esto.

mTextInputEditTextPhoneNumber.addTextChangedListener(new TextWatcher() {
   @Override   public void beforeTextChanged(CharSequence s, int start, int count, int after) {
      
   }
   
   @Override   public void onTextChanged(CharSequence s, int start, int before, int count) {
      
   }
   
   @Override   public void afterTextChanged(Editable s) {
      phoneNumber = s.toString();
   }
});


El resultado es que mi variable phoneNumber siempre va a estar actualizada cada vez que el texto cambie en el TextInputEditTextPhoneNumber.

Dirás, es más código, pero no! Ese código lo agrega Android Studio automáticamente la única línea que tenemos que escribir es phoneNumber = s.toString(); dentro del afterTextChanged.

Espero lo consideren para sus proyectos.

Y sigan creando mejores apps! - #buildbetterapps  - 

lunes, enero 02, 2017

Solicitar permisos en Android en tiempo de ejecución más fácilmente

Feliz año a todos.

Hace tiempo que quería compartir con ustedes un forma más sencilla para solicitar permisos en tiempo de ejecución y con menos código o al menos, para no repetir tanto los métodos de solicitud de permisos en todos lados.

En este enlace pueden descargar el fragmento que hace la magia.

Extiende tu fragment de RequestPermissionFragment, implementa los métodos en tu Fragmento, lo que tienes que hacer en tu Fragmento concreto es solicitar el(los) permiso(s) y luego  verificar el permiso que quieras con ActivityCompat.checkSelfPermission, algo así:

/** * Request fine location permission */private void requestFineLocationPermission() 
{
   requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_CODE_ACCESS_FINE_LOCATION);
}


/** * Set settings of google map UI */private void setGoogleMapUISettings() {
   
   if (ActivityCompat.checkSelfPermission(getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
      return;   
}
Si la aplicación no tiene permiso va a retornar y no hará nada. Pero los métodos extendidos de  se ejecutarán y podrás mostrar tus diálogos.

/** * Handled when all permissions requested are granted * * @param requestCode Request code */
@Overridepublic void onPermissionsGranted(int requestCode) {
   //cool nothing happens}

/** * Gets whether you should show UI with rationale for requesting a permission. * You should do this only if you do not have the permission and the context in which * the permission is requested does not clearly communicate to the user what would be the * benefit from granting this permission. */
@Overridepublic void onShouldShowRequestPermissionsRationale() {
   showRationaleLocationDialog();}

/** * Handled when all permissions requested are denied * * @param requestCode Request code */

@Override
public void onPermissionsDenied(int requestCode) {
   makeSnackBarSettings(coordinatorLayout, R.string.permission_location);
}

Espero les sea de utilidad.

Happy coding.