diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..7bc01d9 --- /dev/null +++ b/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.project b/.project new file mode 100644 index 0000000..f5a86c8 --- /dev/null +++ b/.project @@ -0,0 +1,33 @@ + + + GPS-NMEA + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.core.resources.prefs b/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/AndroidManifest.xml b/AndroidManifest.xml new file mode 100644 index 0000000..15f32e0 --- /dev/null +++ b/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..f479aaa --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Android Read GPS's NMEA Information + +Demo code for: Android Read GPS's NMEA Information + +範例程式: 讀取Android內建GPS的NMEA資訊 + diff --git a/bin/jarlist.cache b/bin/jarlist.cache new file mode 100644 index 0000000..0565465 --- /dev/null +++ b/bin/jarlist.cache @@ -0,0 +1,3 @@ +# cache for current jar dependency. DO NOT EDIT. +# format is +# Encoding is UTF-8 diff --git a/gen/tw/g35gtw/cms/test/gps_nmea/BuildConfig.java b/gen/tw/g35gtw/cms/test/gps_nmea/BuildConfig.java new file mode 100644 index 0000000..15f2ff8 --- /dev/null +++ b/gen/tw/g35gtw/cms/test/gps_nmea/BuildConfig.java @@ -0,0 +1,6 @@ +/** Automatically generated file. DO NOT MODIFY */ +package tw.g35gtw.cms.test.gps_nmea; + +public final class BuildConfig { + public final static boolean DEBUG = true; +} \ No newline at end of file diff --git a/gen/tw/g35gtw/cms/test/gps_nmea/R.java b/gen/tw/g35gtw/cms/test/gps_nmea/R.java new file mode 100644 index 0000000..3a72aa0 --- /dev/null +++ b/gen/tw/g35gtw/cms/test/gps_nmea/R.java @@ -0,0 +1,76 @@ +/* AUTO-GENERATED FILE. DO NOT MODIFY. + * + * This class was automatically generated by the + * aapt tool from the resource data it found. It + * should not be modified by hand. + */ + +package tw.g35gtw.cms.test.gps_nmea; + +public final class R { + public static final class attr { + } + public static final class dimen { + /** Default screen margins, per the Android Design guidelines. + + Example customization of dimensions originally defined in res/values/dimens.xml + (such as screen margins) for screens with more than 820dp of available width. This + would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). + + */ + public static final int activity_horizontal_margin=0x7f040000; + public static final int activity_vertical_margin=0x7f040001; + } + public static final class drawable { + public static final int ic_launcher=0x7f020000; + } + public static final class id { + public static final int action_settings=0x7f080007; + public static final int container=0x7f080000; + public static final int textGPS_Location=0x7f080004; + public static final int textGPS_Quality=0x7f080002; + public static final int textGPS_Satellites=0x7f080006; + public static final int textView1=0x7f080001; + public static final int textView3=0x7f080003; + public static final int textView5=0x7f080005; + } + public static final class layout { + public static final int activity_main=0x7f030000; + } + public static final class menu { + public static final int main=0x7f070000; + } + public static final class string { + public static final int action_settings=0x7f050002; + public static final int app_name=0x7f050000; + public static final int hello_world=0x7f050001; + } + public static final class style { + /** + Base application theme, dependent on API level. This theme is replaced + by AppBaseTheme from res/values-vXX/styles.xml on newer devices. + + + Theme customizations available in newer API levels can go in + res/values-vXX/styles.xml, while customizations related to + backward-compatibility can go here. + + + Base application theme for API 11+. This theme completely replaces + AppBaseTheme from res/values/styles.xml on API 11+ devices. + + API 11 theme customizations can go here. + + Base application theme for API 14+. This theme completely replaces + AppBaseTheme from BOTH res/values/styles.xml and + res/values-v11/styles.xml on API 14+ devices. + + API 14 theme customizations can go here. + */ + public static final int AppBaseTheme=0x7f060000; + /** Application theme. + All customizations that are NOT specific to a particular API-level can go here. + */ + public static final int AppTheme=0x7f060001; + } +} diff --git a/ic_launcher-web.png b/ic_launcher-web.png new file mode 100644 index 0000000..a18cbb4 Binary files /dev/null and b/ic_launcher-web.png differ diff --git a/libs/android-support-v4.jar b/libs/android-support-v4.jar new file mode 100644 index 0000000..96644ed Binary files /dev/null and b/libs/android-support-v4.jar differ diff --git a/proguard-project.txt b/proguard-project.txt new file mode 100644 index 0000000..f2fe155 --- /dev/null +++ b/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/project.properties b/project.properties new file mode 100644 index 0000000..af27382 --- /dev/null +++ b/project.properties @@ -0,0 +1,16 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +android.library.reference.1=../appcompat_v7_2 +android.library.reference.2=../appcompat_v7_3 +# Project target. +target=android-19 diff --git a/res/drawable-hdpi/ic_launcher.png b/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000..288b665 Binary files /dev/null and b/res/drawable-hdpi/ic_launcher.png differ diff --git a/res/drawable-mdpi/ic_launcher.png b/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..6ae570b Binary files /dev/null and b/res/drawable-mdpi/ic_launcher.png differ diff --git a/res/drawable-xhdpi/ic_launcher.png b/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000..d4fb7cd Binary files /dev/null and b/res/drawable-xhdpi/ic_launcher.png differ diff --git a/res/drawable-xxhdpi/ic_launcher.png b/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..85a6081 Binary files /dev/null and b/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/res/layout/activity_main.xml b/res/layout/activity_main.xml new file mode 100644 index 0000000..7f84245 --- /dev/null +++ b/res/layout/activity_main.xml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/menu/main.xml b/res/menu/main.xml new file mode 100644 index 0000000..b2ce368 --- /dev/null +++ b/res/menu/main.xml @@ -0,0 +1,11 @@ + + + + + diff --git a/res/values-v11/styles.xml b/res/values-v11/styles.xml new file mode 100644 index 0000000..3c02242 --- /dev/null +++ b/res/values-v11/styles.xml @@ -0,0 +1,11 @@ + + + + + + diff --git a/res/values-v14/styles.xml b/res/values-v14/styles.xml new file mode 100644 index 0000000..a91fd03 --- /dev/null +++ b/res/values-v14/styles.xml @@ -0,0 +1,12 @@ + + + + + + diff --git a/res/values-w820dp/dimens.xml b/res/values-w820dp/dimens.xml new file mode 100644 index 0000000..f3e7020 --- /dev/null +++ b/res/values-w820dp/dimens.xml @@ -0,0 +1,10 @@ + + + + 64dp + + diff --git a/res/values/dimens.xml b/res/values/dimens.xml new file mode 100644 index 0000000..55c1e59 --- /dev/null +++ b/res/values/dimens.xml @@ -0,0 +1,7 @@ + + + + 16dp + 16dp + + diff --git a/res/values/strings.xml b/res/values/strings.xml new file mode 100644 index 0000000..6fb5769 --- /dev/null +++ b/res/values/strings.xml @@ -0,0 +1,8 @@ + + + + GPS-NMEA + Hello world! + Settings + + diff --git a/res/values/styles.xml b/res/values/styles.xml new file mode 100644 index 0000000..6ce89c7 --- /dev/null +++ b/res/values/styles.xml @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/src/tw/g35gtw/cms/test/gps_nmea/MainActivity.java b/src/tw/g35gtw/cms/test/gps_nmea/MainActivity.java new file mode 100644 index 0000000..c25fcbf --- /dev/null +++ b/src/tw/g35gtw/cms/test/gps_nmea/MainActivity.java @@ -0,0 +1,288 @@ +package tw.g35gtw.cms.test.gps_nmea; + +import java.util.Iterator; + +import android.app.Activity; +import android.app.ActionBar; +import android.app.Fragment; +import android.content.Context; +import android.location.Criteria; +import android.location.GpsSatellite; +import android.location.GpsStatus; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.location.LocationProvider; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewGroup; +import android.widget.TextView; +import android.os.Build; + +/* 日期:2014/04/09 + * 功能:讀取內建GPS的NMEA資料 + * 作者:Danny + * 網站:http://cms.35g.tw/coding + */ +/* date:2014/04/09 + * description:read nmea data from internal GPS + * author:Danny + * website:http://cms.35g.tw/coding + */ + + +public class MainActivity extends Activity { + private LocationManager locationManager=null; + private Criteria criteria=null; + private LocationListener locationListener = null; + private GpsStatus.NmeaListener nmeaListener = null; + private GpsStatus.Listener gpsStatusListener = null; + private TextView txtGPS_Quality = null; + private TextView txtGPS_Location = null; + private TextView txtGPS_Satellites = null; + // + private Handler mHandler = null; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + + // + txtGPS_Quality = (TextView) findViewById(R.id.textGPS_Quality); + txtGPS_Location = (TextView) findViewById(R.id.textGPS_Location); + txtGPS_Satellites = (TextView) findViewById(R.id.textGPS_Satellites); + registerHandler(); + registerListener(); + locationManager=(LocationManager)getSystemService(Context.LOCATION_SERVICE); + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, locationListener); + locationManager.addNmeaListener(nmeaListener); + // + // + + + + } + + +@Override +protected void onDestroy() { + // TODO Auto-generated method stub + super.onDestroy(); + locationManager.removeUpdates(locationListener); + locationManager.removeNmeaListener(nmeaListener); +} + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + //if (id == R.id.action_settings) { + // return true; + //} + return super.onOptionsItemSelected(item); + } + + private void registerListener(){ + locationListener=new LocationListener(){ + + @Override + public void onLocationChanged(Location loc) { + // TODO Auto-generated method stub + //定位資料更新時會回呼 + Log.d("GPS-NMEA", loc.getLatitude() + "," + loc.getLongitude()); + } + + @Override + public void onProviderDisabled(String provider) { + // TODO Auto-generated method stub + //定位提供者如果關閉時會回呼,並將關閉的提供者傳至provider字串中 + } + + @Override + public void onProviderEnabled(String provider) { + // TODO Auto-generated method stub + //定位提供者如果開啟時會回呼,並將開啟的提供者傳至provider字串中 + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + // TODO Auto-generated method stub + Log.d("GPS-NMEA", provider + ""); + //GPS狀態提供,這只有提供者為gps時才會動作 + switch (status) { + case LocationProvider.OUT_OF_SERVICE: + Log.d("GPS-NMEA","OUT_OF_SERVICE"); + break; + case LocationProvider.TEMPORARILY_UNAVAILABLE: + Log.d("GPS-NMEA"," TEMPORARILY_UNAVAILABLE"); + break; + case LocationProvider.AVAILABLE: + Log.d("GPS-NMEA","" + provider + ""); + + break; + } + + } + + }; +// + nmeaListener = new GpsStatus.NmeaListener() { + public void onNmeaReceived(long timestamp, String nmea) { + //check nmea's checksum + if (isValidForNmea(nmea)){ + nmeaProgress(nmea); + Log.d("GPS-NMEA", nmea); + } + + } + }; +// + gpsStatusListener = new GpsStatus.Listener(){ + public void onGpsStatusChanged(int event) { + // TODO Auto-generated method stub + GpsStatus gpsStatus; + gpsStatus= locationManager.getGpsStatus(null); + + switch(event) + { + case GpsStatus.GPS_EVENT_FIRST_FIX: + // + gpsStatus.getTimeToFirstFix(); + Log.d("GPS-NMEA","GPS_EVENT_FIRST_FIX"); + break; + case GpsStatus.GPS_EVENT_SATELLITE_STATUS: + + Iterable allSatellites = gpsStatus.getSatellites(); + Iterator it=allSatellites.iterator(); + + int count = 0; + while(it.hasNext()) + { + GpsSatellite gsl=(GpsSatellite)it.next(); + + if (gsl.getSnr()>0.0){ + count++; + } + + } + + + break; + case GpsStatus.GPS_EVENT_STARTED: + //Event sent when the GPS system has started. + Log.d("GPS-NMEA","GPS_EVENT_STARTED"); + break; + case GpsStatus.GPS_EVENT_STOPPED: + //Event sent when the GPS system has stopped. + Log.d("GPS-NMEA","GPS_EVENT_STOPPED"); + break; + default : + break; + } + } + + }; + + } + +private void registerHandler(){ + /* + GGA Global Positioning System Fix Data. Time, Position and fix related data for a GPS receiver + 11 + 1 2 34 5678 910|121314 15 + ||||||||||||||| $--GGA,hhmmss.ss,llll.ll,a,yyyyy.yy,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh + 1) Time (UTC) + 2) Latitude + 3) N or S (North or South) + 4) Longitude + 5) E or W (East or West) + 6) GPS Quality Indicator, + 0 - fix not available, + 1 - GPS fix, + 2 - Differential GPS fix + 7) Number of satellites in view, 00 - 12 + 8) Horizontal Dilution of precision + 9) Antenna Altitude above/below mean-sea-level (geoid) + 10) Units of antenna altitude, meters + 11) Geoidal separation, the difference between the WGS-84 earth + ellipsoid and mean-sea-level (geoid), "-" means mean-sea-level below ellipsoid + 12) Units of geoidal separation, meters + 13) Age of differential GPS data, time in seconds since last SC104 + type 1 or 9 update, null field when DGPS is not used + 14) Differential reference station ID, 0000-1023 + 15) Checksum + */ + mHandler = new Handler() { + public void handleMessage(Message msg) { + + String str = (String) msg.obj; + String[] rawNmeaSplit = str.split(","); + txtGPS_Quality.setText(rawNmeaSplit[6]); + txtGPS_Location.setText(rawNmeaSplit[2] + " " + rawNmeaSplit[3] + "," + rawNmeaSplit[4] + " " + rawNmeaSplit[5]); + txtGPS_Satellites.setText(rawNmeaSplit[7]); + + } + }; + + +} +//custom +//取得nmea資料的callback + private void nmeaProgress(String rawNmea){ + + String[] rawNmeaSplit = rawNmea.split(","); + + if (rawNmeaSplit[0].equalsIgnoreCase("$GPGGA")){ + //send GGA nmea data to handler + Message msg = new Message(); + msg.obj = rawNmea; + mHandler.sendMessage(msg); + } + + } + + + private boolean isValidForNmea(String rawNmea){ + boolean valid = true; + byte[] bytes = rawNmea.getBytes(); + int checksumIndex = rawNmea.indexOf("*"); + //NMEA 星號後為checksum number + byte checksumCalcValue = 0; + int checksumValue; + + //檢查開頭是否為$ + if ((rawNmea.charAt(0) != '$') || (checksumIndex==-1)){ + valid = false; + } + // + if (valid){ + String val = rawNmea.substring(checksumIndex + 1, rawNmea.length()).trim(); + checksumValue = Integer.parseInt(val, 16); + for (int i = 1; i < checksumIndex; i++){ + checksumCalcValue = (byte) (checksumCalcValue ^ bytes[i]); + } + if (checksumValue != checksumCalcValue){ + valid = false; + } + } + return valid; + } +}