android中的高效gps服务

Posted

技术标签:

【中文标题】android中的高效gps服务【英文标题】:efficient gps service in android 【发布时间】:2012-09-12 17:13:28 【问题描述】:

我在这里搜索了一个想法来构建一个在后台服务中运行的高效位置搜索。我找到了这个链接Energy efficient GPS tracking,但这不是我要找的。我正在寻找一个简单的解决方案,以米为单位检查距离,然后知道用户是靠近还是远离目标位置,然后节省电池寿命。我不希望时间维度在这个算法中只有距离有效。

注意:我拥有所有正确的权限。 这是我的代码(在服务中运行):

public class LocationService extends Service

    private static final int SLEEP = 250;
    private static final int VIBRATE = 500;

    private double targetLat;
    private double targetLng;
    private LocationManager manager;
    private boolean alarm;
    private String ring;
    private Uri soundUri;
    private long [] pattern;        
    private float minDistance;

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

    @SuppressWarnings("static-access")
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
        targetLat = Double.parseDouble(settings.getString("lat", "0"));
        targetLng = Double.parseDouble(settings.getString("lng", "0"));
        targetLat = targetLat / 1E6;
        targetLng = targetLng / 1E6;
        alarm = settings.getBoolean("alarm", true);
        ring = settings.getString("ringDet", "");
        if(ring != "")
            soundUri = Uri.parse(ring);         
        

        manager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
        manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, minDistance, location);
        manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, minDistance, location);

        pattern = new long[200];
        pattern[0] = 0;
        for(int i = 1; i < pattern.length; i++)
            if(i % 2 != 0)
                pattern[i] = SLEEP;
            
            else
                pattern[i] = VIBRATE;
            
        

        //return super.onStartCommand(intent, flags, startId);
        return super.START_STICKY;
       

    LocationListener location = new LocationListener() 

        public void onStatusChanged(String provider, int status, Bundle extras) 
        public void onProviderEnabled(String provider)        
        public void onProviderDisabled(String provider) 

        @SuppressWarnings("deprecation")
        public void onLocationChanged(Location location) 
            float [] results = new float [3];

            Location.distanceBetween(targetLat, targetLng, location.getLatitude(), location.getLongitude(), results);

            float distance = results[0];

            if(distance > 20000)
                minDistance = 15000;
                toaster(">20000");
                manager.removeUpdates(this);
            
            else if(distance > 10000)
                minDistance = 5000;
                toaster(">10000");
                manager.removeUpdates(this);
            
            else if(distance > 5000)
                minDistance = 2500;
                toaster(">5000");
                manager.removeUpdates(this);
            
            else if(distance > 2500)
                minDistance = 1000;
                toaster(">2500");
                manager.removeUpdates(this);
            
            else if(distance > 1000)
                minDistance = 0;
                toaster(">1000");               
            

            if(distance < 800 && alarm)                
                Notification notification = new Notification(R.drawable.ic_launcher, "WakeApp", System.currentTimeMillis());
                Intent notificationIntent = new Intent(getApplicationContext(),MainActivity.class);

                PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(), 0, notificationIntent, 0);
                notification.setLatestEventInfo(getApplicationContext(), getApplicationContext().getResources().getString(R.string.notification_message), "", contentIntent);

                NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);

                //notification.defaults |= Notification.DEFAULT_VIBRATE;
                notification.defaults |= Notification.DEFAULT_LIGHTS;       
                notification.icon = R.drawable.ic_launcher;         

                if(soundUri != null)
                    notification.sound = soundUri;
                
                else if(soundUri == null)
                    soundUri = RingtoneManager.getActualDefaultRingtoneUri(getApplicationContext(), RingtoneManager.TYPE_ALARM);
                    notification.sound = soundUri;
                                                                                                   

                notification.vibrate = pattern;

                alarm = false;
                notificationManager.notify(1, notification);                
                manager.removeUpdates(this);
                stopSelf();
            
        
    ;

    private void toaster(String text)
        Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
    

【问题讨论】:

【参考方案1】:

您可以使用以下方法计算两个 gps 位置之间的距离,以米为单位。

public static float distFrom (float lat1, float lng1, float lat2, float lng2 ) 

    double earthRadius = 3958.75;
    double dLat = Math.toRadians(lat2-lat1);
    double dLng = Math.toRadians(lng2-lng1);
    double a = Math.sin(dLat/2) * Math.sin(dLat/2) +
    Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) *
    Math.sin(dLng/2) * Math.sin(dLng/2);
    double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
    double dist = earthRadius * c;

    int meterConversion = 1609;

    return new Float(dist * meterConversion).floatValue();

原文是我的answer。

对于 GPS 坐标,我创建了一个库代码,如下所示,

public class LocListener implements LocationListener

    private static double lat =0.0;
    private static double lon = 0.0;
    private static double alt = 0.0; 
    private static double speed = 0.0;
    private static long dateTime;

    public static double getLat()
    
        return lat;
    

    public static double getLon() 
    
        return lon;
    

    public static double getAlt()
    
        return alt;
    

    public static double getSpeed()
    
        return speed;
    

    // Added By Kalpen Vaghela on 17 09 2012
    public static long getDateTime()
    
        return dateTime;
    

    @Override
    public void onLocationChanged(Location location) 
    
        lat = location.getLatitude();
        lon = location.getLongitude();
        alt = location.getAltitude();
        speed = location.getSpeed(); 
        dateTime = location.getTime();
    

    @Override
    public void onProviderDisabled(String provider) 
    @Override
    public void onProviderEnabled(String provider) 
    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) 

【讨论】:

感谢您的回答。你对算法 gps 搜索有什么想法吗? 嘿路西法,我不明白您的建议如何帮助 gps 在不同距离内减少工作。据我了解,我需要使用 requestLocationUpdates 方法,这样它才会有效。还是谢谢

以上是关于android中的高效gps服务的主要内容,如果未能解决你的问题,请参考以下文章

没有互联网连接时如何将gps位置存储到android中的服务器

Android 定位模式,无 GPS,AOSP 中的选项

使用android中的计时器每10分钟跟踪一次Gps

如何在Android中使用GPS服务

谷歌地图(安卓)如何如此高效地请求 GPS 修复如此频繁

Android GPS定位精度问题