2016-11-09 1 views
0

Je suis vraiment en difficulté ici. J'essaie d'obtenir lat et lon avec un service d'arrière-plan toutes les 3 secondes mais je ne peux obtenir des données que lorsque je clique sur lat et lon dans les contrôles étendus de l'émulateur, donc le téléphone et l'émulateur ne fonctionnent pas. Voici mon code ci-dessous, ce serait génial si quelqu'un pouvait m'aider. Merci!Impossible d'obtenir l'emplacement avec Service (LocationManager)

service

public class GPSService extends Service { 


    private static final String TAG = "GpsService"; 
    private LocationListener locationListener; 
    private LocationManager locationManager; 


    @Nullable 
    @Override 
    public IBinder onBind(Intent intent) { 
     return null; 
    } 

    @Override 
    public void onCreate() { 

     locationListener = new LocationListener() { 
      @Override 
      public void onLocationChanged(Location location) { 
       Intent i = new Intent("location_update"); 
       i.putExtra("latExtra",location.getLatitude()); 
       i.putExtra("lonExtra",location.getLongitude()); 
       sendBroadcast(i); 
       Log.i(TAG, "onLocationChanged: extras lat lon"+location.getLatitude()+" "+location.getLongitude()); 
      } 

      @Override 
      public void onStatusChanged(String s, int i, Bundle bundle) { 

      } 

      @Override 
      public void onProviderEnabled(String s) { 

      } 

      @Override 
      public void onProviderDisabled(String s) { 
       Log.i(TAG, "onProviderDisabled: DISABLED"); 
       Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
       i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
       startActivity(i); 
      } 
     }; 

     locationManager =(LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE); 

     Criteria c = new Criteria(); 
     String provider =locationManager.getBestProvider(c,true); 
     Log.i(TAG, "onCreate: bestProvider "+provider); 

     //noinspection MissingPermission 
     locationManager.requestLocationUpdates(provider,2000,0,locationListener); 

    } 

    @Override 
    public void onDestroy() { 
     super.onDestroy(); 

     if (locationManager != null){ 
      Log.i(TAG, "onDestroy: Location manager nije null i brisem"); 
      //noinspection MissingPermission 
      locationManager.removeUpdates(locationListener); 
     } 

    } 
} 

MainActivity

private final String TAG = "Main"; 
    ... 
    BroadcastReceiver broadcastReciever; 




    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 
     setSupportActionBar(toolbar); 
     //setStatusBarTranslucent(false); 


     if(!runtimePermisions()){ 
      startLocationUpdate();} 
... 

     FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); 
     fab.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       //stopService(); 
       if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
        //REQUEST PERMISSION 
        Log.i(TAG, "onClick: NO PERMISION"); 
       } else { 
        Log.i(TAG, "onClick: got permision"); 
       } 
... 
    } 
    public void startLocationUpdate(){ 
     Intent i = new Intent(this,GPSService.class); 
     startService(i); 
     Log.i(TAG, "startLocationUpdate: Pokrenuo sam service"); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     if (broadcastReciever == null){ 
      broadcastReciever = new BroadcastReceiver() { 
       @Override 
       public void onReceive(Context context, Intent intent) { 

        lat = (Double) intent.getExtras().get("latExtra"); 
        lon = (Double) intent.getExtras().get("lonExtra"); 

        Log.i(TAG, "onReceive: lat lon "+lat+" "+lon); 
       } 
      }; 
     } 
     registerReceiver(broadcastReciever,new IntentFilter("location_update")); 
    } 

    @Override 
    protected void onDestroy() { 
     super.onDestroy(); 
     if (broadcastReciever!=null){ 
      unregisterReceiver(broadcastReciever); 
     } 
    } 

    @Override 
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
     super.onRequestPermissionsResult(requestCode, permissions, grantResults); 

     if (requestCode == 100) { 
       if (grantResults [0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED){ 
        startLocationUpdate(); 
       }else{ 
        runtimePermisions();} 
      } 

    } 


    private boolean runtimePermisions() { 
     if (Build.VERSION.SDK_INT >= 23 &&ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED && 
       ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED){ 
      requestPermissions(new String[]{ 
        Manifest.permission.ACCESS_COARSE_LOCATION, 
        Manifest.permission.ACCESS_FINE_LOCATION, 

      },100); 
      return true; 
     } 
     return false; 
    } 

MANIFESTE

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.digiart.yoweather"> 

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

    <application 
     android:allowBackup="true" 
     android:icon="@mipmap/ic_launcher" 
     android:label="@string/app_name" 
     android:supportsRtl="true" 
     android:theme="@style/AppTheme"> 
     <activity 
      android:name=".MainActivity" 
      android:label="@string/app_name" 
      android:theme="@style/AppTheme.NoActionBar"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <activity android:name=".SettingsActivity" 
      android:theme="@style/SettingsTheme"></activity> 
     <service android:name=".Gps.GPSService"/> 
    </application> 

</manifest> 

Encore une fois ... Toute aide serait génial! MERCI: D

+0

Pour moi, besoin d'attendre quelques secondes avant que le téléphone peut obtenir l'emplacement. –

Répondre

0

Comme l'a dit K. Sopheak, cela peut prendre un certain temps pour obtenir l'emplacement. De la documentation:

La première mise à jour d'emplacement peut prendre un certain temps. Si un emplacement immédiat est requis, les applications peuvent utiliser la méthode getLastKnownLocation (String).

Donc, vous pouvez essayer d'obtenir la dernière position connue à l'aide getLastKnownLocation(String) lorsque le service est démarré et, en supposant qu'il existe, diffuser de la même manière que vous le feriez pour une mise à jour de l'emplacement. Gardez à l'esprit, cependant, que le dernier emplacement connu pourrait être périmé. En fonction de ce que vous utilisez, l'emplacement pour cela peut être acceptable ou non.

aussi, en aparté, quelques réflexions:

  1. Vous avez dit 3 secondes, mais le code utilise 2.000 millisecondes - a été que juste une faute de frappe?

  2. La fréquence des mises à jour d'emplacement est un minimum time - vous n'êtes pas assuré de recevoir des mises à jour aussi souvent. Selon la documentation:

    L'intervalle de mise à jour de l'emplacement peut être contrôlé à l'aide du paramètre minTime. Le temps écoulé entre les mises à jour d'emplacement ne sera jamais inférieur à minTime, bien que cela puisse être supérieur en fonction de l'implémentation du fournisseur d'emplacement et de l'intervalle de mise à jour demandé par d'autres applications.

  3. Y a-t-il une raison particulière pour laquelle vous avez besoin de mises à jour de localisation à une fréquence aussi élevée? L'obtention d'un emplacement peut exiger beaucoup de batterie, en particulier du fait que vous demandez des autorisations de localisation FINE et COARSE, si vous le demandez si souvent, cela pourrait épuiser énormément la durée de vie de la batterie de l'appareil. Cela est particulièrement vrai étant donné que le code s'exécute dans un service et continuera donc à s'exécuter même lorsque l'application est en arrière-plan ou que l'utilisateur est dans une activité qui ne nécessite pas de données de localisation. Encore une fois, à partir de la documentation:

    Le choix d'une valeur raisonnable pour minTime est important pour conserver la durée de vie de la batterie. Chaque mise à jour d'emplacement nécessite l'alimentation de GPS, WIFI, cellulaire et autres radios. Sélectionnez une valeur minTime aussi élevée que possible tout en offrant une expérience utilisateur raisonnable.Si votre application n'est pas au premier plan et indique l'emplacement à l'utilisateur, votre application doit éviter d'utiliser un fournisseur actif (tel que NETWORK_PROVIDER ou GPS_PROVIDER), mais si vous insistez, sélectionnez minTime de 5 * 60 * 1000 (5 minutes) ou plus grand. Si votre application est au premier plan et indique l'emplacement à l'utilisateur, il convient de sélectionner un intervalle de mise à jour plus rapide.

  4. Google recommande d'utiliser le Google Play services location APIs au lieu des API de localisation du cadre Android:

    Google Play API des services de localisation sont préférés aux API de localisation du cadre Android (de android.location) comme un moyen d'ajouter la localisation de votre application. Si vous utilisez actuellement les API d'emplacement d'infrastructure Android, nous vous recommandons vivement de passer le plus rapidement possible aux API d'emplacement des services Google Play.

+0

Merci beaucoup pour la réponse, eh oui, c'était juste que je l'ai typo je l'ai changé en 2sec pour le vérifier. Ma question est: locationChanged ne devrait-elle pas tirer des données même si elle est nulle? Fondamentalement, j'ai juste besoin d'obtenir un seul emplacement, donc je peux tirer mes données météo et c'est tout, et sur le bouton d'actualisation pour vérifier l'emplacement à nouveau. Je n'ai tout simplement plus d'options parce que tout ce que j'essaie ne fonctionnera pas et j'ai beaucoup d'ennuis avec cela pour les 6 derniers jours. Je ne connais pas les services Google Play, car parfois l'utilisateur ne les active pas. Avez-vous des solutions simples à mon problème? Merci encore – vibetribe93