3

GoogleApiClientを使用してロケーションリスナーサービスを実装していますが、バックグラウンドのサービスでもGPSアイコンが常に表示されています。サービスがバックグラウンドにあるときにGPSアイコンを無効にするには?GoogleApiClient:サービスがバックグラウンドにあるときにステータスバーにGPSアイコンを表示しない

enter image description here

以下源従っ:

活性

public class ShowDistanceActivity extends AppCompatActivity implements ILocationConstants { 

protected static final String TAG = ShowDistanceActivity.class.getSimpleName(); 


@Bind(R.id.tvLocationData) 
TextView tvLocationData; 

@Bind(R.id.toolbar) 
Toolbar toolbar; 


/** 
* Receiver listening to Location updates and updating UI in activity 
*/ 
private LocationReceiver locationReceiver; 

/** 
* Permission util with callback mechanism to avoid boilerplate code 
* <p/> 
* https://github.com/kayvannj/PermissionUtil 
*/ 
private PermissionUtil.PermissionRequestObject mBothPermissionRequest; 


@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_show_distance); 

    ButterKnife.bind(this); 

    setSupportActionBar(toolbar); 

    locationReceiver = new LocationReceiver(); 


} 


private void startLocationService() { 

    Intent serviceIntent = new Intent(this, LocationService.class); 
    startService(serviceIntent); 

} 

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

    LocalBroadcastManager.getInstance(this).registerReceiver(locationReceiver, new IntentFilter(LOACTION_ACTION)); 


    /** 
    * Runtime permissions are required on Android M and above to access User's location 
    */ 
    if (AppUtils.hasM() && !(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED 
      && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)) { 

     askPermissions(); 

    } else { 

     startLocationService(); 

    } 

} 

/** 
* Ask user for permissions to access GPS location on Android M 
*/ 
public void askPermissions() { 

    mBothPermissionRequest = 
      PermissionUtil.with(this).request(Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION).onResult(
        new Func2() { 
         @Override 
         protected void call(int requestCode, String[] permissions, int[] grantResults) { 

          if (grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) { 

           startLocationService(); 

          } else { 

           Toast.makeText(ShowDistanceActivity.this, R.string.permission_denied, Toast.LENGTH_LONG).show(); 
          } 
         } 

        }).ask(PERMISSION_ACCESS_LOCATION_CODE); 

} 


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

    LocalBroadcastManager.getInstance(this).unregisterReceiver(locationReceiver); 
} 

private class LocationReceiver extends BroadcastReceiver { 


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


     if (null != intent && intent.getAction().equals(LOACTION_ACTION)) { 

      String locationData = intent.getStringExtra(LOCATION_MESSAGE); 

      tvLocationData.setText(locationData); 
     } 

    } 
} 


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

    if (null != mBothPermissionRequest) { 
     mBothPermissionRequest.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    } 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
} 

}

をサービス

public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener, ILocationConstants, IPreferenceConstants { 


private static final String TAG = LocationService.class.getSimpleName(); 

/** 
* Provides the entry point to Google Play services. 
*/ 
protected GoogleApiClient mGoogleApiClient; 

/** 
* Stores parameters for requests to the FusedLocationProviderApi. 
*/ 
protected LocationRequest mLocationRequest; 

/** 
* Represents a geographical location. 
*/ 
protected Location mCurrentLocation; 


private String mLatitudeLabel; 
private String mLongitudeLabel; 
private String mLastUpdateTimeLabel; 
private String mDistance; 


/** 
* Time when the location was updated represented as a String. 
*/ 
protected String mLastUpdateTime; 

private Location oldLocation; 

private Location newLocation; 


private AppPreferences appPreferences; 

/** 
* Total distance covered 
*/ 
private float distance; 


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

    Log.d(TAG, "onCreate() called"); 

    appPreferences = new AppPreferences(this); 

    oldLocation = new Location("Point A"); 
    newLocation = new Location("Point B"); 

    mLatitudeLabel = getString(R.string.latitude_label); 
    mLongitudeLabel = getString(R.string.longitude_label); 
    mLastUpdateTimeLabel = getString(R.string.last_update_time_label); 
    mDistance = getString(R.string.distance); 

    mLastUpdateTime = ""; 

    distance = appPreferences.getFloat(PREF_DISTANCE, 0); 

    Log.d(TAG, "onCreate Distance: " + distance); 


} 

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

    Log.d(TAG, "onStartCommand called"); 

    buildGoogleApiClient(); 

    mGoogleApiClient.connect(); 

    if (mGoogleApiClient.isConnected()) { 
     startLocationUpdates(); 
    } 

    return Service.START_STICKY; 

} 


/** 
* Builds a GoogleApiClient. Uses the {@code #addApi} method to request the 
* LocationServices API. 
*/ 
protected synchronized void buildGoogleApiClient() { 

    Log.d(TAG, "buildGoogleApiClient() called"); 

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


protected void createLocationRequest() { 

    Log.d(TAG, "createLocationRequest() called"); 

    mLocationRequest = new LocationRequest(); 

    mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS); 

    mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS); 

    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 

    mLocationRequest.setSmallestDisplacement(DISPLACEMENT); 
} 

/** 
* Requests location updates from the FusedLocationApi. 
*/ 
protected void startLocationUpdates() { 

    try { 

     Log.d(TAG, "startLocationUpdates called"); 

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

    } catch (SecurityException ex) { 

     ex.printStackTrace(); 
    } 
} 


/** 
* Updates the latitude, the longitude, and the last location time in the UI. 
*/ 
private void updateUI() { 

    if (null != mCurrentLocation) { 

     StringBuilder sbLocationData = new StringBuilder(); 
     sbLocationData.append(mLatitudeLabel) 
       .append(" ") 
       .append(mCurrentLocation.getLatitude()) 
       .append("\n") 
       .append(mLongitudeLabel) 
       .append(" ") 
       .append(mCurrentLocation.getLongitude()) 
       .append("\n") 
       .append(mLastUpdateTimeLabel) 
       .append(" ") 
       .append(mLastUpdateTime) 
       .append("\n") 
       .append(mDistance) 
       .append(" ") 
       .append(getUpdatedDistance()) 
       .append(" meters"); 


     /* 
     * update preference with latest value of distance 
     */ 
     appPreferences.putFloat(PREF_DISTANCE, distance); 

     Log.d(TAG, "Location Data:\n" + sbLocationData.toString()); 

     sendLocationBroadcast(sbLocationData.toString()); 
    } else { 

     Toast.makeText(this, R.string.unable_to_find_location, Toast.LENGTH_SHORT).show(); 
    } 
} 


/** 
* Send broadcast using LocalBroadcastManager to update UI in activity 
* 
* @param sbLocationData 
*/ 
private void sendLocationBroadcast(String sbLocationData) { 

    Log.d(TAG, "sendLocationBroadcast() called"); 

    Intent locationIntent = new Intent(); 
    locationIntent.setAction(LOACTION_ACTION); 
    locationIntent.putExtra(LOCATION_MESSAGE, sbLocationData); 

    LocalBroadcastManager.getInstance(this).sendBroadcast(locationIntent); 

} 

/** 
* Removes location updates from the FusedLocationApi. 
*/ 
protected void stopLocationUpdates() { 

    Log.d(TAG, "stopLocationUpdates() called"); 

    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
} 


@Override 
public void onDestroy() { 

    Log.d(TAG, "onDestroy() called"); 

    appPreferences.putFloat(PREF_DISTANCE, distance); 

    stopLocationUpdates(); 

    mGoogleApiClient.disconnect(); 

    Log.d(TAG, "onDestroy Distance " + distance); 

    super.onDestroy(); 
} 


/** 
* Runs when a GoogleApiClient object successfully connects. 
*/ 
@Override 
public void onConnected(Bundle connectionHint) throws SecurityException { 
    Log.i(TAG, "Connected to GoogleApiClient"); 


    if (mCurrentLocation == null) { 
     mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
     mLastUpdateTime = DateFormat.getTimeInstance().format(new Date()); 
     updateUI(); 
    } 

    startLocationUpdates(); 

} 

/** 
* Callback that fires when the location changes. 
*/ 
@Override 
public void onLocationChanged(Location location) { 

    Log.d(TAG, "onLocationChanged() called"); 

    mCurrentLocation = location; 
    mLastUpdateTime = DateFormat.getTimeInstance().format(new Date()); 
    updateUI(); 
} 

@Override 
public void onConnectionSuspended(int cause) { 

    Log.d(TAG, "onConnectionSuspended() called"); 

    mGoogleApiClient.connect(); 
} 

@Override 
public void onConnectionFailed(ConnectionResult result) { 

    Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode()); 
} 


private float getUpdatedDistance() { 

    /** 
    * There is 68% chance that user is with in 100m from this location. 
    * So neglect location updates with poor accuracy 
    */ 


    if (mCurrentLocation.getAccuracy() > ACCURACY_THRESHOLD) { 

     Log.d(TAG, "getUpdatedDistance() called"); 

     return distance; 
    } 


    if (oldLocation.getLatitude() == 0 && oldLocation.getLongitude() == 0) { 

     oldLocation.setLatitude(mCurrentLocation.getLatitude()); 
     oldLocation.setLongitude(mCurrentLocation.getLongitude()); 

     newLocation.setLatitude(mCurrentLocation.getLatitude()); 
     newLocation.setLongitude(mCurrentLocation.getLongitude()); 

     return distance; 
    } else { 

     oldLocation.setLatitude(newLocation.getLatitude()); 
     oldLocation.setLongitude(newLocation.getLongitude()); 

     newLocation.setLatitude(mCurrentLocation.getLatitude()); 
     newLocation.setLongitude(mCurrentLocation.getLongitude()); 

    } 


    /** 
    * Calculate distance between last two geo locations 
    */ 
    distance += newLocation.distanceTo(oldLocation); 

    return distance; 
} 


@Override 
public IBinder onBind(Intent intent) { 

    throw new UnsupportedOperationException("Not yet implemented"); 
} 

}

マニフェスト

Androidのマニフェスト宣言

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.technosavy.showmedistance"> 
    <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=".ShowDistanceActivity" 
      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> 


     <service 
      android:name=".service.LocationService" 
      android:enabled="true" 
      android:exported="true"></service> 

    </application> 

</manifest> 

、任意のヘルプは大歓迎ですしてください。

+0

これはセキュリティ機能であり、隠蔽することはできません。幸せに修正しましたが、これは私が理解するものです。 – Tigger

+0

こんにちはTigger! ( – vinidog

+1

'PRIORITY_NO_POWER'や' PRIORITY_LOW_POWER'で 'android.permission.ACCESS_COARSE_LOCATION'のパーミッション設定を使用しています。ユーザーにとって大まかな場所だけが必要な場合は問題ありません – Tigger

答えて

2

GPSアイコンを削除するには、キャッシュされたWi-Fiロケーションの設定(メモリから)を使用する必要があります。あなたのコードで以下の変更を加えます。マニフェストに

を削除します。

サービスで
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 

、次のように変更します。これは

mLocationRequest.setInterval(10000L); 
mLocationRequest.setFastestInterval(5000L); 
// Do NOT use LocationRequest.PRIORITY_HIGH_ACCURACY here 
// Instead use one of the other option. 
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 
//mLocationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER); 
//mLocationRequest.setPriority(LocationRequest.PRIORITY_NO_POWER); 
// Remove setSmallestDisplacement() as it should not be used 
// unless you are using a GPS/PRIORITY_HIGH_ACCURACY 
//mLocationRequest.setSmallestDisplacement(DISPLACEMENT); 

かなり確信しては、GPSアイコンを削除しますが、あなたはまた、唯一のFusedLocationApi.getLastLocation()の値を取得しますonConnected()メソッドが呼び出されたとき(非常に可能性がありますが、精度は低くなります)。

onLocationChanged()方法は、別のアプリケーションがより高い優先度で、またはより正確に位置要求を行うまで、決してトリガーしません。

+0

Tnxたくさん、私は2日間それに固執しました – vinidog

+1

幸せに役立ちますこれらの設定を使用すると、正確な位置精度が得られることに注意してください。 – Tigger

1

新しい融合位置プロバイダは、以前の方法とは少し異なるアプローチを採用しています。開発者は、デバイスの構成要素を計算するために使用される代わりに、現在の位置を計算するために使用されるバッテリ電力の量を選択します。使用可能なGPS、Wi-Fi、モバイルネットワーク、およびオンボードセンサーの組み合わせを使用して場所を計算します。

なLocationRequestの優先順位の設定は次のようになります。

PRIORITY_NO_POWER(受動的に他のクライアントからの位置情報の更新をリスニング) PRIORITY_LOW_POWER(〜10キロ "都市" 精度) PRIORITY_BALANCED_POWER_ACCURACY(〜100メートル "ブロック" 精度) PRIORITY_HIGH_ACCURACY(正確できるだけバッテリ寿命を犠牲にして) GoogleはLocationRequestクラスをここに記述しています:http://developer.android.com/reference/com/google/android/gms/location/LocationRequest.html

関連する問題