在Android中获取用户GPS位置的最佳方式
在我的Android应用程序中,我想每隔几分钟获取用户当前位置,并使用Web服务更新到我的中心服务器。 目前我正在使用Fused Location Provide获取用户当前位置,请参阅链接
现在我想知道什么是经常获取用户位置和调用Web服务的最佳方式。
下面是我的代码,它给了我用户当前的位置: –
locationrequest = LocationRequest.create(); locationrequest.setInterval(10000); locationclient.requestLocationUpdates(locationrequest,new com.google.android.gms.location.LocationListener() { @Override public void onLocationChanged(Location location) { Log.i(TAG, "Last Known Location :" + location.getLatitude() + "," + location.getLongitude()); } });
现在从哪里我必须调用这个代码。 我可以在后台服务或其他地方使用它。
请提供你的想法。
TIA。
您需要使用Service
:
import android.app.Service; import android.content.Context; import android.content.Intent; import android.location.Location; import android.location.LocationManager; import android.os.Bundle; import android.os.IBinder; import android.util.Log; public class MyService extends Service { private static final String TAG = "BOOMBOOMTESTGPS"; private LocationManager mLocationManager = null; private static final int LOCATION_INTERVAL = 1000; private static final float LOCATION_DISTANCE = 10f; private class LocationListener implements android.location.LocationListener { Location mLastLocation; public LocationListener(String provider) { Log.e(TAG, "LocationListener " + provider); mLastLocation = new Location(provider); } @Override public void onLocationChanged(Location location) { Log.e(TAG, "onLocationChanged: " + location); mLastLocation.set(location); } @Override public void onProviderDisabled(String provider) { Log.e(TAG, "onProviderDisabled: " + provider); } @Override public void onProviderEnabled(String provider) { Log.e(TAG, "onProviderEnabled: " + provider); } @Override public void onStatusChanged(String provider, int status, Bundle extras) { Log.e(TAG, "onStatusChanged: " + provider); } } LocationListener[] mLocationListeners = new LocationListener[] { new LocationListener(LocationManager.GPS_PROVIDER), new LocationListener(LocationManager.NETWORK_PROVIDER) }; @Override public IBinder onBind(Intent arg0) { return null; } @Override public int onStartCommand(Intent intent, int flags, int startId) { Log.e(TAG, "onStartCommand"); super.onStartCommand(intent, flags, startId); return START_STICKY; } @Override public void onCreate() { Log.e(TAG, "onCreate"); initializeLocationManager(); try { mLocationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, mLocationListeners[1]); } catch (java.lang.SecurityException ex) { Log.i(TAG, "fail to request location update, ignore", ex); } catch (IllegalArgumentException ex) { Log.d(TAG, "network provider does not exist, " + ex.getMessage()); } try { mLocationManager.requestLocationUpdates( LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE, mLocationListeners[0]); } catch (java.lang.SecurityException ex) { Log.i(TAG, "fail to request location update, ignore", ex); } catch (IllegalArgumentException ex) { Log.d(TAG, "gps provider does not exist " + ex.getMessage()); } } @Override public void onDestroy() { Log.e(TAG, "onDestroy"); super.onDestroy(); if (mLocationManager != null) { for (int i = 0; i < mLocationListeners.length; i++) { try { mLocationManager.removeUpdates(mLocationListeners[i]); } catch (Exception ex) { Log.i(TAG, "fail to remove location listners, ignore", ex); } } } } private void initializeLocationManager() { Log.e(TAG, "initializeLocationManager"); if (mLocationManager == null) { mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE); } } }
你的AndroidManifest.xml
如下所示:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:label="@string/app_name" android:name=".LocationCheckerActivity" > <intent-filter > <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyService" android:process=":my_service" /> </application>
使用: GCMnetworkingpipe理器
运行这个来启动一个周期性的任务,即使在重新启动后也会运行:
PeriodicTask task = new PeriodicTask.Builder() .setService(MyLocationService.class) .setTag("periodic") .setPeriod(30L) .setPersisted(true) .build(); mGcmNetworkManager.schedule(task);
然后在onRunTask()获取当前位置并使用它(在这个例子中,最后提交的事件,让UI知道位置被发现):
public void getLastKnownLocation() { Location lastKnownGPSLocation; Location lastKnownNetworkLocation; String gpsLocationProvider = LocationManager.GPS_PROVIDER; String networkLocationProvider = LocationManager.NETWORK_PROVIDER; try { locationManager = (LocationManager) App.get().getSystemService(Context.LOCATION_SERVICE); lastKnownNetworkLocation = locationManager.getLastKnownLocation(networkLocationProvider); lastKnownGPSLocation = locationManager.getLastKnownLocation(gpsLocationProvider); if (lastKnownGPSLocation != null) { Log.i(TAG, "lastKnownGPSLocation is used."); this.mCurrentLocation = lastKnownGPSLocation; } else if (lastKnownNetworkLocation != null) { Log.i(TAG, "lastKnownNetworkLocation is used."); this.mCurrentLocation = lastKnownNetworkLocation; } else { Log.e(TAG, "lastLocation is not known."); return; } LocationChangedEvent event = new LocationChangedEvent(); event.setLocation(mCurrentLocation); EventHelper.publishEvent(event); } catch (SecurityException sex) { Log.e(TAG, "Location permission is not granted!"); } return; }
整个MyLocationService:
public class MyLocationService extends GcmTaskService { private static final String TAG = MyLocationService.class.getSimpleName(); private LocationManager locationManager; private Location mCurrentLocation; public static final String TASK_GET_LOCATION_ONCE="location_oneoff_task"; public static final String TASK_GET_LOCATION_PERIODIC="location_periodic_task"; private static final int RC_PLAY_SERVICES = 123; @Override public void onInitializeTasks() { // When your package is removed or updated, all of its network tasks are cleared by // the GcmNetworkManager. You can override this method to reschedule them in the case of // an updated package. This is not called when your application is first installed. // // This is called on your application's main thread. startPeriodicLocationTask(TASK_GET_LOCATION_PERIODIC, 30L, null); } @Override public int onRunTask(TaskParams taskParams) { Log.d(TAG, "onRunTask: " + taskParams.getTag()); String tag = taskParams.getTag(); Bundle extras = taskParams.getExtras(); // Default result is success. int result = GcmNetworkManager.RESULT_SUCCESS; switch (tag) { case TASK_GET_LOCATION_ONCE: getLastKnownLocation(); break; case TASK_GET_LOCATION_PERIODIC: getLastKnownLocation(); break; } return result; } public void getLastKnownLocation() { Location lastKnownGPSLocation; Location lastKnownNetworkLocation; String gpsLocationProvider = LocationManager.GPS_PROVIDER; String networkLocationProvider = LocationManager.NETWORK_PROVIDER; try { locationManager = (LocationManager) App.get().getSystemService(Context.LOCATION_SERVICE); lastKnownNetworkLocation = locationManager.getLastKnownLocation(networkLocationProvider); lastKnownGPSLocation = locationManager.getLastKnownLocation(gpsLocationProvider); if (lastKnownGPSLocation != null) { Log.i(TAG, "lastKnownGPSLocation is used."); this.mCurrentLocation = lastKnownGPSLocation; } else if (lastKnownNetworkLocation != null) { Log.i(TAG, "lastKnownNetworkLocation is used."); this.mCurrentLocation = lastKnownNetworkLocation; } else { Log.e(TAG, "lastLocation is not known."); return; } LocationChangedEvent event = new LocationChangedEvent(); event.setLocation(mCurrentLocation); EventHelper.publishEvent(event); } catch (SecurityException sex) { Log.e(TAG, "Location permission is not granted!"); } return; } public static void startOneOffLocationTask(String tag, Bundle extras) { Log.d(TAG, "startOneOffLocationTask"); GcmNetworkManager mGcmNetworkManager = GcmNetworkManager.getInstance(App.get()); OneoffTask.Builder taskBuilder = new OneoffTask.Builder() .setService(MyLocationService.class) .setTag(tag); if (extras != null) taskBuilder.setExtras(extras); OneoffTask task = taskBuilder.build(); mGcmNetworkManager.schedule(task); } public static void startPeriodicLocationTask(String tag, Long period, Bundle extras) { Log.d(TAG, "startPeriodicLocationTask"); GcmNetworkManager mGcmNetworkManager = GcmNetworkManager.getInstance(App.get()); PeriodicTask.Builder taskBuilder = new PeriodicTask.Builder() .setService(MyLocationService.class) .setTag(tag) .setPeriod(period) .setPersisted(true) .setRequiredNetwork(Task.NETWORK_STATE_CONNECTED); if (extras != null) taskBuilder.setExtras(extras); PeriodicTask task = taskBuilder.build(); mGcmNetworkManager.schedule(task); } public static boolean checkPlayServicesAvailable(Activity activity) { GoogleApiAvailability availability = GoogleApiAvailability.getInstance(); int resultCode = availability.isGooglePlayServicesAvailable(App.get()); if (resultCode != ConnectionResult.SUCCESS) { if (availability.isUserResolvableError(resultCode)) { // Show dialog to resolve the error. availability.getErrorDialog(activity, resultCode, RC_PLAY_SERVICES).show(); } return false; } else { return true; } }
还要将这2个添加到AndroidManifest.xml中:
<manifest... <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <application... <service android:name=".api.location.MyLocationService" android:exported="true" android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE"> <intent-filter> <action android:name="com.google.android.gms.gcm.ACTION_TASK_READY" /> </intent-filter> </service>
没有其他答案使用:
com.google.android.gms.location.FusedLocationProviderClient
这是融合的位置提供商,也是Google与融合的位置提供商交互的主要入口点,很难find一个好例子。 这是谷歌2017年中期发布的。
Google Play服务位置API优先于Android框架位置API(android.location)
如果您目前正在使用Android框架位置API,则强烈build议您尽快切换到Google Play服务位置API。
为了使用Google Location API,首先将其添加到您的build.gradle
compile 'com.google.android.gms:play-services:11.0.0'
那么你可以使用这个类Wherebouts.java
:
import android.location.Location; import android.os.Looper; import android.util.Log; import com.google.android.gms.location.FusedLocationProviderClient; import com.google.android.gms.location.LocationCallback; import com.google.android.gms.location.LocationRequest; import com.google.android.gms.location.LocationResult; import com.google.android.gms.location.LocationServices; import com.google.android.gms.location.LocationSettingsRequest; /** * Uses Google Play API for obtaining device locations * Created by alejandro.tkachuk * alejandro@calculistik.com * www.calculistik.com Mobile Development */ public class Wherebouts { private static final Wherebouts instance = new Wherebouts(); private static final String TAG = Wherebouts.class.getSimpleName(); private FusedLocationProviderClient mFusedLocationClient; private LocationCallback locationCallback; private LocationRequest locationRequest; private LocationSettingsRequest locationSettingsRequest; private Workable<GPSPoint> workable; private static final long UPDATE_INTERVAL_IN_MILLISECONDS = 1000; private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = 1000; private Wherebouts() { this.locationRequest = new LocationRequest(); this.locationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS); this.locationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS); this.locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder(); builder.addLocationRequest(this.locationRequest); this.locationSettingsRequest = builder.build(); this.locationCallback = new LocationCallback() { @Override public void onLocationResult(LocationResult locationResult) { super.onLocationResult(locationResult); // why? this. is. retarded. Android. Location currentLocation = locationResult.getLastLocation(); GPSPoint gpsPoint = new GPSPoint(currentLocation.getLatitude(), currentLocation.getLongitude()); Log.i(TAG, "Location Callback results: " + gpsPoint); if (null != workable) workable.work(gpsPoint); } }; this.mFusedLocationClient = LocationServices.getFusedLocationProviderClient(MainApplication.getAppContext()); this.mFusedLocationClient.requestLocationUpdates(this.locationRequest, this.locationCallback, Looper.myLooper()); } public static Wherebouts instance() { return instance; } public void onChange(Workable<GPSPoint> workable) { this.workable = workable; } public LocationSettingsRequest getLocationSettingsRequest() { return this.locationSettingsRequest; } public void stop() { Log.i(TAG, "stop() Stopping location tracking"); this.mFusedLocationClient.removeLocationUpdates(this.locationCallback); } }
从你的Activity中,你可以像这样使用它,通过传递一个Workable
对象。 可操作的对象只不过是一个自定义的callback对象。
Wherebouts.instance().onChange(workable);
通过使用类似于Workable的callback,您将在您的Activity中编写与UI相关的代码,并将使用GPS的忙碌工作交给助手类(如Wherebouts)。
new Workable<GPSPoint>() { @Override public void work(GPSPoint gpsPoint) { // draw something in the UI with this new data } };
当然,您需要向Android操作系统请求相应的权限以供您的应用程序使用。 你可以阅读下面的文档,以获得更多关于这方面的信息,或做一些研究。
从这里下载源代码( 使用后台服务获取当前位置 )
AndroidManifest.xml中
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="servicetutorial.service"> <uses-permission android:name="android.permission.INTERNET"></uses-permission> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission> <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:theme="@android:style/Theme.Translucent.NoTitleBar"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".GoogleService"></service> </application> </manifest>
activity_main.xml中
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:background="#ffffff" android:layout_height="match_parent"> <TextView android:layout_width="match_parent" android:layout_height="50dp" android:background="#3F51B5" android:text="Location using service" android:textColor="#ffffff" android:textSize="20dp" android:gravity="center"/> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerInParent="true" android:orientation="vertical"> <LinearLayout android:layout_width="match_parent" android:orientation="horizontal" android:layout_height="50dp"> <TextView android:layout_width="150dp" android:layout_height="wrap_content" android:text="Latitude" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:textColor="#000000" android:textSize="20dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" android:id="@+id/tv_latitude" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:textColor="#000000" android:textSize="20dp"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:orientation="horizontal" android:layout_height="50dp"> <TextView android:layout_width="150dp" android:layout_height="wrap_content" android:text="Longitude" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:textColor="#000000" android:textSize="20dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" android:id="@+id/tv_longitude" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:textColor="#000000" android:textSize="20dp"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:orientation="horizontal" android:layout_height="50dp"> <TextView android:layout_width="150dp" android:layout_height="wrap_content" android:text="Address" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:textColor="#000000" android:textSize="20dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" android:id="@+id/tv_address" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:textColor="#000000" android:textSize="20dp"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:orientation="horizontal" android:layout_height="50dp"> <TextView android:layout_width="150dp" android:layout_height="wrap_content" android:text="Area" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:textColor="#000000" android:textSize="20dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" android:id="@+id/tv_area" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:textColor="#000000" android:textSize="20dp"/> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:orientation="horizontal" android:layout_height="50dp"> <TextView android:layout_width="150dp" android:layout_height="wrap_content" android:text="Locality" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:textColor="#000000" android:textSize="20dp"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="" android:id="@+id/tv_locality" android:layout_gravity="center_vertical" android:layout_marginLeft="10dp" android:textColor="#000000" android:textSize="20dp"/> </LinearLayout> </LinearLayout> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/btn_start" android:text="Get Location" android:layout_alignParentBottom="true"/> </RelativeLayout>
MainActivity.java
package servicetutorial.service; import android.*; import android.app.Activity; import android.app.ActivityManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.location.Address; import android.location.Geocoder; import android.preference.PreferenceManager; import android.renderscript.Double2; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import java.io.IOException; import java.util.List; import java.util.Locale; public class MainActivity extends Activity { Button btn_start; private static final int REQUEST_PERMISSIONS = 100; boolean boolean_permission; TextView tv_latitude, tv_longitude, tv_address,tv_area,tv_locality; SharedPreferences mPref; SharedPreferences.Editor medit; Double latitude,longitude; Geocoder geocoder; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); btn_start = (Button) findViewById(R.id.btn_start); tv_address = (TextView) findViewById(R.id.tv_address); tv_latitude = (TextView) findViewById(R.id.tv_latitude); tv_longitude = (TextView) findViewById(R.id.tv_longitude); tv_area = (TextView)findViewById(R.id.tv_area); tv_locality = (TextView)findViewById(R.id.tv_locality); geocoder = new Geocoder(this, Locale.getDefault()); mPref = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()); medit = mPref.edit(); btn_start.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (boolean_permission) { if (mPref.getString("service", "").matches("")) { medit.putString("service", "service").commit(); Intent intent = new Intent(getApplicationContext(), GoogleService.class); startService(intent); } else { Toast.makeText(getApplicationContext(), "Service is already running", Toast.LENGTH_SHORT).show(); } } else { Toast.makeText(getApplicationContext(), "Please enable the gps", Toast.LENGTH_SHORT).show(); } } }); fn_permission(); } private void fn_permission() { if ((ContextCompat.checkSelfPermission(getApplicationContext(), android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)) { if ((ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.ACCESS_FINE_LOCATION))) { } else { ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION }, REQUEST_PERMISSIONS); } } else { boolean_permission = true; } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); switch (requestCode) { case REQUEST_PERMISSIONS: { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { boolean_permission = true; } else { Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show(); } } } } private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { latitude = Double.valueOf(intent.getStringExtra("latutide")); longitude = Double.valueOf(intent.getStringExtra("longitude")); List<Address> addresses = null; try { addresses = geocoder.getFromLocation(latitude, longitude, 1); String cityName = addresses.get(0).getAddressLine(0); String stateName = addresses.get(0).getAddressLine(1); String countryName = addresses.get(0).getAddressLine(2); tv_area.setText(addresses.get(0).getAdminArea()); tv_locality.setText(stateName); tv_address.setText(countryName); } catch (IOException e1) { e1.printStackTrace(); } tv_latitude.setText(latitude+""); tv_longitude.setText(longitude+""); tv_address.getText(); } }; @Override protected void onResume() { super.onResume(); registerReceiver(broadcastReceiver, new IntentFilter(GoogleService.str_receiver)); } @Override protected void onPause() { super.onPause(); unregisterReceiver(broadcastReceiver); } }
GoogleService.java
package servicetutorial.service; import android.app.Service; import android.content.Context; import android.content.Intent; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.support.annotation.Nullable; import android.util.Log; import java.util.Timer; import java.util.TimerTask; /** * Created by deepshikha on 24/11/16. */ public class GoogleService extends Service implements LocationListener{ boolean isGPSEnable = false; boolean isNetworkEnable = false; double latitude,longitude; LocationManager locationManager; Location location; private Handler mHandler = new Handler(); private Timer mTimer = null; long notify_interval = 1000; public static String str_receiver = "servicetutorial.service.receiver"; Intent intent; public GoogleService() { } @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); mTimer = new Timer(); mTimer.schedule(new TimerTaskToGetLocation(),5,notify_interval); intent = new Intent(str_receiver); // fn_getlocation(); } @Override public void onLocationChanged(Location location) { } @Override public void onStatusChanged(String provider, int status, Bundle extras) { } @Override public void onProviderEnabled(String provider) { } @Override public void onProviderDisabled(String provider) { } private void fn_getlocation(){ locationManager = (LocationManager)getApplicationContext().getSystemService(LOCATION_SERVICE); isGPSEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); isNetworkEnable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER); if (!isGPSEnable && !isNetworkEnable){ }else { if (isNetworkEnable){ location = null; locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,1000,0,this); if (locationManager!=null){ location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); if (location!=null){ Log.e("latitude",location.getLatitude()+""); Log.e("longitude",location.getLongitude()+""); latitude = location.getLatitude(); longitude = location.getLongitude(); fn_update(location); } } } if (isGPSEnable){ location = null; locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,1000,0,this); if (locationManager!=null){ location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); if (location!=null){ Log.e("latitude",location.getLatitude()+""); Log.e("longitude",location.getLongitude()+""); latitude = location.getLatitude(); longitude = location.getLongitude(); fn_update(location); } } } } } private class TimerTaskToGetLocation extends TimerTask{ @Override public void run() { mHandler.post(new Runnable() { @Override public void run() { fn_getlocation(); } }); } } private void fn_update(Location location){ intent.putExtra("latutide",location.getLatitude()+""); intent.putExtra("longitude",location.getLongitude()+""); sendBroadcast(intent); } }
添加这个依赖
编译'com.google.android.gms:play-services:9.4.0'
你必须创build服务。这个服务应该实现LocationListener。 那么您必须在一定的时间限制内重复使用AlarmManager来拨打服务。
我希望这一个将帮助你:)
我已经尝试我的代码,并成功尝试这一点
package com.mobeyosoft.latitudelongitude; import android.app.Service; import android.content.Context; import android.content.Intent; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.widget.Toast; /** * Created by 5943 6417 on 14-09-2016. */ public class LocationService extends Service { public static final String BROADCAST_ACTION = "Hello World"; private static final int TWO_MINUTES = 1000 * 60 * 1; public LocationManager locationManager; public MyLocationListener listener; public Location previousBestLocation = null; Context context; Intent intent; int counter = 0; @Override public void onCreate() { super.onCreate(); intent = new Intent(BROADCAST_ACTION); context=this; } @Override public void onStart(Intent intent, int startId) { locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE); listener = new MyLocationListener(); locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 4000, 0, listener); locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener); } @Override public IBinder onBind(Intent intent){ return null; } protected 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 > TWO_MINUTES; boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES; 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; } /** Checks whether two providers are the same */ private boolean isSameProvider(String provider1, String provider2) { if (provider1 == null) { return provider2 == null; } return provider1.equals(provider2); } @Override public void onDestroy() { // handler.removeCallbacks(sendUpdatesToUI); super.onDestroy(); Log.v("STOP_SERVICE", "DONE"); locationManager.removeUpdates(listener); } public static Thread performOnBackgroundThread(final Runnable runnable) { final Thread t = new Thread() { @Override public void run() { try { runnable.run(); } finally { } } }; t.start(); return t; } public class MyLocationListener implements LocationListener{ public void onLocationChanged(final Location loc) { Log.i("**********", "Location changed"); if(isBetterLocation(loc, previousBestLocation)) { loc.getLatitude(); loc.getLongitude(); Toast.makeText(context, "Latitude" + loc.getLatitude() + "\nLongitude"+loc.getLongitude(),Toast.LENGTH_SHORT).show(); intent.putExtra("Latitude", loc.getLatitude()); intent.putExtra("Longitude", loc.getLongitude()); intent.putExtra("Provider", loc.getProvider()); sendBroadcast(intent); } } public void onProviderDisabled(String provider) { Toast.makeText( getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT ).show(); } public void onProviderEnabled(String provider) { Toast.makeText( getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show(); } public void onStatusChanged(String provider, int status, Bundle extras) { } } }
您可以使用服务和报警pipe理器对其进行归档,但要小心,因为如果您设置了高优先级,则会耗尽电话的电池,另一方面,您是否真的需要每分钟通知一次? 这是因为要看到用户位置发生相当大的变化的唯一方法,就是在汽车或火车上旅行。 我只问,因为这将取决于你的应用程序和跟踪的要求。
那么创build一个扩展Service的类,这个服务将包含你的Location监听器类(Fused Location Provider),这个服务的目的是定期获取位置,像这样
public class LocationGetter extends Service { ...... public class MyLocationListener implements GooglePlayServicesClient.ConnectionCallbacks,GooglePlayServicesClient.OnConnectionFailedListener,LocationListener, com.google.android.gms.location.LocationListener { //your fused Location provider code } ...... }
然后创build一个扩展广播接收器的类,这样广播接收器的目的是检查服务是否活着如果不重新启动服务,即使在电话开/关….
注册接收器在你的活动,听广播,取消接收器取决于你的需要…
在LocationChange上获得callback
定义一个接口
public interface LocationCallback { public void locationChanged(Location location); }
callback您的活动
public static LocationCallback callback; public void getUserLocation() { callback = new LocationCallback() { @Override public void locationChanged(Location location) { Toast.makeText(getApplicationContext(), location.getLatitude() + "," + location.getLongitude(), Toast.LENGTH_SHORT).show(); } }; Intent service_intent = new Intent(this, GPSService.class); startService(service_intent); }
将onLocationChange方法更改为
@Override public void onLocationChanged(Location location) { Log.e(TAG, "onLocationChanged: " + location); MapsActivity.callback.locationChanged(location); mLastLocation.set(location); }
startService(新的意图(HomePageActivity.this,MyService.class));
为了跟踪每10分钟(根据要求)的位置,请按照此链接工作正常,没有任何问题
https://github.com/safetysystemtechnology/location-tracker-background
借助GoogleApiClient的LocationServices API,我们可以在特定的时间间隔内获取用户/设备的当前位置。 这可以被添加到后台服务,当onLocationChangedcallback时更新Activity
只要应用程序存在内存中,后台服务就会继续运行,并粘贴到通知抽屉中。 该服务处理以下function,
- 连接到Google LocationServices API
- 获取当前位置
- 将结果分享给活动
服务与位置监听器
public class LocationMonitoringService extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { ... ... ... @Override public int onStartCommand(Intent intent, int flags, int startId) { mLocationClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); mLocationRequest.setInterval(10000); //10 secs mLocationRequest.setFastestInterval(5000); //5 secs int priority = LocationRequest.PRIORITY_HIGH_ACCURACY; //by default //PRIORITY_BALANCED_POWER_ACCURACY, PRIORITY_LOW_POWER, PRIORITY_NO_POWER are the other priority modes mLocationRequest.setPriority(priority); mLocationClient.connect(); //Make it stick to the notification panel so it is less prone to get cancelled by the Operating System. return START_STICKY; } @Nullable @Override public IBinder onBind(Intent intent) { return null; } /* * LOCATION CALLBACKS */ @Override public void onConnected(Bundle dataBundle) { 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. Log.d(TAG, "== Error On onConnected() Permission not granted"); //Permission not granted by user so cancel the further execution. return; } LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, mLocationRequest, this); Log.d(TAG, "Connected to Google API"); } /* * Called by Location Services if the connection to the * location client drops because of an error. */ @Override public void onConnectionSuspended(int i) { Log.d(TAG, "Connection suspended"); } @Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.d(TAG, "Failed to connect to Google API"); } //to get the location change @Override public void onLocationChanged(Location location) { Log.d(TAG, "Location changed"); if (location != null) { //Do something with the location details, if (location != null) { //call your API callAPI(String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude())); } } } }
请参阅完整教程使用源代码和详细解释>>
- Android SQLiteDatabase中的游标大小限制
- Android – build立通知,TaskStackBuilder.addParentStack不能正常工作
- 如何在Google地图应用中将Android工具栏菜单/图标alignment到左侧?
- 什么是Android PendingIntent?
- Android中使用的SQLite版本?
- 测量在canvas上绘制的文本高度(Android)
- 在PreferenceActivity中使用什么而不是“addPreferencesFromResource”?
- 为什么RxJava经常与改造一起使用?
- Genymotion设备不出现在设备select器 – Android Studio上