实训第三周(1)

李晨晨:

本周我用高德定位SDK实现了定位。

1.首先是账号的申请和key值的获取,可以根据其网站的指示文档申请。

实训第三周(1)

实训第三周(1)

重点是SHA1安全码,要和自己的Android Studio的对应;PackageName要和自己项目的包名对应。否则会报错。

我用的方式为远程构建,所以要在build.gradle(Module:app)中加入

[cpp] view plain copy
  1. // 高德地图,定位相关  
  2.     compile 'com.amap.api:map2d:latest.integration'  
  3.     compile 'com.amap.api:location:latest.integration'  
  4.     compile 'com.amap.api:search:latest.integration'  
其他与官网上的过程相同:http://lbs.amap.com/api/android-location-sdk/locationsummary

2.然后是选择位置并发送位置的selectLocActivity及相应的布局文件:

实训第三周(1)

初始化主要的是initPoiList方法(初始化周围位置列表)和initMap(初始化上方的地图显示界面);其他的当位置移动和滑动地图时通过高德接口的监听器实现。

[java] view plain copy
  1. @Override  
  2.    protected void onCreate(@Nullable Bundle savedInstanceState) {  
  3.        super.onCreate(savedInstanceState);  
  4.        setStatusBarColor(R.color.app_blue_color);  
  5.        setContentView(R.layout.activity_select_location);  
  6.        ButterKnife.bind(this);  
  7.        mMapView.onCreate(savedInstanceState);  
  8.        initPoiList();  
  9.        initMap();  
  10.   
  11.    }  

3.initPoiList,主要为mRecyclerView的内容,初始化位置循环列表,并对条目绑定OnClickListener,当选定条目时,取消上一次勾选,勾选当前条目,并将地图中心移到当前条目所表示的位置。

[java] view plain copy
  1. private void initPoiList(){  
  2.        mLayoutManager = new LinearLayoutManager(this);  
  3.        mRecyclerView.setLayoutManager(mLayoutManager);  
  4.        mPointList = new ArrayList<>();  
  5.        mAdapter = new RecycleViewAdapter<LocationPoint>(this,mPointList) {  
  6.            @Override  
  7.            public int setItemLayoutId(int position) {  
  8.                return R.layout.item_round_poi;  
  9.            }  
  10.   
  11.            @Override  
  12.            public void bindView(RViewHolder holder, int position) {  
  13.                LocationPoint point = mPointList.get(position);  
  14.                holder.setText(R.id.tv_poi_name,point.getName());  
  15.                holder.setText(R.id.tv_poi_address,point.getAddress());  
  16.                if (point.isSelected()){  
  17.                    holder.getImageView(R.id.iv_selected).setVisibility(View.VISIBLE);  
  18.                }else {  
  19.                    holder.getImageView(R.id.iv_selected).setVisibility(View.INVISIBLE);  
  20.                }  
  21.            }  
  22.        };  
  23.        mAdapter.setItemClickListener(new OnItemClickListener() {  
  24.            @Override  
  25.            public void onItemClick(RViewHolder holder, int position) {  
  26.   
  27.                // 清除原来已选的  
  28.                mPointList.get(mCurrentSelect).setSelected(false);  
  29.                mAdapter.notifyItemChanged(mCurrentSelect);  
  30.   
  31.                // 更新当前已选点  
  32.                mCurrentSelect = position;  
  33.                mPointList.get(position).setSelected(true);  
  34.                mAdapter.notifyItemChanged(position);  
  35.   
  36.                // 刷新地图  
  37.                LatLonPoint point = mPointList.get(position).getPoint();  
  38.                setMapCenter(point.getLatitude(),point.getLongitude());  
  39.            }  
  40.        });  
  41.   
  42.        mRecyclerView.setAdapter(mAdapter);  
  43.    }  

设置地图中心方法:

[java] view plain copy
  1. private void setMapCenter(double latitude, double longitude) {  
  2.         // 设置地图中心点  
  3.         mCenterPoint = new LatLng(latitude, longitude);  
  4.         // 将地图移动到当前位置  
  5.         CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(mCenterPoint, mZoomLevel);  
  6.         mAMap.animateCamera(cameraUpdate);  
  7.     }  

4.initMap方法:

[java] view plain copy
  1. private void initMap(){  
  2.   
  3.         mAMap = mMapView.getMap();  
  4.         // 初始位置,广州市中心  
  5.         setMapCenter(23.13023113.253171);  
  6.   
  7.         // 地图中心发生变化监听  
  8.         <strong>mAMap.setOnCameraChangeListener(this);</strong>  
  9.   
  10.         // 缩放控件  
  11.         UiSettings settings = mAMap.getUiSettings();  
  12.         settings.setZoomGesturesEnabled(true);  
  13.   
  14.         settings.setMyLocationButtonEnabled(false);  
  15.         settings.setZoomControlsEnabled(false);  
  16.   
  17.         mLocationClient = new AMapLocationClient(getApplicationContext());  
  18.         //mLocationClient.setApiKey("9f06a419f114f90a8a0156fd37a5ebf3");  
  19.   
  20.         AMapLocationClientOption option = new AMapLocationClientOption();  
  21.         option.setGpsFirst(false);  
  22.         option.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);  
  23.         // 单次定位  
  24.         option.setOnceLocation(true);  
  25.   
  26.         mLocationClient.setLocationOption(option);  
  27.        <strong> mLocationClient.setLocationListener(this);</strong>  
  28.         mLocationClient.startLocation();  
  29.   
  30.     }  

onCameraChangeListener重写:

当地图镜头移动时,如果与原中心点距离超过10米,刷新POI列表(searchRoundPoi),并将地图中心设置为当前位置。

[java] view plain copy
  1. /**地图镜头被移动*****/  
  2.   
  3.     @Override  
  4.     public void onCameraChange(CameraPosition cameraPosition) {  
  5.   
  6.     }  
  7.   
  8.     @Override  
  9.     public void onCameraChangeFinish(CameraPosition cameraPosition) {  
  10.   
  11.         mZoomLevel = cameraPosition.zoom;  
  12.   
  13.         // 判断是否已经定位成功  
  14.         if (mLocation != null){  
  15.             // 若移动后,与原中心点距离超过10米,刷新 POI 列表  
  16.             float distance = AMapUtils.  
  17.                     calculateLineDistance(mCenterPoint,cameraPosition.target);  
  18.              if (distance >= 10.0f){  
  19.                  setMapCenter(cameraPosition.target.latitude,cameraPosition.target.longitude);  
  20.                  searchRoundPoi(new LatLonPoint(cameraPosition.target.latitude,  
  21.                          cameraPosition.target.longitude));  
  22.              }  
  23.         }  
  24.     }  

searchRoundPoi方法:

[java] view plain copy
  1. private void searchRoundPoi(LatLonPoint point){  
  2.   
  3.         mProgressBar.setVisibility(View.VISIBLE);  
  4.   
  5.         // 清除原有数据  
  6.         mPointList.clear();  
  7.         mAdapter.notifyDataSetChanged();  
  8.   
  9.         // 关键字 类型 区域  
  10.         PoiSearch.Query query = new PoiSearch.Query("","",mLocation.getCityCode());  
  11.         query.setPageNum(1);  
  12.         query.setPageSize(50);  
  13.   
  14.         // 位置点周边1000米范围搜索  
  15.         PoiSearch search = new PoiSearch(this,query);  
  16.         PoiSearch.SearchBound bound = new  PoiSearch.SearchBound(point,1000);  
  17.         search.setBound(bound);  
  18.   
  19.         search.setOnPoiSearchListener(this);  
  20.         search.searchPOIAsyn();  
  21.     }  
LocationListener的onLocationChanged重写:
[java] view plain copy
  1. /**我的位置发生移动**/  
  2.     @Override  
  3.     public void onLocationChanged(AMapLocation location) {  
  4.         if (location != null) {  
  5.             if (location.getErrorCode() == 0) {  
  6.                 // 保存当前定位点  
  7.                 mLocation = location;  
  8.                 // 移动到定位点  
  9.                 setMapCenter(location.getLatitude(), location.getLongitude());  
  10.                 // 显示位置点  
  11.                 drawLocationPoint();  
  12.   
  13.                 // 搜索并显示周边POI点列表  
  14.                 searchRoundPoi(new LatLonPoint(location.getLatitude(),location.getLongitude()));  
  15.   
  16.             }else {  
  17.                 //显示错误信息ErrCode是错误码,errInfo是错误信息,详见错误码表。  
  18.                 Log.e("AmapError","location Error, ErrCode:"  
  19.                         + location.getErrorCode() + ", errInfo:"  
  20.                         + location.getErrorInfo());  
  21.             }  
  22.         }  
  23.     }  

drawLocationPoint方法:

[java] view plain copy
  1. private void drawLocationPoint(){  
  2.        mLocationMarker = new MarkerOptions();  
  3.        BitmapDescriptor descriptor = BitmapDescriptorFactory.fromResource(R.mipmap.ic_my_loc);  
  4.        mLocationMarker.icon(descriptor);  
  5.        mLocationMarker.position(mCenterPoint);  
  6.        mAMap.addMarker(mLocationMarker);  
  7.    }  
5.
[java] view plain copy
  1. @OnClick(R.id.iv_back_btn)  
  2.     public void backOnClick(){  
  3.         this.finish();  
  4.     }  
  5.   
  6.     @OnClick(R.id.tv_btn_send)  
  7.     public void send(){  
  8.         if (!mPointList.isEmpty() && mCurrentSelect != -1){  
  9.             Intent intent = new Intent();  
  10.             intent.putExtra("location",mPointList.get(mCurrentSelect).getPoint());  
  11.             intent.putExtra("address",mPointList.get(mCurrentSelect).getAddress());  
  12.             setResult(RESULT_OK,intent);  
  13.             finish();  
  14.         }else {  
  15.             ToastUtils.showMessage(this,"位置获取失败,请稍后再试~");  
  16.         }  
  17.     }  
  18.   
  19.     @Override  
  20.     protected void onResume() {  
  21.         super.onResume();  
  22.         mMapView.onResume();  
  23.     }  
  24.   
  25.     @Override  
  26.     protected void onPause() {  
  27.         super.onPause();  
  28.         mMapView.onPause();  
  29.   
  30.         if (mLocationClient.isStarted()){  
  31.             mLocationClient.stopLocation();  
  32.         }  
  33.     }  
  34.   
  35.     @Override  
  36.     protected void onDestroy() {  
  37.         super.onDestroy();  
  38.         mMapView.onDestroy();  
  39.         mLocationClient.onDestroy();  
  40.     }  

6.具体效果图:

实训第三周(1)





仝心:

 本周我完成了将所有的字符存入数据库的操作,并对这些字符添加了一些手机传感器获得的参数的影响。

    首先是存储所有手绘字符,在这里定义了一个int类型的计数器count,用于记录这是存储的第几个字符,字符的顺序按照ASC码的排序逐个绘制,同时数据库中添加了一项name,用于记录字符的count。每次点击“下一页”时,count计数加一,用于显示要绘制的字符的TextView按照ASC码的顺序刷新一次。

[java] view plain copy
  1. ContentValues values = new ContentValues();  
  2. char letter = (char)('!'+count);  
  3. String str = ""+letter;  
  4. values.put("id",str);  
  5. values.put("content",s);  
  6. values.put("name",count);  
  7. ImageSQLiteHelper dbHelper = new ImageSQLiteHelper(CreateActivity.this,"my_nn_database");  
  8. SQLiteDatabase db = dbHelper.getWritableDatabase();  
  9. db.insert("array",null,values);  
  10. s="";  
[java] view plain copy
  1. class nextListener implements View.OnClickListener{  
  2.   
  3.     @Override  
  4.     public void onClick(View view) {  
  5.         count++;  
  6.         char letter = (char)('!'+ count);  
  7.         tv.setText(""+letter);  
  8.         resumeCanvas();  
  9.   
  10.     }  
  11. }  


    接下来通过手机的加速度计获得了手机的抖动程度,重力传感器获得了手机的偏向,通过按下和抬起的时间差记录触键时间,通过传入随机数在每次输出时对原始字符图片进行一些随机偏移。这些作用效果叠加起来构成了输出效果。

[java] view plain copy
  1. SensorEventListener sensorListener = new SensorEventListener() {  
  2.     //传感器改变时,一般是通过这个方法里面的参数确定传感器状态的改变  
  3.     @Override  
  4.     public void onSensorChanged(SensorEvent sensorEvent) {  
  5.         if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER)  
  6.         {  
  7.             accelerometerValues = sensorEvent.values.clone();  
  8.             float[] values = sensorEvent.values;//获取传感器的数据  
  9.         //float max = sensor.getMaximumRange();//获取最大值范围  
  10.             if (values.length >= 3) {  
  11.                 float x = values[0];//右侧面向上时为g(9.8)  
  12.                 float y = values[1];//上侧面向上时为g(9.8)  
  13.                 float z = values[2];  
  14.   
  15.                 //抖动  
  16.                 float xx = values[0] - usedValues[0];  
  17.                 float yy = values[1] - usedValues[1];  
  18.                 float zz = values[2] - usedValues[2];  
  19.                 float Tense = Math.abs(xx)+Math.abs(yy)+Math.abs(zz);  
  20.   
  21.                 usedValues[0] = x;  
  22.                 usedValues[1] = y;  
  23.                 usedValues[2] = z;  
  24.                 if(Tense >=15)  
  25.                     tempTense = 1;  
  26.                 else if(Tense >=6&&Tense < 15)  
  27.                     tempTense = 2;  
  28.                 else if(Tense>=4&&Tense < 6)  
  29.                     tempTense = 3;  
  30.                 else if(Tense >=2&&Tense<4)  
  31.                     tempTense = 4;  
  32.                 else if(Tense>=1&&Tense<2)  
  33.                     tempTense = 5;  
  34.                 else  
  35.                     tempTense = 10;  
  36.                 //倾斜  
  37.                 float angle;  
  38.                 if(y>0)  
  39.                 {  
  40.                     angle = x*8;  
  41.                     if(angle>25)  
  42.                         angle = 25;  
  43.                 }  
  44.                 else  
  45.                     angle = 0;  
  46.                 numboardUtil.getSkewData(angle);  
  47.             }  
  48.         numboardUtil.getSensorData(tempTense);  
  49.         }else if (sensorEvent.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {  
  50.         }  
  51.     }  
[java] view plain copy
  1. /*获得触键时间*/  
  2. class touchKeyListener implements View.OnTouchListener{  
  3.   
  4.     @Override  
  5.     public boolean onTouch(View view, MotionEvent motionEvent) {  
  6.         switch (motionEvent.getAction()) {  
  7.             case MotionEvent.ACTION_DOWN://按键的时间  
  8.                 Calendar calendar = Calendar.getInstance();  
  9.                 int SS = calendar.get(Calendar.SECOND);  
  10.                 int MI = calendar.get(Calendar.MILLISECOND);  
  11.                 second1 = SS;  
  12.                 millisecond1 = MI;  
  13.                 break;  
  14.             case MotionEvent.ACTION_UP://抬起的时间  
  15.                 Calendar c = Calendar.getInstance();  
  16.                 int S = c.get(Calendar.SECOND);  
  17.                 int mi = c.get(Calendar.MILLISECOND);  
  18.                 second2 = S;  
  19.                 millisecond2 = mi;  
  20.                 totalMilliSecond = (second2-second1)*1000+millisecond2-millisecond1;//时间差,以毫秒计  
  21.                 int thick;  
  22.                 if(totalMilliSecond<20)  
  23.                     thick = 0;  
  24.                 else if(totalMilliSecond>=20&&totalMilliSecond<80)  
  25.                     thick = 1;  
  26.                 else if (totalMilliSecond>=80&&totalMilliSecond<150)  
  27.                     thick = 3;  
  28.                 else if(totalMilliSecond>=150&&totalMilliSecond<300)  
  29.                     thick = 5;  
  30.                 else if(totalMilliSecond>=300&&totalMilliSecond<600)  
  31.                     thick = 7;  
  32.                 else if(totalMilliSecond>=600&&totalMilliSecond<800)  
  33.                     thick = 8;  
  34.                 else if(totalMilliSecond>=800&&totalMilliSecond<1000)  
  35.                     thick = 9;  
  36.                 else  thick = 10;  
  37.                 numboardUtil.getTouchTime(thick);  
  38.                 break;  
  39.             case MotionEvent.ACTION_MOVE:  
  40.                 break;  
  41.             default:  
  42.                 break;  
  43.         }  
  44.         return false;  
  45.     }  
  46. }  

    在按键的同时进行反应当前形态的字符绘制,其中的具体变形方法时在之前的工作中完成过的,这里将传感器获得的数据加工后作为参数传入。

[java] view plain copy
  1. protected Bitmap paintNewImage(int[][] arr,float tense,int level,float angle) {//抖动程度、画笔粗细、倾斜角度  
  2.   
  3.     int row = arr.length;  
  4.     int col = arr[0].length;  
  5.     int min=0;  
  6.     int max=30;  
  7.     Random random = new Random();  
  8.     int num1 = random.nextInt(max)%(max-min+1) -15;  
  9.     int num2 = random.nextInt(max)%(max-min+1) -15;  
  10.     int[][] arr1 = distort1(arr,num1,num2,row,col);//异形文字  
  11.     arr = trembleImage(arr1,tense);//抖动  
  12.     paint = new Paint();  
  13.     //if (showBitmap == null) {  
  14.     //}  
  15.   
  16.     int left = 0,right = 0;  
  17.     boolean flag = true;  
  18.     //判断最左和最右的像素,对图片进行一个裁剪  
  19.     for(int i = 0;i<col&&flag;i++)  
  20.     {  
  21.         for(int j = 0;j<row;j++)  
  22.         {  
  23.             if(arr[j][i] == 0&&j<0.95*row)  
  24.             {  
  25.                 left = i;  
  26.                 flag = false;  
  27.                 break;  
  28.             }  
  29.         }  
  30.     }  
  31.     flag = true;  
  32.   
  33.   
  34.     for(int i = col-1;i>0&&flag;i--)  
  35.     {  
  36.         for(int j = 0;j<row;j++)  
  37.         {  
  38.             if(arr[j][i] == 0&&j<0.95*row)  
  39.             {  
  40.                 right = i;  
  41.                 flag = false;  
  42.                 break;  
  43.             }  
  44.         }  
  45.     }  
  46.   
  47.     showBitmap = Bitmap.createBitmap(right - left +15,  
  48.             MY_ROW, Bitmap.Config.ARGB_8888);  
  49.     show_canvas = new Canvas(showBitmap);  
  50.     show_canvas.drawColor(Color.WHITE);  
  51.   
  52.     show_canvas.skew((float)Math.tan(angle*3.14/180),0f);  
  53.     show_canvas.translate(-50*(float)Math.tan(angle*3.14/180),0);  
  54.   
  55.     for (int i = 0; i < row; i++) {  
  56.         for (int j = left; j < right; j++) {  
  57.             paint.setARGB(255000);  
  58.             paint.setStrokeWidth(level);  
  59.             if (arr[i][j] == 0&&i<0.95*row)  
  60.                 show_canvas.drawPoint(j-left+8, i, paint);  
  61.         }  
  62.     }  
  63.     return  showBitmap;  
  64. }  

字符绘制界面添加了四线三格作为输入参考

实训第三周(1)

键盘的输出效果可以看出手机的左右偏向、按键时间以及抖动程度,同时同一字母的两次绘制不会完全相同,符合书写现实。

实训第三周(1)




张静:

本周完成了如下工作:

上一周未完成的NimUserHandler

(1)初始化

通过NimClient的getService接口获取到UserService(用户资料操作相关接口)服务实例,调用getUserInfo方法从本地数据库中获取用户资料

通过NimClient的getService接口获取到UserServiceObserve(用户资料变更通知)服务实例,调用observeUserInfoUpdate方法进行用户资料变更观察者通知

[java] view plain copy
  1. public void init(){  
  2.         mUserInfo = NIMClient.getService(UserService.class).getUserInfo(mMyAccount);  
  3.         mUpdateListeners = new ArrayList<>();  
  4.         // 初始化监听  
  5.         //用户资料托管接口,提供获取用户资料,修改个人资料等  
  6.         NIMClient.getService(UserServiceObserve.class)  
  7.                 .observeUserInfoUpdate(new Observer<List<NimUserInfo>>() {  
  8.             @Override  
  9.             public void onEvent(List<NimUserInfo> userInfoList) {  
  10.                 NimUserInfo userInfo = userInfoList.get(0);  
  11.                 Log.e(TAG,"UserInfoUpdate"+userInfo.toString());  
  12.             }  
  13.         },true);  
  14.     }  

(2)从服务器账户数据到本地数据库

通过NimClient的getService接口获取到UserService(用户资料操作相关接口)服务实例,调用fetchUserInfo从服务器获取用户资料

三种情况:同步成功,同步失败,同步出错

[java] view plain copy
  1. public void fetchAccountInfo(){  
  2.         List<String> accounts = new ArrayList<>();  
  3.         accounts.add(mMyAccount);  
  4.         NIMClient.getService(UserService.class).fetchUserInfo(accounts)  
  5.                 .setCallback(new RequestCallback<List<NimUserInfo>>() {  
  6.             @Override  
  7.             public void onSuccess(List<NimUserInfo> param) {  
  8.                 Log.e(TAG,"fetchAccountInfo onSuccess ");  
  9.                 mUserInfo = param.get(0);  
  10.                 // 同步成功,通知刷新  
  11.                 for (OnInfoUpdateListener listener : mUpdateListeners){  
  12.                     listener.myInfoUpdate();  
  13.                 }  
  14.             }  
  15.   
  16.             @Override  
  17.             public void onFailed(int code) {  
  18.                 Log.e(TAG,"fetchAccountInfo onFailed code " + code);  
  19.             }  
  20.   
  21.             @Override  
  22.             public void onException(Throwable exception) {  
  23.                 Log.e(TAG,"fetchAccountInfo onException message " + exception.getMessage());  
  24.             }  
  25.         });  
  26.     }  

(3)将数据更新到服务器

将各项属性值(头像、生日、地址、签名、昵称、性别)存储到fields

再通过NimClient的getService接口获取到UserService(用户资料操作相关接口)服务实例,调用updateUserInfo更新本人用户资料

上传更新过程同样有三种情况:上传成功(更新本地数据库(调用fetchAccountInfo)),上传失败,上传出错

[java] view plain copy
  1. public void syncChange2Service(){  
  2.         Map<UserInfoFieldEnum,Object> fields = new HashMap<>();  
  3.         if(!TextUtils.isEmpty(mLocalAccount.getHeadImgUrl())){  
  4.             fields.put(UserInfoFieldEnum.AVATAR,mLocalAccount.getHeadImgUrl());  
  5.         }  
  6.         if (!TextUtils.isEmpty(mLocalAccount.getBirthDay())){  
  7.             fields.put(UserInfoFieldEnum.BIRTHDAY,mLocalAccount.getBirthDay());  
  8.         }  
  9.         if (!TextUtils.isEmpty(mLocalAccount.getLocation())){  
  10.             fields.put(UserInfoFieldEnum.EXTEND,mLocalAccount.getLocation());  
  11.         }  
  12.         if (!TextUtils.isEmpty(mLocalAccount.getSignature())){  
  13.             fields.put(UserInfoFieldEnum.SIGNATURE,mLocalAccount.getSignature());  
  14.         }  
  15.   
  16.         fields.put(UserInfoFieldEnum.Name,mLocalAccount.getNick());  
  17.         fields.put(UserInfoFieldEnum.GENDER,mLocalAccount.getGenderEnum().getValue());  
  18.         NIMClient.getService(UserService.class).updateUserInfo(fields)  
  19.                 .setCallback(new RequestCallback<Void>() {  
  20.             @Override  
  21.             public void onSuccess(Void param) {  
  22.                 Log.e(TAG,"syncChange2Service onSuccess");  
  23.                 // 上传成功,更新本地数据库  
  24.                 fetchAccountInfo();  
  25.             }  
  26.   
  27.             @Override  
  28.             public void onFailed(int code) {  
  29.                 Log.e(TAG,"syncChange2Service onFailed code " + code);  
  30.                 //TODO 同步失败应当后台服务上传  
  31.             }  
  32.   
  33.             @Override  
  34.             public void onException(Throwable exception) {  
  35.                 Log.e(TAG,"syncChange2Service onException message " + exception.getMessage());  
  36.             }  
  37.         });  
  38.     }  

其中mLocalAccount为LocalAccountBean类,LocalAccountBean.java:

设置本地账户中的各项属性以及获取属性的方法

[java] view plain copy
  1. package com.ezreal.ezchat.bean;  
  2.   
  3. import com.netease.nimlib.sdk.uinfo.constant.GenderEnum;  
  4.   
  5. import java.io.Serializable;  
  6.   
  7. /** 
  8.  * Created by 张静. 
  9.  */  
  10.   
  11. public class LocalAccountBean implements Serializable {  
  12.   
  13.     private String mHeadImgUrl;  
  14.     private String mAccount;  
  15.     private String mNick;  
  16.     private GenderEnum mGenderEnum;  
  17.     private String mBirthDay;  
  18.     private String mLocation;  
  19.     private String mSignature;  
  20.   
  21.     public String getHeadImgUrl() {  
  22.         return mHeadImgUrl;  
  23.     }  
  24.   
  25.     public void setHeadImgUrl(String headImgUrl) {  
  26.         mHeadImgUrl = headImgUrl;  
  27.     }  
  28.   
  29.     public String getAccount() {  
  30.         return mAccount;  
  31.     }  
  32.   
  33.     public void setAccount(String account) {  
  34.         mAccount = account;  
  35.     }  
  36.   
  37.     public String getNick() {  
  38.         return mNick;  
  39.     }  
  40.   
  41.     public void setNick(String nick) {  
  42.         mNick = nick;  
  43.     }  
  44.   
  45.     public GenderEnum getGenderEnum() {  
  46.         return mGenderEnum;  
  47.     }  
  48.   
  49.     public void setGenderEnum(GenderEnum genderEnum) {  
  50.         mGenderEnum = genderEnum;  
  51.     }  
  52.   
  53.     public String getBirthDay() {  
  54.         return mBirthDay;  
  55.     }  
  56.   
  57.     public void setBirthDay(String birthDay) {  
  58.         mBirthDay = birthDay;  
  59.     }  
  60.   
  61.     public String getLocation() {  
  62.         return mLocation;  
  63.     }  
  64.   
  65.     public void setLocation(String location) {  
  66.         mLocation = location;  
  67.     }  
  68.   
  69.     public String getSignature() {  
  70.         return mSignature;  
  71.     }  
  72.   
  73.     public void setSignature(String signature) {  
  74.         mSignature = signature;  
  75.     }  
  76.   
  77.     @Override  
  78.     public String toString() {  
  79.         StringBuilder builder = new StringBuilder();  
  80.         return builder.append("account = ")  
  81.                 .append(mAccount)  
  82.                 .append(",url = ")  
  83.                 .append(mHeadImgUrl)  
  84.                 .append(",location = ")  
  85.                 .append(mLocation)  
  86.                 .toString();  
  87.   
  88.     }  
  89. }  
(4)获取本地账户
[java] view plain copy
  1. public LocalAccountBean getLocalAccount() {  
  2.         mLocalAccount = new LocalAccountBean();  
  3.         mLocalAccount.setAccount(mUserInfo.getAccount());   
  4.         mLocalAccount.setHeadImgUrl(mUserInfo.getAvatar());   
  5.         mLocalAccount.setBirthDay(mUserInfo.getBirthday());   
  6.         mLocalAccount.setNick(mUserInfo.getName());  
  7.         mLocalAccount.setSignature(mUserInfo.getSignature());  
  8.         mLocalAccount.setGenderEnum(mUserInfo.getGenderEnum());  
  9.         String extension = mUserInfo.getExtension();  
  10.         if (!TextUtils.isEmpty(extension)){  
  11.             mLocalAccount.setLocation(extension);   
  12.         }  
  13.         return mLocalAccount;  
  14.     }  


附上完整NimUserHandler.java

[java] view plain copy
  1. package com.ezreal.ezchat.handler;  
  2.   
  3. import android.util.Log;  
  4.   
  5. import com.ezreal.ezchat.bean.LocalAccountBean;  
  6. import com.netease.nimlib.sdk.NIMClient;  
  7. import com.netease.nimlib.sdk.Observer;  
  8. import com.netease.nimlib.sdk.RequestCallback;  
  9. import com.netease.nimlib.sdk.uinfo.UserService;  
  10. import com.netease.nimlib.sdk.uinfo.UserServiceObserve;  
  11. import com.netease.nimlib.sdk.uinfo.constant.UserInfoFieldEnum;  
  12. import com.netease.nimlib.sdk.uinfo.model.NimUserInfo;  
  13. import com.suntek.commonlibrary.utils.TextUtils;  
  14.   
  15. import java.util.ArrayList;  
  16. import java.util.HashMap;  
  17. import java.util.List;  
  18. import java.util.Map;  
  19.   
  20. /** 
  21.  * Created by 张静. 
  22.  */  
  23.   
  24. public class NimUserHandler {  
  25.   
  26.     private static final String TAG = NimUserHandler.class.getSimpleName();  
  27.     private static NimUserHandler instance;  
  28.     private String mMyAccount;  
  29.     private NimUserInfo mUserInfo;  
  30.     private LocalAccountBean mLocalAccount;  
  31.     private List<OnInfoUpdateListener> mUpdateListeners;  
  32.   
  33.     public static NimUserHandler getInstance(){  
  34.         if (instance == null){  
  35.             synchronized (NimUserHandler.class){  
  36.                 if (instance == null){  
  37.                     instance = new NimUserHandler();  
  38.                 }  
  39.             }  
  40.         }  
  41.         return instance;  
  42.     }  
  43.   
  44.     public void init(){  
  45.         mUserInfo = NIMClient.getService(UserService.class).getUserInfo(mMyAccount);  
  46.         mUpdateListeners = new ArrayList<>();  
  47.         // 初始化监听  
  48.         //用户资料托管接口,提供获取用户资料,修改个人资料等  
  49.         NIMClient.getService(UserServiceObserve.class)  
  50.                 .observeUserInfoUpdate(new Observer<List<NimUserInfo>>() {  
  51.             @Override  
  52.             public void onEvent(List<NimUserInfo> userInfoList) {  
  53.                 NimUserInfo userInfo = userInfoList.get(0);  
  54.                 Log.e(TAG,"UserInfoUpdate"+userInfo.toString());  
  55.             }  
  56.         },true);  
  57.     }  
  58.   
  59.     /** 
  60.      * 从服务器账户数据到本地数据库 
  61.      */  
  62.     public void fetchAccountInfo(){  
  63.         List<String> accounts = new ArrayList<>();  
  64.         accounts.add(mMyAccount);  
  65.         NIMClient.getService(UserService.class).fetchUserInfo(accounts)  
  66.                 .setCallback(new RequestCallback<List<NimUserInfo>>() {  
  67.             @Override  
  68.             public void onSuccess(List<NimUserInfo> param) {  
  69.                 Log.e(TAG,"fetchAccountInfo onSuccess ");  
  70.                 mUserInfo = param.get(0);  
  71.                 // 同步成功,通知刷新  
  72.                 for (OnInfoUpdateListener listener : mUpdateListeners){  
  73.                     listener.myInfoUpdate();  
  74.                 }  
  75.             }  
  76.   
  77.             @Override  
  78.             public void onFailed(int code) {  
  79.                 Log.e(TAG,"fetchAccountInfo onFailed code " + code);  
  80.             }  
  81.   
  82.             @Override  
  83.             public void onException(Throwable exception) {  
  84.                 Log.e(TAG,"fetchAccountInfo onException message " + exception.getMessage());  
  85.             }  
  86.         });  
  87.     }  
  88.   
  89.     public void syncChange2Service(){  
  90.         Map<UserInfoFieldEnum,Object> fields = new HashMap<>();  
  91.         if(!TextUtils.isEmpty(mLocalAccount.getHeadImgUrl())){  
  92.             fields.put(UserInfoFieldEnum.AVATAR,mLocalAccount.getHeadImgUrl());  
  93.         }  
  94.         if (!TextUtils.isEmpty(mLocalAccount.getBirthDay())){  
  95.             fields.put(UserInfoFieldEnum.BIRTHDAY,mLocalAccount.getBirthDay());  
  96.         }  
  97.         if (!TextUtils.isEmpty(mLocalAccount.getLocation())){  
  98.             fields.put(UserInfoFieldEnum.EXTEND,mLocalAccount.getLocation());  
  99.         }  
  100.         if (!TextUtils.isEmpty(mLocalAccount.getSignature())){  
  101.             fields.put(UserInfoFieldEnum.SIGNATURE,mLocalAccount.getSignature());  
  102.         }  
  103.   
  104.         fields.put(UserInfoFieldEnum.Name,mLocalAccount.getNick());  
  105.         fields.put(UserInfoFieldEnum.GENDER,mLocalAccount.getGenderEnum().getValue());  
  106.         NIMClient.getService(UserService.class).updateUserInfo(fields)  
  107.                 .setCallback(new RequestCallback<Void>() {  
  108.             @Override  
  109.             public void onSuccess(Void param) {  
  110.                 Log.e(TAG,"syncChange2Service onSuccess");  
  111.                 // 上传成功,更新本地数据库  
  112.                 fetchAccountInfo();  
  113.             }  
  114.   
  115.             @Override  
  116.             public void onFailed(int code) {  
  117.                 Log.e(TAG,"syncChange2Service onFailed code " + code);  
  118.                 //TODO 同步失败应当后台服务上传  
  119.             }  
  120.   
  121.             @Override  
  122.             public void onException(Throwable exception) {  
  123.                 Log.e(TAG,"syncChange2Service onException message " + exception.getMessage());  
  124.             }  
  125.         });  
  126.     }  
  127.   
  128.     public LocalAccountBean getLocalAccount() {  
  129.         mLocalAccount = new LocalAccountBean();  
  130.         mLocalAccount.setAccount(mUserInfo.getAccount());  
  131.         mLocalAccount.setHeadImgUrl(mUserInfo.getAvatar());  
  132.         mLocalAccount.setBirthDay(mUserInfo.getBirthday());  
  133.         mLocalAccount.setNick(mUserInfo.getName());  
  134.         mLocalAccount.setSignature(mUserInfo.getSignature());  
  135.         mLocalAccount.setGenderEnum(mUserInfo.getGenderEnum());  
  136.         String extension = mUserInfo.getExtension();  
  137.         if (!TextUtils.isEmpty(extension)){  
  138.             mLocalAccount.setLocation(extension);  
  139.         }  
  140.         return mLocalAccount;  
  141.     }  
  142.   
  143.   
  144.     public void setLocalAccount(LocalAccountBean account){  
  145.         this.mLocalAccount = account;  
  146.     }  
  147.   
  148.     public String getMyAccount() {  
  149.         return mMyAccount;  
  150.     }  
  151.   
  152.     public void setMyAccount(String account) {  
  153.         mMyAccount = account;  
  154.     }  
  155.   
  156.     public NimUserInfo getUserInfo() {  
  157.         return mUserInfo;  
  158.     }  
  159.   
  160.     public void setUpdateListeners(OnInfoUpdateListener listeners){  
  161.         mUpdateListeners.add(listeners);  
  162.     }  
  163.   
  164.     public interface OnInfoUpdateListener{  
  165.         void myInfoUpdate();  
  166.     }  
  167. }