2013-11-26 21 views
29

を取得していない場合、私は場所を取得するためのコードの下に与えられ、これを使用しています、GPS位置を取得します。Androidの場所のマネージャー、何のGPSは、[ネットワークプロバイダの場所に

public Location getLocation() { 
     try { 
      mLocationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE); 

      // getting GPS status 
      boolean isGPSEnabled = mLocationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); 

      // getting network status 
      boolean isNetworkEnabled = mLocationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

      if (!isGPSEnabled && !isNetworkEnabled) { 
       // no network provider is enabled 
      } else { 
       // First get location from Network Provider 
       if (isNetworkEnabled) { 
        mLocationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
        Log.d("Network", "Network"); 
        if (mLocationManager != null) { 
         location = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
         if (location != null) { 
          lat = location.getLatitude(); 
          lng = location.getLongitude(); 
         } 
        } 
       } 
       //get the location by gps 
       if (isGPSEnabled) { 
        if (location == null) { 
         mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,MIN_TIME_BW_UPDATES,MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
         Log.d("GPS Enabled", "GPS Enabled"); 
         if (mLocationManager != null) {location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
          if (location != null) { 
           lat = location.getLatitude(); 
           lng = location.getLongitude(); 
          } 
         } 
        } 
       } 
      } 

     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     return location; 
    } 

それが正常に動作しているが、私はGPSを取得したいと思い場所が最初に使用され、使用できない場合は、ロケーションマネージャは、問題が発生しているネットワークプロバイダを照会する必要があります。

これを行うには良い方法を教えてください。

+0

Play Serviceの新しいlocationclientを使用します。理解しやすいです。 – TeeTracker

+0

このリンクはあなたに最適な方法を提供します http://stackoverflow.com/questions/3145089/what-is-the-simplest-and-most-robust-way-to-get-the-users-current -location-in-a?lq = 1 –

答えて

1

上記のコードでGPSとネットワークの両方で約5秒間の位置修正を探して、その中から最もよく知られている場所を教えてください。上記のクラスで

public class LocationService implements LocationListener { 

    boolean isGPSEnabled = false; 

    boolean isNetworkEnabled = false; 

    boolean canGetLocation = false; 

    final static long MIN_TIME_INTERVAL = 60 * 1000L; 

    Location location; 


    // The minimum distance to change Updates in meters 
    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 0; // 10 

    // The minimum time between updates in milliseconds 
    private static final long MIN_TIME_BW_UPDATES = 1; // 1 minute 

    protected LocationManager locationManager; 

    private CountDownTimer timer = new CountDownTimer(5 * 1000, 1000) { 

     public void onTick(long millisUntilFinished) { 

     } 

     public void onFinish() { 
      stopUsingGPS(); 
     } 
    }; 

    public LocationService() { 
     super(R.id.gps_service_id); 
    } 


    public void start() { 
     if (Utils.isNetworkAvailable(context)) { 

      try { 


       timer.start(); 


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

       isGPSEnabled = locationManager 
         .isProviderEnabled(LocationManager.GPS_PROVIDER); 

       isNetworkEnabled = locationManager 
         .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
       this.canGetLocation = true; 
       if (isNetworkEnabled) { 
        locationManager.requestLocationUpdates(
          LocationManager.NETWORK_PROVIDER, 
          MIN_TIME_BW_UPDATES, 
          MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
        Log.d("Network", "Network"); 
        if (locationManager != null) { 
         Location tempLocation = locationManager 
           .getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
         if (tempLocation != null 
           && isBetterLocation(tempLocation, 
             location)) 
          location = tempLocation; 
        } 
       } 
       if (isGPSEnabled) { 

        locationManager.requestSingleUpdate(
          LocationManager.GPS_PROVIDER, this, null); 
        locationManager.requestLocationUpdates(
          LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, 
          MIN_DISTANCE_CHANGE_FOR_UPDATES, this); 
        Log.d("GPS Enabled", "GPS Enabled"); 
        if (locationManager != null) { 
         Location tempLocation = locationManager 
           .getLastKnownLocation(LocationManager.GPS_PROVIDER); 
         if (tempLocation != null 
           && isBetterLocation(tempLocation, 
             location)) 
          location = tempLocation; 
        } 
       } 

      } catch (Exception e) { 
       onTaskError(e.getMessage()); 
       e.printStackTrace(); 
      } 
     } else { 
      onOfflineResponse(requestData); 
     } 
    } 

    public void stopUsingGPS() { 
     if (locationManager != null) { 
      locationManager.removeUpdates(LocationService.this); 
     } 
    } 

    public boolean canGetLocation() { 
     locationManager = (LocationManager) context 
       .getSystemService(Context.LOCATION_SERVICE); 
     isGPSEnabled = locationManager 
       .isProviderEnabled(LocationManager.GPS_PROVIDER); 

     // getting network status 
     isNetworkEnabled = locationManager 
       .isProviderEnabled(LocationManager.NETWORK_PROVIDER); 
     return isGPSEnabled || isNetworkEnabled; 
    } 

    @Override 
    public void onLocationChanged(Location location) { 

     if (location != null 
       && isBetterLocation(location, this.location)) { 

      this.location = location; 

     } 
    } 

    @Override 
    public void onProviderDisabled(String provider) { 
    } 

    @Override 
    public void onProviderEnabled(String provider) { 
    } 

    @Override 
    public void onStatusChanged(String provider, int status, Bundle extras) { 
    } 

    @Override 
    public Object getResponseObject(Object location) { 
     return location; 
    } 

    public static boolean isBetterLocation(Location location, 
      Location currentBestLocation) { 
     if (currentBestLocation == null) { 
      // A new location is always better than no location 
      return true; 
     } 

     // Check whether the new location fix is newer or older 
     long timeDelta = location.getTime() - currentBestLocation.getTime(); 
     boolean isSignificantlyNewer = timeDelta > MIN_TIME_INTERVAL; 
     boolean isSignificantlyOlder = timeDelta < -MIN_TIME_INTERVAL; 
     boolean isNewer = timeDelta > 0; 

     // If it's been more than two minutes since the current location, 
     // use the new location 
     // because the user has likely moved 
     if (isSignificantlyNewer) { 
      return true; 
      // If the new location is more than two minutes older, it must 
      // be worse 
     } else if (isSignificantlyOlder) { 
      return false; 
     } 

     // Check whether the new location fix is more or less accurate 
     int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation 
       .getAccuracy()); 
     boolean isLessAccurate = accuracyDelta > 0; 
     boolean isMoreAccurate = accuracyDelta < 0; 
     boolean isSignificantlyLessAccurate = accuracyDelta > 200; 

     // Check if the old and new location are from the same provider 
     boolean isFromSameProvider = isSameProvider(location.getProvider(), 
       currentBestLocation.getProvider()); 

     // Determine location quality using a combination of timeliness and 
     // accuracy 
     if (isMoreAccurate) { 
      return true; 
     } else if (isNewer && !isLessAccurate) { 
      return true; 
     } else if (isNewer && !isSignificantlyLessAccurate 
       && isFromSameProvider) { 
      return true; 
     } 
     return false; 
    } 

} 

、私はそうonLocationChangedコールバックは、いずれかまたは両方を複数回呼び出すことができ、我々はただで新しい位置フィックスを比較し、GPSとネットワークの両方のための場所のリスナーを登録しています私たちは既に持っていて、最高のものを保つ。

+0

'isSromProvider'は' boolean isFromSameProvider = isSameProvider(location.getProvider()、 currentBestLocation.getProvider());で宣言されていますか? – VikramV

+0

こんにちは、私はあなたのコードに興味があります、ところで、なぜタイマーを使用したのですか? onOfflineResponse(requestData)とonTaskError(e.getMessage)関数はどこにありますか?ありがとう。 – NPE

+0

GPSの場所を常に探している代わりに、startを呼び出すたびに(タイマーで設定された)時間を探します。最終的には、その時に発見された最高の場所があります。 –

15

あなたは、利用可能な場合はGPSの位置が必要であると言っていますが、あなたがしたことは、まずネットワークプロバイダからGPSを取得してからです。これは、ネットワークとGPSの両方から利用可能な場合は、その場所を取得します。あなたができることは、これらのケースをif..else ifブロックに書き込むことです。類似している -

これは、GPSからのロケーションを最初に取得します(利用可能な場合)。そうでない場合、ネットワークプロバイダからロケーションを取得しようとします。

EDIT

それを改善するために、私はスニペットを投稿します。それはtry-catchである考えてみましょう:

boolean gps_enabled = false; 
boolean network_enabled = false; 

LocationManager lm = (LocationManager) mCtx 
       .getSystemService(Context.LOCATION_SERVICE); 

gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER); 
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER); 

Location net_loc = null, gps_loc = null, finalLoc = null; 

if (gps_enabled) 
    gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
if (network_enabled) 
    net_loc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 

if (gps_loc != null && net_loc != null) { 

    //smaller the number more accurate result will 
    if (gps_loc.getAccuracy() > net_loc.getAccuracy()) 
     finalLoc = net_loc; 
    else 
     finalLoc = gps_loc; 

     // I used this just to get an idea (if both avail, its upto you which you want to take as I've taken location with more accuracy) 

} else { 

    if (gps_loc != null) { 
     finalLoc = gps_loc; 
    } else if (net_loc != null) { 
     finalLoc = net_loc; 
    } 
} 

今、あなたはreturnそれをnullためfinalLocをチェックし、そうでない場合。 上記のコードは、目的の(finalLoc)場所を返す関数で記述することができます。私はこれが助けるかもしれないと思う。

+0

私が知っている限り、isGetworkEnabledはisGPSEnabledと同様、プロバイダが有効かどうかを伝えます。しかし、GPSプロバイダが有効になっていても、その場所を取得できなくても、その場合は、もう一方のネットワークプロバイダ、つまりネットワークプロバイダを使用して位置更新を再クエリする必要があります。それはどうやってできますか? –

+0

をご覧ください。まだ何かが必要な場合は教えてください。ありがとう。 – thegiga

+0

あなたの編集を確認しました。私が疑問に思っているのは、lm.getLastKnownLocationです。それは信頼できますか?私が24時間前に最後のGPS修正を入手したらどうしますか?ステートメントは - "gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);" 「null」または24時間前の位置を返しますか? –

5

上に述べたようにそれを行うためのより良い方法は、これを行う際に推奨されるがLocationClientを使用することですがあります。

まず、位置更新間隔の値を定義します。これをあなたのニーズに合わせて調整してください。

private static final int MILLISECONDS_PER_SECOND = 1000; 
private static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS; 
private static final int FASTEST_INTERVAL_IN_SECONDS = 1; 
private static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS; 

あなたActivityGooglePlayServicesClient.ConnectionCallbacksGooglePlayServicesClient.OnConnectionFailedListener、そしてLocationListenerを実装してもらいます。その後

public class LocationActivity extends Activity implements 
GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {} 

、あなたのActivityonCreate()方法でLocationClientを設定します。

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 

    mLocationClient = new LocationClient(this, this, this); 

    mLocationRequest = LocationRequest.create(); 
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
    mLocationRequest.setInterval(UPDATE_INTERVAL); 
    mLocationRequest.setFastestInterval(FASTEST_INTERVAL); 
} 

は、あなたのActivityに必要なメソッドを追加します。 onConnected()は、LocationClientが接続するときに呼び出されるメソッドです。 onLocationChanged()は、最新の場所を取得する場所です。

@Override 
public void onConnectionFailed(ConnectionResult connectionResult) { 
    Log.w(TAG, "Location client connection failed"); 
} 

@Override 
public void onConnected(Bundle dataBundle) { 
    Log.d(TAG, "Location client connected"); 
    mLocationClient.requestLocationUpdates(mLocationRequest, this); 
} 

@Override 
public void onDisconnected() { 
    Log.d(TAG, "Location client disconnected"); 
} 

@Override 
public void onLocationChanged(Location location) { 
    if (location != null) { 
     Log.d(TAG, "Updated Location: " + Double.toString(location.getLatitude()) + "," + Double.toString(location.getLongitude())); 
    } else { 
     Log.d(TAG, "Updated location NULL"); 
    } 
}  

時に絶対に必要なので、それが唯一の予備のバッテリーを使用していますLocationClientを切断/接続するので、GPSが無期限に実行されないことを確認してください。 LocationClientは、データを取得するために接続する必要があります。

public void onResume() { 
    super.onResume(); 
    mLocationClient.connect(); 
} 

public void onStop() { 
    if (mLocationClient.isConnected()) { 
     mLocationClient.removeLocationUpdates(this); 
    } 
    mLocationClient.disconnect(); 
    super.onStop(); 
} 

ユーザーの所在地を取得します。まず、LocationClientを使用してみてください。それが失敗した場合は、LocationManagerに戻ってください。

public Location getLocation() { 
    if (mLocationClient != null && mLocationClient.isConnected()) { 
     return mLocationClient.getLastLocation(); 
    } else { 
     LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); 
     if (locationManager != null) { 
      Location lastKnownLocationGPS = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); 
      if (lastKnownLocationGPS != null) { 
       return lastKnownLocationGPS; 
      } else { 
       return locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); 
      } 
     } else { 
      return null; 
     } 
    } 
} 
+0

確かにそれはお勧めしません。 'このクラスは非推奨です。 Use LocationServices.' https://developer.android.com/reference/com/google/android/gms/location/LocationClient.html – levi

+0

「LocationManager」、「LocationClient」、および「LocationServices」は非常に異なります。 LocationManager'はAndroidシステムからのアップデートを取得するためのものです.LocationClientはGoogle Playサービスに依存し、廃止されました。私の経験では、スピード、精度、バッテリーの使い方が悪いです。また、LocationServicesはGoogle Playサービスに依存しており、APIにアクセスするために異なるパラダイムを使用しています。私の経験では、それは 'LocationClient'の"固定 "バージョンのようです(私は主要な変更がサービスにアクセスするためのメソッドであると予想していたかもしれません。 –

+0

私が普遍的に適用することを知っている(つまり自分の経験に基づいていない)主な違いは、Google Playサービスに依存していない3人のうち、LocationManagerが唯一のものであるということです。つまり、Google Play(

1

メインクラス:

public class AndroidLocationActivity extends Activity { 

Button btnGPSShowLocation; 
Button btnNWShowLocation; 

AppLocationService appLocationService; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    appLocationService = new AppLocationService(
      AndroidLocationActivity.this); 

    btnGPSShowLocation = (Button) findViewById(R.id.btnGPSShowLocation); 
    btnGPSShowLocation.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View arg0) { 

      Location gpsLocation = appLocationService 
        .getLocation(LocationManager.GPS_PROVIDER); 

      if (gpsLocation != null) { 
       double latitude = gpsLocation.getLatitude(); 
       double longitude = gpsLocation.getLongitude(); 
       Toast.makeText(
         getApplicationContext(), 
         "Mobile Location (GPS): \nLatitude: " + latitude 
           + "\nLongitude: " + longitude, 
         Toast.LENGTH_LONG).show(); 
      } else { 
       showSettingsAlert("GPS"); 
      } 

     } 
    }); 

    btnNWShowLocation = (Button) findViewById(R.id.btnNWShowLocation); 
    btnNWShowLocation.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View arg0) { 

      Location nwLocation = appLocationService 
        .getLocation(LocationManager.NETWORK_PROVIDER); 

      if (nwLocation != null) { 
       double latitude = nwLocation.getLatitude(); 
       double longitude = nwLocation.getLongitude(); 
       Toast.makeText(
         getApplicationContext(), 
         "Mobile Location (NW): \nLatitude: " + latitude 
           + "\nLongitude: " + longitude, 
         Toast.LENGTH_LONG).show(); 

      } else { 
       showSettingsAlert("NETWORK"); 
      } 

     } 
    }); 

} 

public void showSettingsAlert(String provider) { 
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(
      AndroidLocationActivity.this); 

    alertDialog.setTitle(provider + " SETTINGS"); 

    alertDialog.setMessage(provider 
      + " is not enabled! Want to go to settings menu?"); 

    alertDialog.setPositiveButton("Settings", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int which) { 
        Intent intent = new Intent(
          Settings.ACTION_LOCATION_SOURCE_SETTINGS); 
        AndroidLocationActivity.this.startActivity(intent); 
       } 
      }); 

    alertDialog.setNegativeButton("Cancel", 
      new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int which) { 
        dialog.cancel(); 
       } 
      }); 

    alertDialog.show(); 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.main, menu); 
    return true; 

} 

} 

次のクラス:

public class AppLocationService extends Service implements LocationListener { 

protected LocationManager locationManager; 
Location location; 

private static final long MIN_DISTANCE_FOR_UPDATE = 10; 
private static final long MIN_TIME_FOR_UPDATE = 1000 * 60 * 2; 

public AppLocationService(Context context) { 
    locationManager = (LocationManager) context 
      .getSystemService(LOCATION_SERVICE); 
} 

public Location getLocation(String provider) { 
    if (locationManager.isProviderEnabled(provider)) { 
     locationManager.requestLocationUpdates(provider, 
       MIN_TIME_FOR_UPDATE, MIN_DISTANCE_FOR_UPDATE, this); 
     if (locationManager != null) { 
      location = locationManager.getLastKnownLocation(provider); 
      return location; 
     } 
    } 
    return null; 
} 

@Override 
public void onLocationChanged(Location location) { 
} 

@Override 
public void onProviderDisabled(String provider) { 
} 

@Override 
public void onProviderEnabled(String provider) { 
} 

@Override 
public void onStatusChanged(String provider, int status, Bundle extras) { 
} 

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

} 

マニフェストに追加することを忘れないでください。

<!-- to get location using GPS --> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

<!-- to get location using NetworkProvider --> 
<uses-permission android:name="android.permission.INTERNET" /> 
+0

ネットワークプロバイダの使用には 'INTERNET'パーミッションが必要だと思います。実際には 'ACCESS_COURSE_LOCATION'が必要だと思います。 – trooper

2

、Googleの開発者はまた、位置を計算または推定するためにWiFiまたはセルの場所を使用して、GPSセンサ、磁力計の融合と加速度計を開発した融合APIを使用します。また、建物内の場所の更新も正確に行うことができます。

package com.example.ashis.gpslocation; 

import android.app.Activity; 
import android.location.Location; 
import android.os.Bundle; 
import android.support.v7.app.ActionBarActivity; 
import android.support.v7.app.AppCompatActivity; 
import android.util.Log; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.GooglePlayServicesUtil; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; 
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener; 
import com.google.android.gms.location.LocationListener; 
import com.google.android.gms.location.LocationRequest; 
import com.google.android.gms.location.LocationServices; 

import java.util.concurrent.Executors; 
import java.util.concurrent.TimeUnit; 

/** 
* Location sample. 
* 
* Demonstrates use of the Location API to retrieve the last known location for a device. 
* This sample uses Google Play services (GoogleApiClient) but does not need to authenticate a user. 
* See https://github.com/googlesamples/android-google-accounts/tree/master/QuickStart if you are 
* also using APIs that need authentication. 
*/ 

public class MainActivity extends Activity implements LocationListener, 
     GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener { 

    private static final long ONE_MIN = 500; 
    private static final long TWO_MIN = 500; 
    private static final long FIVE_MIN = 500; 
    private static final long POLLING_FREQ = 1000 * 20; 
    private static final long FASTEST_UPDATE_FREQ = 1000 * 5; 
    private static final float MIN_ACCURACY = 1.0f; 
    private static final float MIN_LAST_READ_ACCURACY = 1; 

    private LocationRequest mLocationRequest; 
    private Location mBestReading; 
TextView tv; 
    private GoogleApiClient mGoogleApiClient; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     if (!servicesAvailable()) { 
      finish(); 
     } 

     setContentView(R.layout.activity_main); 
tv= (TextView) findViewById(R.id.tv1); 
     mLocationRequest = LocationRequest.create(); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     mLocationRequest.setInterval(POLLING_FREQ); 
     mLocationRequest.setFastestInterval(FASTEST_UPDATE_FREQ); 

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


     if (mGoogleApiClient != null) { 
      mGoogleApiClient.connect(); 
     } 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 

     if (mGoogleApiClient != null) { 
      mGoogleApiClient.connect(); 
     } 
    } 

    @Override 
    protected void onPause() {d 
     super.onPause(); 

     if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) { 
      mGoogleApiClient.disconnect(); 
     } 
    } 


     tv.setText(location + ""); 
     // Determine whether new location is better than current best 
     // estimate 
     if (null == mBestReading || location.getAccuracy() < mBestReading.getAccuracy()) { 
      mBestReading = location; 


      if (mBestReading.getAccuracy() < MIN_ACCURACY) { 
       LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
      } 
     } 
    } 

    @Override 
    public void onConnected(Bundle dataBundle) { 
     // Get first reading. Get additional location updates if necessary 
     if (servicesAvailable()) { 

      // Get best last location measurement meeting criteria 
      mBestReading = bestLastKnownLocation(MIN_LAST_READ_ACCURACY, FIVE_MIN); 

      if (null == mBestReading 
        || mBestReading.getAccuracy() > MIN_LAST_READ_ACCURACY 
        || mBestReading.getTime() < System.currentTimeMillis() - TWO_MIN) { 

       LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 

       //Schedule a runnable to unregister location listeners 

        @Override 
        public void run() { 
         LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, MainActivity.this); 

        } 

       }, ONE_MIN, TimeUnit.MILLISECONDS); 

      } 

     } 
    } 

    @Override 
    public void onConnectionSuspended(int i) { 

    } 


    private Location bestLastKnownLocation(float minAccuracy, long minTime) { 
     Location bestResult = null; 
     float bestAccuracy = Float.MAX_VALUE; 
     long bestTime = Long.MIN_VALUE; 

     // Get the best most recent location currently available 
     Location mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
     //tv.setText(mCurrentLocation+""); 
     if (mCurrentLocation != null) { 
      float accuracy = mCurrentLocation.getAccuracy(); 
      long time = mCurrentLocation.getTime(); 

      if (accuracy < bestAccuracy) { 
       bestResult = mCurrentLocation; 
       bestAccuracy = accuracy; 
       bestTime = time; 
      } 
     } 

     // Return best reading or null 
     if (bestAccuracy > minAccuracy || bestTime < minTime) { 
      return null; 
     } 
     else { 
      return bestResult; 
     } 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 

    } 

    private boolean servicesAvailable() { 
     int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this); 

     if (ConnectionResult.SUCCESS == resultCode) { 
      return true; 
     } 
     else { 
      GooglePlayServicesUtil.getErrorDialog(resultCode, this, 0).show(); 
      return false; 
     } 
    } 
} 
+0

Hello Ashis、いいコードスニペットですが、コードスニペットを実装した後、モバイル機器**(Micromex、Samsung note 4)**はほぼ30 ** ** [内ばかりの場合** **はうまくいきません。 – user2617214

+0

@ user26174問題を解決したかどうかあなたに私のgithub.comアカウントへのアクセス権を与えて、働くコードを手に入れることを知らせなければ。 – AshisParajuli

2

バックグラウンドサービス内で実行し、フォアグラウンドでデータを取得する場合は、以下のものを使用してテストされ、検証されます。

public class MyService extends Service 
     implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener, 
     com.google.android.gms.location.LocationListener { 


    private static final int ASHIS = 1234; 
    Intent intentForPendingIntent; 
    HandlerThread handlerThread; 
    Looper looper; 
    GoogleApiClient mGoogleApiClient; 
    private LocationRequest mLocationRrequest; 
    private static final int UPDATE_INTERVAL = 1000; 
    private static final int FASTEST_INTERVAL = 100; 
    private static final int DSIPLACEMENT_UPDATES = 1; 
    ; 
    private Handler handler1; 
    private Runnable runable1; 
    private Location mLastLocation; 
    private float waitingTime; 
    private int waiting2min; 
    private Location locationOld; 
    private double distance; 
    private float totalWaiting; 
    private float speed; 
    private long timeGpsUpdate; 
    private long timeOld; 
    private NotificationManager mNotificationManager; 
    Notification notification; 
    PendingIntent resultPendingIntent; 
    NotificationCompat.Builder mBuilder; 


    // Sets an ID for the notification 
    int mNotificationId = 001; 
    private static final String TAG = "BroadcastService"; 
    public static final String BROADCAST_ACTION = "speedExceeded"; 
    private final Handler handler = new Handler(); 
    Intent intentforBroadcast; 
    int counter = 0; 
    private Runnable sendUpdatesToUI; 

    @Nullable 
    @Override 
    public IBinder onBind(Intent intent) { 
     Toast.makeText(MyService.this, "binder", Toast.LENGTH_SHORT).show(); 

     return null; 
    } 


    @Override 
    public void onCreate() { 
     showNotification(); 
     intentforBroadcast = new Intent(BROADCAST_ACTION); 

     Toast.makeText(MyService.this, "created", Toast.LENGTH_SHORT).show(); 

     if (mGoogleApiClient == null) { 
      mGoogleApiClient = new GoogleApiClient.Builder(this) 
        .addConnectionCallbacks(this) 
        .addOnConnectionFailedListener(this) 
        .addApi(LocationServices.API) 
        .build(); 
     } 
     createLocationRequest(); 
     mGoogleApiClient.connect(); 


    } 

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN) 
    private void showNotification() { 

     mBuilder = 
       (NotificationCompat.Builder) new NotificationCompat.Builder(this) 
         .setSmallIcon(R.drawable.ic_media_play) 
         .setContentTitle("Total Waiting Time") 
         .setContentText(totalWaiting+""); 


     Intent resultIntent = new Intent(this, trackingFusion.class); 

     // Because clicking the notification opens a new ("special") activity, there's 
     // no need to create an artificial back stack. 
     PendingIntent resultPendingIntent = 
       PendingIntent.getActivity(
         this, 
         0, 
         resultIntent, 
         PendingIntent.FLAG_UPDATE_CURRENT 
       ); 
     mBuilder.setContentIntent(resultPendingIntent); 
     NotificationManager mNotifyMgr = 
       (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 
     // Builds the notification and issues it. 

     mNotifyMgr.notify(mNotificationId, mBuilder.build()); 


     startForeground(001, mBuilder.getNotification()); 
    } 


    @Override 
    public void onLocationChanged(Location location) { 

     //handler.removeCallbacks(runable); 

     Toast.makeText(MyService.this, "speed" + speed, Toast.LENGTH_SHORT).show(); 
     timeGpsUpdate = location.getTime(); 
     float delta = (timeGpsUpdate - timeOld)/1000; 
     if (location.getAccuracy() < 100) { 
      speed = location.getSpeed(); 
      distance += mLastLocation.distanceTo(location); 
      Log.e("distance", "onLocationChanged: " + distance); 
      //mLastLocation = location; 
      //newLocation = mLastLocation; 

      Log.e("location:", location + ""); 


      //speed = (long) (distance/delta); 


      locationOld = location; 
      mLastLocation = location; 

      diaplayViews(); 
     } 

     diaplayViews(); 
    /*if (map != null) { 
     map.addMarker(new MarkerOptions() 
       .position(new LatLng(location.getLatitude(), location.getLongitude())) 
       .title("Hello world")); 


    }*/ 
    } 


    private void createLocationRequest() { 

     mLocationRrequest = new LocationRequest(); 

     mLocationRrequest.setInterval(UPDATE_INTERVAL); 
     mLocationRrequest.setFastestInterval(FASTEST_INTERVAL); 
     mLocationRrequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     mLocationRrequest.setSmallestDisplacement(DSIPLACEMENT_UPDATES); 

    } 


    private void methodToCalculateWaitingTime() { 


     if (handler1 != null) { 
      handler1.removeCallbacks(runable1); 

     } 


     Log.e("Here", "here1"); 
     handler1 = new Handler(Looper.getMainLooper()); 
     runable1 = new Runnable() { 
      public void run() { 

       Log.e("Here", "here2:" + mLastLocation.getSpeed()); 


       if (mLastLocation != null) { 
        diaplayViews(); 
        if ((mLastLocation.getSpeed() == 0.0)) { 

         increaseTime(); 

        } else { 
         if (waitingTime <= 120) { 
          waiting2min = 0; 

         } 
        } 
        handler1.postDelayed(this, 10000); 
       } else { 
        if (ActivityCompat.checkSelfPermission(MyService.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MyService.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
         // TODO: Consider calling 
         // ActivityCompat#requestPermissions 
         // here to request the missing permissions, and then overriding 
         // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
         //           int[] grantResults) 
         // to handle the case where the user grants the permission. See the documentation 
         // for ActivityCompat#requestPermissions for more details. 
         return; 
        } 

        locationOld = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
        mLastLocation = locationOld; 

       } 
      } 
     }; 

     handler1.postDelayed(runable1, 10000); 


    } 

    private void diaplayViews() { 
     float price = (float) (14 + distance * 0.5); 

     //textDistance.setText(waitingTime);a 
    } 


    private void increaseTime() { 
     waiting2min = waiting2min + 10; 
     if (waiting2min >= 120) 

     { 
      if (waiting2min == 120) { 
       waitingTime = waitingTime + 2 * 60; 


      } else { 
       waitingTime = waitingTime + 10; 
      } 


      totalWaiting = waitingTime/60; 
      showNotification(); 
      Log.e("waiting Time", "increaseTime: " + totalWaiting); 
     } 


    } 

    @Override 
    public void onDestroy() { 
     Toast.makeText(MyService.this, "distroyed", Toast.LENGTH_SHORT).show(); 
     if (mGoogleApiClient.isConnected()) { 

      mGoogleApiClient.disconnect(); 
     } 
     mGoogleApiClient.disconnect(); 

    } 

    @Override 
    public void onConnected(Bundle bundle) { 
     Log.e("Connection_fusion", "connected"); 

     startLocationUpdates(); 


    } 


    @Override 
    public void onConnectionSuspended(int i) { 

    } 

    private void startLocationUpdates() { 
     Location location = plotTheInitialMarkerAndGetInitialGps(); 
     if (location == null) { 
      plotTheInitialMarkerAndGetInitialGps(); 


     } else { 

      mLastLocation = location; 
      methodToCalculateWaitingTime(); 
     } 
    } 

    private Location plotTheInitialMarkerAndGetInitialGps() { 
     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      // TODO: Consider calling 
      // ActivityCompat#requestPermissions 
      // here to request the missing permissions, and then overriding 
      // public void onRequestPermissionsResult(int requestCode, String[] permissions, 
      //           int[] grantResults) 
      // to handle the case where the user grants the permission. See the documentation 
      // for ActivityCompat#requestPermissions for more details. 
      return null; 
     } 
     LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRrequest, this); 
     locationOld = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
     if ((locationOld != null)) { 
      mLastLocation = locationOld; 

      timeOld = locationOld.getTime(); 
     } else { 
      startLocationUpdates(); 
     } 

     return mLastLocation; 
    } 


    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) { 
     onStart(intent, startId); 
     Toast.makeText(MyService.this, "start command", Toast.LENGTH_SHORT).show(); 

     sendUpdatesToUI = new Runnable() { 
      public void run() { 
       DisplayLoggingInfo(); 
       handler.postDelayed(this, 10000); // 5 seconds 
      } 
     }; 
     handler.postDelayed(sendUpdatesToUI, 10000); // 1 second 
     Log.i("LocalService", "Received start id " + startId + ": " + intent); 
     return START_NOT_STICKY; 
    } 

    @Override 
    public void onStart(Intent intent, int startId) { 
     sendUpdatesToUI = new Runnable() { 
      public void run() { 
       Log.e("sent", "sent"); 
       DisplayLoggingInfo(); 
       handler.postDelayed(this, 5000); // 5 seconds 
      } 
     }; 
     handler.postDelayed(sendUpdatesToUI, 1000); // 1 second 
     Log.i("LocalService", "Received start id " + startId + ": " + intent); 
     super.onStart(intent, startId); 
    } 

    private void DisplayLoggingInfo() { 
     Log.d(TAG, "entered DisplayLoggingInfo"); 
     intentforBroadcast.putExtra("distance", distance); 
     LocalBroadcastManager.getInstance(this).sendBroadcast(intentforBroadcast); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 

    } 

    @Override 
    public void onMapReady(GoogleMap googleMap) { 

    } 
}