Android基础知识复习(六)

14 篇文章 0 订阅
6 篇文章 0 订阅

学习内容

  1. Google Android Training
    http://developer.android.com/training/index.html
  2. Github托管
    https://github.com/kesenhoo/android-training-course-in-chinese
  3. 中文阅读地址
    http://hukai.me/android-training-course-in-chinese/index.html

以下是仅对我个人有意义的笔记

6. Android联系人与位置信息

6.1. Android联系人信息

6.1.1. 获取联系人列表

  1. manifest 里面需要获取的权限

    <uses-permission android:name="android.permission.READ_CONTACTS" />
    
  2. CursorAdapter+Contacts Provider+ContactsContract(该类定义了一些对查询Contacts Provider很有用的常量和方法。当我们使用这个类的时候,我们不用自己定义内容URI、表名、列名等常量[例如,Contacts.DISPLAY_NAME=联系人的名字])

  3. 查询联系人列表(实现)

    • 自定义一个listview
    • 使用CursorAdapter,在onItemClick上实现点击获取个人信息

      // Create the contact's content Uri;这里就可以为个人信息操作提供个人详情信息了
      mContactUri = Contacts.getLookupUri(mContactId, mContactKey);
      
  4. CursorLoader获取获取Contacts Provider中的数据。CursorLoader在一个与UI线程相独立的工作线程进行查询操作。

    • 初始化

      //  在onActivityCreated()/onCreate()中
      getLoaderManager().initLoader(0, null, this);
      
    • 调用上面语句后,会被loader框架自动调用onCreateLoader()

      @Override
      public Loader<Cursor> onCreateLoader(int loaderId, Bundle args) {
          /*
           * Makes search string into pattern and
           * stores it in the selection array
           */
          mSelectionArgs[0] = "%" + mSearchString + "%";
          // Starts the query
          return new CursorLoader(
                  getActivity(),
                  Contacts.CONTENT_URI,//对于内容URI,则使用了Contacts.CONTENT_URI,这个URI关联到整个表
                  PROJECTION,//定义查询映射,如果要查询
                  SELECTION,//定义查询标准,这里就是写数据库查询语句的地方
                  mSelectionArgs,//定义包含选择字符串的变量
                  null
          );
      }
      
      • 根据特定的数据类型匹配联系人,就设置一下SELECTION
      • 根据任意类型的数据匹配联系人,在CursorLoader里面设置使用 Contacts.CONTENT_FILTER_URI,并且PROJECTION、SELECTION、mSelectionArgs设为null。
    • onLoadFinished()返回查询结果

      mCursorAdapter.swapCursor(cursor);
      
    • onLoaderReset()发现搜索到的东西过时的时候会调用,需要先删除SimpleCursorAdapter对已经存在Cursor的引用

      mCursorAdapter.swapCursor(null);
      

6.1.2. 获取联系人详情

  1. 依旧是需要读取联系人权限
  2. 果要把Cursor绑定到ListView,记得要获取Data._ID,否则的话,界面绑定就不会起作用。同时也需要获取Data.MIMETYPE列,这样才能识别我们获取到的每一行数据的数据类型。
  3. 这里大概就是比较考验数据库语句的地方,根据需求来定义语句

6.1.3. 使用Intents修改联系人信息(通过Intent启动Contacts应用去运行适当的Activity)

  1. 添加一个联系人

    • 原理:使用Contacts应用去插入一个联系人将会向Contacts Provider中的ContactsContract.RawContacts表中插入一个原始联系人。

      Intent intent = new Intent(Intents.Insert.ACTION);
      
    • 实现:比较简单,略。
  2. update联系人

    • 原理: 跟添加差不多,但是需要给这个Intent添加对应联系人的Contacts.CONTENT_LOOKUP_URI和MIME类型Contacts.CONTENT_ITEM_TYPE。

       Intent editIntent = new Intent(Intent.ACTION_EDIT);
      //该方法的参数分别是联系人的Contacts._ID和Contacts.LOOKUP_KEY
      mSelectedContactUri =
      Contacts.getLookupUri(mCurrentId, mCurrentLookupKey);
      
    • 扩展 :让用户自己选择插入还是编辑

      Intent intentInsertEdit = new Intent(Intent.ACTION_INSERT_OR_EDIT);
      

6.1.4. 显示联系人头像(QuickContactBadge)

6.2. Android位置信息

6.2.1. 获取最后可知位置(Google Play services location APIs,fused location provider)

  1. SDK Manager下载和安装Google Play services location APIs组件
  2. 获取权限和决定选取哪种精度

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    //精度:一个城市的街区
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    
  3. 实现,在Activity的onConnect里面调用

    mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
            mGoogleApiClient);
    

6.2.2. 获取位置更新

  1. 创建一个 LocationRequest 以保存请求 fused location provider 的参数

        protected void createLocationRequest() {
            //更新间隔: setInterval()) - 接收位置更新的速率(每毫秒)
            LocationRequest mLocationRequest = new LocationRequest();
            //最快更新间隔:setFastestInterval()) - 处理位置更新的最快速率(每毫秒)。
            mLocationRequest.setInterval(10000);
            //精度:setPriority()) 
            mLocationRequest.setFastestInterval(5000);
            mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        }   
    
  2. 使用LocationRequest

     @Override
    public void onConnected(Bundle connectionHint) {
        ...
        if (mRequestingLocationUpdates) {
            startLocationUpdates();
        }
    }
    /**调用mLocationRequest更新地点*/
    protected void startLocationUpdates() {
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);
    }
    
  3. 在Activity里面调用

    public class MainActivity extends ActionBarActivity implements
            ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
        ...
        @Override
        public void onLocationChanged(Location location) {
            mCurrentLocation = location;
            mCurrentLocation.getLatitude();
            mCurrentLocation.getLongitude()
        }
    
    
    }
    
  4. 停止。onPause()

    LocationServices.FusedLocationApi.removeLocationUpdates(
        mGoogleApiClient, this);
    
  5. 激活 onResume()

    if (mGoogleApiClient.isConnected() && !mRequestingLocationUpdates) {
    startLocationUpdates();}    
    
  6. 把状态保存在activity,也就是保存在 bundle,在onCreate的时候实现

    private void updateValuesFromBundle(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
        // Update the value of mRequestingLocationUpdates from the Bundle, and
        // make sure that the Start Updates and Stop Updates buttons are
        // correctly enabled or disabled.
        if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
            mRequestingLocationUpdates = savedInstanceState.getBoolean(
                    REQUESTING_LOCATION_UPDATES_KEY);
            setButtonsEnabledState();
        }
    
        // Update the value of mCurrentLocation from the Bundle and update the
        // UI to show the correct latitude and longitude.
        if (savedInstanceState.keySet().contains(LOCATION_KEY)) {
            // Since LOCATION_KEY was found in the Bundle, we can be sure that
            // mCurrentLocationis not null.
            mCurrentLocation = savedInstanceState.getParcelable(LOCATION_KEY);
        }
    
        // Update the value of mLastUpdateTime from the Bundle and update the UI.
        if (savedInstanceState.keySet().contains(LAST_UPDATED_TIME_STRING_KEY)) {
            mLastUpdateTime = savedInstanceState.getString(
                    LAST_UPDATED_TIME_STRING_KEY);
        }
        updateUI();
    }
    

6.2.3. 显示位置地址

  1. FetchAddressIntentService 继承 IntentService(IntentService 类提供了一种结构使一个任务在后台线程运行。AsyncTask 类也可以执行后台操作,但是它被设计用于短时间运行的操作。)

    • 在manifest里面注册
    • 用Geocoder完成反向地理编码(将一个地理位置传换成地址的过程)

          @Override
      protected void onHandleIntent(Intent intent) {
          Geocoder geocoder = new Geocoder(this, Locale.getDefault());
          ...
      }
      
    • 获取数据(需要完善错误机制)

       // Get the location passed to this service through an extra.
      Location location = intent.getParcelableExtra(
              Constants.LOCATION_DATA_EXTRA);
              ……
      //获取到的地址信息
      addresses = geocoder.getFromLocation(
          location.getLatitude(),
          location.getLongitude(),
          1);
      
    • 返回信息

      private void deliverResultToReceiver(int resultCode, String message) {
      Bundle bundle = new Bundle();
      bundle.putString(Constants.RESULT_DATA_KEY, message);
      mReceiver.send(resultCode, bundle);
      }
      
  2. activity使用 (要在确认连接稳定的情况下调取方法)

    public class MainActivity extends ActionBarActivity implements
            ConnectionCallbacks, OnConnectionFailedListener {
        ...
        @Override
        public void onConnected(Bundle connectionHint) {
            // Gets the best and most recent location currently available,
            // which may be null in rare cases when a location is not available.
            mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                    mGoogleApiClient);
    
            if (mLastLocation != null) {
                // Determine whether a Geocoder is available.
                if (!Geocoder.isPresent()) {
                    Toast.makeText(this, R.string.no_geocoder_available,
                            Toast.LENGTH_LONG).show();
                    return;
                }
    
                if (mAddressRequested) {
                    startIntentService();
                }
            }
        }
    }
    /**关键方法*/
       protected void startIntentService() {
        Intent intent = new Intent(this, FetchAddressIntentService.class);
        intent.putExtra(Constants.RECEIVER, mResultReceiver);
        intent.putExtra(Constants.LOCATION_DATA_EXTRA, mLastLocation);
        startService(intent);
    }
    

6.2.4. 创建和监视地理围栏

  1. 原理:经纬度+半径=地理围栏
  2. 创建:获取权限 + Geofence.Builder 创建地理围栏+ GeofencingRequest中的 GeofencingRequestBuilder 类来需要监视的地理围栏,监视并设置如何触发
  3. 使用
    • 定义地理围栏转义Intent PendingIntent
    • 添加地理围栏 GeoencingApi.addGeofences()
  4. 停止

    LocationServices.GeofencingApi.removeGeofences(
            mGoogleApiClient,
            // This is the same pending intent that was used in addGeofences().
            getGeofencePendingIntent()
    ).setResultCallback(this); // Result processed in onResult().
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值