package com.dayu.pipirrapp.service;
|
|
import android.annotation.SuppressLint;
|
import android.app.Notification;
|
import android.app.PendingIntent;
|
import android.app.Service;
|
import android.content.Intent;
|
import android.graphics.BitmapFactory;
|
import android.location.Criteria;
|
import android.location.Location;
|
import android.location.LocationListener;
|
import android.location.LocationManager;
|
import android.os.Bundle;
|
import android.os.IBinder;
|
|
import androidx.annotation.Nullable;
|
|
import com.baidu.location.BDAbstractLocationListener;
|
import com.baidu.location.BDLocation;
|
import com.baidu.location.LocationClient;
|
import com.baidu.location.LocationClientOption;
|
import com.dayu.pipirrapp.R;
|
import com.dayu.pipirrapp.activity.MainActivity;
|
import com.dayu.pipirrapp.utils.MyLog;
|
import com.tencent.bugly.crashreport.CrashReport;
|
|
/**
|
* author: zuo
|
* Date: 2024-01-10
|
* Time: 14:39
|
* 备注:
|
*/
|
public class MyLocationService extends Service {
|
|
private LocationManager locationManager;
|
private MyLocationListener listener;
|
|
private LocationClient mBDLocationClient = null;
|
private MyBDLocationListener mBDLocationListener;
|
|
/**
|
* 是否一次性定位
|
*/
|
boolean isSingle;
|
|
@Nullable
|
@Override
|
public IBinder onBind(Intent intent) {
|
return null;
|
}
|
|
|
@Override
|
public int onStartCommand(Intent intent, int flags, int startId) {
|
MyLog.i("onStartCommand()");
|
isSingle = intent.getBooleanExtra("isSingle", false);
|
if (!isSingle) {
|
// 在API11之后构建Notification的方式
|
Notification.Builder builder = new Notification.Builder
|
(this.getApplicationContext());
|
//获取一个Notification构造器
|
Intent nfIntent = new Intent(this, MainActivity.class);
|
|
builder.setContentIntent(PendingIntent.
|
getActivity(this, 0, nfIntent, PendingIntent.FLAG_IMMUTABLE)) // 设置PendingIntent
|
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(),
|
R.mipmap.ic_launcher)) // 设置下拉列表中的图标(大图标)
|
.setContentTitle(getResources().getString(R.string.app_name)) // 设置下拉列表里的标题
|
.setSmallIcon(R.mipmap.ic_launcher) // 设置状态栏内的小图标
|
.setContentText("正在后台运行") // 设置上下文内容
|
.setWhen(System.currentTimeMillis()); // 设置该通知发生的时间
|
|
Notification notification = builder.build(); // 获取构建好的Notification
|
notification.defaults = Notification.DEFAULT_SOUND; //设置为默认的声音
|
}
|
return super.onStartCommand(intent, flags, startId);
|
}
|
|
|
@Override
|
public void onCreate() {
|
super.onCreate();
|
|
createNativeLocation();
|
// createBDLocation();
|
}
|
|
// /**
|
// * @param isSingle 是否是单次定位
|
// */
|
// public MyLocationService(boolean isSingle) {
|
// this.isSingle = isSingle;
|
//
|
// }
|
|
/**
|
* 原生的定位服务
|
*/
|
@SuppressLint("MissingPermission")
|
private void createNativeLocation() {
|
|
try {
|
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
|
listener = new MyLocationListener();
|
|
Criteria criteria = new Criteria();
|
// 查询精度:高,Criteria.ACCURACY_COARSE比较粗略,Criteria.ACCURACY_FINE则比较精确
|
criteria.setAccuracy(Criteria.ACCURACY_FINE);
|
//不要求海拔
|
criteria.setAltitudeRequired(false);
|
//不要求方位
|
criteria.setBearingRequired(false);
|
//允许有花费
|
criteria.setCostAllowed(true);
|
//低功耗
|
criteria.setPowerRequirement(Criteria.POWER_LOW);
|
String provider = locationManager.getBestProvider(criteria, true);
|
MyLog.i("定位的provider:" + provider);
|
|
//第二个参数是间隔时间 第三个参数是间隔多少距离,这里我试过了不同的各种组合,能获取到位置就是能,不能获取就是不能
|
locationManager.requestLocationUpdates(provider, 1000, 0, listener);
|
} catch (Exception e) {
|
CrashReport.postCatchedException(e);
|
}
|
}
|
|
|
/**
|
* 第三方百度定位服务
|
*/
|
private void createBDLocation() {
|
try {
|
LocationClient.setAgreePrivacy(true);
|
mBDLocationClient = new LocationClient(this.getBaseContext());
|
mBDLocationListener = new MyBDLocationListener();
|
//注册监听函数
|
mBDLocationClient.registerLocationListener(mBDLocationListener);
|
//配置百度定位的选项
|
LocationClientOption option = new LocationClientOption();
|
//可选,默认高精度,设置定位模式,高精度,低功耗,仅设备
|
option.setLocationMode(LocationClientOption.LocationMode.Battery_Saving);
|
//可选,默认gcj02,设置返回的定位结果坐标系,如果配合百度地图使用,建议设置为bd09ll;
|
option.setCoorType("WGS84");
|
//可选,默认0,即仅定位一次,设置发起连续定位请求的间隔需要大于等于1000ms才是有效的
|
option.setScanSpan(1000);
|
//可选,设置是否需要地址信息,默认不需要
|
option.setIsNeedAddress(true);
|
//可选,设置是否需要地址描述
|
option.setIsNeedLocationDescribe(false);
|
//可选,设置是否需要设备方向结果
|
option.setNeedDeviceDirect(false);
|
//可选,默认false,设置是否当卫星定位有效时按照1S1次频率输出卫星定位结果
|
option.setLocationNotify(true);
|
//可选,默认true,定位SDK内部是一个SERVICE,并放到了独立进程,设置是否在stop的时候杀死这个进程,默认不杀死
|
option.setIgnoreKillProcess(true);
|
//可选,默认false,设置是否开启卫星定位
|
option.setOpenGnss(true);
|
//可选,默认false,设置定位时是否需要海拔信息,默认不需要,除基础定位版本都可用
|
option.setIsNeedAltitude(false);
|
|
mBDLocationClient.setLocOption(option);
|
//开启百度定位
|
mBDLocationClient.start();
|
} catch (Exception e) {
|
e.printStackTrace();
|
CrashReport.postCatchedException(e);
|
}
|
}
|
|
|
class MyLocationListener implements LocationListener {
|
// 位置改变时获取经纬度
|
@Override
|
public void onLocationChanged(Location location) {
|
|
String longitude = "Longitude:" + location.getLongitude();
|
String latitude = "Latitude:" + location.getLatitude();
|
MyLog.i("原生定位onLocationChanged: Latitude:" + latitude + " Longitude:" + longitude);
|
// 是否一次性定位
|
if (isSingle) {
|
stopSelf(); // 获取到经纬度以后,停止该service
|
}
|
}
|
|
// 状态改变时
|
@Override
|
public void onStatusChanged(String provider, int status, Bundle extras) {
|
MyLog.i("onStatusChanged - provider:" + provider + " status:" + status);
|
}
|
|
// 提供者可以使用时
|
@Override
|
public void onProviderEnabled(String provider) {
|
MyLog.i("GPS开启了");
|
}
|
|
// 提供者不可以使用时
|
@Override
|
public void onProviderDisabled(String provider) {
|
MyLog.i("GPS关闭了");
|
}
|
|
}
|
|
/**
|
* 百度定位的监听
|
*/
|
class MyBDLocationListener extends BDAbstractLocationListener {
|
|
@Override
|
public void onReceiveLocation(BDLocation location) {
|
|
double latitude = location.getLatitude(); //获取纬度信息
|
double longitude = location.getLongitude(); //获取经度信息
|
// MyLog.i("百度的监听 latitude:" + latitude);
|
// MyLog.i("百度的监听 longitude:" + longitude);
|
MyLog.i("百度的监听 onBaiduLocationChanged: latitude:" + latitude + " longitude:" + longitude);
|
if (isSingle) {
|
stopSelf(); // 获取到经纬度以后,停止该service
|
}
|
}
|
|
}
|
|
@Override
|
public void onDestroy() {
|
MyLog.i("MyLocationService--onDestroy");
|
// 停止前台服务--参数:表示是否移除之前的通知
|
stopForeground(true);
|
super.onDestroy();
|
// 停止所有的定位服务
|
try {
|
if (locationManager != null) {
|
locationManager.removeUpdates(listener);
|
}
|
if (mBDLocationClient != null) {
|
mBDLocationClient.stop();
|
mBDLocationClient.unRegisterLocationListener(mBDLocationListener);
|
}
|
|
} catch (Exception e) {
|
CrashReport.postCatchedException(e);
|
}
|
|
|
}
|
|
|
}
|