How to locate data of "android architecture article" from GPS chip to application layer (i)

Source: Internet
Author: User
<span id="Label3"></p><p><p></p></p><pre name="code" class="html"><pre name="code" class="html">Android:v4.2.2source Insight</pre></pre><p><p></p></p>Write in front<p><p>In the long process of compiling the Android source code, I think of a part of the Android positioning implementation of the exploration sketch, so continue to Explore.</p></p><p><p><span style="background-color:rgb(255,0,0)"><strong>Note</strong></span> : The code is a fragmented code that is used to sketchy the description Problem.<br></p></p><p><p><strong><span style="background-color:rgb(51,255,51)">basic knowledge of positioning</span></strong> :<br>1. Communication between the locating chip and the CPU via serial port<br>2, the serial and CPU transmission between the ASCII format of NMEA (national Marine Electronics association) information, such as:<br></p></p><pre name="code" class="html"><pre name="code" class="html">$GPGGA, 092204.999,4250.5589,s,14718.5084,e,1,04,24.4,19.7,m,,,, 0000*1f$gpgll,4250.5589,s,14718.5084,e, 092204.999,a*2d$gpgsv,3,1,10,20,78,331,45,01,59,235,47,22,41,069,,13,32,252,45*70$gprmc,092204.999,a,4250.5589 , s,14718.5084,e,0.00,89.68,211200,,*25</pre></pre>Based on the above two points, the best way to explore the process of locating data from the GPS chip to the application layer is to start from where the application layer outputs the NEMA Information.<p><p></p></p>Application layer realization of GPS positioning<p><p>luckily, at the application level we can obtain the NMEA information through the onnmeareceived () method, as follows code Fragment:</p></p><p><p></p></p><pre name="code" class="java"><pre name="code" class="java">public class Gpstestactivity extends actionbaractivity {/* other Codes *//** get the location services of the system, remember to assign permissions to the location in Androidmanifest: * <uses-permission android:name= "android.permission.ACCESS_FINE_LOCATION"/> * <uses-permission Android:name= "android.permission.ACCESS_LOCATION_EXTRA_COMMANDS"/> * <uses-permission android:name= " Android.permission.ACCESS_COARSE_LOCATION "/> */locationmanager mlocationservice = (locationmanager) Getsystemservice (context.location_service); Mlocationservice.addnmealistener (mnmealistener);p rivate Gpsstatus.nmealistener Mnmealistener = new Nmealistener () {@Overridepublic void onnmeareceived (long timestamp, String Nmea) {System.out.println (nmea + "\ n");}};}</pre></pre><p><p></p></p>second, the implementation of the framework layer of GPS positioning<p><p>Gpsstatus.nmealistener is an interface class from the Gpsstatus.java file:<br></p></p><pre name="code" class="java"><pre name="code" class="java">frameworks\base\location\java\android\location\gpsstatus.java/** * Used for receiving NMEA sentences from the GPS. * NMEA 0183 is a standard for communicating with marine electronic devices * and are a common method for receiving data fro M a GPS, typically over a serial port. * See <a href= ' http://en.wikipedia.org/wiki/NMEA_0183 ' >nmea 0183</a> for more details. * Can implement this interface and call {@link locationmanager#addnmealistener} * To receive NMEA data from the GPS en Gine. */public interface Nmealistener {void onnmeareceived (long timestamp, String nmea);}</pre></pre>In the app above, our application implements this method, and once the NMEA data arrives, the onnmeareceived () method is called once, and we can see the original NEMA information on the Console.<br>So next, look for the source of the NMEA Data.<br><br>Mnmealistener is registered through the Addnmealistener () method of the Locationmanager class (register):<p><p></p></p><p><p></p></p><pre name="code" class="java">frameworks\base\location\java\android\location\locationmanager.java/** * Adds an NMEA listener. * * @param listener a {@link gpsstatus.nmealistener} object to register * * @return True if the listener is successfully Added * * @throws SecurityException If the access_fine_location permission is not present */public Boolean Addnmealistener (gpsstatus.nmealistener Listener) {boolean result;/* Mnmealisteners is a member variable of the Locationmanager class: * Private Final hashmap<gpsstatus.nmealistener, gpsstatuslistenertransport> mnmealisteners = * New hashmap<gpsstatus.nmealistener, GPSSTATUSLISTENERTRANSPO Rt> (); */if (mnmealisteners.get (listener) = Null) {//listener is already registeredreturn true;} Try {gpsstatuslistenertransport transport = new Gpsstatuslistenertransport (listener); result = Mservice.addgpsstatuslistener (transport); if (result) {mnmealisteners.put (listener, transport);}} Catch (remoteexception e) {log.e (TAG, "remoteexception in registergpsstatuslistener:", e); result = False;} Return result;}</pre>here, The first detection of the definition of Nmealistener has been registered, if not, Registered.<br>Where have you been registered?<br>As defined by the Mnmealisteners member, it is the gpsstatuslistenertransport that is associated with gpsstatus.nmealistener, and it is an inner class of the Locationmanager class.<br>See only the relevant sections:<p><p></p></p><p><p></p></p><pre name="code" class="java">This was used to send GPS status events to the client ' s main thread.private class Gpsstatuslistenertransport Exten DS igpsstatuslistener.stub {private final Gpsstatus.nmealistener mnmealistener;//this must not equal any of the Gpsstatus Event idsprivate static final int nmea_received = 1000;private class NMEA {long mtimestamp; String mnmea; NMEA (long timestamp, String nmea) {mtimestamp = Timestamp;mnmea = nmea;}} Private arraylist<nmea> mnmeabuffer;//g psstatuslistenertransport (gpsstatus.listener Listener) {} Gpsstatuslistenertransport (gpsstatus.nmealistener listener) {mnmealistener = Listener;mlistener = Null;mNmeaBuffer = New Arraylist<nmea> ();} @Overridepublic void onnmeareceived (long timestamp, String nmea) {if (mnmealistener! = Null) {synchronized (mnmeabuffer) { Mnmeabuffer.add (new NMEA (timestamp, nmea));} Message msg = message.obtain (); msg.what = nmea_received;//remove any nmea_received messages already in the Queuemgpshandl Er.removemessages (nmea_received); MgpshandLer.sendmessage (msg);}} Private final Handler Mgpshandler = new Handler () {@Overridepublic void handlemessage (Message msg) {if (msg.what = = Nmea_r Eceived) {synchronized (mnmeabuffer) {int length = mnmeabuffer.size (); for (int i = 0; i < length; i++) {nmea NMEA = mNm Eabuffer.get (i); mnmealistener.onnmeareceived (nmea.mtimestamp, nmea.mnmea);} Mnmeabuffer.clear ();}} else {//synchronize on Mgpsstatus to ensure the data is copied atomically.}}};}</pre>In the Gpsstatuslistenertransport class:<br>Define an nmea-type list mnmeabuffer, once onnmeareceived () receives the NMEA data, the new data is loaded into the list mnmeabuffer (mnmeabuffer.add (new NMEA (timestamp, nmea)), the hand message flag is nmea_received (msg.what = nmea_received).<br>Mgpshandler the above nmea_received messages, and eventually sends the NMEA data sent to the application layer gpstestactivity onnmeareceived ().<br>so, who provides the NMEA data for onnmeareceived (long timestamp, String Nmea) method in the Gpsstatuslistenertransport class?<br><br>The Gpsstatuslistenertransport class inherits from igpsstatuslistener, the character "I" before the class, and we know that it is a file with the Extension. aidl.<br>Note:<br>The aidl:aidl mechanism is used to complete communication between processes (it is not allowed to share data between processes in android), and its detailed knowledge is in addition to Google.<br>Here we see again the onnmeareceived ():<br><pre name="code" class="java"><pre name="code" class="java">Rameworks\base\location\java\android\location\igpsstatuslistener.aidloneway Interface IGpsStatusListener{ void ongpsstarted (); void ongpsstopped (); void Onfirstfix (int ttff); void onsvstatuschanged (int svcount, in int[] prns, in float[] snrs, in float[] elevations, in float[] azimuths, int epheme rismask, int almanacmask, int usedinfixmask); void onnmeareceived (long timestamp, String nmea);}</pre></pre><strong><strong><span style="background-color:rgb(255,0,0)">Note</span></strong></strong>:<br>The OneWay keyword is used to decorate the remote invocation Behavior. When using this keyword, the remote call is not blocked, it simply sends the thing data and returns IMMEDIATELY. The final implementation of the interface is to receive normal remote calls in accordance with the calling rules of the binder thread pool, if OneWay is used on local calls, then there is no effect and the call is still asynchronous.<br>below, The inquiry must enter the third Layer.<p><p></p></p>third, the implementation of the LIB layer of GPs positioning<p><p>And the Igpsstatuslistener connector is the Gpslocationprovider class:<br></p></p><pre name="code" class="java">Frameworks\base\services\java\com\android\server\location\gpslocationprovider.javapublic class Gpslocationprovider implements Locationproviderinterface {//omitted here 1000+n line private arraylist<listener> mListeners = new Arraylist<listener> ();p rivate final class Listener implements Ibinder.deathrecipient {final Igpsstatus Listener mlistener; Listener (igpsstatuslistener Listener) {mlistener = Listener; } @Override public void binderdied () {if (DEBUG) log.d (TAG, "GPS status Listener died"); Synchronized (mlisteners) {mlisteners.remove (this); } If (mlistener! = Null) {mlistener.asbinder (). unlinktodeath (this, 0); }}}/** * Called from native code to report NMEA data received */private void Reportnmea (long times Tamp) {synchronized (mlisteners) {int size = mlisteners.size (); If (size > 0) { Don ' t bother creating the String if we have no listeners int length = Native_read_nmea (mnmeabuffer , mnmeabuffer.length); String NMEA = new string (mnmeabuffer, 0, length); for (int i = 0; i < size; i++) {Listener Listener = Mlisteners.get (i); Try {listener.mListener.onNmeaReceived (timestamp, nmea); } catch (remoteexception E) {log.w (TAG, "remoteexception in reportnmea"); Mlisteners.remove (listener); Adjust for size of list changing size--; } } } } }}</pre>The GPS positioning function finally needs to invoke the hardware implementation, the operation hardware must complete through the C + +, Gpslocationprovider contains many native methods, uses the JNI mechanism to provide the service to the upper Layer.<br>In the code frame above, get the NMEA data by calling the local method Native_read_nmea () and then pass the data to the Onnmeareceived () method of the Igpsstatuslistener interface class.<br>Reportnmea () is the method of the Jni method callback, in the implementation of jni, through the callback of these methods to pass the execution result of the JNI layer.<p><p></p></p><p><p><em>The source code compiles the error, solves the problem to ...</em><br></p></p><p><p>Native_read_nmea () is defined in the Gpslocationprovider class:</p></p><p><p></p></p><pre name="code" class="java"><pre name="code" class="java">Private native int Native_read_nmea (byte[] buffer, int buffersize);</pre></pre>Native indicates that it is a local method, and that the implementation of the C + + file corresponding to it is:<br><pre name="code" class="cpp"><pre name="code" class="cpp">Static Jint Android_location_gpslocationprovider_read_nmea (jnienv* env, jobject obj, jbytearray nmeaarray, jint buffer_ size);</pre></pre>how? Next ...<p><p></p></p><p><p></p></p><pre name="code" class="cpp"><pre name="code" class="cpp">Frameworks\base\services\jni\com_android_server_location_gpslocationprovider.cppstatic JNINativeMethod sMethods[ ] = { /* name, signature, funcptr * /* other Members ... * /{"native_read_nmea", "([BI) I", (void*) android_loc ation_gpslocationprovider_read_nmea},/* other members ... */};</pre></pre>Jninativemethod is a way to map the Java and C + + functions used in Android and describes the parameters and return values of the Functions:<p><p></p></p><p><p></p></p><pre name="code" class="cpp"><pre name="code" class="cpp">typedef struct { Const char* Name;//the Local method in the Java file const char* signature;//describes the Function's parameters and return value void* fnptr;// pointer, pointing to the specific C + + function} jninativemethod;</pre></pre>The details are still not open here.<br>See the implementation of Android_location_gpslocationprovider_read_nmea ():<br><pre name="code" class="cpp"><pre name="code" class="cpp">Static Jint Android_location_gpslocationprovider_read_nmea (jnienv* env, jobject obj, jbytearray nmeaarray, jint Buffer_size) { //this should is called from within a call to Reportnmea jbyte* NMEA = (jbyte *) env->getpri Mitivearraycritical (nmeaarray, 0); int length = snmeastringlength; If (length > Buffer_size) length = buffer_size; memcpy (nmea, snmeastring, length); Env->releaseprimitivearraycritical (nmeaarray, nmea, jni_abort); Return length;}</pre></pre><br><br><br><br><p><p></p></p><p><p>Cond.....<br></p></p> <p style="font-size:12px;"><p style="font-size:12px;">Copyright Notice: This article for Bo Master original article, without Bo Master permission not Reproduced.</p></p> <p><p>How to locate data of "android architecture article" from GPS chip to application layer (i)</p></p></span>

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.