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;
+ }
+}