2017-03-17 12 views
0

私はGPSを使用する必要があるアプリケーションを作ろうとしています。だから私はサービスを開始するMainActivityを書いています。このサービスは、融合ロケーションプロバイダを使用してロケーションを取得します。だから私のポイントは定期的に場所を取得することです、息子私はrequestedLocationUpdatesを使用します。それから私はその結果をその活動に放送することを試みています。これはonLocationChangedが不要なgetlastlocation()で動作します。私はonLocationChangedがrequesLocationUpdatesへのコールバックのリスナーとして機能することを理解しています。私はたくさんのグーグル・グーグルで答えを得ることができません。どのような助けにも感謝します。前もって感謝します。 onLocationChanged()が呼び出されていない

この

は私MainActivity.class

import android.content.BroadcastReceiver; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.widget.TextView; 
import android.widget.Toast; 

//Como queremos recibir datos del servicio locationinfo implementamos BroadcastReceiver a la clase principal 
public class MainActivity extends AppCompatActivity { 

private IntentFilter mIntentFilter; 
private TextView mTextView; 
public static final String latinfo=""; 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    mIntentFilter = new IntentFilter(); 
    mIntentFilter.addAction(latinfo); 
    mTextView = (TextView) findViewById(R.id.texto); 
    //Iniciamos el servicio locationinfo. Para ello creamos una petición (intent) 

    Intent serviceIntent = new Intent(this, locationinfo.class); 
    startService(serviceIntent); 
    //Registramos el recibidor del servicio. 
    //registerReceiver(mReceiver, mIntentFilter); 
} 

@Override 
public void onResume() { 
    super.onResume(); 
    registerReceiver(mReceiver, mIntentFilter); 
} 

private BroadcastReceiver mReceiver = new BroadcastReceiver() { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     mTextView.setText(mTextView.getText()+ "Respuesta del GPS \n"); 
     if (intent.getAction().equals(latinfo)) { 
      mTextView.setText(mTextView.getText() 
        + intent.getStringExtra("longitud") + "\n\n"); 

     } 
     else { 

      Toast.makeText(context,"No se recibe nada",Toast.LENGTH_LONG).show(); 
      Intent stopIntent = new Intent(MainActivity.this, 
        locationinfo.class); 
      stopService(stopIntent); 
     } 

     } 


}; 

}

であり、これはservice.class

import android.Manifest; 
import android.app.Service; 
import android.content.Intent; 
import android.content.pm.PackageManager; 
import android.location.Location; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.support.v4.app.ActivityCompat; 
import android.support.v4.content.LocalBroadcastManager; 
import android.util.Log; 
import android.widget.Toast; 
import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.location.LocationListener; 
import com.google.android.gms.location.LocationRequest; 
import com.google.android.gms.location.LocationServices; 




//Servicio de localizacion mediante FusedLocationProvider 

public class locationinfo extends Service implements GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener, LocationListener { 
    //Definimos las variables que vamos a utilizar 
    GoogleApiClient miGoogleApi; 
Double longitud; // declaramos el valor de longitud 
Double latitud; // declaramos el valor de latitud 
String infolongi; //Si queremos utilizar el texto para mostrarlo de la longitud, lo haremos como string. Por tanto lo declaramos 
String infolati; //Si queremos utilizar el texto para mostrarlo de la latitud, lo haremos como string. Por tanto lo declaramos 
Location localizacion; //el objeto localizacion que tendrá toda la geo-informacion 
//int causafallo; 
private static final String TAG = "LocationActivity"; 



//Creamos el servicio y creamos tambien el objeto/cliente que se conectará con los servicios de Google. 
//Para ello utilizamos un constructor (Builder) que engloba varios métodos. Entre ellos los métodos addConnectionCallbacks y 
//addOnConnectionFailedListener. Estos métodos exigen ser implementados en la clase y necesitan de 2 métodos heredados que 
//se tienen que declarar en el código. addOnConnectionFailedListener exige la declaración de onConnectionFailed(ConnectionResult algo) 
//y addConnectionCallback exige la declaración de onConnectionSuspended(int). 

public void onCreate(){ 

    miGoogleApi=new GoogleApiClient.Builder(this) 
    .addConnectionCallbacks(this) 
    .addOnConnectionFailedListener(this) 
    .addApi(LocationServices.API) 
    .build(); 

    //Una vez creado el objeto lo conectamos con los servicios de Google (Esta conexión se debe hacer en el método 
    //onResume() en caso de tratarse de una Activity al igual que la desconexión se debe hacer con 'objeto.disconnect() 
    // en el método onPause() 

    miGoogleApi.connect(); 
} 

//Una vez que está conectado. Necesario por le metodo ConnectionCallBAck() 
@Override 
public void onConnected(Bundle melasuda) { 



    //Llenamos el objeto 'localizacion' con la informacion solicitada al proveedor FusedLocationServices 
    //En este caso pedimos la última posición conocida mediante el método getLastLocation() al que se le dice que 
    // utilice el objeto/cliente que hemos creado 


    //localizacion = LocationServices.FusedLocationApi.getLastLocation(miGoogleApi); 

    //Creamos el objeto LocationRequest que tendrá varios parametros 

    LocationRequest mlocationrequest=new LocationRequest(); 
    mlocationrequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    mlocationrequest.setInterval(5000); // Actualizamos cada 5 segundos 
    mlocationrequest.setFastestInterval(3000); //El caso más rápido de actualizacion 
    mlocationrequest.setSmallestDisplacement(10); //Distancia para hacer actualizaion 

    //Ahora en vez de obterner la última localización, vamos a pedir que actualice la posición cada cierto tiempo. Para ello vamos a llamar 
    //a una función que vamos a crear. Esta llamada debe de hacerse desde aquí, desde onConnected() 


    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) 
      == PackageManager.PERMISSION_GRANTED) { 
     Toast.makeText(getBaseContext(), "Permisos de uso de GPS activados", Toast.LENGTH_LONG).show(); 
     //localizacion = LocationServices.FusedLocationApi.getLastLocation(miGoogleApi); 
     LocationServices.FusedLocationApi.requestLocationUpdates(miGoogleApi, mlocationrequest, this); 
    } 

} 


//Este método funciona como el Listener de requestLocationUpdates 
@Override 
public void onLocationChanged(Location location){ 
    localizacion = location; 
    Toast.makeText(getBaseContext(),"estamos en onlocationchanged",Toast.LENGTH_LONG).show(); 
    updateUI(); 

} 

private void updateUI() { 
    infolati=String.valueOf(localizacion.getLatitude()); 
    infolongi=String.valueOf(localizacion.getLongitude()); 

    new Thread(new Runnable() { 
     public void run() { 
      if (localizacion != null) { 
       //Le pasamos el objeto con la informacion a una funcion que vamos a crear para que obtenga lo que queramos 
       longitud=localizacion.getLongitude(); 
       latitud=localizacion.getLatitude(); 
       infolongi=String.valueOf(longitud); 
       infolati=String.valueOf(latitud); 


      } else { 
       infolongi="El valor de localizacion devuelve nulo"; 

      } 

      //Le damos 5 segundos para que puede conectar con la señal GPS 
      try { 
       Thread.sleep(5000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } 
      //Enviamos los datos para que puedan ser recogidos por la aplicación 
      Intent broadcastIntent = new Intent(); 
      broadcastIntent.setAction(MainActivity.latinfo); 
      broadcastIntent.putExtra("longitud",infolongi); 
      broadcastIntent.putExtra("latitud",infolati); 
      sendBroadcast(broadcastIntent); 

     } 
    }).start(); 

} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 

    Log.i("MyService", "Received start id " + startId + ": " + intent); 
    return START_STICKY; // run until explicitly stopped. 
} 
//Se llama desde la aplicación con startService(Intent). Asigna un codigo al servicio 




//Método necesario para addConnectionCallback(). Devuelve un entero con la causa de fallo 
public void onConnectionSuspended(int causafallo){ 

} 
//Método necesario para addOnConnectionFailedListener(). Devuelve un código que puede ser del tipo boolean,string, int, 
//o pendingintent del probela encontrado si falla la conexión. Lo hace utilizando la clase ConnectionResult 
public void onConnectionFailed(ConnectionResult result){ 
    Toast.makeText(getBaseContext(),"Ha fallado la conexion:"+result.getErrorCode(),Toast.LENGTH_LONG).show(); 
//Y hacemos un log por si tenemos que hace un debug 

    Log.i(TAG,"onConnectionFailed:"+result.getErrorCode()+","+result.getErrorMessage()); 
} 

//Función que apaga el servicio 
@Override 
public void onDestroy() { 
    // Cancel the persistent notification. 


    // Tell the user we stopped. 
    Toast.makeText(this, "Se ha parado el servicio de localizacion", Toast.LENGTH_SHORT).show(); 
} 

//Lanza el servicio 
@Override 
public IBinder onBind(Intent intent) { 
    // TODO: Return the communication channel to the service. 
    throw new UnsupportedOperationException("Todavía no implementado"); 
} 
} 
+0

あなたのrequestlocationupdates()は呼び出されていません。アプリをテストしているAPIバージョンはどれですか? 23歳以上の場合は、プログラムで許可を要求する必要があります。 – HaroldSer

+0

私はAPI 23を使用しています。しかし、私はこのコードで "if ActivityCompat.checkSelfPermission(this、Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){..."の直前にrequestLocationUpdatesから、プログラムで許可を要求しています。実際に私がgetLastLocationに変更した場合、それは機能します。 – ilpadrino

答えて

1

私は解決策を見つけました。 OnLocationChangedは、「場所を変更する」の後にのみ呼び出されます。これは、比較する先の場所を取得する必要があることを意味します。これはgetLastLocation()によって得られます。

関連する問題