很久之前就想做一个车载相关的app、需要实现如下功能:

    (1)每0.2秒更新一次当前车辆的最新速度值。
    
(2)可控制性记录行驶里程。
    
(3)不连接网络情况下获取当前车辆位置。如(北京市X区X路X号)
    
(4)实时快速获取车辆运动方向。
    
(5)获取当前太空卫星数量以及GPS状态。

以上功能不需要连接网络、不需要开蓝牙、APP显示名字等可定制;

条件是有个大屏的Android系统车载导航。

好了、实现上面的第一步是需要一个汽车仪表盘的source、网上搜索了一下是有的,所以直接下载了;详细请点击:

搜索一个然后点击下载即可。 然后用宇宙最骚的eclipse打开。

(1)首先是配置文件如下:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. package="cgenfei.gz.cn"
  4. android:versionCode="1"
  5. android:versionName="1.0" >
  6.  
  7. <uses-sdk android:minSdkVersion="8" />
  8.  
  9. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
  10. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  11.  
  12. <!-- SDCard中创建与删除文件权限 -->
  13. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
  14. <!-- 向SDCard写入数据权限 -->
  15. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  16.  
  17. <application
  18. android:icon="@drawable/logo"
  19. android:label="@string/app_name"
  20. android:theme="@android:style/Theme.NoTitleBar" >
  21. <activity
  22. android:name=".PGSLActivity"
  23. android:label="@string/app_name" >
  24. <intent-filter>
  25. <action android:name="android.intent.action.MAIN" />
  26.  
  27. <category android:name="android.intent.category.LAUNCHER" />
  28. </intent-filter>
  29. </activity>
  30. </application>
  31.  
  32. </manifest>

1、需要连接网络的权限(<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />)

2、存储卡访问权限(<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />)

代码注释都有的哈、请仔细查看。

(2)页面布局

布局文件代码

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:id="@+id/speedup"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. android:background="@drawable/bg3"
  7. android:orientation="vertical" >
  8.  
  9. <LinearLayout
  10. xmlns:android="http://schemas.android.com/apk/res/android"
  11. android:layout_width="wrap_content"
  12. android:layout_height="wrap_content"
  13. android:layout_gravity="center"
  14. android:layout_marginTop="2dp"
  15. android:orientation="horizontal" >
  16.  
  17. <honda.Server.SpeedControlView
  18. android:id="@+id/speed_control"
  19. android:layout_width="wrap_content"
  20. android:layout_height="wrap_content"
  21. android:layout_centerInParent="true" />
  22. </LinearLayout>
  23.  
  24. </LinearLayout>

采用Android开发中的线性布局。

(3)Android源代码

首先需要一个model类进行数据交换读写操作、本人新建的实体如下:

3.1- 实体类:

  1. /*
  2. * Project Name:honda
  3. * File Name:ModelGPS.java
  4. * Package Name:model
  5. * Date:2016-8-16下午1:39:56
  6. * Copyright (c) 2016,xxx Rights Reserved.
  7. *
  8. */
  9. package model;
  10.  
  11. /*
  12. * ClassName:ModelGPS
  13. * Function: ADD FUNCTION.
  14. * Reason: ADD REASON.
  15. * Date: 2016-8-16 下午1:39:56
  16. * @author xxxx
  17. * @version
  18. * @since JDK 1.6
  19. */
  20. public class ModelGPS {
  21. public String lng;
  22.  
  23. public String getLng() {
  24. return lng;
  25. }
  26.  
  27. public double Getlngdouble() {
  28. return Double.parseDouble(lng);
  29. }
  30.  
  31. public double Getlatdouble() {
  32. return Double.parseDouble(lat);
  33. }
  34.  
  35. public void setLng(String lng) {
  36. this.lng = lng;
  37. }
  38.  
  39. public String getLat() {
  40. return lat;
  41. }
  42.  
  43. public void setLat(String lat) {
  44. this.lat = lat;
  45. }
  46.  
  47. public String getAds() {
  48. return ads;
  49. }
  50.  
  51. public void setAds(String ads) {
  52. this.ads = ads;
  53. }
  54.  
  55. public String lat;
  56. public String ads;
  57. }

3.2- common类:

全部静态变量存储以便其他函数调用该变量值

  1. /*
  2. * ClassName:ComcomData
  3. * Function: ADD FUNCTION.
  4. * Reason: ADD REASON.
  5. * Date: 2017-4-16 下午10:59:30
  6. * @author xxx
  7. * @version
  8. * @since JDK 1.6
  9. */
  10. public class ComData {
  11.  
  12. public static int spdnow = 0;// 当前速度GPS获取
  13.  
  14. public static String ads = "";// 地址
  15.  
  16. public static double step = 0.04;// 搜索范围
  17.  
  18. }

3.3- commonfunction类

公用方法、比如获取点x1到点x2的距离

  1. /*
  2. * ClassName:Common
  3. * Function: ADD FUNCTION.
  4. * Reason: ADD REASON.
  5. * Date: 2016-8-12 上午11:33:39
  6. * @author xxx
  7. * @version
  8. * @since JDK 1.6
  9. */
  10. public class Common {
  11.  
  12. private final double EARTH_RADIUS = 6378.137;// 地球半径
  13.  
  14. private double rad(double d) {
  15. return d * Math.PI / 180.0;
  16. }
  17.  
  18. public long Getlongtime() {
  19. return new Date().getTime();
  20. }
  21.  
  22. // 计算距离
  23. public double Getdisdb(double lng1, double lat1, double lng2, double lat2) {
  24.  
  25. if (lng1 == 0 || lat1 == 0)
  26. return -1;
  27.  
  28. if (lng1 == lng2 && lat1 == lat2) {
  29. return 0;
  30. }
  31. try {
  32.  
  33. double radLat1 = rad(lat1);
  34. double radLat2 = rad(lat2);
  35. double a = radLat1 - radLat2;
  36. double b = rad(lng1) - rad(lng2);
  37.  
  38. double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
  39. + Math.cos(radLat1) * Math.cos(radLat2)
  40. * Math.pow(Math.sin(b / 2), 2)));
  41.  
  42. s = s * EARTH_RADIUS;
  43.  
  44. s = Math.round(s * 10000) / 10000;
  45.  
  46. return s;
  47. } catch (Exception e) {
  48. return 0;
  49. }
  50. }
  51.  
  52. // 计算距离
  53. public double Getdis(double lng1, double lat1, double lng2, double lat2) {
  54.  
  55. if (lng1 == lng2 && lat1 == lat2)
  56. return 0;
  57.  
  58. try {
  59. double radLat1 = rad(lat1);
  60. double radLat2 = rad(lat2);
  61. double a = radLat1 - radLat2;
  62. double b = rad(lng1) - rad(lng2);
  63.  
  64. double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
  65. + Math.cos(radLat1) * Math.cos(radLat2)
  66. * Math.pow(Math.sin(b / 2), 2)));
  67.  
  68. s = s * EARTH_RADIUS;
  69.  
  70. s = Math.round(s * 10000);
  71.  
  72. return s;
  73. } catch (Exception e) {
  74. return 0;
  75. }
  76. }
  77.  
  78. public String GetClostADS(ArrayList<ModelGPS> arr, double lng, double lat) {
  79.  
  80. // 没有该地区
  81. if (arr == null)
  82. return "";
  83.  
  84. // 放大范围
  85. if (arr.size() == 0) {
  86. ComData.step = ComData.step + 0.01;
  87. return "";
  88. }
  89.  
  90. // 缩小范围
  91. if (arr.size() > 3 && ComData.step > 0.02)
  92. ComData.step = ComData.step - 0.01;
  93.  
  94. String resut = "", fx = "";
  95. double min = Double.MAX_VALUE;
  96. double tem = 0;
  97.  
  98. // 查找相距最近的Point
  99. for (int i = 0; i < arr.size(); i++) {
  100. tem = Getdis(lng, lat, Double.parseDouble(arr.get(i).getLng()),
  101. Double.parseDouble(arr.get(i).getLat()));
  102. if (min > tem) {
  103. min = tem;
  104. resut = arr.get(i).getAds();
  105.  
  106. fx = null;
  107. if (lng > arr.get(i).Getlngdouble())
  108. fx = "东";
  109. else
  110. fx = "西";
  111.  
  112. if (lat < arr.get(i).Getlngdouble())
  113. fx += "南";
  114. else
  115. fx += "北";
  116. }
  117. }
  118.  
  119. arr = null;
  120. return resut + "(" + fx + ")方向" + (min / 10) + "米";
  121. }
  122. }

3.4- man.java 主程序代码

该类实现调用各个函数之间的传值以及保存结果、显示在仪表盘上。代码中有日文、、、、不喜欢的请不要喷口水、谢谢。

  1. /*
  2. * Project Name:honda
  3. * File Name:PGSLActivity.java
  4. * Package Name:cgenfei.gz.cn
  5. * Date:2016-8-12上午11:33:39
  6. * Copyright (c) 2016, xxx
  7. *
  8. */
  9. package cgenfei.gz.cn;
  10.  
  11. import java.util.ArrayList;
  12.  
  13. import cgenfei.gz.cn.Common;
  14.  
  15. import model.ModelGPS;
  16.  
  17. import xx.Server.SpeedControlView;
  18. import xx.Server.UserService;
  19.  
  20. import android.app.Activity;
  21. import android.content.Context;
  22. import android.content.Intent;
  23. import android.location.Criteria;
  24. import android.location.GpsStatus;
  25. import android.location.Location;
  26. import android.location.LocationListener;
  27. import android.location.LocationManager;
  28. import android.os.Bundle;
  29. import android.provider.Settings;
  30.  
  31. public class PGSLActivity extends Activity {
  32. private LocationManager lm;
  33. private UserService uService = new UserService(PGSLActivity.this);
  34. private Common Common = new Common();
  35. private SpeedControlView speedControlView;// 仪表盘
  36.  
  37. //刷新状态
  38. public void refresh() {
  39. speedControlView.refresh();
  40. }
  41.  
  42. @Override
  43. protected void onDestroy() {
  44. super.onDestroy();
  45. lm.removeUpdates(locationListener);
  46. }
  47.  
  48. @Override
  49. public void onCreate(Bundle savedInstanceState) {
  50. super.onCreate(savedInstanceState);
  51. setContentView(R.layout.main);
  52.  
  53. // 仪表盘
  54. speedControlView = (SpeedControlView) findViewById(R.id.speed_control);
  55. new Thread(speedControlView).start();
  56.  
  57. //GPS
  58. lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
  59.  
  60. // 判断GPS是否正常启动
  61. if (!lm.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
  62. // 返回开启GPS导航设置界面
  63. Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
  64. startActivityForResult(intent, 0);
  65. return;
  66. }
  67.  
  68. // 为获取地理位置信息时设置查询条件
  69. String bestProvider = lm.getBestProvider(getCriteria(), true);
  70. // 获取位置信息
  71. // 如果不设置查询要求,getLastKnownLocation方法传人的参数为LocationManager.GPS_PROVIDER
  72. Location location = lm.getLastKnownLocation(bestProvider);
  73. updateView(location);
  74. // 监听状态
  75. lm.addGpsStatusListener(listener);
  76. // 绑定监听,有4个参数
  77. // 参数1,设备:有GPS_PROVIDER和NETWORK_PROVIDER两种
  78. // 参数2,位置信息更新周期,单位毫秒
  79. // 参数3,位置变化最小距离:当位置距离变化超过此值时,将更新位置信息
  80. // 参数4,监听
  81. // 备注:参数2和3,如果参数3不为0,则以参数3为准;参数3为0,则通过时间来定时更新;两者为0,则随时刷新
  82. // 1秒更新一次,或最小位移变化超过1米更新一次;
  83. // 注意:此处更新准确度非常低,推荐在service里面启动一个Thread,在run中sleep(1000);然后执行handler.sendMessage(),更新位置
  84. lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 760, 1,locationListener);//
  85. }
  86.  
  87. // 位置监听
  88. private LocationListener locationListener = new LocationListener() {
  89. /**
  90. * 位置信息变化时触发
  91. */
  92. public void onLocationChanged(Location location) {
  93. updateView(location);
  94. }
  95.  
  96. /**
  97. * GPS状态变化时触发
  98. */
  99. public void onStatusChanged(String provider, int status, Bundle extras) {
  100. /*switch (status) {
  101. // GPS状态为可见时
  102. case LocationProvider.AVAILABLE:
  103. //CommonData.ads="現在のGPSのステータスが表示されています";
  104. break;
  105. // GPS状态为服务区外时
  106. case LocationProvider.OUT_OF_SERVICE:
  107. //CommonData.ads="現在のGPSのステータスが圏外状態であります";
  108. break;
  109. // GPS状态为暂停服务时
  110. case LocationProvider.TEMPORARILY_UNAVAILABLE:
  111. //CommonData.ads="現在のGPSの状態サスペンド状態";
  112. break;
  113. }*/
  114. }
  115.  
  116. /**
  117. * GPS开启时触发
  118. */
  119. public void onProviderEnabled(String provider) {
  120. Location location = lm.getLastKnownLocation(provider);
  121. updateView(location);
  122. }
  123.  
  124. /**
  125. * GPS禁用时触发
  126. */
  127. public void onProviderDisabled(String provider) {
  128. updateView(null);
  129. }
  130. };
  131.  
  132. // 状态监听
  133. GpsStatus.Listener listener = new GpsStatus.Listener() {
  134. public void onGpsStatusChanged(int event) {
  135.  
  136. };
  137. };
  138.  
  139. double lnglast = 0, latlast = 0;
  140. double lngnow = 0, latnow = 0, speed = 0;
  141. long lasttime = Common.Getlongtime(), nowtime = 0;
  142.  
  143. /**
  144. * 实时更新文本内容
  145. *
  146. * @param location
  147. */
  148. private void updateView(Location location) {
  149. if (location != null) {
  150.  
  151. lngnow = location.getLongitude();
  152. latnow = location.getLatitude();
  153. speed = location.getSpeed() * 3.6;
  154.  
  155. //没有移动
  156. if (lnglast == lngnow && latnow == latlast)
  157. return;
  158.  
  159. // 位置--首先时间5000毫秒控制查询一次
  160. nowtime = Common.Getlongtime();
  161. if (nowtime - lasttime > 6000) {
  162. setads(GetADSI());
  163. lasttime = nowtime;
  164. }
  165.  
  166. // 速度
  167. if (speed < 3.6)
  168. ComData.spdnow = 0;
  169. else
  170. ComData.spdnow = (int) Math.ceil(speed);// 取上限
  171.  
  172. refresh();
  173. }
  174. }
  175.  
  176. private void setads(String info) {
  177. if (info == null || info.equals(""))
  178. return;
  179. ComData.ads = info + "附近";
  180. }
  181.  
  182. private String GetADSI() {
  183. if (lnglast == lngnow && latlast == latnow)
  184. return "";
  185.  
  186. ArrayList<ModelGPS> arrayList = uService.Getads(lngnow, latnow);
  187. return Common.GetClostADS(arrayList, lngnow, latnow);
  188. }
  189.  
  190. //获取定位设置属性
  191. private Criteria getCriteria() {
  192. Criteria criteria = new Criteria();
  193. // 设置定位精确度 Criteria.ACCURACY_COARSE比较粗略,Criteria.ACCURACY_FINE则比较精细
  194. criteria.setAccuracy(Criteria.ACCURACY_FINE);
  195. // 设置是否要求速度
  196. criteria.setSpeedRequired(true);
  197. // 设置是否允许运营商收费
  198. criteria.setCostAllowed(false);
  199. // 设置是否需要方位信息
  200. criteria.setBearingRequired(false);
  201. // 设置是否需要海拔信息
  202. criteria.setAltitudeRequired(false);
  203. // 设置对电源的需求
  204. criteria.setPowerRequirement(Criteria.POWER_LOW);
  205. return criteria;
  206. }
  207. }

3.5 -SpeedControlView.java 绘制仪表盘

根据数学的math.cos sin tan atan 等绘制图形。这个折叠起来!

  1. /*
  2. * Project Name:PGSL
  3. * File Name:SpeedControlView.java
  4. * Package Name:chenfei.Server
  5. * Date:2017-4-16下午1:51:19
  6. * Copyright (c) 2017, xx@163.com xx Rights Reserved.
  7. *
  8. */
  9. package chenfei.Server;
  10.  
  11. /*
  12. * ClassName:SpeedControlView
  13. * Function: ADD FUNCTION.
  14. * Reason: ADD REASON.
  15. * Date: 2017-4-16 下午1:51:19
  16. * @author xx
  17. * @version
  18. * @since JDK 1.6
  19. */
  20.  
  21. import cgenfei.gz.cn.ComData;
  22. import android.app.Activity;
  23. import android.content.Context;
  24. import android.graphics.Canvas;
  25. import android.graphics.Color;
  26. import android.graphics.LinearGradient;
  27. import android.graphics.Paint;
  28. import android.graphics.RectF;
  29. import android.graphics.Shader;
  30. import android.graphics.Typeface;
  31. import android.util.AttributeSet;
  32. import android.util.DisplayMetrics;
  33. import android.view.View;
  34.  
  35. public class SpeedControlView extends View implements Runnable {
  36.  
  37. private float radius, sRadius; // 圆的半径
  38. private float screenWith, screenHeight;// 屏幕宽高
  39. private float pointX, pointY;// 圆xy坐标
  40. private float baseX, baseY;
  41.  
  42. private Paint mPaint, speedAreaPaint, textPaint;
  43. private float textScale;
  44. // 速度范围的2个扇形外切矩形
  45. private RectF speedRectF, speedRectFInner;
  46. private float mDensitydpi = 0;
  47.  
  48. // 设置速度 并重绘视图
  49. public void refresh() {
  50. postInvalidate();
  51. }
  52.  
  53. public SpeedControlView(Context context) {
  54. super(context);
  55. }
  56.  
  57. public SpeedControlView(Context context, AttributeSet attrs) {
  58. super(context, attrs);
  59.  
  60. screenWith = ((Activity) context).getWindowManager().getDefaultDisplay().getWidth();
  61.  
  62. screenHeight = ((Activity) context).getWindowManager().getDefaultDisplay().getHeight();
  63.  
  64. DisplayMetrics displayMetrice = getResources().getDisplayMetrics();
  65.  
  66. screenWith = displayMetrice.widthPixels;
  67.  
  68. screenHeight = displayMetrice.heightPixels;
  69.  
  70. mDensitydpi = (float) displayMetrice.densityDpi / 320;
  71.  
  72. if (mDensitydpi < 1)
  73. mDensitydpi = 1;
  74.  
  75. setLayerType(LAYER_TYPE_SOFTWARE, null);
  76. mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  77. mPaint.setAntiAlias(true);
  78. mPaint.setStyle(Paint.Style.FILL);
  79. mPaint.setStrokeWidth(5 * mDensitydpi);
  80.  
  81. textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  82. textPaint.setAntiAlias(true);
  83. textPaint.setStyle(Paint.Style.FILL);
  84. textPaint.setColor(Color.parseColor("#76EE00"));
  85. Typeface typeface = Typeface.createFromAsset(context.getAssets(),"kt.ttf");
  86. textPaint.setTypeface(typeface);
  87.  
  88. radius = screenHeight / 2 - 8;
  89. pointX = screenWith / 2;
  90. pointY = screenHeight / 2;
  91. sRadius = radius - 60 * mDensitydpi;
  92.  
  93. // 设置抗锯齿
  94. speedAreaPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
  95. speedAreaPaint.setAntiAlias(true);
  96. // 设置画笔样式
  97. speedAreaPaint.setStyle(Paint.Style.FILL);
  98. // 设置速度范围扇形的渐变颜色
  99. Shader mShader = new LinearGradient(0, 0, 100, 100, new int[] {0x7001EC9, 0xBF001EC9, 0xFF001EC9 }, null,Shader.TileMode.CLAMP);
  100.  
  101. speedAreaPaint.setShader(mShader);
  102.  
  103. // 初始化速度范围的2个扇形外切矩形
  104. speedRectF = new RectF(pointX - radius + 10 * mDensitydpi, pointY
  105. - radius + 10 * mDensitydpi,
  106. pointX + radius - 10 * mDensitydpi, pointY + radius - 10
  107. * mDensitydpi);
  108.  
  109. speedRectFInner = new RectF(pointX - radius / 2, pointY - radius / 2,
  110. pointX + radius / 2, pointY + radius / 2);
  111. }
  112.  
  113. public SpeedControlView(Context context, AttributeSet attrs,int defStyleAttr) {
  114. super(context, attrs, defStyleAttr);
  115. }
  116.  
  117. @Override
  118. protected void onDraw(Canvas canvas) {
  119. super.onDraw(canvas);
  120. // 绘制速度范围扇形区域
  121. speedAreaPaint.setColor(0x7E3F51B5);
  122. drawSpeedArea(canvas);
  123. drawSpeedCircle(canvas);
  124. drawScale(canvas);
  125. for (int i = 0; i < 8; i++) {
  126. drawSpeedText(canvas, i * 6);
  127. }
  128. }
  129.  
  130. // 速度刻度值
  131. private void drawSpeedText(Canvas canvas, int value) {
  132. double hudu = 0;
  133. textPaint.setTextSize(25 * mDensitydpi);
  134. textScale = (int) (textPaint.descent() + textPaint.ascent()) / 2;
  135. String TEXT = String.valueOf(value * 5);
  136. hudu = (2 * Math.PI / 360) * 6 * (value + 39);
  137. baseX = (int) (pointX + Math.sin(hudu) * sRadius - textScale / 2 - textPaint.measureText(TEXT) / 1.5);
  138. baseY = (int) (pointY - Math.cos(hudu) * sRadius - textScale / 2);
  139. canvas.drawText(TEXT, baseX, baseY, textPaint);
  140. }
  141.  
  142. private void drawSpeedCircle(Canvas canvas) {
  143. mPaint.setColor(0xFF343434);
  144. canvas.drawCircle(pointX, pointY, radius, mPaint);
  145.  
  146. // 外圈2个圆
  147. mPaint.setStrokeWidth(4 * mDensitydpi);
  148. mPaint.setStyle(Paint.Style.STROKE);
  149. mPaint.setColor(0xBF3F6AB5);
  150. canvas.drawCircle(pointX, pointY, radius, mPaint);
  151. mPaint.setStrokeWidth(3 * mDensitydpi);
  152. canvas.drawCircle(pointX, pointY, radius - 10 * mDensitydpi, mPaint);
  153.  
  154. // 内圈2个圆
  155. mPaint.setStrokeWidth(5 * mDensitydpi);
  156. mPaint.setColor(0xE73F51B5);
  157. canvas.drawCircle(pointX, pointY, radius / 2, mPaint);
  158. mPaint.setColor(0x7E3F51B5);
  159. canvas.drawCircle(pointX, pointY, radius / 2 + 5 * mDensitydpi, mPaint);
  160.  
  161. // 速度显示lab
  162. textPaint.setTextSize(85 * mDensitydpi);
  163. float textWidth = textPaint.measureText(ComData.spdnow + "");
  164. baseX = (int) (pointX - textWidth / 2);
  165. baseY = (int) (pointY + Math.abs(textPaint.ascent() + textPaint.descent()) / 4);
  166. canvas.drawText(ComData.spdnow + "", baseX, baseY, textPaint);
  167.  
  168. //速度单位lab
  169. textPaint.setTextSize(20 * mDensitydpi);
  170. textWidth = textPaint.measureText("Km/h");
  171. baseX = (int) (pointX - textWidth / 2);
  172. baseY = (int) (pointY + Math.abs(textPaint.ascent()+ textPaint.descent()) / 4);
  173. canvas.drawText("Km/h", baseX, baseY + 50 * mDensitydpi, textPaint);
  174.  
  175. //地理位置lab
  176. textPaint.setTextSize(20 * mDensitydpi);
  177. textWidth = textPaint.measureText(ComData.ads);
  178. baseX = (int) (pointX - textWidth / 2);
  179. baseY = (int) (pointY * 8 / 5) - 2;
  180. canvas.drawText(ComData.ads, baseX, baseY + 50 * mDensitydpi, textPaint);
  181.  
  182. }
  183.  
  184. private void drawScale(Canvas canvas) {
  185. for (int i = 0; i < 60; i++) {
  186. if (i % 6 == 0)
  187. canvas.drawLine(pointX - radius + 10 * mDensitydpi, pointY,pointX - radius + 50 * mDensitydpi, pointY, mPaint);
  188. else
  189. canvas.drawLine(pointX - radius + 10 * mDensitydpi, pointY,pointX - radius + 30 * mDensitydpi, pointY, mPaint);
  190.  
  191. canvas.rotate(6, pointX, pointY);
  192. }
  193. }
  194.  
  195. /**
  196. * 绘制速度区域扇形
  197. */
  198. private void drawSpeedArea(Canvas canvas) {
  199. float degree;
  200. if (ComData.spdnow < 210) {
  201. degree = (float) (ComData.spdnow * 1.2);
  202. } else {
  203. degree = 252;
  204. }
  205.  
  206. canvas.drawArc(speedRectF, 144, degree, true, speedAreaPaint);
  207. mPaint.setStyle(Paint.Style.FILL);
  208. //mPaint.setColor(Color.BLACK);
  209. canvas.drawArc(speedRectFInner, 144, degree, true, mPaint);
  210. mPaint.setStyle(Paint.Style.STROKE);
  211. }
  212.  
  213. @Override
  214. public void run() {
  215. /*while (true) {
  216. try {
  217. Thread.sleep(40);
  218. refresh();
  219. } catch (InterruptedException e) {
  220. e.printStackTrace();
  221. }
  222. }*/
  223. }
  224. }

ok  到了这里应该有一个华丽的分割线了

---------------------------------------------------------------------------------------

以上可以实现仪表盘以及获取GPS等数据的功能了。

下面是要获取该lng lat经纬度所在地名称。

3.6- 抓取XX度的地图经纬度数据。

调用api,然后是这样的获取经纬度

  1. for(lng){
  2. for(lat){
  3. get_xx_api(lng,lat,sign);
  4. }
  5. }

遍历整个中国大地的经度以及纬度,然后会得到一堆json、解析后存储到db文件中、本人存储的方式是这样的做法。

  1. sql="insert into GPS117(lng,lat,ads) values (117.289,40.65,'北京市密云县Y264')"; db.execSQL(sql);
  2. sql="insert into GPS117(lng,lat,ads) values (117.289,40.61,'北京市密云县Y257')"; db.execSQL(sql);
  3. sql="insert into GPS117(lng,lat,ads) values (117.289,40.17,'北京市平谷区韩海路')"; db.execSQL(sql);
  4. sql="insert into GPS117(lng,lat,ads) values (117.289,40.09,'天津市蓟县砖蓟路')"; db.execSQL(sql);
  5. sql="insert into GPS117(lng,lat,ads) values (117.289,40.05,'天津市蓟县S1(津蓟高速)')"; db.execSQL(sql);
  6. sql="insert into GPS117(lng,lat,ads) values (117.289,40.01,'天津市蓟县许邦路')"; db.execSQL(sql);
  7. sql="insert into GPS117(lng,lat,ads) values (117.289,39.890,'天津市蓟县东毛路')"; db.execSQL(sql);
  8. sql="insert into GPS117(lng,lat,ads) values (117.289,39.770,'天津市宝坻区G1(京哈高速)')"; db.execSQL(sql);
  9. sql="insert into GPS117(lng,lat,ads) values (117.289,39.730,'天津市宝坻区西关街')"; db.execSQL(sql);
  10. sql="insert into GPS117(lng,lat,ads) values (117.289,39.690,'天津市宝坻区开元路')"; db.execSQL(sql);
  11. sql="insert into GPS117(lng,lat,ads) values (117.289,39.650,'天津市宝坻区国泰路')"; db.execSQL(sql);

这样的数据很多,获取数据过程中lng和lat的自增因子越小导致代码越多;当然你可以用程序生成、解放双手干其TA的。

有这些代码后就可以在app第一次安装启动时候执行到本地的db中了、是不是很完美呢、解决了不需要网络的大难题。

3.7- DatabaseHelper.java

该类就是程序安装启动时候执行的函数功能类了。

  1. /*
  2. * Project Name:PGSL
  3. * File Name:DatabaseHelper.java
  4. * Package Name:xx.db
  5. * Date:2016-8-16下午1:16:07
  6. * Copyright (c) 2016, xx@163.com xx Rights Reserved.
  7. *
  8. */
  9. package xx.db;
  10.  
  11. import android.content.Context;
  12. import android.database.sqlite.SQLiteDatabase;
  13. import android.database.sqlite.SQLiteOpenHelper;
  14.  
  15. /*
  16. * ClassName:DatabaseHelper
  17. * Function: ADD FUNCTION.
  18. * Reason: ADD REASON.
  19. * Date: 2016-8-16 下午1:16:07
  20. * @author xx
  21. * @version
  22. * @since JDK 1.6
  23. */
  24. public class DatabaseHelper extends SQLiteOpenHelper {
  25. static String name = "xxxxxxxxxxx4dwd6f9w4f4wf4ew5f4ew54f.db";
  26. static int dbVersion = 1;
  27.  
  28. public DatabaseHelper(Context context) {
  29. super(context, name, null, dbVersion);
  30. }
  31.  
  32. // 只在创建的时候用一次
  33. public void onCreate(SQLiteDatabase db) {
  34. CommonTab tab = new CommonTab();
  35. tab.CreateTable(db);
  36. tab = null;
  37.  
  38. CommonDBBASE base = new CommonDBBASE();
  39. base.AddDATA(db); // BASE
  40. base = null;
  41.  
  42. CommonCNOne one = new CommonCNOne();
  43. one.AddDATA(db);
  44. one = null;
  45.  
  46. CommonCNTwo two = new CommonCNTwo();
  47. two.AddDATA(db);
  48. two = null;
  49.  
  50. CommonCNThree three = new CommonCNThree();
  51. three.AddDATA(db);
  52. three = null;
  53.  
  54. CommonCNF fo = new CommonCNF();
  55. fo.AddDATA(db);
  56. fo = null;
  57. }
  58.  
  59. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  60.  
  61. }
  62. }

OK。。。。代码到此结束!

(4)实例图

好了、、、、这是目前本人实现的基于Android系统的车载app。

.

.

.

.

.

.

接下来本人琢磨着使用andrunio做一个类似于某宝上的抬头显示那玩意、、前提是接入汽车预留的接口(一般在方向盘)下面那玩意。

以上!

开发一个基于 Android系统车载智能APP的更多相关文章

  1. ZT自老罗的博客 Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析

    Android系统的智能指针(轻量级指针.强指针和弱指针)的实现原理分析 分类: Android 2011-09-23 00:59 31568人阅读 评论(42) 收藏 举报 androidclass ...

  2. Android系统的智能指针(轻量级指针、强指针和弱指针)的实现原理分析

    文章转载至CSDN社区罗升阳的安卓之旅,原文地址:http://blog.csdn.net/luoshengyang/article/details/6786239 Android 系统的运行时库层代 ...

  3. RP4412开发板在Android系统编译生成ramdisk-uboot.img

    荣品RP4412开发板在android系统编译的时候,怎么生成ramdisk-uboot.img生成流程分析: mkimage -A arm -O linux -T ramdisk -C none - ...

  4. 用VSCode开发一个基于asp.net core 2.0/sql server linux(docker)/ng5/bs4的项目(1)

    最近使用vscode比较多. 学习了一下如何在mac上使用vscode开发asp.netcore项目. 这里是我写的关于vscode的一篇文章: https://www.cnblogs.com/cgz ...

  5. Android Studio 蓝牙开发实例——基于Android 6.0

    因项目需要做一个Android 的蓝牙app来通过手机蓝牙传输数据以及控制飞行器,在此,我对这段时间里写的蓝牙app的代码进行知识梳理和出现错误的总结. 该应用的Compile Sdk Version ...

  6. Android系统自带APP分析——短信app

    Android操作系统本身就是一个巨大的开源软件仓库,熟悉它既可以了解到Android系统的设计框架,也可以获得高效的应用程序编写方式.本文所分析的源码来自于Google官方的AOSP源码4.0.1_ ...

  7. Django完整的开发一个博客系统

    今天花了一些时间搭了一个博客系统,虽然并没有相关于界面的美化,但是发布是没问题的. 开发环境 操作系统:windows 7 64位 Django: 1.96 Python:2.7.11 IDE: Py ...

  8. [转载]查看基于Android 系统单个进程内存、CPU使用情况的几种方法

    转载自: http://www.linuxidc.com/Linux/2011-11/47587.htm 一.利用Android API函数查看1.1 ActivityManager查看可用内存. A ...

  9. [系统开发] 一个基于Django和PureCSS的内容管理系统

    这是我刚开发的一套基于Django和PureCSS的内容管理系统,目标是优雅.简洁.实用,目前功能还在完善中. 系统参考了网上的教程,除了文章管理.搜索.RSS,还增加了类别管理.用户管理,以及评论管 ...

随机推荐

  1. oracle数据库备份、还原 (如何将Oracle 11g备份的dat文件导入到10g数据库里面)

    如何将Oracle 11g备份的dat文件导入到10g数据库里面 解决方法:      导出的时候后面加上目标数据库的版本号   导出: 在SQL plus下执行:create or replace  ...

  2. Spring Framework 5.0 新特性

    Spring Framework 5.0是在Spring Framework 4.0之后将近四年内一次重大的升级. 在这个时间框架内,主要的发展之一就是Spring Boot项目的演变. Spring ...

  3. hdu 4468 spy 极其精彩的一道kmp灵活运用题

    出的超级好的一道题.至于好在哪里,请思考题目: 题意抽象出来为给定一个字符串r,找出它的一个最短后缀s,使得这个r可以被 s的某前缀+s的某前缀+......+s的某前缀+s本身构造出来. 具体题目描 ...

  4. 【NOIP】OpenJudge - 15-02:财务管理

    #include<stdio.h>//财务管理 int main() { ]={},sum=,ave=; ;i<=;i++) { scanf("%f",& ...

  5. python修改注册表

    与注册表操作相关的函数可以分为打开注册表.关闭注册表.读取项值.c添加项值.添加项,以及删除项等几类. 表1   Windows注册表基本项 项名 描述 HKEY_CLASSES_ROOT 是HKEY ...

  6. 配合JdbcUtils最终版重写QueryRunner

    在使用QueryRunner类的时候,直接new本类,无需传递连接池或连接,如果是普通连接,最终释放连接 /** * * 在使用QueryRunner类的时候,直接new本类,无需传递连接池或连接 * ...

  7. Echarts数据可视化dataZoom,开发全解+完美注释

    全栈工程师开发手册 (作者:栾鹏) Echarts数据可视化开发代码注释全解 Echarts数据可视化开发参数配置全解 6大公共组件详解(点击进入): title详解. tooltip详解.toolb ...

  8. 如何抽象一个 Vue 公共组件

    之前一直想写一篇关于抽象 Vue 组件的随笔,无奈一直没想到好的例子.恰巧最近为公司项目做了一个数字键盘的组件,于是就以这个为例聊聊如何抽象 Vue 的组件. 先上 Demo 与 源码.(demo最好 ...

  9. Java继承--子父类中的构造函数

    子父类中的构造函数的特点: 1.在子类构造对象时,发现,访问子类构造函数时,父类构造函数也运行了.   原因是:在子类的构造函数中第一行有一个默认的隐式语句. super(); 类似于this(); ...

  10. 用Eclipse 创建一个 简单的 Maven JavaWeb 项目

    使用Maven 创建一个简单的 javaWeb 项目: 本篇属于 创建 JavaWeb 项目的第三篇: 建议阅读本篇之前 阅读 用 Eclipse 创建一个简单的web项目  ;本篇是这这篇文章的基础 ...