Como registrar las coordenadas en background a una base de datos en mysql y android studio

Hola amig@s como están, hoy les traigo un nuevo tutorial, a pedido de un usuario hoy veremos :

Como registrar las coordenadas en background(segundo  plano) a una base de datos en mysql y android studio
oordenadas en background a una base de datos en mysql y android studio



La ves pasada vimos algunos tutoriales al respecto, vimos un tutorial de como registrar  las coordenadas sin necesidad de darle clic algún botón.
como enviar la direccion y coordenadas del gps a una base de datos de forma automatica en android studio

Bueno esta vez sera algo parecido al darle clic al botón start tendrá que guardarse de forma infinita registros cada x tiempo a nuestra base de datos aunque cerremos la app, hasta que le demos clic en el botón stop sin mas rodeos empezamos con este tutorial a esto le llamamos  background o en segundo plano.

Como guía básica tendremos un ejercicio anterior donde teníamos un solo botón y para que se registre los datos teníamos que hacer un clic por registro:
como guardar la direccion y coordenadas del gps a una base de datos en android studio

Por favor entra al enlace de arriba y crea la base de datos y el archivo insertar.php de la webservices. Luego vuelve aquí y podemos continuar:

Primero debe dar estos permisos en tu AndroidManifest

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

Ahora les dejo el activity_main para que puedan reemplazar:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.androfast.pc.appsegundoplanoguardargpsbd.MainActivity">

<LinearLayout
android:layout_width="368dp"
android:layout_height="495dp"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:orientation="vertical"
tools:layout_editor_absoluteX="8dp"
tools:layout_editor_absoluteY="8dp">

<TextView
android:id="@+id/textView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:text="MIS COORDENADAS SON:" />

<TextView
android:id="@+id/mensaje_id"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />

<TextView
android:id="@+id/textView2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="MI DIRECCION ES:" />

<TextView
android:id="@+id/mensaje_id2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="TextView" />

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="393dp"
android:gravity="center"
android:orientation="horizontal">

<Button
android:id="@+id/btnStop"
android:layout_width="fill_parent"
android:layout_height="65dp"
android:layout_weight="1"
android:gravity="center"
android:text="STOP" />

<Button
android:id="@+id/btnGuardar"
android:layout_width="fill_parent"
android:layout_height="65dp"
android:layout_weight="1"
android:gravity="center"
android:text="START"></Button>
</LinearLayout>

</LinearLayout>

</android.support.constraint.ConstraintLayout>

Ahora les paso a explicar la parte del código mucha atención no seas don vergas y doña vergas al menos date un minuto y con eso te quitas mil dudas:

Primero debemos crear un objeto de tipo Handler si quieres leer algo mas de la clase Handler  léelo aqui

 private Handler handler = new Handler();

Ahora implementaremos un objeto de la clase Runnable  y dentro de ella un método publico llamado run y ahí es donde se hace toda la magia:

private Runnable runnable = new Runnable() {
@Override
public void run() {
try {
new Insertar(MainActivity.this).execute();
handler.postDelayed(runnable, 10000);
}
catch (Exception e) {
e.printStackTrace();
}

}
};

Dentro del run observan que llamamos al método Insertar y le decimos que se ejecute(execute)
y también llamamos al atributo postDelayed de la clase Handler y le estamos  mandando  como parámetro (runnable, 10000) ahí le indicamos que se repita cada 10 segundos osea que cada 10 segundos se enviaran las coordenadas y la dirección a nuestra base de datos.

Ahora debemos ver como funciona los botones:
Empezamos con el botón que guarda los datos:

btnGuardar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.postDelayed(runnable, 5000);
}
});

Aquí le estamos indicando que cada vez que hagamos clic en el botón guardar empezara a correr nuestro handler, pero eso lo hará después de 5 segundos y porque?? porque me dio la gana jajaj no es cierto sucede que los datos demoran en cargar del gps si le ponemos que empiece a enviar datos desde el segundo 0 enviaremos null en cambio después de 5 segundos ya habrá cargado las coordenadas y la dirección.

Ahora miremos el código del botón Stop:

btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.removeCallbacks(runnable);
Toast.makeText(MainActivity.this,"Finalizo", Toast.LENGTH_SHORT).show();

}
});

Llamamos a otro atributo de Handler llamado removeCallbacks  y le mandamos como parametro a runnable lo que estamos haciendo aqui es cortar de golpe a la ejucion y luego con un Toast mostramos un mensaje de que finalizo el background.
NOTA: Si cierran su aplicación seguirá ejecutándose los envíos de coordenadas a la base de datos  y por cada inserción se le mostrara un mensaje de Datos insertados con éxito sino quiere que aparezca ese mensaje solamente vallan al método Insertar y ahí eliminan el Toast con dicho mensaje y ya no les aparecerá el mensaje.
Ahora les dejo el código completo y funcional:
package com.androfast.pc.appsegundoplanoguardargpsbd;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.provider.Settings;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class MainActivity extends AppCompatActivity {
TextView mensaje1;
TextView mensaje2;
Button btnGuardar, btnStop;
private Handler handler = new Handler();

private Runnable runnable = new Runnable() {
@Override
public void run() {
try {
new Insertar(MainActivity.this).execute();
handler.postDelayed(runnable, 10000);
}
catch (Exception e) {
e.printStackTrace();
}

}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// handler.post(sendData);

mensaje1 = (TextView) findViewById(R.id.mensaje_id);
mensaje2 = (TextView) findViewById(R.id.mensaje_id2);
btnGuardar =(Button) findViewById(R.id.btnGuardar);
btnStop =(Button) findViewById(R.id.btnStop);
btnGuardar.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.postDelayed(runnable, 5000);
}
});
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
handler.removeCallbacks(runnable);
Toast.makeText(MainActivity.this,"Finalizo", Toast.LENGTH_SHORT).show();

}
});

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION,}, 1000);
} else {
locationStart();
}
}
//Insertamos los datos a nuestra webService
private boolean insertar(){
HttpClient httpClient;
List<NameValuePair> nameValuePairs;
HttpPost httpPost;
httpClient = new DefaultHttpClient();
httpPost = new HttpPost("http://192.168.8.133/gpsbd/insertar.php");//url del servidor
//empezamos añadir nuestros datos
nameValuePairs = new ArrayList<NameValuePair>(4);
nameValuePairs.add(new BasicNameValuePair("coordenadas",mensaje1.getText().toString().trim()));
nameValuePairs.add(new BasicNameValuePair("direccion",mensaje2.getText().toString().trim()));

try {
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
httpClient.execute(httpPost);
return true;


} catch(UnsupportedEncodingException e){
e.printStackTrace();
}catch (ClientProtocolException e){
e.printStackTrace();

}catch (IOException e){
e.printStackTrace();
}
return false;
}
//AsyncTask para insertar Datos
class Insertar extends AsyncTask<String,String,String> {

private Activity context;

Insertar(Activity context){
this.context=context;
}

protected String doInBackground(String... params) {
// TODO Auto-generated method stub
if(insertar())
context.runOnUiThread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Toast.makeText(context, "Datos insertado con éxito", Toast.LENGTH_LONG).show();
mensaje1.setText("");
mensaje2.setText("");

}
});
else
context.runOnUiThread(new Runnable(){
@Override
public void run() {
// TODO Auto-generated method stub
Toast.makeText(context, "Datos no insertado con éxito", Toast.LENGTH_LONG).show();
}
});
return null;
}
}

//Apartir de aqui empezamos a obtener la direciones y coordenadas
private void locationStart() {
LocationManager mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
Localizacion Local = new Localizacion();
Local.setMainActivity(this);
final boolean gpsEnabled = mlocManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!gpsEnabled) {
Intent settingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(settingsIntent);
}
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION,}, 1000);
return;
}
mlocManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, (LocationListener) Local);
mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, (LocationListener) Local);

mensaje1.setText("Localizacion agregada");
mensaje2.setText("");
}

public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == 3000) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
locationStart();
return;
}
}
}

public void setLocation(Location loc) {
//Obtener la direccion de la calle a partir de la latitud y la longitud
if (loc.getLatitude() != 0.0 && loc.getLongitude() != 0.0) {
try {
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
List<Address> list = geocoder.getFromLocation(
loc.getLatitude(), loc.getLongitude(), 1);
if (!list.isEmpty()) {
Address DirCalle = list.get(0);
mensaje2.setText(DirCalle.getAddressLine(0));
}

} catch (IOException e) {
e.printStackTrace();
}
}
}
/* Aqui empieza la Clase Localizacion */
public class Localizacion implements LocationListener {
MainActivity mainActivity;

public MainActivity getMainActivity() {
return mainActivity;
}

public void setMainActivity(MainActivity mainActivity) {
this.mainActivity = mainActivity;
}

@Override
public void onLocationChanged(Location loc) {
// Este metodo se ejecuta cada vez que el GPS recibe nuevas coordenadas
// debido a la deteccion de un cambio de ubicacion

loc.getLatitude();
loc.getLongitude();

String Text = "Lat = "+ loc.getLatitude() + "n Long = " + loc.getLongitude();
mensaje1.setText(Text);
this.mainActivity.setLocation(loc);
}

@Override
public void onProviderDisabled(String provider) {
// Este metodo se ejecuta cuando el GPS es desactivado
mensaje1.setText("GPS Desactivado");
}

@Override
public void onProviderEnabled(String provider) {
// Este metodo se ejecuta cuando el GPS es activado
mensaje1.setText("GPS Activado");
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
switch (status) {
case LocationProvider.AVAILABLE:
Log.d("debug", "LocationProvider.AVAILABLE");
break;
case LocationProvider.OUT_OF_SERVICE:
Log.d("debug", "LocationProvider.OUT_OF_SERVICE");
break;
case LocationProvider.TEMPORARILY_UNAVAILABLE:
Log.d("debug", "LocationProvider.TEMPORARILY_UNAVAILABLE");
break;
}
}
}
}

Y con eso hemos terminado, espero les haya gustado este pequeño tutorial hay otras formas de hacerlo como por ejemplo con la clase Service pero eso lo haremos en otra ocasión:
Igual si piensas que hablo escribo en chino te dejo el ejercicio:

  Link de la descarga
Programador alfa, lomo plateado, barba de clavos, mentón de roca, no descarga la aplicación sigue el tutorial. Clic para DESCARGAR
     
ENLACES DE INTERÉS:

27 comentarios en «Como registrar las coordenadas en background a una base de datos en mysql y android studio»

  1. Miguel

    Hola,

    La aplicación android me funciona casi correctamente. Al cerrar la aplicación se siguen enviando datos al mysql de mi servidor, pero cuando pasa un rato (sobre media hora o así), ya no inserta más datos. El icono del gps en las notificaciones de la pantalla arriba a la izquierda deja de estar presente.

    ¿Por que ocurre?, como consigo que se ejecute siempre el envio de datos¿?¿?

    Si quieres te envío todo el código que tengo, pero vamos, solo he tocado textos del toast sin importancia.

      1. Miguel S Chehade Duran

        estoy usando la ultima version de android studio con el ejemplo y con las actualziacion y me marca este error:

        04:41 AM Instant Run is not supported on devices with API levels 20 or lower.
        (Don’t show again)

        04:41 AM Executing tasks: [:app:assembleDebug]

        04:43 AM Gradle build finished in 1m 12s 887ms

        04:43 AM Session ‘app’: Error Installing APK
        la verdad no tengo idea apenas estoy empezando a entender como manejar android, alguna sugerencia?

        1. AndroFast Autor

          La respuesta esta en la primera linea de tu error te dice lo siguiente: La ejecución no es compatible con dispositivos con niveles de API 20 o inferiores.
          Tu móvil puede ser un poco anticuado, pero para descartar, me podría decir que tipo de móvil es y que versión de Android es la que tiene instalada.

          1. AndroFast Autor

            Miguel esa versión es antigua trae la Api 21 sino me equivoco, desconozco si tu huawei puede actualizarse a la versión 6 por ejemplo, en todo caso tienes dos opciones la primera es usar el android estudio 2.33 o cualquier versión que sea inferior a la 3.0 y usar la api 21 como entorno de trabajo de lo contrario la segunda opción es cambiarte a un móvil mas actualizado.

      2. Antonio

        Hola hace una horas te comente en otro post, acerca de un ejemplo similar a este, sabes estoy poniendo en practica esto que pusiste, sin embargo al poco tiempo de que ejecuto la app, dejo de registrar coordenadas, arriba comentas que solo agregare el permiso de uso de batería, yo agregue este android.permission.WAKE_LOCK, pero me sucede lo mismo como a las 5 minutos el icono que aparece en la parte superior que indica la posición deja de aparecer. ¿Si esta correcto el permiso que agregue?

      3. Antonio

        Buenas noches. Sabes estoy probando la app pero como a Los cinco minutos deja de registrar las coordenadas, estando la aplicación en seguridad plano o el teléfono bloqueado. Leí que faltaba algo del permiso de batería, yo utilice el siguiente, nosé si sea el correcto. .

  2. Miguel S Chehade Duran

    ya solucione la parte de la instalacion de la aplicacion en el celular para probrarla ya tengo creada la base de datos, y tengo subido el archivo insertar.php en el servidor, sigo leyendo el codigo para entenderle mejor, estoy en la parte de guardar donde me dice que los datos no se guardan con exito, espero ver el problema por mi mismo

  3. Miguel S Chehade Duran

    listo, ya graba en la base de datos latitud y longitud, a seguir leyendo articulos para pasarle 4 parametros mas a la base de datos, % de bateria, nombre, numero de telefono y hora de la ultima conexion, de verdad que sus tutoriales son excelentes, de antemano muchas gracias por compartir conocimientos

      1. Miguel S Chehade Duran

        ya tengo casi terminado mi proyecto ya envia el nombre el telefono latitud y longitud, solo una duda, como hacer que envie datos cada x segundos, en el codigo veo que se reenvian datos cuando cambia la localizacion, como lo podria hacer como te comento, muchas gracias de antemano

  4. Miguel S Chehade Duran

    ya lo corregi muchas gracias, inclusive le aguegue como comentaste con mi tocayo el permiso de bateria, lo unico que me faltaria y que ando leyendo aqui y buscandole, es que cuando le aprieten el boton de reposo al celular, ese que hace que se “apague la pantalla” me siga transmitiendo, y de verdad me gustaria hacerles alguna contribucion de alguna manera por que la ayuda que me han brindado ha sido mucha, terminado el proyecto te lo enviare de vuelta con las modificaciones que hice por si alguien mas necesita agregarle campos vean como lo hice yo

  5. Miguel S Chehade Duran

    leido muchas gracias, como todo casi es nuevo para mi mejor preguntar y quedar como tonto que no preguntar y quedarme con la duda,

  6. Miguel S Chehade Duran

    ya tengo mi aplicacion creada graccias a todos tus tutoriales, hice las pruebas de cambiar aplicaciones y contestar el tel y sigue funcionando bien, pero me salto un nuevo error que no habia visto, trabaja bien, pero solo por 50 minutos, hice varias pruebas, pero exactamente a los 50 minutos de estar enviando los datos se detiene, como podria solucionar esto? alguna idea, sigo navegando a ver si encuentro alguna solucion pero no le doy

    gracias

    1. ANDROFAST Autor

      Lo felicito, como sabrá todos los dispositivos móviles de por si tienen integrado en su núcleo el sistema de ahorro de energía, entonces usted debe darle permisos de batería a su aplicación.

  7. Miguel S Chehade Duran

    si se lo di creo, agregue este linea , ademas le otorgue el permiso directamente en el celular a la aplicacion para seguir trabajando en segundo plano, con esto solucione lo del protector de pantalla tambien y de cuando ponen el celular en reposo, es decir, que cuando aprietan el boton que apaga la pantalla

      1. Miguel S Chehade Duran

        ya lo implemente y esta corriendo bien, sigo agregando detalles para ir guardando datos, use tu otro tutorial de “como mostrar el porcentaje de bateria” y me funciona muy bien, y la graba bien en la base de datos, use este codigo BroadcastReceiver bateriaReciever = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {

        context.unregisterReceiver(this);
        int currentLevel = intent.getIntExtra(BatteryManager.EXTRA_LEVEL,-1);
        int scale = intent.getIntExtra(BatteryManager.EXTRA_SCALE,-1);
        int level = -1;
        if (currentLevel >=0 && scale > 0){
        level= (currentLevel * 100)/scale;
        }
        mensaje6.setText(“”+level+”%”);

        }
        };
        IntentFilter batteryFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
        registerReceiver(bateriaReciever,batteryFilter);

        y mando mensaje6 a la base de datos y todo correcto, pero tengo otra consulta, solamente me manda el primer dato, como puedo actualizarlo para que envie el ultimo dato de bateria? en este caso solo me manda el primero que toma la aplicacion al inicializarse, alguna sugerencia o algun otro tutorial para leer?

        gracias

          1. Aitana

            Hola, ya ha pasado mucho tiempo, pero podría poner el código modificado.

            Gracias. Lo agradecería mucho

Deja una respuesta

Tu dirección de correo electrónico no será publicada.

WhatsApp chat