背景
某导航巡航时才能悬浮车速,导航时是不能悬浮车速的。本人不太喜欢全屏导航,因此就写了个app自己用。
原始巡航图,带车速的。
,本来导航要是有这个车速就很好,可惜官方没有。那就自己动手咯。
目前软件已开车实测500公里,无闪退问题。下面贴下核心代码。
[Java] 纯文本查看 复制代码
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.IBinder;
import android.util.Log;
import android.view.*;
import android.widget.TextView;
import com.hd.hdcart.amap.AMapCartReceiver;
import com.hd.hdcart.event.AMapAreaInfoMessageEvent;
import com.hd.hdcart.event.AMapFloatingWindowSettingsChangeMessageEvent;
import com.hd.hdcart.event.FloatShowEnableEvent;
import com.hd.hdcart.utils.SharedPreUtil;
import com.hd.hdcart.utils.TaskExecutor;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.concurrent.ScheduledFuture;
public class AMapCartService extends Service
{
private static final String TAG = "AMapCartService";
public static final String RECEIVE_ACTION = "AUTONAVI_STANDARD_BROADCAST_SEND";
public static final String SEND_ACTION = "AUTONAVI_STANDARD_BROADCAST_RECV";
public static final String KEY_TYPE = "KEY_TYPE";
private WindowManager windowManager;
private WindowManager.LayoutParams layoutParams;
private View displayView;
public int curSpeed = 0;//时速
public String road = "";//道路
public String sourceArea = "";//行政区
public double ecurSpeed = 0.0d;
public double cameraSpeed = 0.0d;
public double limitSpeed = 0.0d;
public final double lowerLimit = 10.0d;
double proportion = 0.0d;
private AMapCartReceiver aMapCartReceiver;
public AMapCartService()
{
}
@Override
public IBinder onBind(Intent intent)
{
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().register(this);
}
registerAMapReceiver();
startSendAMapAreaInfoReceiverTask();
windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
if (SharedPreUtil.getBoolean("FLOATING_WINDOW_AMAP_AREA_ENABLE", false)) {
initLayoutParams();
showFloatView();
}
return super.onStartCommand(intent, flags, startId);
}
/**
* 注册监听高德广播
*/
private void registerAMapReceiver()
{
aMapCartReceiver = new AMapCartReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(RECEIVE_ACTION);
intentFilter.addAction(SEND_ACTION);
unregisterReceiver();
registerReceiver(aMapCartReceiver, intentFilter);//再进行监听
}
/**
* 请求高德行政区域信息
*
* [url=home.php?mod=space&uid=952169]@Param[/url] context
*/
public static void sendAMapAreaInfoReceiver(Context context)
{
Intent intent = new Intent();
intent.setAction(SEND_ACTION);
intent.putExtra(KEY_TYPE, 10029);
context.sendBroadcast(intent);
}
/**
* 取消监听高德广播
*/
private void unregisterReceiver()
{
try {
if (aMapCartReceiver != null) {
unregisterReceiver(aMapCartReceiver);//先取消监听
}
} catch (Exception exception) {
}
}
ScheduledFuture<?> scheduledFuture;
/**
* 开启定时发送高德行政区域信息
*/
public void startSendAMapAreaInfoReceiverTask()
{
scheduledFuture = TaskExecutor.self().repeatRun(() -> {
sendAMapAreaInfoReceiver(this);
}, 90 * 1000);
}
public void stopSendAMapAreaInfoReceiverTask()
{
if (scheduledFuture != null) {
scheduledFuture.cancel(true);
}
}
/**
* 初始化悬浮窗参数
*/
private void initLayoutParams()
{
layoutParams = new WindowManager.LayoutParams();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
layoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
} else {
layoutParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
}
layoutParams.format = PixelFormat.RGBA_8888;
//设置透明度
layoutParams.alpha = 0.65f;
layoutParams.gravity = Gravity.LEFT | Gravity.TOP;
layoutParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
layoutParams.width = SharedPreUtil.getInteger("FLOATING_WINDOW_AMAP_AREA_CONTAINER_WIDTH", 424);
layoutParams.height = SharedPreUtil.getInteger("FLOATING_WINDOW_AMAP_AREA_CONTAINER_HEIGHT", 162);
layoutParams.x = SharedPreUtil.getInteger("FLOATING_WINDOW_AMAP_AREA_CONTAINER_X", 300);
layoutParams.y = SharedPreUtil.getInteger("FLOATING_WINDOW_AMAP_AREA_CONTAINER_Y", 300);
}
/**
* 显示悬浮窗
*/
private void showFloatView()
{
LayoutInflater layoutInflater = LayoutInflater.from(this);
displayView = layoutInflater.inflate(R.layout.amap_area_floating_window, null);
if (layoutParams == null) {
initLayoutParams();
}
displayView.setOnTouchListener(new View.OnTouchListener()
{
@Override
public boolean onTouch(View v, MotionEvent event)
{
if (layoutParams != null) {
layoutParams.x = (int) event.getRawX() - displayView.getMeasuredWidth() / 2;
layoutParams.y = (int) event.getRawY() - displayView.getMeasuredHeight() / 2;
SharedPreUtil.saveInteger("FLOATING_WINDOW_AMAP_AREA_CONTAINER_X", layoutParams.x);
SharedPreUtil.saveInteger("FLOATING_WINDOW_AMAP_AREA_CONTAINER_Y", layoutParams.y);
windowManager.updateViewLayout(displayView, layoutParams);
}
return false;
}
});
TextView txtCurSpeed = (TextView) displayView.findViewById(R.id.txtCurSpeed);
txtCurSpeed.setText(curSpeed+ " km/h");
txtCurSpeed.setTextSize(SharedPreUtil.getInteger("FLOATING_WINDOW_AMAP_SD_FONT_SIZE", 40));
TextView txtArea = (TextView) displayView.findViewById(R.id.txtArea);
if (sourceArea != null && !sourceArea.equals("")) {
txtArea.setText(sourceArea);
} else {
txtArea.setText("waiting...");
}
txtArea.setTextSize(SharedPreUtil.getInteger("FLOATING_WINDOW_AMAP_AREA_FONT_SIZE", 20));
TextView txtRoad = (TextView) displayView.findViewById(R.id.txtRoad);
txtRoad.setText(road);
txtRoad.setTextSize(SharedPreUtil.getInteger("FLOATING_WINDOW_AMAP_AREA_FONT_SIZE", 20));
windowManager.addView(displayView, layoutParams);
}
/**
* 接收高德行政区域信息
*
* @param event
*/
@Subscribe(threadMode = ThreadMode.MAIN)
public void onAMapAreaInfoMessageEvent(AMapAreaInfoMessageEvent event)
{
if (event.getType().equals("10030")) {
if (!sourceArea.equals(event.toString())) {
updateFloatViewContent(event.toString());
sourceArea = event.toString();
}
} else if (event.getType().equals("10065")) {
TextView txtCcurSpeed = (TextView) displayView.findViewById(R.id.txtCurSpeed);
txtCcurSpeed.setText(event.getCurSpeed() + " km/h");
}else {
updateFloatViewcurSpeed(event);
}
}
/**
* 更新悬浮窗文本内容
*
* @param content
*/
private void updateFloatViewContent(String content)
{
if (displayView != null) {
TextView txtArea = (TextView) displayView.findViewById(R.id.txtArea);
txtArea.setText(content);
}
}
/**
* 更新悬浮窗的车速
*
* @param event
*/
private void updateFloatViewcurSpeed(AMapAreaInfoMessageEvent event)
{
ecurSpeed = Double.valueOf(event.getCurSpeed());
cameraSpeed = Double.valueOf(event.getCameraSpeed());
limitSpeed = Double.valueOf(event.getLimitedSpeed());
curSpeed = event.getCurSpeed();
if (displayView != null) {
TextView txtCcurSpeed = (TextView) displayView.findViewById(R.id.txtCurSpeed);
txtCcurSpeed.setText(curSpeed + " km/h");
TextView txtRoad = (TextView) displayView.findViewById(R.id.txtRoad);
if (cameraSpeed <= 0) {
cameraSpeed = limitSpeed;
}
proportion = (ecurSpeed - cameraSpeed) / cameraSpeed * 100;
String tempStr = event.getCurRoadName() + " 无限速 ";
txtCcurSpeed.setTextColor(Color.WHITE);
if (cameraSpeed > 0 && proportion < lowerLimit) {
txtCcurSpeed.setTextColor(Color.MAGENTA); //无测速
tempStr = event.getCurRoadName() + " 限速 " + cameraSpeed + "km/h ";
} else if (cameraSpeed > 0 && proportion >= lowerLimit) {
String num = String.format("%.0f", proportion);
tempStr = event.getCurRoadName() + " 限速 " + cameraSpeed + " km/h 已超速" + num + "%";
txtCcurSpeed.setTextColor(Color.RED); //有测速
}
txtRoad.setText(tempStr);
road = tempStr;
}
}
/**
* 接收悬浮窗设置变化
*
* @param event
*/
@Subscribe(threadMode = ThreadMode.MAIN)
public void updateFloatView(AMapFloatingWindowSettingsChangeMessageEvent event)
{
if (layoutParams != null && displayView != null) {
layoutParams.width = SharedPreUtil.getInteger("FLOATING_WINDOW_AMAP_AREA_CONTAINER_WIDTH", 424);
layoutParams.height = SharedPreUtil.getInteger("FLOATING_WINDOW_AMAP_AREA_CONTAINER_HEIGHT", 162);
layoutParams.x = SharedPreUtil.getInteger("FLOATING_WINDOW_AMAP_AREA_CONTAINER_X", 300);
layoutParams.y = SharedPreUtil.getInteger("FLOATING_WINDOW_AMAP_AREA_CONTAINER_Y", 300);
// GradientDrawable drawable = (GradientDrawable) displayView.getBackground();
// drawable.setColor(SharedPreUtil.getInteger("FLOATING_WINDOW_AMAP_AREA_CONTAINER_BACKGROUND_COLOR", Color.parseColor("#060E19")));
// displayView.setBackground(drawable);
//当前车速
TextView curSpeed = displayView.findViewById(R.id.txtCurSpeed);
curSpeed.setTextSize(SharedPreUtil.getInteger("FLOATING_WINDOW_AMAP_SD_FONT_SIZE", 40));
//
TextView txtArea = displayView.findViewById(R.id.txtArea);
txtArea.setTextSize(SharedPreUtil.getInteger("FLOATING_WINDOW_AMAP_AREA_FONT_SIZE", 20));
windowManager.updateViewLayout(displayView, layoutParams);
}
}
/**
* 隐藏悬浮窗
*/
private void hideFloatView()
{
if (displayView != null) {
windowManager.removeView(displayView);
}
}
//FloatShowEnableEvent
@Subscribe(threadMode = ThreadMode.MAIN)
public void onFloatShowEnableEvent(FloatShowEnableEvent event)
{
if (event.isEnable()) {
showFloatView();
} else {
hideFloatView();
}
}
@Override
public void onDestroy()
{
if (!EventBus.getDefault().isRegistered(this)) {
EventBus.getDefault().unregister(this);
}
unregisterReceiver();
stopSendAMapAreaInfoReceiverTask();
hideFloatView();
}
} |