zoukankan      html  css  js  c++  java
  • Android之指南针(电子罗盘)学习

    点我下载源码

    5月12日更新到V5版:http://download.csdn.net/detail/weidi1989/5364243

    今天,在小米的开源项目中下载了一个指南针源码学习了一下,感觉不仅界面做得很漂亮,代码也是很精致,所以我在研究了之后,加了比较多的注释,果断跟大家分享一下,很精简的几段代码,仔细品味可以学到很多东西,我稍微总结一下:

    ①.handler的灵活运用,每20秒后执行一次自己,用来检测方向变化值,更新指南针旋转。

    ②.传感器和谷歌位置服务的使用。

    ③.自定义View,这里面是自定义一个ImageView,自己增加一个旋转图片的方法。

    ④.Android动画Interpolator插入器:AccelerateInterpolator加速插入器的运用。顺便说一下另外几个插入器:

                                         ——AccelerateInterpolator:动画从开始到结束,变化率是一个加速的过程。

                                         ——DecelerateInterpolator:动画从开始到结束,变化率是一个减速的过程。

                                         ——CycleInterpolator:动画从开始到结束,变化率是循环给定次数的正弦曲线。

                                        ——AccelerateDecelerateInterpolator:动画从开始到结束,变化率是先加速后减速的过程。

                                         ——LinearInterpolator:动画从开始到结束,变化率是线性变化。
                                        AccelerateInterpolator有一个方法:getInterpolation(float input);

    ⑤.巧妙的数字替换成对应的数字图片和根据本地语言使用对应的图片资源(图片资源国际化,哈哈)。还有一些其他的小知识,朋友们,自己下载去研究吧!

     

    下面看一下效果图(我的是模拟器,木有传感器也木有定位的):

    下面我们来看一下这个界面的布局文件(main.xml):

    1. <?xml version="1.0" encoding="UTF-8"?>  
    2. <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    3.     android:layout_width="fill_parent"  
    4.     android:layout_height="fill_parent" >  
    5.   
    6.     <FrameLayout  
    7.         android:layout_width="fill_parent"  
    8.         android:layout_height="fill_parent"  
    9.         android:background="@drawable/background" >  
    10.   
    11.         <LinearLayout  
    12.             android:id="@+id/view_compass"  
    13.             android:layout_width="fill_parent"  
    14.             android:layout_height="fill_parent"  
    15.             android:background="@drawable/background_light"  
    16.             android:orientation="vertical" >  
    17.   
    18.             <LinearLayout  
    19.                 android:layout_width="fill_parent"  
    20.                 android:layout_height="0dip"  
    21.                 android:layout_weight="1"  
    22.                 android:orientation="vertical" >  
    23.   
    24.                 <FrameLayout  
    25.                     android:layout_width="fill_parent"  
    26.                     android:layout_height="wrap_content"  
    27.                     android:background="@drawable/prompt" >  
    28.   
    29.                     <LinearLayout  
    30.                         android:layout_width="fill_parent"  
    31.                         android:layout_height="wrap_content"  
    32.                         android:layout_gravity="center_horizontal"  
    33.                         android:layout_marginTop="70dip"  
    34.                         android:orientation="horizontal" >  
    35.   
    36.                         <LinearLayout  
    37.                             android:id="@+id/layout_direction"  
    38.                             android:layout_width="0dip"  
    39.                             android:layout_height="wrap_content"  
    40.                             android:layout_weight="1"  
    41.                             android:gravity="right"  
    42.                             android:orientation="horizontal" >  
    43.                         </LinearLayout>  
    44.   
    45.                         <ImageView  
    46.                             android:layout_width="20dip"  
    47.                             android:layout_height="fill_parent" >  
    48.                         </ImageView>  
    49.   
    50.                         <LinearLayout  
    51.                             android:id="@+id/layout_angle"  
    52.                             android:layout_width="0dip"  
    53.                             android:layout_height="wrap_content"  
    54.                             android:layout_weight="1"  
    55.                             android:gravity="left"  
    56.                             android:orientation="horizontal" >  
    57.                         </LinearLayout>  
    58.                     </LinearLayout>  
    59.                 </FrameLayout>  
    60.   
    61.                 <LinearLayout  
    62.                     android:layout_width="fill_parent"  
    63.                     android:layout_height="0dip"  
    64.                     android:layout_weight="1"  
    65.                     android:orientation="vertical" >  
    66.   
    67.                     <FrameLayout  
    68.                         android:layout_width="fill_parent"  
    69.                         android:layout_height="wrap_content"  
    70.                         android:layout_gravity="center" >  
    71.   
    72.                         <ImageView  
    73.                             android:layout_width="wrap_content"  
    74.                             android:layout_height="wrap_content"  
    75.                             android:layout_gravity="center"  
    76.                             android:src="@drawable/background_compass" />  
    77.   
    78.                         <net.micode.compass.CompassView  
    79.                             android:id="@+id/compass_pointer"  
    80.                             android:layout_width="wrap_content"  
    81.                             android:layout_height="wrap_content"  
    82.                             android:layout_gravity="center"  
    83.                             android:src="@drawable/compass" />  
    84.   
    85.                         <ImageView  
    86.                             android:layout_width="wrap_content"  
    87.                             android:layout_height="wrap_content"  
    88.                             android:layout_gravity="center"  
    89.                             android:src="@drawable/miui_cover" />  
    90.                     </FrameLayout>  
    91.                 </LinearLayout>  
    92.             </LinearLayout>  
    93.   
    94.             <FrameLayout  
    95.                 android:id="@+id/location_layout"  
    96.                 android:layout_width="fill_parent"  
    97.                 android:layout_height="wrap_content" >  
    98.   
    99.                 <LinearLayout  
    100.                     android:layout_width="fill_parent"  
    101.                     android:layout_height="wrap_content"  
    102.                     android:background="@drawable/background_bottom"  
    103.                     android:orientation="vertical" >  
    104.                 </LinearLayout>  
    105.   
    106.                 <TextView  
    107.                     android:id="@+id/textview_location"  
    108.                     android:layout_width="wrap_content"  
    109.                     android:layout_height="wrap_content"  
    110.                     android:layout_gravity="center"  
    111.                     android:text="@string/getting_location"  
    112.                     android:textAppearance="?android:attr/textAppearanceMedium"  
    113.                     android:textColor="#7FFFFFFF" />  
    114.             </FrameLayout>  
    115.         </LinearLayout>  
    116.     </FrameLayout>  
    117.   
    118. </FrameLayout>  


    这其中用到了一个自定义view,其实就是中间那个可以旋转的指南针,我们也来看看它的代码(CompassView.java):

    1. /** 
    2.  * 自定义一个View继承ImageView,增加一个通用的旋转图片资源的方法 
    3.  *  
    4.  * @author way 
    5.  *  
    6.  */  
    7. public class CompassView extends ImageView {  
    8.     private float mDirection;// 方向旋转浮点数  
    9.     private Drawable compass;// 图片资源  
    10.       
    11.     //三个构造器  
    12.     public CompassView(Context context) {  
    13.         super(context);  
    14.         mDirection = 0.0f;// 默认不旋转  
    15.         compass = null;  
    16.     }  
    17.   
    18.     public CompassView(Context context, AttributeSet attrs) {  
    19.         super(context, attrs);  
    20.         mDirection = 0.0f;  
    21.         compass = null;  
    22.     }  
    23.   
    24.     public CompassView(Context context, AttributeSet attrs, int defStyle) {  
    25.         super(context, attrs, defStyle);  
    26.         mDirection = 0.0f;  
    27.         compass = null;  
    28.     }  
    29.   
    30.     @Override  
    31.     protected void onDraw(Canvas canvas) {  
    32.         if (compass == null) {  
    33.             compass = getDrawable();// 获取当前view的图片资源  
    34.             compass.setBounds(0, 0, getWidth(), getHeight());// 图片资源在view的位置,此处相当于充满view  
    35.         }  
    36.   
    37.         canvas.save();  
    38.         canvas.rotate(mDirection, getWidth() / 2, getHeight() / 2);// 绕图片中心点旋转,  
    39.         compass.draw(canvas);// 把旋转后的图片画在view上,即保持旋转后的样子  
    40.         canvas.restore();// 保存一下  
    41.     }  
    42.   
    43.     /** 
    44.      * 自定义更新方向的方法 
    45.      *  
    46.      * @param direction 
    47.      *            传入的方向 
    48.      */  
    49.     public void updateDirection(float direction) {  
    50.         mDirection = direction;  
    51.         invalidate();// 重新刷新一下,更新方向  
    52.     }  
    53.   
    54. }  


    接下来就只剩下一个Activity了,其实总体结构还是很简单的,CompassActivity.java:

    1. /** 
    2.  * MainActivity 
    3.  *  
    4.  * @author way 
    5.  *  
    6.  */  
    7. public class CompassActivity extends Activity {  
    8.     private static final int EXIT_TIME = 2000;// 两次按返回键的间隔判断  
    9.     private final float MAX_ROATE_DEGREE = 1.0f;// 最多旋转一周,即360°  
    10.     private SensorManager mSensorManager;// 传感器管理对象  
    11.     private Sensor mOrientationSensor;// 传感器对象  
    12.     private LocationManager mLocationManager;// 位置管理对象  
    13.     private String mLocationProvider;// 位置提供者名称,GPS设备还是网络  
    14.     private float mDirection;// 当前浮点方向  
    15.     private float mTargetDirection;// 目标浮点方向  
    16.     private AccelerateInterpolator mInterpolator;// 动画从开始到结束,变化率是一个加速的过程,就是一个动画速率  
    17.     protected final Handler mHandler = new Handler();  
    18.     private boolean mStopDrawing;// 是否停止指南针旋转的标志位  
    19.     private boolean mChinease;// 系统当前是否使用中文  
    20.     private long firstExitTime = 0L;// 用来保存第一次按返回键的时间  
    21.   
    22.     View mCompassView;  
    23.     CompassView mPointer;// 指南针view  
    24.     TextView mLocationTextView;// 显示位置的view  
    25.     LinearLayout mDirectionLayout;// 显示方向(东南西北)的view  
    26.     LinearLayout mAngleLayout;// 显示方向度数的view  
    27.   
    28.     // 这个是更新指南针旋转的线程,handler的灵活使用,每20毫秒检测方向变化值,对应更新指南针旋转  
    29.     protected Runnable mCompassViewUpdater = new Runnable() {  
    30.         @Override  
    31.         public void run() {  
    32.             if (mPointer != null && !mStopDrawing) {  
    33.                 if (mDirection != mTargetDirection) {  
    34.   
    35.                     // calculate the short routine  
    36.                     float to = mTargetDirection;  
    37.                     if (to - mDirection > 180) {  
    38.                         to -= 360;  
    39.                     } else if (to - mDirection < -180) {  
    40.                         to += 360;  
    41.                     }  
    42.   
    43.                     // limit the max speed to MAX_ROTATE_DEGREE  
    44.                     float distance = to - mDirection;  
    45.                     if (Math.abs(distance) > MAX_ROATE_DEGREE) {  
    46.                         distance = distance > 0 ? MAX_ROATE_DEGREE  
    47.                                 : (-1.0f * MAX_ROATE_DEGREE);  
    48.                     }  
    49.   
    50.                     // need to slow down if the distance is short  
    51.                     mDirection = normalizeDegree(mDirection  
    52.                             + ((to - mDirection) * mInterpolator  
    53.                                     .getInterpolation(Math.abs(distance) > MAX_ROATE_DEGREE ? 0.4f  
    54.                                             : 0.3f)));// 用了一个加速动画去旋转图片,很细致  
    55.                     mPointer.updateDirection(mDirection);// 更新指南针旋转  
    56.                 }  
    57.   
    58.                 updateDirection();// 更新方向值  
    59.   
    60.                 mHandler.postDelayed(mCompassViewUpdater, 20);// 20毫米后重新执行自己,比定时器好  
    61.             }  
    62.         }  
    63.     };  
    64.   
    65.     @Override  
    66.     protected void onCreate(Bundle savedInstanceState) {  
    67.         super.onCreate(savedInstanceState);  
    68.         setContentView(R.layout.main);  
    69.         initResources();// 初始化view  
    70.         initServices();// 初始化传感器和位置服务  
    71.     }  
    72.   
    73.     @Override  
    74.     public void onBackPressed() {// 覆盖返回键  
    75.         long curTime = System.currentTimeMillis();  
    76.         if (curTime - firstExitTime < EXIT_TIME) {// 两次按返回键的时间小于2秒就退出应用  
    77.             finish();  
    78.         } else {  
    79.             Toast.makeText(this, R.string.exit_toast, Toast.LENGTH_SHORT)  
    80.                     .show();  
    81.             firstExitTime = curTime;  
    82.         }  
    83.     }  
    84.   
    85.     @Override  
    86.     protected void onResume() {// 在恢复的生命周期里判断、启动位置更新服务和传感器服务  
    87.         super.onResume();  
    88.         if (mLocationProvider != null) {  
    89.             updateLocation(mLocationManager  
    90.                     .getLastKnownLocation(mLocationProvider));  
    91.             mLocationManager.requestLocationUpdates(mLocationProvider, 2000,  
    92.                     10, mLocationListener);// 2秒或者距离变化10米时更新一次地理位置  
    93.         } else {  
    94.             mLocationTextView.setText(R.string.cannot_get_location);  
    95.         }  
    96.         if (mOrientationSensor != null) {  
    97.             mSensorManager.registerListener(mOrientationSensorEventListener,  
    98.                     mOrientationSensor, SensorManager.SENSOR_DELAY_GAME);  
    99.         } else {  
    100.             Toast.makeText(this, R.string.cannot_get_sensor, Toast.LENGTH_SHORT)  
    101.                     .show();  
    102.         }  
    103.         mStopDrawing = false;  
    104.         mHandler.postDelayed(mCompassViewUpdater, 20);// 20毫秒执行一次更新指南针图片旋转  
    105.     }  
    106.   
    107.     @Override  
    108.     protected void onPause() {// 在暂停的生命周期里注销传感器服务和位置更新服务  
    109.         super.onPause();  
    110.         mStopDrawing = true;  
    111.         if (mOrientationSensor != null) {  
    112.             mSensorManager.unregisterListener(mOrientationSensorEventListener);  
    113.         }  
    114.         if (mLocationProvider != null) {  
    115.             mLocationManager.removeUpdates(mLocationListener);  
    116.         }  
    117.     }  
    118.   
    119.     // 初始化view  
    120.     private void initResources() {  
    121.         mDirection = 0.0f;// 初始化起始方向  
    122.         mTargetDirection = 0.0f;// 初始化目标方向  
    123.         mInterpolator = new AccelerateInterpolator();// 实例化加速动画对象  
    124.         mStopDrawing = true;  
    125.         mChinease = TextUtils.equals(Locale.getDefault().getLanguage(), "zh");// 判断系统当前使用的语言是否为中文  
    126.   
    127.         mCompassView = findViewById(R.id.view_compass);// 实际上是一个LinearLayout,装指南针ImageView和位置TextView  
    128.         mPointer = (CompassView) findViewById(R.id.compass_pointer);// 自定义的指南针view  
    129.         mLocationTextView = (TextView) findViewById(R.id.textview_location);// 显示位置信息的TextView  
    130.         mDirectionLayout = (LinearLayout) findViewById(R.id.layout_direction);// 顶部显示方向名称(东南西北)的LinearLayout  
    131.         mAngleLayout = (LinearLayout) findViewById(R.id.layout_angle);// 顶部显示方向具体度数的LinearLayout  
    132.   
    133.         mPointer.setImageResource(mChinease ? R.drawable.compass_cn  
    134.                 : R.drawable.compass);// 如果系统使用中文,就用中文的指南针图片  
    135.     }  
    136.   
    137.     // 初始化传感器和位置服务  
    138.     private void initServices() {  
    139.         // sensor manager  
    140.         mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);  
    141.         mOrientationSensor = mSensorManager  
    142.                 .getDefaultSensor(Sensor.TYPE_ORIENTATION);  
    143.   
    144.         // location manager  
    145.         mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);  
    146.         Criteria criteria = new Criteria();// 条件对象,即指定条件过滤获得LocationProvider  
    147.         criteria.setAccuracy(Criteria.ACCURACY_FINE);// 较高精度  
    148.         criteria.setAltitudeRequired(false);// 是否需要高度信息  
    149.         criteria.setBearingRequired(false);// 是否需要方向信息  
    150.         criteria.setCostAllowed(true);// 是否产生费用  
    151.         criteria.setPowerRequirement(Criteria.POWER_LOW);// 设置低电耗  
    152.         mLocationProvider = mLocationManager.getBestProvider(criteria, true);// 获取条件最好的Provider  
    153.   
    154.     }  
    155.   
    156.     // 更新顶部方向显示的方法  
    157.     private void updateDirection() {  
    158.         LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,  
    159.                 LayoutParams.WRAP_CONTENT);  
    160.         // 先移除layout中所有的view  
    161.         mDirectionLayout.removeAllViews();  
    162.         mAngleLayout.removeAllViews();  
    163.   
    164.         // 下面是根据mTargetDirection,作方向名称图片的处理  
    165.         ImageView east = null;  
    166.         ImageView west = null;  
    167.         ImageView south = null;  
    168.         ImageView north = null;  
    169.         float direction = normalizeDegree(mTargetDirection * -1.0f);  
    170.         if (direction > 22.5f && direction < 157.5f) {  
    171.             // east  
    172.             east = new ImageView(this);  
    173.             east.setImageResource(mChinease ? R.drawable.e_cn : R.drawable.e);  
    174.             east.setLayoutParams(lp);  
    175.         } else if (direction > 202.5f && direction < 337.5f) {  
    176.             // west  
    177.             west = new ImageView(this);  
    178.             west.setImageResource(mChinease ? R.drawable.w_cn : R.drawable.w);  
    179.             west.setLayoutParams(lp);  
    180.         }  
    181.   
    182.         if (direction > 112.5f && direction < 247.5f) {  
    183.             // south  
    184.             south = new ImageView(this);  
    185.             south.setImageResource(mChinease ? R.drawable.s_cn : R.drawable.s);  
    186.             south.setLayoutParams(lp);  
    187.         } else if (direction < 67.5 || direction > 292.5f) {  
    188.             // north  
    189.             north = new ImageView(this);  
    190.             north.setImageResource(mChinease ? R.drawable.n_cn : R.drawable.n);  
    191.             north.setLayoutParams(lp);  
    192.         }  
    193.         // 下面是根据系统使用语言,更换对应的语言图片资源  
    194.         if (mChinease) {  
    195.             // east/west should be before north/south  
    196.             if (east != null) {  
    197.                 mDirectionLayout.addView(east);  
    198.             }  
    199.             if (west != null) {  
    200.                 mDirectionLayout.addView(west);  
    201.             }  
    202.             if (south != null) {  
    203.                 mDirectionLayout.addView(south);  
    204.             }  
    205.             if (north != null) {  
    206.                 mDirectionLayout.addView(north);  
    207.             }  
    208.         } else {  
    209.             // north/south should be before east/west  
    210.             if (south != null) {  
    211.                 mDirectionLayout.addView(south);  
    212.             }  
    213.             if (north != null) {  
    214.                 mDirectionLayout.addView(north);  
    215.             }  
    216.             if (east != null) {  
    217.                 mDirectionLayout.addView(east);  
    218.             }  
    219.             if (west != null) {  
    220.                 mDirectionLayout.addView(west);  
    221.             }  
    222.         }  
    223.         // 下面是根据方向度数显示度数图片数字  
    224.         int direction2 = (int) direction;  
    225.         boolean show = false;  
    226.         if (direction2 >= 100) {  
    227.             mAngleLayout.addView(getNumberImage(direction2 / 100));  
    228.             direction2 %= 100;  
    229.             show = true;  
    230.         }  
    231.         if (direction2 >= 10 || show) {  
    232.             mAngleLayout.addView(getNumberImage(direction2 / 10));  
    233.             direction2 %= 10;  
    234.         }  
    235.         mAngleLayout.addView(getNumberImage(direction2));  
    236.         // 下面是增加一个°的图片  
    237.         ImageView degreeImageView = new ImageView(this);  
    238.         degreeImageView.setImageResource(R.drawable.degree);  
    239.         degreeImageView.setLayoutParams(lp);  
    240.         mAngleLayout.addView(degreeImageView);  
    241.     }  
    242.   
    243.     // 获取方向度数对应的图片,返回ImageView  
    244.     private ImageView getNumberImage(int number) {  
    245.         ImageView image = new ImageView(this);  
    246.         LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT,  
    247.                 LayoutParams.WRAP_CONTENT);  
    248.         switch (number) {  
    249.         case 0:  
    250.             image.setImageResource(R.drawable.number_0);  
    251.             break;  
    252.         case 1:  
    253.             image.setImageResource(R.drawable.number_1);  
    254.             break;  
    255.         case 2:  
    256.             image.setImageResource(R.drawable.number_2);  
    257.             break;  
    258.         case 3:  
    259.             image.setImageResource(R.drawable.number_3);  
    260.             break;  
    261.         case 4:  
    262.             image.setImageResource(R.drawable.number_4);  
    263.             break;  
    264.         case 5:  
    265.             image.setImageResource(R.drawable.number_5);  
    266.             break;  
    267.         case 6:  
    268.             image.setImageResource(R.drawable.number_6);  
    269.             break;  
    270.         case 7:  
    271.             image.setImageResource(R.drawable.number_7);  
    272.             break;  
    273.         case 8:  
    274.             image.setImageResource(R.drawable.number_8);  
    275.             break;  
    276.         case 9:  
    277.             image.setImageResource(R.drawable.number_9);  
    278.             break;  
    279.         }  
    280.         image.setLayoutParams(lp);  
    281.         return image;  
    282.     }  
    283.   
    284.     // 更新位置显示  
    285.     private void updateLocation(Location location) {  
    286.         if (location == null) {  
    287.             mLocationTextView.setText(R.string.getting_location);  
    288.         } else {  
    289.             StringBuilder sb = new StringBuilder();  
    290.             double latitude = location.getLatitude();  
    291.             double longitude = location.getLongitude();  
    292.   
    293.             if (latitude >= 0.0f) {  
    294.                 sb.append(getString(R.string.location_north,  
    295.                         getLocationString(latitude)));  
    296.             } else {  
    297.                 sb.append(getString(R.string.location_south,  
    298.                         getLocationString(-1.0 * latitude)));  
    299.             }  
    300.   
    301.             sb.append("    ");  
    302.   
    303.             if (longitude >= 0.0f) {  
    304.                 sb.append(getString(R.string.location_east,  
    305.                         getLocationString(longitude)));  
    306.             } else {  
    307.                 sb.append(getString(R.string.location_west,  
    308.                         getLocationString(-1.0 * longitude)));  
    309.             }  
    310.             mLocationTextView.setText(sb.toString());// 显示经纬度,其实还可以作反向编译,显示具体地址  
    311.         }  
    312.     }  
    313.   
    314.     // 把经纬度转换成度分秒显示  
    315.     private String getLocationString(double input) {  
    316.         int du = (int) input;  
    317.         int fen = (((int) ((input - du) * 3600))) / 60;  
    318.         int miao = (((int) ((input - du) * 3600))) % 60;  
    319.         return String.valueOf(du) + "°" + String.valueOf(fen) + "′"  
    320.                 + String.valueOf(miao) + "″";  
    321.     }  
    322.   
    323.     // 方向传感器变化监听  
    324.     private SensorEventListener mOrientationSensorEventListener = new SensorEventListener() {  
    325.   
    326.         @Override  
    327.         public void onSensorChanged(SensorEvent event) {  
    328.             float direction = event.values[0] * -1.0f;  
    329.             mTargetDirection = normalizeDegree(direction);// 赋值给全局变量,让指南针旋转  
    330.         }  
    331.   
    332.         @Override  
    333.         public void onAccuracyChanged(Sensor sensor, int accuracy) {  
    334.         }  
    335.     };  
    336.   
    337.     // 调整方向传感器获取的值  
    338.     private float normalizeDegree(float degree) {  
    339.         return (degree + 720) % 360;  
    340.     }  
    341.   
    342.     // 位置信息更新监听  
    343.     LocationListener mLocationListener = new LocationListener() {  
    344.   
    345.         @Override  
    346.         public void onStatusChanged(String provider, int status, Bundle extras) {  
    347.             if (status != LocationProvider.OUT_OF_SERVICE) {  
    348.                 updateLocation(mLocationManager  
    349.                         .getLastKnownLocation(mLocationProvider));  
    350.             } else {  
    351.                 mLocationTextView.setText(R.string.cannot_get_location);  
    352.             }  
    353.         }  
    354.   
    355.         @Override  
    356.         public void onProviderEnabled(String provider) {  
    357.         }  
    358.   
    359.         @Override  
    360.         public void onProviderDisabled(String provider) {  
    361.         }  
    362.   
    363.         @Override  
    364.         public void onLocationChanged(Location location) {  
    365.             updateLocation(location);// 更新位置  
    366.         }  
    367.     };  
    368. }  

    好了,核心代码就这些了,其实思路还是很简单,最后,感谢各位看到文章最后,祝愿各位程序猿们好好学习,天天向上!

  • 相关阅读:
    任意数字 保留 两位 小数 PHP
    在JavaScript中处理JSON数据 jquery js 定义 json 格式
    相对定位 绝对定位 relative absolute position 图片定位a标签
    oracle: listener.ora 、sqlnet.ora 、tnsnames.ora的配置及例子
    python
    python
    python-判断alter是否存在
    python-IE浏览器调用
    Python语言编写脚本时,对日期控件的处理方式
    python报错UnicodeDecodeError:
  • 原文地址:https://www.cnblogs.com/welhzh/p/4190939.html
Copyright © 2011-2022 走看看