Hi all again,

Today i have had time to isolate a class to have a localization service ready-to-use in the library JavocSoft Android Toolbox.

JavocSoft Android Toolbox LibraryThis will allow, very easily, to have an application that watches for any location change (or GPS enabled/disabled) event in background even if the application is not running because is an Android service 🙂

To use it, first declare in your AndroidManifest.xml:

<service android:name="es.javocsoft.android.lib.toolbox.location.service.LocationService" android:label="Location Service" android:enabled="true"/>

And launch it:

Intent mLocServiceIntent = new Intent(getBaseContext(), LocationService.class);
Bundle extras = new Bundle();
extras.putInt(LocationService.LOCATION_SERVICE_PARAM_MIN_DISTANCE, 2);
extras.putInt(LocationService.LOCATION_SERVICE_PARAM_MIN_TIME, 4000);
mLocServiceIntent.putExtras(extras);
startService(mLocServiceIntent);

And to stop it, when required:

Intent mLocServiceIntent = new Intent(getBaseContext(), LocationService.class);
stopService(mLocServiceIntent);

 

The localization service can also be customized when launched by setting in the service launching intent these parameters:

  • LocationService.LOCATION_SERVICE_PARAM_MIN_DISTANCE
  • LocationService.LOCATION_SERVICE_PARAM_MIN_TIME

Once is running, the service will broadcast the following events:

  • LOCATION_SERVICE_STARTED. Intent filter name:
    es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_SERVICE_STARTED
  • LOCATION_SERVICE_SHUTDOWN. Intent filter name:
    es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_SERVICE_SHUTDOWN
  • LOCATION_CHANGED. Intent filter name:
    es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_CHANGED
  • LOCATION_GPS_DISABLED. Intent filter name:
    es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_GPS_DISABLED
  • LOCATION_GPS_ENABLED. Intent filter name:
    es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_GPS_ENABLED

So now, to attend the localization events you only have to create a BroadcastReceiver:

public class LocationChangedReceiver extends WakefulBroadcastReceiver {
 
 protected static String TAG = "LocationChangedReceiver";
 
 
 public LocationChangedReceiver() {
 
 }
 @Override
 public void onReceive(Context context, Intent intent) {
 
   Bundle bundle = intent.getExtras(); 
   if(intent.getAction().equals(LocationService.ACTION_LOCATION_CHANGED)) { 
     //The Location Service leaves the detected location in the extras using
     //the key LocationService.LOCATION_KEY.
     Location location = bundle.getParcelable(LocationService.LOCATION_KEY);
     //Do something
   }else if(intent.getAction().equals(LocationService.ACTION_LOCATION_GPS_ENABLED)){
     //Do something
   }else if(intent.getAction().equals(LocationService.ACTION_LOCATION_GPS_DISABLED)){
     //Do something
   }else if(intent.getAction().equals(LocationService.ACTION_LOCATION_SERVICE_STARTED))
     //Do something 
   }else if(intent.getAction().equals(LocationService.ACTION_LOCATION_SERVICE_SHUTDOWN)){
     //Do something
   }
 }
}

And declare this receiver in your application AndroidManifest.xml:

<receiver android:name="your_application_package.LocationReceiver" android:enabled="true" android:exported="false"/>
 <intent-filter>
 <action android:name="es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_SERVICE_STARTED"/>
 <action android:name="es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_SERVICE_SHUTDOWN"/>
 <action android:name="es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_CHANGED"/>
 <action android:name="es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_GPS_ENABLED"/>
 <action android:name="es.javocsoft.android.lib.toolbox.location.service.intent.action.LOCATION_GPS_ENABLED"/>
 </intent-filter>
<receiver/>

 

I hope this addition make your life easier 🙂

Do not forget to check the blog to get more updates!

More info and HowTo at https://github.com/javocsoft/javocsoft-toolbox/wiki.

github_icon

As always, library is available on GitHub

javocsoft-toolbox.

Bye.

JavocSoft 2015.

Hi all,

With new versions of Android, the library needs to be adapted to deal with new possibilities JavocSoft Android Toolbox Libraryand requirements. In this case, the new library JavocSoft Android Toolbox version has resources to handle new Android 6+ Permission system. This will allow us to embrace and adapt our applications to Android 6 new permissions usage approach.

Android 6 and Permissions

Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app. If the device is running Android 5.1 (API level 22) or lower, or the app’s targetSdkVersion is 22 or lower, the system asks the user to grant the permissions at install time.

System permissions are divided into two categories, normal and dangerous (more info):

  • Normal permissions do not directly risk the user’s privacy. If your app lists a normal permission in its manifest, the system grants the permission automatically. See the list here.
  • Dangerous permissions can give the app access to the user’s confidential data. If your app lists a normal permission in its manifest, the system grants the permission automatically. If you list a dangerous permission, the user has to explicitly give approval to your app. If an app requests a dangerous permission listed in its manifest, and the app already has another dangerous permission in the same permission group, the system immediately grants the permission without any interaction with the user.

See Google Developer Permissions to know more about it.

Adapt your application

To adapt an application to the new permissions usage approach of Android 6+, the application has to be able to deal with these use cases:

  • Start the App. Ask for permission (showing before a message telling why do you need before ask for them)
    • Accept. Ask for permissions:
      • Accept -> App runs normally with the service that requires the permissions.
      • Not accept -> App runs normally without the service that requires the permissions.
    • Cancel. App runs normally without the service that requires the permissions.
  • With previously granted permissions, start the App:
    • Start the App -> App runs normally with the service that requires the permissions.
  • In a running App with granted permissions:
    • Deny the permissions -> When returning to the App, it Asks for permissions (showing before a message telling why do you need before ask for them):
      • Accept. Ask for permissions:
        • Accept -> App runs normally with the service that requires the permissions.
        • Not accept -> App runs normally without the service that requires the permissions.
      • Cancel. App runs normally without the service that requires the permissions.
  • User denies the permission and marks “Never ask again”
    • Start the App:
      • Show a message to the user about the required permissions (showing before a message telling why do you need before ask for them)
        • Accept. Ask for permissions:
          • Accept -> App runs normally with the service that requires the permissions.
          • Not accept -> App runs normally without the service that requires the permissions.
        • Cancel. App runs normally without the service that requires the permissions.

For devices with Android minor than 6 version, API Level 23, you should be able to open the application normally and use it without prompting for any permission because they are already granted when the application is installed.

 

The library JavocSoft Android Toolbox gives you the method to achieve these point in a relative easy way.

Usage

ToolBox provides methods to check for permissions allowing us to present to the user an informative dialog and also ask to allow them if they are not already granted. ToolBox uses the Android Support Library for backward Android compatibility.

The list of functions to handle permissions are:

  • permission_askFor
  • permission_checkAskPermissionsresult
  • permission_isGranted
  • permission_areGranted

ToolBox also provides a set of permissions packages according with Google permissions group. This makes easy for you to ask for permissions for a service that requires a set of permissions.

  • PERMISSION_CALENDAR
  • PERMISSION_CAMERA
  • PERMISSION_LOCATION
  • PERMISSION_MICROPHONE
  • PERMISSION_PHONE
  • PERMISSION_SENSORS
  • PERMISSION_SMS
  • PERMISSION_STORAGE

Here is an example of usage. In this case we are going to use the localization service.

This service requires two permissions that are not automatically granted (not in Google NORMAL permissions group):

  • ACCESS_COARSE_LOCATION
  • ACCESS_FINE_LOCATION

ToolBox has these two permissions in the PERMISSION_LOCATION set. We will use this set to ask for permission to the user:

<!-- Before use it, we check if the permissions are already granted. -->
if(!ToolBox.permission_areGranted(TheActivity.this, ToolBox.PERMISSION_LOCATION.keySet())) {
    //Permissions not yet granted, we need to be ask.
    ToolBox.permission_askFor(TheActivity.this, ToolBox.PERMISSION_LOCATION,     
            ToolBox.PERMISSIONS_REQUEST_CODE_ASK_LOCATION, 
        getString(R.string.permissions_required_title), 
        getString(R.string.permissions_button_ok),
        getString(R.string.permissions_button_deny),
        getString(R.string.permissions_location_required_text));
}else{
     //Permissions are already granted, continue using the localization service...
 
}

To handle the permissions ask response, we must do the following:

<!-- This method handles the response -->
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    permissionsLocationGranted = checkAskPermissionsresult(requestCode, permissions, grantResults);
    Log.i(Constants.TAG, "Location permissions granted? " + permissionsLocationGranted);
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
 
    if(permissionsLocationGranted) {
        //Continue with the usage of the service that needs the permissions...
 
    }else{
        //Do something if required...
    }        
}
 
private boolean checkAskPermissionsresult(int requestCode, String[] permissions, int[] grantResults) {
    boolean res = false;   
    if(requestCode == ToolBox.PERMISSIONS_REQUEST_CODE_ASK_LOCATION) {
            //We could check the permissions in our system
        //res = ToolBox.permission_areGranted(SplashActivity.this, Arrays.asList(permissions));         
            //We check the returned result. Only returns TRUE if all permissions are granted.
        res = ToolBox.permission_checkAskPermissionsresult(permissions, grantResults);
    }
    return res;
}

Have in mind that every time you use a service o function that requires permissions, you should check the current permissions by using:

ToolBox.permission_areGranted(TheActivity.this, ToolBox.PERMISSION_LOCATION.keySet());

To know more about it goto https://github.com/javocsoft/javocsoft-toolbox/wiki#android-6-permissions-handle.

 

Recommended videos about permissions in Android M that you should check:

 

I hope these addition could be useful for your applications.

Do not forget to check the blog to get more updates!

More info and HowTo at https://github.com/javocsoft/javocsoft-toolbox/wiki.

github_icon

As always, library is available on GitHub

javocsoft-toolbox.

Bye.

JavocSoft 2015.

Hola,

Día de revisión/mantenimiento del servidor. Una de las cosas que uno ha de hacer cuando tiene un servidor dedicado, es preocuparse de hacer backups y disponer de estos backups en otra máquina (un dropbox, un ftp, etc) como medida de seguridad para poder srvdedicadousarlos en caso de que algo vaya realmente mal. En el caso de ser un servidor virtual es más sencillo ya que tan solo basta con configurar esto en el propio panel de configuración del hosting.

El caso es que hasta la fecha, no tenía automatizado del todo este proceso (porque siempre hay alguna otra cosa que hacer), disponiendo solo de backups parciales que además, se quedaban en el servidor. Debido a esto ya he tenido algún susto, con las consiguientes horas perdidas volviendo a configurar ciertas cosas desde 0 y no pudiendo restaurar alguna que otra cosa que por suerte, al final no he necesitado.

Continue reading

Programar para Android, una de las cosas de las que nos quejamos todos es de la lentitud del emulador en arrancar comparado con el de iOS. Es una verdad que merece una explicación.

Mientras que Android emula el teléfono completo, con su CPU, la GPU, su tarjeta SD, la memoria, etc. Está ejecutando código real que podríamos poner en un teléfono, compilado para una CPU de una arquitectura que no tenemos en el PC (p.e: ARM). En Mac, el simulador de iOS lo que hace sin embargo es crear un ejecutable (x86) que “simula” correr dentro de un teléfono cuando en realidad no es mas que un programa Mac disfrazado. Por ello, el emulador Android será siempre más fideligno a la realidad.

Android HAXM TechnologyPese a todo, en el día a día, los tiempos de carga son en lo que la mayoría de la gente se suele fijar fijar y en eso, iOS sigue ganando. Para evitar esto, hace poco descubrí HAXM (Hardware Accelerated Execution Manager), de Intel. Este programa (es un driver) lo que hace es instalar una capa de aceleración por encima del emulador de Android (por debajo utiliza qEmu, un emulador de CPUs). Eso sí, para que funcione, nuestra CPU ha de ser Intel y disponer además de la tecnología VT-x.

Bueno, vayamos al meollo, a lo interesante 🙂

Instalación de HAXM

Windows/Linux

Sencillo, abre el SDK Manager y al final del todo de la lista, verás el componente llamado “Intel x86 Emulator Accelerator (HAXM)“. Selecciónalo y pulsa en “Install”. Cuando acabe, tendrás que irte a tu directorio del SDK de Android, dentro de la carpeta “extras”, concretamente en “extras\intel\Hardware_Accelerated_Execution_Manager“. Aquí dentro esta el ejecutable, lo ejecutamos para que HAXM se instale en nuestro sistema.

android_emu_faster_1

Mac

Si al usar HAXM el Mac se cuelga, si, a veces también pasa en un Mac, nos vamos a la página de instalación de HAXM en HAXM Install y bajamos el .dmg. Para confirmar que se instaló bien ejecutamos lo siguiente:

$ kextstat | grep haxm

Lo que debe salir es algo así

115  0 0xffffff7f81e29000 0x13000 0x13000  com.intel.kext.intelhaxm

Uso de HAXM

Ahora nos toca bajarnos las imágenes Android que nos proporciona Intel también para usar con HAXM. La cosa es que en vez de acelerar un emulador ARM, Intel nos da Android para Intel Atom. De esta manera, cuando se ejecutan instrucciones en el Intel Atom emulado estas pasan directamente a nuestra CPU real, por eso va más rápido.

Para localizar estas imágenes busca en el SDK manager, para cada API Level del SDK, aquellos componentes llamados tal que “Intel x86 Atom System Image”. Verás que no los encuentras en todos los API levels, parece que estan en los que más son usados.

android_emu_faster_2

Una vez instaladas las imágenes Intel Atom, solo nos queda crearnos una AVD que las utilice. Para ello, haz como siempre solo que en “target” selecciona la opción de Intel Atom…”. Guarda y dale a “Ok”.

android_emu_faster_3

Cuando arranques verás la diferencia :).

Y si quieres que aún vaya más rápido, puedes probar a activar también la aceleración por GPU.

Espero que cuando useis el emulador ya no se os haga tan eterno XD

 

Un saludo,

JavocSoft 2013

Hola.

Hace poco hice root y flasheo de mi móvil HTC Desire cansado ya de depender de mi operadora (Orange) y de que HTC liberara una nueva OTA para disponer de las actualizaciones y correcciones de Google.

Como me parece una historia interesante y además he creado un manual para que cualquiera con un móvil HTC pueda realizar el proceso y así poder obrtener la máxima potencia de su Android, os dejo el link para que podais leer como hacer y mi experiencia con el proceso :).

Android DEV Diary – Rooteo y Flasheo de móvil HTC

Un saludo y espero que os sirva de ayuda!