原生android实现定位java实现

打印 上一主题 下一主题

主题 1600|帖子 1600|积分 4800

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
1. 完备的LocationUtils工具类实现

  1. import android.Manifest;
  2. import android.app.Activity;
  3. import android.content.Context;
  4. import android.content.pm.PackageManager;
  5. import android.location.Location;
  6. import android.location.LocationListener;
  7. import android.location.LocationManager;
  8. import android.os.Bundle;
  9. import android.os.Looper;
  10. import androidx.core.app.ActivityCompat;
  11. import androidx.core.content.ContextCompat;
  12. public class LocationUtils {
  13.     private static final int LOCATION_PERMISSION_REQUEST_CODE = 1001;
  14.     private static LocationManager locationManager;
  15.     private static LocationListener locationListener;
  16.    
  17.     // 回调接口
  18.     public interface LocationCallback {
  19.         void onLocationResult(Location location);
  20.         void onPermissionDenied();
  21.         void onLocationError(String error);
  22.     }
  23.     /**
  24.      * 检查并获取当前位置
  25.      * @param activity 当前Activity
  26.      * @param callback 位置回调
  27.      * @param requireFineLocation 是否需要高精度定位
  28.      */
  29.     public static void getCurrentLocation(Activity activity, LocationCallback callback, boolean requireFineLocation) {
  30.         String permission = requireFineLocation ?
  31.                 Manifest.permission.ACCESS_FINE_LOCATION :
  32.                 Manifest.permission.ACCESS_COARSE_LOCATION;
  33.                
  34.         if (checkPermission(activity, permission)) {
  35.             startLocationUpdates(activity, callback, requireFineLocation);
  36.         } else {
  37.             requestLocationPermission(activity, callback, requireFineLocation);
  38.         }
  39.     }
  40.     /**
  41.      * 检查权限是否已授予
  42.      */
  43.     private static boolean checkPermission(Context context, String permission) {
  44.         return ContextCompat.checkSelfPermission(context, permission)
  45.                 == PackageManager.PERMISSION_GRANTED;
  46.     }
  47.     /**
  48.      * 请求定位权限
  49.      */
  50.     private static void requestLocationPermission(Activity activity,
  51.             final LocationCallback callback, final boolean requireFineLocation) {
  52.         
  53.         String permission = requireFineLocation ?
  54.                 Manifest.permission.ACCESS_FINE_LOCATION :
  55.                 Manifest.permission.ACCESS_COARSE_LOCATION;
  56.                
  57.         if (ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
  58.             // 解释为什么需要权限
  59.             callback.onLocationError("需要位置权限才能获取当前位置");
  60.         }
  61.         
  62.         ActivityCompat.requestPermissions(activity,
  63.                 new String[]{permission},
  64.                 LOCATION_PERMISSION_REQUEST_CODE);
  65.     }
  66.     /**
  67.      * 处理权限请求结果
  68.      * 需要在Activity的onRequestPermissionsResult中调用
  69.      */
  70.     public static void onRequestPermissionsResult(int requestCode,
  71.             String[] permissions, int[] grantResults,
  72.             Activity activity, LocationCallback callback,
  73.             boolean requireFineLocation) {
  74.         
  75.         if (requestCode == LOCATION_PERMISSION_REQUEST_CODE) {
  76.             if (grantResults.length > 0 &&
  77.                     grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  78.                 startLocationUpdates(activity, callback, requireFineLocation);
  79.             } else {
  80.                 callback.onPermissionDenied();
  81.             }
  82.         }
  83.     }
  84.     /**
  85.      * 开始获取位置更新
  86.      */
  87.     private static void startLocationUpdates(Activity activity,
  88.             final LocationCallback callback, boolean requireFineLocation) {
  89.         
  90.         locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
  91.         
  92.         if (locationManager == null) {
  93.             callback.onLocationError("无法获取位置服务");
  94.             return;
  95.         }
  96.         // 检查GPS和网络是否可用
  97.         boolean isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
  98.         boolean isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
  99.         
  100.         if (!isGpsEnabled && !isNetworkEnabled) {
  101.             callback.onLocationError("请打开位置服务");
  102.             return;
  103.         }
  104.         String provider = requireFineLocation ?
  105.                 LocationManager.GPS_PROVIDER :
  106.                 LocationManager.NETWORK_PROVIDER;
  107.         locationListener = new LocationListener() {
  108.             @Override
  109.             public void onLocationChanged(Location location) {
  110.                 // 获取到位置后停止更新并返回结果
  111.                 stopLocationUpdates();
  112.                 callback.onLocationResult(location);
  113.             }
  114.             @Override
  115.             public void onStatusChanged(String provider, int status, Bundle extras) {}
  116.             @Override
  117.             public void onProviderEnabled(String provider) {}
  118.             @Override
  119.             public void onProviderDisabled(String provider) {
  120.                 callback.onLocationError("位置服务被禁用");
  121.             }
  122.         };
  123.         try {
  124.             if (ActivityCompat.checkSelfPermission(activity,
  125.                     requireFineLocation ?
  126.                             Manifest.permission.ACCESS_FINE_LOCATION :
  127.                             Manifest.permission.ACCESS_COARSE_LOCATION)
  128.                     != PackageManager.PERMISSION_GRANTED) {
  129.                 return;
  130.             }
  131.             
  132.             // 请求位置更新
  133.             locationManager.requestSingleUpdate(provider, locationListener, Looper.getMainLooper());
  134.             
  135.             // 同时获取最后一次已知位置
  136.             Location lastKnownLocation = locationManager.getLastKnownLocation(provider);
  137.             if (lastKnownLocation != null) {
  138.                 callback.onLocationResult(lastKnownLocation);
  139.             }
  140.             
  141.         } catch (SecurityException e) {
  142.             callback.onLocationError("位置权限异常: " + e.getMessage());
  143.         } catch (IllegalArgumentException e) {
  144.             callback.onLocationError("位置提供者不可用: " + e.getMessage());
  145.         }
  146.     }
  147.     /**
  148.      * 停止位置更新
  149.      */
  150.     public static void stopLocationUpdates() {
  151.         if (locationManager != null && locationListener != null) {
  152.             locationManager.removeUpdates(locationListener);
  153.         }
  154.     }
  155. }
复制代码
2. 利用示例

在Activity中利用

  1. public class MainActivity extends AppCompatActivity {
  2.     @Override
  3.     protected void onCreate(Bundle savedInstanceState) {
  4.         super.onCreate(savedInstanceState);
  5.         setContentView(R.layout.activity_main);
  6.         
  7.         Button btnGetLocation = findViewById(R.id.btn_get_location);
  8.         btnGetLocation.setOnClickListener(v -> {
  9.             // 获取高精度位置
  10.             LocationUtils.getCurrentLocation(this, new LocationUtils.LocationCallback() {
  11.                 @Override
  12.                 public void onLocationResult(Location location) {
  13.                     double latitude = location.getLatitude();
  14.                     double longitude = location.getLongitude();
  15.                     // 处理位置信息
  16.                     Log.d("Location", "Lat: " + latitude + ", Lng: " + longitude);
  17.                 }
  18.                 @Override
  19.                 public void onPermissionDenied() {
  20.                     // 处理权限被拒绝
  21.                     Toast.makeText(MainActivity.this,
  22.                             "需要位置权限才能使用此功能",
  23.                             Toast.LENGTH_SHORT).show();
  24.                 }
  25.                 @Override
  26.                 public void onLocationError(String error) {
  27.                     // 处理位置错误
  28.                     Toast.makeText(MainActivity.this, error, Toast.LENGTH_SHORT).show();
  29.                 }
  30.             }, true); // true表示需要高精度定位
  31.         });
  32.     }
  33.     @Override
  34.     public void onRequestPermissionsResult(int requestCode,
  35.             @NonNull String[] permissions, @NonNull int[] grantResults) {
  36.         super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  37.         // 将权限结果转发给工具类处理
  38.         LocationUtils.onRequestPermissionsResult(
  39.                 requestCode, permissions, grantResults,
  40.                 this, new LocationUtils.LocationCallback() {
  41.                     @Override
  42.                     public void onLocationResult(Location location) {
  43.                         // 处理位置信息
  44.                     }
  45.                     @Override
  46.                     public void onPermissionDenied() {
  47.                         // 处理权限被拒绝
  48.                     }
  49.                     @Override
  50.                     public void onLocationError(String error) {
  51.                         // 处理错误
  52.                     }
  53.                 }, true);
  54.     }
  55.    
  56.     @Override
  57.     protected void onDestroy() {
  58.         super.onDestroy();
  59.         // 停止位置更新
  60.         LocationUtils.stopLocationUpdates();
  61.     }
  62. }
复制代码
3. 工具类功能说明


  • 权限管理

    • 自动查抄定位权限
    • 动态哀求缺少的权限
    • 处置惩罚权限哀求结果

  • 位置获取

    • 支持高精度(GPS)和低精度(网络)定位
    • 获取单次位置更新
    • 获取最后一次已知位置作为快速响应

  • 错误处置惩罚

    • 权限被拒绝
    • 位置服务不可用
    • 其他位置获取错误

  • 资源管理

    • 提供制止位置更新的方法
    • 制止内存走漏

4. 高级功能扩展

如果须要更高级的功能,可以思量添加以下内容:

  • 超时处置惩罚
  1. // 添加超时Handler
  2. private static final int LOCATION_TIMEOUT_MS = 30000; // 30秒超时
  3. private static Handler timeoutHandler = new Handler();
  4. private static void startLocationUpdatesWithTimeout(...) {
  5.     // 设置超时任务
  6.     timeoutHandler.postDelayed(() -> {
  7.         stopLocationUpdates();
  8.         callback.onLocationError("获取位置超时");
  9.     }, LOCATION_TIMEOUT_MS);
  10.    
  11.     startLocationUpdates(...);
  12. }
  13. // 在获取到位置后取消超时任务
  14. locationListener = new LocationListener() {
  15.     @Override
  16.     public void onLocationChanged(Location location) {
  17.         timeoutHandler.removeCallbacksAndMessages(null);
  18.         // ...原有逻辑
  19.     }
  20. };
复制代码

  • 背景定位支持
  1. // 在AndroidManifest.xml中添加
  2. <uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
  3. // 在工具类中检查Android 10+的后台权限
  4. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
  5.     if (ContextCompat.checkSelfPermission(context,
  6.             Manifest.permission.ACCESS_BACKGROUND_LOCATION)
  7.             != PackageManager.PERMISSION_GRANTED) {
  8.         // 请求后台权限
  9.     }
  10. }
复制代码

  • 位置缓存
  1. // 添加静态变量缓存位置
  2. private static Location lastLocation;
  3. private static long lastLocationTime;
  4. public static Location getCachedLocation() {
  5.     // 如果缓存的位置在有效期内(如5分钟内)则返回
  6.     if (lastLocation != null &&
  7.             System.currentTimeMillis() - lastLocationTime < 300000) {
  8.         return lastLocation;
  9.     }
  10.     return null;
  11. }
复制代码
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

水军大提督

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表