11111
This commit is contained in:
@@ -152,8 +152,8 @@ dependencies {
|
||||
api 'com.google.code.gson:gson:2.8.8'
|
||||
api 'cn.rongcloud.sdk:rtc_lib:5.2.0' // 音视频通话基础能力库
|
||||
//此处以集成 5.1.2 版本为例
|
||||
api 'cn.rongcloud.sdk:im_lib:5.2.0.2'
|
||||
|
||||
api 'cn.rongcloud.sdk:im_lib:5.1.3.10' // 即时通讯基础能力库
|
||||
api 'cn.rongcloud.sdk:im_kit:5.1.3.10' // 即时通讯 UI 基础组件
|
||||
api 'com.facebook.android:facebook-login:8.2.0'
|
||||
api 'com.facebook.android:facebook-android-sdk:[5,6)'
|
||||
|
||||
|
||||
@@ -13,23 +13,24 @@ import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.Parcelable;
|
||||
import android.provider.MediaStore;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.loader.content.CursorLoader;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.loader.content.Loader;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.loader.app.LoaderManager;
|
||||
import androidx.loader.content.CursorLoader;
|
||||
import androidx.loader.content.Loader;
|
||||
import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import com.yunbao.common.R;
|
||||
import com.yunbao.common.adapter.ImageAdapter;
|
||||
import com.yunbao.common.adapter.ImageFolderAdapter;
|
||||
@@ -62,17 +63,11 @@ public class SelectImageActivity extends AbsActivity implements ImageFolderView.
|
||||
public static int MAX_SIZE = 5;
|
||||
private static final int PERMISSION_REQUEST_CODE = 88;
|
||||
private static final int TAKE_PHOTO = 99;
|
||||
// @BindView(R.id.tv_back)
|
||||
TextView mTvBack;
|
||||
// @BindView(R.id.tv_ok)
|
||||
TextView mTvSelectCount;
|
||||
// @BindView(R.id.rv)
|
||||
RecyclerView mRvImage;
|
||||
// @BindView(R.id.tv_photo)
|
||||
TextView mTvPhoto;
|
||||
// @BindView(R.id.tv_preview)
|
||||
TextView mTvPreview;
|
||||
// @BindView(R.id.image_folder_view)
|
||||
ImageFolderView mImageFolderView;
|
||||
View v_back;
|
||||
|
||||
@@ -180,33 +175,6 @@ public class SelectImageActivity extends AbsActivity implements ImageFolderView.
|
||||
}
|
||||
}
|
||||
|
||||
// @OnClick({R.id.tv_back, R.id.tv_ok, R.id.tv_photo, R.id.tv_preview})
|
||||
// public void onViewClicked(View view) {
|
||||
// switch (view.getId()) {
|
||||
// case R.id.tv_back:
|
||||
// finish();
|
||||
// break;
|
||||
// case R.id.tv_ok:
|
||||
// Intent intent = new Intent();
|
||||
// intent.putParcelableArrayListExtra(EXTRA_RESULT, (ArrayList<? extends Parcelable>) mSelectedImages);
|
||||
// setResult(RESULT_OK, intent);
|
||||
// finish();
|
||||
// break;
|
||||
// case R.id.tv_photo:
|
||||
// if (mImageFolderView.isShowing()) {
|
||||
// mImageFolderView.hide();
|
||||
// } else {
|
||||
// mImageFolderView.show();
|
||||
// }
|
||||
// break;
|
||||
// case R.id.tv_preview:
|
||||
// Intent previewIntent = new Intent(this, PreviewImageActivity.class);
|
||||
// previewIntent.putParcelableArrayListExtra("preview_images", (ArrayList<? extends Parcelable>) mSelectedImages);
|
||||
// startActivity(previewIntent);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
private void addImageFoldersToAdapter() {
|
||||
if (mImageFolderAdapter == null) {
|
||||
mImageFolderAdapter = new ImageFolderAdapter(this, mImageFolders, R.layout.item_list_folder);
|
||||
@@ -460,12 +428,6 @@ public class SelectImageActivity extends AbsActivity implements ImageFolderView.
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if (resultCode == RESULT_OK && requestCode == TAKE_PHOTO) {
|
||||
//缩略图信息是储存在返回的intent中的Bundle中的,对应Bundle中的键为data,因此从Intent中取出 Bundle再根据data取出来Bitmap即可
|
||||
// Bundle extras = data.getExtras();
|
||||
// Bitmap bitmap = (Bitmap) extras.get("data");
|
||||
// BitmapFactory.decodeFile(this.getContentResolver().)
|
||||
// galleryAddPictures(mImageUri);
|
||||
// getSupportLoaderManager().restartLoader(0, null, mLoaderCallbacks);
|
||||
galleryAddPictures();
|
||||
try {
|
||||
Bitmap bitmap = BitmapFactory.decodeStream(this.getContentResolver().openInputStream(mImageUri));
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.yunbao.common.bean;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 数据类基类实现序列化
|
||||
*/
|
||||
public class BaseModel implements Serializable {
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.yunbao.common.bean;
|
||||
|
||||
/**
|
||||
* 聊天备注信息
|
||||
*/
|
||||
public class ChatRemarkModel extends BaseModel {
|
||||
private String userId;
|
||||
private String remarks;
|
||||
}
|
||||
437
common/src/main/java/com/yunbao/common/bean/IMLoginModel.java
Normal file
437
common/src/main/java/com/yunbao/common/bean/IMLoginModel.java
Normal file
@@ -0,0 +1,437 @@
|
||||
package com.yunbao.common.bean;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* 登录账号的数据类型(和com.yunbao.common.bean.UserBean重复分别单独使用,后续优化去掉其中一个)
|
||||
*/
|
||||
public class IMLoginModel extends BaseModel {
|
||||
|
||||
/**
|
||||
* avatar : https://napi.yaoulive.com/default.jpg
|
||||
* avatar_thumb : https://napi.yaoulive.com/default_thumb.jpg
|
||||
* birthday :
|
||||
* city :
|
||||
* coin : 0
|
||||
* consumption : 10200
|
||||
* front_task : 0
|
||||
* gold : 1020
|
||||
* goldsumption : 0
|
||||
* goodnum :
|
||||
* id : 146267
|
||||
* issuper : 0
|
||||
* langue : chinese
|
||||
* level : 6
|
||||
* level_anchor : 1
|
||||
* liang : {"name":"0"}
|
||||
* location :
|
||||
* medal_level : 0
|
||||
* medal_name :
|
||||
* noble_id : 0
|
||||
* province :
|
||||
* sex : 1
|
||||
* signature : 这家伙很懒,什么都没留下
|
||||
* token : 857706071fb09255b370eaf18d152d69
|
||||
* token_rong : PT2F9Czs6EdhMRnO1KKIZx0w4VLHhDYtXuIXO7PWfrA=@xln2.sg.rongnav.com;xln2.sg.rongcfg.com
|
||||
* user_nicename : 测试03
|
||||
* user_status : 1
|
||||
* vip : {"type":"0"}
|
||||
* votestotal : 0
|
||||
*/
|
||||
//用户头像
|
||||
@SerializedName("avatar")
|
||||
private String avatar = "";
|
||||
//头像缩略图
|
||||
@SerializedName("avatar_thumb")
|
||||
private String avatarThumb = "";
|
||||
//用户生日
|
||||
@SerializedName("birthday")
|
||||
private String birthday = "";
|
||||
//用户城市
|
||||
@SerializedName("city")
|
||||
private String city = "";
|
||||
//
|
||||
@SerializedName("coin")
|
||||
private long coin = 0;
|
||||
//
|
||||
@SerializedName("consumption")
|
||||
private long consumption = 0;
|
||||
//
|
||||
@SerializedName("front_task")
|
||||
private long frontTask = 0;
|
||||
//
|
||||
@SerializedName("gold")
|
||||
private long gold = 0;
|
||||
//
|
||||
@SerializedName("goldsumption")
|
||||
private long goldsumption = 0;
|
||||
//
|
||||
@SerializedName("goodnum")
|
||||
private String goodnum = "";
|
||||
//用户ID唯一识别标志
|
||||
@SerializedName("id")
|
||||
private long id = 0;
|
||||
//
|
||||
@SerializedName("issuper")
|
||||
private long issuper = 0;
|
||||
//
|
||||
@SerializedName("langue")
|
||||
private String langue = "";
|
||||
//
|
||||
@SerializedName("level")
|
||||
private String level = "";
|
||||
//
|
||||
@SerializedName("level_anchor")
|
||||
private String levelAnchor = "";
|
||||
//
|
||||
@SerializedName("liang")
|
||||
private LiangModel liang = new LiangModel();
|
||||
//
|
||||
@SerializedName("location")
|
||||
private String location = "";
|
||||
//
|
||||
@SerializedName("medal_level")
|
||||
private String medalLevel = "";
|
||||
//
|
||||
@SerializedName("medal_name")
|
||||
private String medalName = "";
|
||||
//
|
||||
@SerializedName("noble_id")
|
||||
private long nobleId = 0;
|
||||
//
|
||||
@SerializedName("province")
|
||||
private String province = "";
|
||||
//性别
|
||||
@SerializedName("sex")
|
||||
private long sex = 0;
|
||||
//
|
||||
@SerializedName("signature")
|
||||
private String signature = "";
|
||||
//平台token
|
||||
@SerializedName("token")
|
||||
private String token = "";
|
||||
//融云token(由服务器维护)
|
||||
@SerializedName("token_rong")
|
||||
private String tokenRong = "";
|
||||
//昵称
|
||||
@SerializedName("user_nicename")
|
||||
private String userNicename = "";
|
||||
//
|
||||
@SerializedName("user_status")
|
||||
private long userStatus = 0;
|
||||
//
|
||||
@SerializedName("vip")
|
||||
private VipModel vip = new VipModel();
|
||||
//
|
||||
@SerializedName("votestotal")
|
||||
private long votestotal = 0;
|
||||
//是否首次登录
|
||||
@SerializedName("first_login")
|
||||
private long firstLogin = 0;
|
||||
//
|
||||
@SerializedName("isagent")
|
||||
private long isagent = 0;
|
||||
//未读消息数(只在MessageIMManager中使用)
|
||||
@SerializedName("num")
|
||||
private String num = "";
|
||||
//是否是管理员
|
||||
@SerializedName("is_admin")
|
||||
private String isAdmin = "";
|
||||
|
||||
public String getIsAdmin() {
|
||||
return isAdmin;
|
||||
}
|
||||
|
||||
public IMLoginModel setIsAdmin(String isAdmin) {
|
||||
this.isAdmin = isAdmin;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getNum() {
|
||||
return num;
|
||||
}
|
||||
|
||||
public IMLoginModel setNum(String num) {
|
||||
this.num = num;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getFirstLogin() {
|
||||
return firstLogin;
|
||||
}
|
||||
|
||||
public IMLoginModel setFirstLogin(long firstLogin) {
|
||||
this.firstLogin = firstLogin;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getIsagent() {
|
||||
return isagent;
|
||||
}
|
||||
|
||||
public IMLoginModel setIsagent(long isagent) {
|
||||
this.isagent = isagent;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getAvatar() {
|
||||
return avatar;
|
||||
}
|
||||
|
||||
public IMLoginModel setAvatar(String avatar) {
|
||||
this.avatar = avatar;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getAvatarThumb() {
|
||||
return avatarThumb;
|
||||
}
|
||||
|
||||
public IMLoginModel setAvatarThumb(String avatarThumb) {
|
||||
this.avatarThumb = avatarThumb;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getBirthday() {
|
||||
return birthday;
|
||||
}
|
||||
|
||||
public IMLoginModel setBirthday(String birthday) {
|
||||
this.birthday = birthday;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getCity() {
|
||||
return city;
|
||||
}
|
||||
|
||||
public IMLoginModel setCity(String city) {
|
||||
this.city = city;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getCoin() {
|
||||
return coin;
|
||||
}
|
||||
|
||||
public IMLoginModel setCoin(long coin) {
|
||||
this.coin = coin;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getConsumption() {
|
||||
return consumption;
|
||||
}
|
||||
|
||||
public IMLoginModel setConsumption(long consumption) {
|
||||
this.consumption = consumption;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getFrontTask() {
|
||||
return frontTask;
|
||||
}
|
||||
|
||||
public IMLoginModel setFrontTask(long frontTask) {
|
||||
this.frontTask = frontTask;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getGold() {
|
||||
return gold;
|
||||
}
|
||||
|
||||
public IMLoginModel setGold(long gold) {
|
||||
this.gold = gold;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getGoldsumption() {
|
||||
return goldsumption;
|
||||
}
|
||||
|
||||
public IMLoginModel setGoldsumption(long goldsumption) {
|
||||
this.goldsumption = goldsumption;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getGoodnum() {
|
||||
return goodnum;
|
||||
}
|
||||
|
||||
public IMLoginModel setGoodnum(String goodnum) {
|
||||
this.goodnum = goodnum;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public IMLoginModel setId(long id) {
|
||||
this.id = id;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getIssuper() {
|
||||
return issuper;
|
||||
}
|
||||
|
||||
public IMLoginModel setIssuper(long issuper) {
|
||||
this.issuper = issuper;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getLangue() {
|
||||
return langue;
|
||||
}
|
||||
|
||||
public IMLoginModel setLangue(String langue) {
|
||||
this.langue = langue;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public IMLoginModel setLevel(String level) {
|
||||
this.level = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getLevelAnchor() {
|
||||
return levelAnchor;
|
||||
}
|
||||
|
||||
public IMLoginModel setLevelAnchor(String levelAnchor) {
|
||||
this.levelAnchor = levelAnchor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public LiangModel getLiang() {
|
||||
return liang;
|
||||
}
|
||||
|
||||
public IMLoginModel setLiang(LiangModel liang) {
|
||||
this.liang = liang;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getLocation() {
|
||||
return location;
|
||||
}
|
||||
|
||||
public IMLoginModel setLocation(String location) {
|
||||
this.location = location;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getMedalLevel() {
|
||||
return medalLevel;
|
||||
}
|
||||
|
||||
public IMLoginModel setMedalLevel(String medalLevel) {
|
||||
this.medalLevel = medalLevel;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getMedalName() {
|
||||
return medalName;
|
||||
}
|
||||
|
||||
public IMLoginModel setMedalName(String medalName) {
|
||||
this.medalName = medalName;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getNobleId() {
|
||||
return nobleId;
|
||||
}
|
||||
|
||||
public IMLoginModel setNobleId(long nobleId) {
|
||||
this.nobleId = nobleId;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getProvince() {
|
||||
return province;
|
||||
}
|
||||
|
||||
public IMLoginModel setProvince(String province) {
|
||||
this.province = province;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getSex() {
|
||||
return sex;
|
||||
}
|
||||
|
||||
public IMLoginModel setSex(long sex) {
|
||||
this.sex = sex;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getSignature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
public IMLoginModel setSignature(String signature) {
|
||||
this.signature = signature;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getToken() {
|
||||
return token;
|
||||
}
|
||||
|
||||
public IMLoginModel setToken(String token) {
|
||||
this.token = token;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getTokenRong() {
|
||||
return tokenRong;
|
||||
}
|
||||
|
||||
public IMLoginModel setTokenRong(String tokenRong) {
|
||||
this.tokenRong = tokenRong;
|
||||
return this;
|
||||
}
|
||||
|
||||
public String getUserNicename() {
|
||||
return userNicename;
|
||||
}
|
||||
|
||||
public IMLoginModel setUserNicename(String userNicename) {
|
||||
this.userNicename = userNicename;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getUserStatus() {
|
||||
return userStatus;
|
||||
}
|
||||
|
||||
public IMLoginModel setUserStatus(long userStatus) {
|
||||
this.userStatus = userStatus;
|
||||
return this;
|
||||
}
|
||||
|
||||
public VipModel getVip() {
|
||||
return vip;
|
||||
}
|
||||
|
||||
public IMLoginModel setVip(VipModel vip) {
|
||||
this.vip = vip;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getVotestotal() {
|
||||
return votestotal;
|
||||
}
|
||||
|
||||
public IMLoginModel setVotestotal(long votestotal) {
|
||||
this.votestotal = votestotal;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
21
common/src/main/java/com/yunbao/common/bean/LiangModel.java
Normal file
21
common/src/main/java/com/yunbao/common/bean/LiangModel.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.yunbao.common.bean;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class LiangModel extends BaseModel {
|
||||
/**
|
||||
* name : 0
|
||||
*/
|
||||
|
||||
@SerializedName("name")
|
||||
private String name = "";
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public LiangModel setName(String name) {
|
||||
this.name = name;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
21
common/src/main/java/com/yunbao/common/bean/VipModel.java
Normal file
21
common/src/main/java/com/yunbao/common/bean/VipModel.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package com.yunbao.common.bean;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class VipModel extends BaseModel {
|
||||
/**
|
||||
* type : 0
|
||||
*/
|
||||
|
||||
@SerializedName("type")
|
||||
private String type = "";
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public VipModel setType(String type) {
|
||||
this.type = type;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,10 @@
|
||||
package com.yunbao.common.custom;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.viewpager.widget.ViewPager;
|
||||
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
@@ -54,7 +56,6 @@ public class TabButtonGroup extends LinearLayout implements View.OnClickListener
|
||||
public void setCurPosition(int position) {
|
||||
//点击事件切换
|
||||
if (position == mCurPosition) {
|
||||
// return;
|
||||
long curTime = System.currentTimeMillis();
|
||||
if (curTime - mLastClickBackTime <= 500) {
|
||||
if (position != 2 && position != 3) {
|
||||
@@ -80,6 +81,9 @@ public class TabButtonGroup extends LinearLayout implements View.OnClickListener
|
||||
Object tag = v.getTag();
|
||||
if (tag != null) {
|
||||
setCurPosition((int) tag);
|
||||
if (listener != null) {
|
||||
listener.onPageSelected(v, (int) tag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,11 +96,19 @@ public class TabButtonGroup extends LinearLayout implements View.OnClickListener
|
||||
for (TabButton tbn : mTabButtons) {
|
||||
if (tbn != null) {
|
||||
tbn.cancelAnim();
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public interface TabButtonGroupChangeListener {
|
||||
void onPageSelected(View view, int index);
|
||||
}
|
||||
|
||||
private TabButtonGroupChangeListener listener = null;
|
||||
|
||||
public void addTabButtonGroupChangeListener(TabButtonGroupChangeListener mListener) {
|
||||
listener = mListener;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.yunbao.common.event;
|
||||
|
||||
import com.yunbao.common.bean.BaseModel;
|
||||
|
||||
/**
|
||||
* 未读消息整合
|
||||
*/
|
||||
public class MessageIMEvent extends BaseModel {
|
||||
private int number = 0;
|
||||
|
||||
public int getNumber() {
|
||||
return number;
|
||||
}
|
||||
|
||||
public MessageIMEvent setNumber(int number) {
|
||||
this.number = number;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.yunbao.common.manager;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.yunbao.common.bean.IMLoginModel;
|
||||
import com.yunbao.common.manager.base.BaseCacheManager;
|
||||
|
||||
/**
|
||||
* 登录者信息管理
|
||||
*/
|
||||
public class IMLoginManager extends BaseCacheManager {
|
||||
|
||||
|
||||
private final static String KEY_USER_INFO = "keyUserInfo";
|
||||
|
||||
private static IMLoginManager manager;
|
||||
private IMLoginModel userInfo;
|
||||
|
||||
private IMLoginManager(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单利
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public static IMLoginManager get(Context context) {
|
||||
if (null == manager) {
|
||||
manager = new IMLoginManager(context);
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public IMLoginModel getUserInfo() {
|
||||
if (null == userInfo) {
|
||||
userInfo = new Gson().fromJson(
|
||||
getString(KEY_USER_INFO), IMLoginModel.class);
|
||||
}
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置已登录的用户信息
|
||||
*
|
||||
* @param model
|
||||
*/
|
||||
public void setupLoginUser(@NonNull IMLoginModel model) {
|
||||
put(KEY_USER_INFO, new Gson().toJson(model));
|
||||
this.userInfo = model;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 退出登录
|
||||
*/
|
||||
public void logout() {
|
||||
//删除用户登录信息
|
||||
deleteByKey(KEY_USER_INFO);
|
||||
//用户对象置空
|
||||
userInfo=null;
|
||||
manager = null;
|
||||
}
|
||||
|
||||
}
|
||||
858
common/src/main/java/com/yunbao/common/manager/base/ACache.java
Normal file
858
common/src/main/java/com/yunbao/common/manager/base/ACache.java
Normal file
@@ -0,0 +1,858 @@
|
||||
/**
|
||||
* Copyright (c) 2012-2013, Michael Yang 杨福海 (www.yangfuhai.com).
|
||||
* <p/>
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* <p/>
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* <p/>
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.yunbao.common.manager.base;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.io.Serializable;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
/**
|
||||
* android轻量级缓存框架
|
||||
*/
|
||||
public class ACache {
|
||||
public static final int TIME_HOUR = 60 * 60;
|
||||
public static final int TIME_DAY = TIME_HOUR * 24;
|
||||
private static final int MAX_SIZE = 1000 * 1000 * 50; // 50 mb
|
||||
private static final int MAX_COUNT = Integer.MAX_VALUE; // 不限制存放数据的数量
|
||||
private static Map<String, ACache> mInstanceMap = new HashMap<>();
|
||||
private ACacheManager mCache;
|
||||
|
||||
public static ACache get(Context ctx) {
|
||||
return get(ctx, "ACache");
|
||||
}
|
||||
|
||||
public static ACache get(Context ctx, String cacheName) {
|
||||
File f = new File(ctx.getCacheDir(), cacheName);
|
||||
return get(f, MAX_SIZE, MAX_COUNT);
|
||||
}
|
||||
|
||||
public static ACache get(File cacheDir) {
|
||||
return get(cacheDir, MAX_SIZE, MAX_COUNT);
|
||||
}
|
||||
|
||||
public static ACache get(Context ctx, long max_zise, int max_count) {
|
||||
File f = new File(ctx.getCacheDir(), "ACache");
|
||||
return get(f, max_zise, max_count);
|
||||
}
|
||||
|
||||
public static ACache get(File cacheDir, long max_zise, int max_count) {
|
||||
ACache manager = mInstanceMap.get(cacheDir.getAbsoluteFile() + myPid());
|
||||
if (manager == null) {
|
||||
manager = new ACache(cacheDir, max_zise, max_count);
|
||||
mInstanceMap.put(cacheDir.getAbsolutePath() + myPid(), manager);
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
|
||||
private static String myPid() {
|
||||
return "_" + android.os.Process.myPid();
|
||||
}
|
||||
|
||||
private ACache(File cacheDir, long max_size, int max_count) {
|
||||
if (!cacheDir.exists() && !cacheDir.mkdirs()) {
|
||||
throw new RuntimeException("can't make dirs in "
|
||||
+ cacheDir.getAbsolutePath());
|
||||
}
|
||||
mCache = new ACacheManager(cacheDir, max_size, max_count);
|
||||
}
|
||||
|
||||
// =======================================
|
||||
// ============ String数据 读写 ==============
|
||||
// =======================================
|
||||
|
||||
/**
|
||||
* 保存 String数据 到 缓存中
|
||||
*
|
||||
* @param key 保存的key
|
||||
* @param value 保存的String数据
|
||||
*/
|
||||
public void put(String key, String value) {
|
||||
File file = mCache.newFile(key);
|
||||
BufferedWriter out = null;
|
||||
try {
|
||||
out = new BufferedWriter(new FileWriter(file), 1024);
|
||||
out.write(value);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (out != null) {
|
||||
try {
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
mCache.put(file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存 String数据 到 缓存中
|
||||
*
|
||||
* @param key 保存的key
|
||||
* @param value 保存的String数据
|
||||
* @param saveTime 保存的时间,单位:秒
|
||||
*/
|
||||
public void put(String key, String value, int saveTime) {
|
||||
if (saveTime != -1) {
|
||||
put(key, Utils.newStringWithDateInfo(saveTime, value));
|
||||
} else {
|
||||
put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取 String数据
|
||||
*
|
||||
* @param key 键
|
||||
* @return String 数据
|
||||
*/
|
||||
public String getAsString(String key) {
|
||||
File file = mCache.get(key);
|
||||
if (!file.exists())
|
||||
return null;
|
||||
boolean removeFile = false;
|
||||
BufferedReader in = null;
|
||||
try {
|
||||
in = new BufferedReader(new FileReader(file));
|
||||
String readString = "";
|
||||
String currentLine;
|
||||
while ((currentLine = in.readLine()) != null) {
|
||||
readString += currentLine;
|
||||
}
|
||||
if (!Utils.isDue(readString)) {
|
||||
return Utils.clearDateInfo(readString);
|
||||
} else {
|
||||
removeFile = true;
|
||||
return null;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} finally {
|
||||
if (in != null) {
|
||||
try {
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (removeFile)
|
||||
remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================
|
||||
// ============= JSONObject 数据 读写 ==============
|
||||
// =======================================
|
||||
|
||||
/**
|
||||
* 保存 JSONObject数据 到 缓存中
|
||||
*
|
||||
* @param key 保存的key
|
||||
* @param value 保存的JSON数据
|
||||
*/
|
||||
public void put(String key, JSONObject value) {
|
||||
put(key, value.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存 JSONObject数据 到 缓存中
|
||||
*
|
||||
* @param key 保存的key
|
||||
* @param value 保存的JSONObject数据
|
||||
* @param saveTime 保存的时间,单位:秒
|
||||
*/
|
||||
public void put(String key, JSONObject value, int saveTime) {
|
||||
if (saveTime != -1) {
|
||||
put(key, value.toString(), saveTime);
|
||||
} else {
|
||||
put(key, value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取JSONObject数据
|
||||
*
|
||||
* @param key 键
|
||||
* @return JSONObject数据
|
||||
*/
|
||||
public JSONObject getAsJSONObject(String key) {
|
||||
String JSONString = getAsString(key);
|
||||
try {
|
||||
JSONObject obj = new JSONObject(JSONString);
|
||||
return obj;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================
|
||||
// ============ JSONArray 数据 读写 =============
|
||||
// =======================================
|
||||
|
||||
/**
|
||||
* 保存 JSONArray数据 到 缓存中
|
||||
*
|
||||
* @param key 保存的key
|
||||
* @param value 保存的JSONArray数据
|
||||
*/
|
||||
public void put(String key, JSONArray value) {
|
||||
put(key, value.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存 JSONArray数据 到 缓存中
|
||||
*
|
||||
* @param key 保存的key
|
||||
* @param value 保存的JSONArray数据
|
||||
* @param saveTime 保存的时间,单位:秒
|
||||
*/
|
||||
public void put(String key, JSONArray value, int saveTime) {
|
||||
if (saveTime != -1) {
|
||||
put(key, value.toString(), saveTime);
|
||||
} else {
|
||||
put(key, value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取JSONArray数据
|
||||
*
|
||||
* @param key 键
|
||||
* @return JSONArray数据
|
||||
*/
|
||||
public JSONArray getAsJSONArray(String key) {
|
||||
String JSONString = getAsString(key);
|
||||
try {
|
||||
JSONArray obj = new JSONArray(JSONString);
|
||||
return obj;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================
|
||||
// ============== byte 数据 读写 =============
|
||||
// =======================================
|
||||
|
||||
/**
|
||||
* 保存 byte数据 到 缓存中
|
||||
*
|
||||
* @param key 保存的key
|
||||
* @param value 保存的数据
|
||||
*/
|
||||
public void put(String key, byte[] value) {
|
||||
File file = mCache.newFile(key);
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
out = new FileOutputStream(file);
|
||||
out.write(value);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (out != null) {
|
||||
try {
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
mCache.put(file);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存 byte数据 到 缓存中
|
||||
*
|
||||
* @param key 保存的key
|
||||
* @param value 保存的数据
|
||||
* @param saveTime 保存的时间,单位:秒
|
||||
*/
|
||||
public void put(String key, byte[] value, int saveTime) {
|
||||
if (saveTime != -1) {
|
||||
put(key, Utils.newByteArrayWithDateInfo(saveTime, value));
|
||||
} else {
|
||||
put(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 byte 数据
|
||||
*
|
||||
* @param key 键
|
||||
* @return byte 数据
|
||||
*/
|
||||
public byte[] getAsBinary(String key) {
|
||||
RandomAccessFile RAFile = null;
|
||||
boolean removeFile = false;
|
||||
try {
|
||||
File file = mCache.get(key);
|
||||
if (!file.exists())
|
||||
return null;
|
||||
RAFile = new RandomAccessFile(file, "r");
|
||||
byte[] byteArray = new byte[(int) RAFile.length()];
|
||||
RAFile.read(byteArray);
|
||||
if (!Utils.isDue(byteArray)) {
|
||||
return Utils.clearDateInfo(byteArray);
|
||||
} else {
|
||||
removeFile = true;
|
||||
return null;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} finally {
|
||||
if (RAFile != null) {
|
||||
try {
|
||||
RAFile.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (removeFile)
|
||||
remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
// =======================================
|
||||
// ============= 序列化 数据 读写 ===============
|
||||
// =======================================
|
||||
|
||||
/**
|
||||
* 保存 Serializable数据 到 缓存中
|
||||
*
|
||||
* @param key 保存的key
|
||||
* @param value 保存的value
|
||||
*/
|
||||
public void put(String key, Serializable value) {
|
||||
put(key, value, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存 Serializable数据到 缓存中
|
||||
*
|
||||
* @param key 保存的key
|
||||
* @param value 保存的value
|
||||
* @param saveTime 保存的时间,单位:秒
|
||||
*/
|
||||
public void put(String key, Serializable value, int saveTime) {
|
||||
ByteArrayOutputStream baos = null;
|
||||
ObjectOutputStream oos = null;
|
||||
try {
|
||||
baos = new ByteArrayOutputStream();
|
||||
oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject(value);
|
||||
byte[] data = baos.toByteArray();
|
||||
if (saveTime != -1) {
|
||||
put(key, data, saveTime);
|
||||
} else {
|
||||
put(key, data);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
try {
|
||||
oos.close();
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取 Serializable数据
|
||||
*
|
||||
* @param key key
|
||||
* @return Serializable 数据
|
||||
*/
|
||||
public Object getAsObject(String key) {
|
||||
byte[] data = getAsBinary(key);
|
||||
if (data != null) {
|
||||
ByteArrayInputStream bais = null;
|
||||
ObjectInputStream ois = null;
|
||||
try {
|
||||
bais = new ByteArrayInputStream(data);
|
||||
ois = new ObjectInputStream(bais);
|
||||
Object reObject = ois.readObject();
|
||||
return reObject;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} finally {
|
||||
try {
|
||||
if (bais != null)
|
||||
bais.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
try {
|
||||
if (ois != null)
|
||||
ois.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
// =======================================
|
||||
// ============== bitmap 数据 读写 =============
|
||||
// =======================================
|
||||
|
||||
/**
|
||||
* 保存 bitmap 到 缓存中
|
||||
*
|
||||
* @param key 保存的key
|
||||
* @param value 保存的bitmap数据
|
||||
*/
|
||||
public void put(String key, Bitmap value) {
|
||||
put(key, Utils.Bitmap2Bytes(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存 bitmap 到 缓存中
|
||||
*
|
||||
* @param key 保存的key
|
||||
* @param value 保存的 bitmap 数据
|
||||
* @param saveTime 保存的时间,单位:秒
|
||||
*/
|
||||
public void put(String key, Bitmap value, int saveTime) {
|
||||
put(key, Utils.Bitmap2Bytes(value), saveTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取 bitmap 数据
|
||||
*
|
||||
* @param key key
|
||||
* @return bitmap 数据
|
||||
*/
|
||||
public Bitmap getAsBitmap(String key) {
|
||||
if (getAsBinary(key) == null) {
|
||||
return null;
|
||||
}
|
||||
return Utils.Bytes2Bimap(getAsBinary(key));
|
||||
}
|
||||
|
||||
// =======================================
|
||||
// ============= drawable 数据 读写 =============
|
||||
// =======================================
|
||||
|
||||
/**
|
||||
* 保存 drawable 到 缓存中
|
||||
*
|
||||
* @param key 保存的key
|
||||
* @param value 保存的drawable数据
|
||||
*/
|
||||
public void put(String key, Drawable value) {
|
||||
put(key, Utils.drawable2Bitmap(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存 drawable 到 缓存中
|
||||
*
|
||||
* @param key 保存的key
|
||||
* @param value 保存的 drawable 数据
|
||||
* @param saveTime 保存的时间,单位:秒
|
||||
*/
|
||||
public void put(String key, Drawable value, int saveTime) {
|
||||
put(key, Utils.drawable2Bitmap(value), saveTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 读取 Drawable 数据
|
||||
*
|
||||
* @param key key
|
||||
* @return Drawable 数据
|
||||
*/
|
||||
public Drawable getAsDrawable(String key) {
|
||||
if (getAsBinary(key) == null) {
|
||||
return null;
|
||||
}
|
||||
return Utils.bitmap2Drawable(Utils.Bytes2Bimap(getAsBinary(key)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存文件
|
||||
*
|
||||
* @param key key
|
||||
* @return value 缓存的文件
|
||||
*/
|
||||
public File file(String key) {
|
||||
File f = mCache.newFile(key);
|
||||
if (f.exists())
|
||||
return f;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除某个key
|
||||
*
|
||||
* @param key key
|
||||
* @return 是否移除成功
|
||||
*/
|
||||
public boolean remove(String key) {
|
||||
return mCache.remove(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除所有数据
|
||||
*/
|
||||
public void clear() {
|
||||
mCache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @author 杨福海(michael) www.yangfuhai.com
|
||||
* @version 1.0
|
||||
*/
|
||||
public class ACacheManager {
|
||||
private final AtomicLong cacheSize;
|
||||
private final AtomicInteger cacheCount;
|
||||
private final long sizeLimit;
|
||||
private final int countLimit;
|
||||
private final Map<File, Long> lastUsageDates = Collections
|
||||
.synchronizedMap(new HashMap<File, Long>());
|
||||
protected File cacheDir;
|
||||
|
||||
private ACacheManager(File cacheDir, long sizeLimit, int countLimit) {
|
||||
this.cacheDir = cacheDir;
|
||||
this.sizeLimit = sizeLimit;
|
||||
this.countLimit = countLimit;
|
||||
cacheSize = new AtomicLong();
|
||||
cacheCount = new AtomicInteger();
|
||||
calculateCacheSizeAndCacheCount();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算 cacheSize和cacheCount
|
||||
*/
|
||||
private void calculateCacheSizeAndCacheCount() {
|
||||
new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int size = 0;
|
||||
int count = 0;
|
||||
File[] cachedFiles = cacheDir.listFiles();
|
||||
if (cachedFiles != null) {
|
||||
for (File cachedFile : cachedFiles) {
|
||||
size += calculateSize(cachedFile);
|
||||
count += 1;
|
||||
lastUsageDates.put(cachedFile,
|
||||
cachedFile.lastModified());
|
||||
}
|
||||
cacheSize.set(size);
|
||||
cacheCount.set(count);
|
||||
}
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void put(File file) {
|
||||
int curCacheCount = cacheCount.get();
|
||||
while (curCacheCount + 1 > countLimit) {
|
||||
long freedSize = removeNext();
|
||||
cacheSize.addAndGet(-freedSize);
|
||||
|
||||
curCacheCount = cacheCount.addAndGet(-1);
|
||||
}
|
||||
cacheCount.addAndGet(1);
|
||||
|
||||
long valueSize = calculateSize(file);
|
||||
long curCacheSize = cacheSize.get();
|
||||
while (curCacheSize + valueSize > sizeLimit) {
|
||||
long freedSize = removeNext();
|
||||
curCacheSize = cacheSize.addAndGet(-freedSize);
|
||||
}
|
||||
cacheSize.addAndGet(valueSize);
|
||||
|
||||
Long currentTime = System.currentTimeMillis();
|
||||
file.setLastModified(currentTime);
|
||||
lastUsageDates.put(file, currentTime);
|
||||
}
|
||||
|
||||
private File get(String key) {
|
||||
File file = newFile(key);
|
||||
Long currentTime = System.currentTimeMillis();
|
||||
file.setLastModified(currentTime);
|
||||
lastUsageDates.put(file, currentTime);
|
||||
|
||||
return file;
|
||||
}
|
||||
|
||||
private File newFile(String key) {
|
||||
return new File(cacheDir, key.hashCode() + "");
|
||||
}
|
||||
|
||||
private boolean remove(String key) {
|
||||
File image = get(key);
|
||||
return image.delete();
|
||||
}
|
||||
|
||||
private void clear() {
|
||||
lastUsageDates.clear();
|
||||
cacheSize.set(0);
|
||||
File[] files = cacheDir.listFiles();
|
||||
if (files != null) {
|
||||
for (File f : files) {
|
||||
f.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除旧的文件
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private long removeNext() {
|
||||
if (lastUsageDates.isEmpty()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Long oldestUsage = null;
|
||||
File mostLongUsedFile = null;
|
||||
Set<Entry<File, Long>> entries = lastUsageDates.entrySet();
|
||||
synchronized (lastUsageDates) {
|
||||
for (Entry<File, Long> entry : entries) {
|
||||
if (mostLongUsedFile == null) {
|
||||
mostLongUsedFile = entry.getKey();
|
||||
oldestUsage = entry.getValue();
|
||||
} else {
|
||||
Long lastValueUsage = entry.getValue();
|
||||
if (lastValueUsage < oldestUsage) {
|
||||
oldestUsage = lastValueUsage;
|
||||
mostLongUsedFile = entry.getKey();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
long fileSize = calculateSize(mostLongUsedFile);
|
||||
if (mostLongUsedFile.delete()) {
|
||||
lastUsageDates.remove(mostLongUsedFile);
|
||||
}
|
||||
return fileSize;
|
||||
}
|
||||
|
||||
private long calculateSize(File file) {
|
||||
return file.length();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author 杨福海(michael) www.yangfuhai.com
|
||||
* @version 1.0
|
||||
* @title 时间计算工具类
|
||||
*/
|
||||
private static class Utils {
|
||||
|
||||
/**
|
||||
* 判断缓存的String数据是否到期
|
||||
*
|
||||
* @param str key
|
||||
* @return true:到期了 false:还没有到期
|
||||
*/
|
||||
private static boolean isDue(String str) {
|
||||
return isDue(str.getBytes());
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断缓存的byte数据是否到期
|
||||
*
|
||||
* @param data 数据集合
|
||||
* @return true:到期了 false:还没有到期
|
||||
*/
|
||||
private static boolean isDue(byte[] data) {
|
||||
String[] strs = getDateInfoFromDate(data);
|
||||
if (strs != null && strs.length == 2) {
|
||||
String saveTimeStr = strs[0];
|
||||
while (saveTimeStr.startsWith("0")) {
|
||||
saveTimeStr = saveTimeStr
|
||||
.substring(1, saveTimeStr.length());
|
||||
}
|
||||
long saveTime = Long.valueOf(saveTimeStr);
|
||||
long deleteAfter = Long.valueOf(strs[1]);
|
||||
if (System.currentTimeMillis() > saveTime + deleteAfter * 1000) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static String newStringWithDateInfo(int second, String strInfo) {
|
||||
return createDateInfo(second) + strInfo;
|
||||
}
|
||||
|
||||
private static byte[] newByteArrayWithDateInfo(int second, byte[] data2) {
|
||||
byte[] data1 = createDateInfo(second).getBytes();
|
||||
byte[] retdata = new byte[data1.length + data2.length];
|
||||
System.arraycopy(data1, 0, retdata, 0, data1.length);
|
||||
System.arraycopy(data2, 0, retdata, data1.length, data2.length);
|
||||
return retdata;
|
||||
}
|
||||
|
||||
private static String clearDateInfo(String strInfo) {
|
||||
if (strInfo != null && hasDateInfo(strInfo.getBytes())) {
|
||||
strInfo = strInfo.substring(strInfo.indexOf(mSeparator) + 1,
|
||||
strInfo.length());
|
||||
}
|
||||
return strInfo;
|
||||
}
|
||||
|
||||
private static byte[] clearDateInfo(byte[] data) {
|
||||
if (hasDateInfo(data)) {
|
||||
return copyOfRange(data, indexOf(data, mSeparator) + 1,
|
||||
data.length);
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
private static boolean hasDateInfo(byte[] data) {
|
||||
return data != null && data.length > 15 && data[13] == '-'
|
||||
&& indexOf(data, mSeparator) > 14;
|
||||
}
|
||||
|
||||
private static String[] getDateInfoFromDate(byte[] data) {
|
||||
if (hasDateInfo(data)) {
|
||||
String saveDate = new String(copyOfRange(data, 0, 13));
|
||||
String deleteAfter = new String(copyOfRange(data, 14,
|
||||
indexOf(data, mSeparator)));
|
||||
return new String[]{saveDate, deleteAfter};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int indexOf(byte[] data, char c) {
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
if (data[i] == c) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static byte[] copyOfRange(byte[] original, int from, int to) {
|
||||
int newLength = to - from;
|
||||
if (newLength < 0)
|
||||
throw new IllegalArgumentException(from + " > " + to);
|
||||
byte[] copy = new byte[newLength];
|
||||
System.arraycopy(original, from, copy, 0,
|
||||
Math.min(original.length - from, newLength));
|
||||
return copy;
|
||||
}
|
||||
|
||||
private static final char mSeparator = ' ';
|
||||
|
||||
private static String createDateInfo(int second) {
|
||||
String currentTime = System.currentTimeMillis() + "";
|
||||
while (currentTime.length() < 13) {
|
||||
currentTime = "0" + currentTime;
|
||||
}
|
||||
return currentTime + "-" + second + mSeparator;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitmap → byte[]
|
||||
*/
|
||||
private static byte[] Bitmap2Bytes(Bitmap bm) {
|
||||
if (bm == null) {
|
||||
return null;
|
||||
}
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
|
||||
return baos.toByteArray();
|
||||
}
|
||||
|
||||
/*
|
||||
* byte[] → Bitmap
|
||||
*/
|
||||
private static Bitmap Bytes2Bimap(byte[] b) {
|
||||
if (b.length == 0) {
|
||||
return null;
|
||||
}
|
||||
return BitmapFactory.decodeByteArray(b, 0, b.length);
|
||||
}
|
||||
|
||||
/*
|
||||
* Drawable → Bitmap
|
||||
*/
|
||||
private static Bitmap drawable2Bitmap(Drawable drawable) {
|
||||
if (drawable == null) {
|
||||
return null;
|
||||
}
|
||||
// 取 drawable 的长宽
|
||||
int w = drawable.getIntrinsicWidth();
|
||||
int h = drawable.getIntrinsicHeight();
|
||||
// 取 drawable 的颜色格式
|
||||
Bitmap.Config config = drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888
|
||||
: Bitmap.Config.RGB_565;
|
||||
// 建立对应 bitmap
|
||||
Bitmap bitmap = Bitmap.createBitmap(w, h, config);
|
||||
// 建立对应 bitmap 的画布
|
||||
Canvas canvas = new Canvas(bitmap);
|
||||
drawable.setBounds(0, 0, w, h);
|
||||
// 把 drawable 内容画到画布中
|
||||
drawable.draw(canvas);
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bitmap → Drawable
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
private static Drawable bitmap2Drawable(Bitmap bm) {
|
||||
if (bm == null) {
|
||||
return null;
|
||||
}
|
||||
return new BitmapDrawable(bm);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,406 @@
|
||||
package com.yunbao.common.manager.base;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 缓存管理基类
|
||||
*/
|
||||
public class BaseCacheManager {
|
||||
private int mode;
|
||||
private Gson gson;
|
||||
private ACache aCache;
|
||||
private Context context;
|
||||
private SharedPreferences sharedPreferences;
|
||||
|
||||
public BaseCacheManager(Context context) {
|
||||
this(context, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
public BaseCacheManager(Context context, int mode) {
|
||||
this.context = context;
|
||||
this.mode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 懒加载acache对象
|
||||
*
|
||||
* @return 当前类对象
|
||||
*/
|
||||
private ACache getACache() {
|
||||
if (null == aCache) {
|
||||
this.aCache = ACache.get(context, getCacheName());
|
||||
}
|
||||
return aCache;
|
||||
}
|
||||
|
||||
/**
|
||||
* 懒加载SharedPreferences对象
|
||||
*
|
||||
* @return sp对象
|
||||
*/
|
||||
private SharedPreferences getSharedPreferences() {
|
||||
if (null == sharedPreferences) {
|
||||
this.sharedPreferences = context.getSharedPreferences(getCacheName(), mode);
|
||||
}
|
||||
return sharedPreferences;
|
||||
}
|
||||
|
||||
/**
|
||||
* 懒加载Gson对象
|
||||
*
|
||||
* @return gson对象
|
||||
*/
|
||||
private Gson getGson() {
|
||||
if (null == gson) {//首次获取gson
|
||||
this.gson = getCustomizeGson();
|
||||
if (null == gson) {//为空则创建默认gson
|
||||
this.gson = new Gson();
|
||||
}
|
||||
}
|
||||
return gson;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入byte[]类型
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
*/
|
||||
public void put(String key, Byte[] value) {
|
||||
put(key, value, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入byte[]类型
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param saveTime 存储时间
|
||||
*/
|
||||
public void put(String key, Byte[] value, int saveTime) {
|
||||
getACache().put(key, value, saveTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入string类型
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
*/
|
||||
public void put(String key, String value) {
|
||||
put(key, value, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入string类型
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param saveTime 存储时间
|
||||
*/
|
||||
public void put(String key, String value, int saveTime) {
|
||||
getACache().put(key, value, saveTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入实现了serializable接口的对象
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param <D> 泛型
|
||||
*/
|
||||
public <D extends Serializable> void put(String key, D value) {
|
||||
put(key, value, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入实现了serializable接口的对象
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param <D> 泛型
|
||||
* @param saveTime 存储时间
|
||||
*/
|
||||
public <D extends Serializable> void put(String key, D value, int saveTime) {
|
||||
getACache().put(key, value, saveTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入jsonobject对象
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
*/
|
||||
public void put(String key, JSONObject value) {
|
||||
put(key, value, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入jsonobject对象
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param saveTime 存储时间
|
||||
*/
|
||||
public void put(String key, JSONObject value, int saveTime) {
|
||||
getACache().put(key, value, saveTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入jsonarray对象
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
*/
|
||||
public void put(String key, JSONArray value) {
|
||||
put(key, value, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入jsonarray对象
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @param saveTime 存储时间
|
||||
*/
|
||||
public void put(String key, JSONArray value, int saveTime) {
|
||||
getACache().put(key, value, saveTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入一个集合
|
||||
*
|
||||
* @param key 键
|
||||
* @param values 值
|
||||
* @param <D> 泛型
|
||||
* @return 是否插入成功
|
||||
*/
|
||||
public <D> boolean put(String key, List<D> values) {
|
||||
return put(key, values, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入一个集合,使用gson解析为jsonarray进行存储,可能会出现很多对象不兼容的问题
|
||||
*
|
||||
* @param key 键
|
||||
* @param values 值
|
||||
* @param saveTime 存储时间
|
||||
* @param <D> 泛型
|
||||
* @return 是否存储成功
|
||||
*/
|
||||
public <D> boolean put(String key, List<D> values, int saveTime) {
|
||||
String json = getGson().toJson(values);
|
||||
if (!TextUtils.isEmpty(json)) {
|
||||
getACache().put(key, json, saveTime);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入int类型数据
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return 是否存储成功
|
||||
*/
|
||||
public boolean put(String key, int value) {
|
||||
return getSharedPreferences()
|
||||
.edit()
|
||||
.putInt(key, value)
|
||||
.commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入boolean类型数据
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return 是否存储成功
|
||||
*/
|
||||
public boolean put(String key, boolean value) {
|
||||
return getSharedPreferences()
|
||||
.edit()
|
||||
.putBoolean(key, value)
|
||||
.commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入float类型
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return 是否存储成功
|
||||
*/
|
||||
public boolean put(String key, float value) {
|
||||
return getSharedPreferences()
|
||||
.edit()
|
||||
.putFloat(key, value)
|
||||
.commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入long类型
|
||||
*
|
||||
* @param key 键
|
||||
* @param value 值
|
||||
* @return 是否存储成功
|
||||
*/
|
||||
public boolean put(String key, long value) {
|
||||
return getSharedPreferences()
|
||||
.edit()
|
||||
.putLong(key, value)
|
||||
.commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据key删除文件
|
||||
*
|
||||
* @param key 键
|
||||
* @return 是否删除成功
|
||||
*/
|
||||
public boolean deleteByKey(@NonNull String key) {
|
||||
return getACache().remove(key) || getSharedPreferences()
|
||||
.edit()
|
||||
.remove(key)
|
||||
.commit();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查byte[]类型
|
||||
*
|
||||
* @param key 键
|
||||
* @return 获取byte数组
|
||||
*/
|
||||
public byte[] getBinary(@NonNull String key) {
|
||||
return getACache().getAsBinary(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 差String类型
|
||||
*
|
||||
* @param key 键
|
||||
* @return 获取存储的string 类型值
|
||||
*/
|
||||
public String getString(@NonNull String key) {
|
||||
return getACache().getAsString(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询实现了Serializable的对象
|
||||
*
|
||||
* @param key 键
|
||||
* @param <R> 泛型
|
||||
* @return 序列化的对象
|
||||
*/
|
||||
public <R extends Serializable> R getSerializable(@NonNull String key) {
|
||||
return (R) getACache().getAsObject(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询jsonobject
|
||||
*
|
||||
* @param key 键
|
||||
* @return jsonobject对象
|
||||
*/
|
||||
public JSONObject getJsonObject(@NonNull String key) {
|
||||
return getACache().getAsJSONObject(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询jsonarray
|
||||
*
|
||||
* @param key 键
|
||||
* @return jsonarray集合
|
||||
*/
|
||||
public JSONArray getJsonArray(@NonNull String key) {
|
||||
return getACache().getAsJSONArray(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取一个集合
|
||||
*
|
||||
* @param key 键
|
||||
* @param typeOfT 类别
|
||||
* @param <D> 泛型
|
||||
* @return 集合
|
||||
*/
|
||||
public <D> List<D> getList(@NonNull String key, Type typeOfT) {
|
||||
JSONArray jsonArray = getJsonArray(key);
|
||||
return getGson().fromJson(null != jsonArray ? jsonArray.toString() : "[]", typeOfT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询int
|
||||
*
|
||||
* @param key 键
|
||||
* @param defValut 默认值
|
||||
* @return int值
|
||||
*/
|
||||
public int getInt(@NonNull String key, int defValut) {
|
||||
return getSharedPreferences().getInt(key, defValut);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询boolean
|
||||
*
|
||||
* @param key 键
|
||||
* @param defValue 默认值
|
||||
* @return 布尔值
|
||||
*/
|
||||
public boolean getBoolean(@NonNull String key, boolean defValue) {
|
||||
return getSharedPreferences().getBoolean(key, defValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询float
|
||||
*
|
||||
* @param key 键
|
||||
* @param defValue 默认值
|
||||
* @return float值
|
||||
*/
|
||||
public float getFloat(@NonNull String key, float defValue) {
|
||||
return getSharedPreferences().getFloat(key, defValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询long
|
||||
*
|
||||
* @param key 键
|
||||
* @param defVlaue 默认值
|
||||
* @return long值
|
||||
*/
|
||||
public long getLong(@NonNull String key, long defVlaue) {
|
||||
return getSharedPreferences().getLong(key, defVlaue);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取缓存路径名
|
||||
*
|
||||
* @return 获取存储路径名
|
||||
*/
|
||||
public String getCacheName() {
|
||||
return "jtechCache";
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取定制gson,使用者可以重写,不为空则会使用当前返回
|
||||
*
|
||||
* @return 获取自定义的gson
|
||||
*/
|
||||
public Gson getCustomizeGson() {
|
||||
return new Gson();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
package com.yunbao.common.manager.imrongcloud;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.yunbao.common.bean.IMLoginModel;
|
||||
import com.yunbao.common.event.MessageIMEvent;
|
||||
import com.yunbao.common.http.HttpCallback;
|
||||
import com.yunbao.common.http.HttpClient;
|
||||
import com.yunbao.common.manager.IMLoginManager;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import io.rong.imkit.manager.UnReadMessageManager;
|
||||
import io.rong.imlib.model.Conversation;
|
||||
|
||||
/**
|
||||
* 消息的监听管理
|
||||
*/
|
||||
public class MessageIMManager {
|
||||
private static MessageIMManager manager;
|
||||
private Context mContext;
|
||||
//Handler统一管理系统和融云的未读消息
|
||||
private Handler unreadMessagesHandler = new Handler();
|
||||
private int number = 0, imNumber = 0, systemNumber = 0;
|
||||
|
||||
public MessageIMManager(Context mContext) {
|
||||
this.mContext = mContext;
|
||||
number = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单利
|
||||
*/
|
||||
public static MessageIMManager get(Context context) {
|
||||
if (null == manager) {
|
||||
manager = new MessageIMManager(context);
|
||||
}
|
||||
return manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加融云消息监听
|
||||
*/
|
||||
public void addImRongCloudObserver() {
|
||||
// //只监听私聊消息
|
||||
Conversation.ConversationType[] conversationTypes = {Conversation.ConversationType.PRIVATE};
|
||||
UnReadMessageManager.getInstance().addObserver(conversationTypes, new UnReadMessageManager.IUnReadMessageObserver() {
|
||||
@Override
|
||||
public void onCountChanged(int integer) {
|
||||
imNumber = integer;
|
||||
//发送通知
|
||||
unreadMessagesHandler.post(essagesRunnable);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统消息(有未读数展示红点)
|
||||
*/
|
||||
public void getSystemMessages() {
|
||||
IMLoginModel userInfo = IMLoginManager.get(mContext).getUserInfo();
|
||||
HttpClient.getInstance().get("Message.getLists", "getImUserInfo")
|
||||
.params("uid", userInfo.getId())
|
||||
.params("token", userInfo.getToken())
|
||||
.execute(new HttpCallback() {
|
||||
@Override
|
||||
public void onSuccess(int code, String msg, String[] info) {
|
||||
if (code == 0) {
|
||||
List<IMLoginModel> listUserBean = JSON.parseArray(Arrays.toString(info), IMLoginModel.class);
|
||||
if (listUserBean != null && listUserBean.size() >= 2) {
|
||||
//目前就三条消息,需求判断前两条消息是否有未读消息
|
||||
for (int i = 0; i < listUserBean.size() - 2; i++) {
|
||||
//消息对象
|
||||
IMLoginModel userBean = listUserBean.get(i);
|
||||
//未读消息数
|
||||
String number = userBean.getNum();
|
||||
//未读消息不为空并且大于0
|
||||
try {
|
||||
if (!TextUtils.isEmpty(number) && Integer.parseInt(number) > 0) {
|
||||
systemNumber = Integer.parseInt(number);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
systemNumber = 0;
|
||||
}
|
||||
}
|
||||
//发送通知
|
||||
unreadMessagesHandler.post(essagesRunnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取系统消息(有未读数展示红点)
|
||||
*/
|
||||
public void getSystemMessages(SystemMessagesHttpCallback callback) {
|
||||
IMLoginModel userInfo = IMLoginManager.get(mContext).getUserInfo();
|
||||
HttpClient.getInstance().get("Message.getLists", "getImUserInfo")
|
||||
.params("uid", userInfo.getId())
|
||||
.params("token", userInfo.getToken())
|
||||
.execute(new HttpCallback() {
|
||||
@Override
|
||||
public void onSuccess(int code, String msg, String[] info) {
|
||||
if (callback != null) {
|
||||
callback.onSuccess(code, msg, info);
|
||||
}
|
||||
if (code == 0) {
|
||||
List<IMLoginModel> listUserBean = JSON.parseArray(Arrays.toString(info), IMLoginModel.class);
|
||||
if (listUserBean != null && listUserBean.size() >= 2) {
|
||||
//目前就三条消息,需求判断前两条消息是否有未读消息
|
||||
for (int i = 0; i < listUserBean.size() - 2; i++) {
|
||||
//消息对象
|
||||
IMLoginModel userBean = listUserBean.get(i);
|
||||
//未读消息数
|
||||
String number = userBean.getNum();
|
||||
//未读消息不为空并且大于0
|
||||
try {
|
||||
if (!TextUtils.isEmpty(number) && Integer.parseInt(number) > 0) {
|
||||
systemNumber = Integer.parseInt(number);
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
systemNumber = 0;
|
||||
}
|
||||
}
|
||||
//发送通知
|
||||
unreadMessagesHandler.post(essagesRunnable);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 系统消息的数据回传接口
|
||||
*/
|
||||
public interface SystemMessagesHttpCallback {
|
||||
void onSuccess(int code, String msg, String[] info);
|
||||
}
|
||||
|
||||
//整合未读消息数目并且发送出去
|
||||
private final Runnable essagesRunnable = () -> {
|
||||
number = imNumber + systemNumber;
|
||||
EventBus.getDefault().postSticky(new MessageIMEvent().setNumber(number));
|
||||
};
|
||||
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
package com.yunbao.common.manager.imrongcloud;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import android.util.Log;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.bumptech.glide.Glide;
|
||||
import com.bumptech.glide.load.resource.bitmap.CircleCrop;
|
||||
import com.bumptech.glide.request.RequestOptions;
|
||||
import com.yunbao.common.bean.IMLoginModel;
|
||||
import com.yunbao.common.manager.IMLoginManager;
|
||||
|
||||
import io.rong.imkit.GlideKitImageEngine;
|
||||
import io.rong.imkit.IMCenter;
|
||||
import io.rong.imkit.RongIM;
|
||||
import io.rong.imkit.config.RongConfigCenter;
|
||||
import io.rong.imlib.RongIMClient;
|
||||
import io.rong.imlib.model.Conversation;
|
||||
import io.rong.imlib.model.Message;
|
||||
|
||||
/**
|
||||
* 会话列表
|
||||
* 融云即时通讯的管理类
|
||||
*/
|
||||
public class RongcloudIMManager {
|
||||
//融云开发者平台注册app唯一识别符
|
||||
private static final String RONG_IM_KEY = "uwd1c0sxu1p71";
|
||||
private static final String CLASSNAME = "RongcloudIMManager";
|
||||
|
||||
/**
|
||||
* 融云初始化
|
||||
*
|
||||
* @param application 应用上下文
|
||||
*/
|
||||
public static void initRongIM(Application application) {
|
||||
//第三个参数代表是否开启推送
|
||||
RongIM.init(application, RONG_IM_KEY, true);
|
||||
Log.e(CLASSNAME, "initRongIM:");
|
||||
initPhotoGlide();
|
||||
}
|
||||
|
||||
private static RongIMClient.OnReceiveMessageWrapperListener listener = new RongIMClient.OnReceiveMessageWrapperListener() {
|
||||
@Override
|
||||
public boolean onReceived(Message message, int left, boolean hasPackage, boolean offline) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 设置消息接受监听器
|
||||
*/
|
||||
public static void addRongcloudIMOnReceiveMessageListener() {
|
||||
IMCenter.getInstance().addOnReceiveMessageListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* 移除消息接受监听器
|
||||
*/
|
||||
public static void removeRongcloudIMOnReceiveMessageListener() {
|
||||
IMCenter.getInstance().removeOnReceiveMessageListener(listener);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改聊天列表头像为圆形
|
||||
*/
|
||||
private static void initPhotoGlide() {
|
||||
RongConfigCenter.featureConfig().setKitImageEngine(new GlideKitImageEngine() {
|
||||
@Override
|
||||
public void loadConversationListPortrait(@NonNull Context context,
|
||||
@NonNull String url,
|
||||
@NonNull ImageView imageView,
|
||||
Conversation conversation) {
|
||||
Glide.with(imageView).load(url)
|
||||
.apply(RequestOptions.bitmapTransform(new CircleCrop()))
|
||||
.into(imageView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadConversationPortrait(@NonNull Context context, @NonNull String url, @NonNull ImageView imageView, Message message) {
|
||||
Glide.with(imageView).load(url)
|
||||
.apply(RequestOptions.bitmapTransform(new CircleCrop()))
|
||||
.into(imageView);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 连接融云服务器
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public static void connectIM(Context context) {
|
||||
MessageIMManager.get(context).addImRongCloudObserver();
|
||||
MessageIMManager.get(context).getSystemMessages();
|
||||
IMLoginModel userInfo = IMLoginManager.get(context).getUserInfo();
|
||||
String IMToken = userInfo.getTokenRong();
|
||||
Log.e(CLASSNAME, "connectIM:" + IMToken);
|
||||
//参数注解:IMToken :从服务端获取的 Token
|
||||
//timeLimit :超时时间(秒)。超时后不再重连。取值 <=0 则将一直连接,直到连接成功或者发生业务错误。
|
||||
//connectCallback : 连接回调。
|
||||
RongIM.connect(IMToken, 0, new RongIMClient.ConnectCallback() {
|
||||
@Override
|
||||
public void onSuccess(String s) {
|
||||
//连接成功,如果 onDatabaseOpened() 时没有页面跳转,也可在此时进行跳转。
|
||||
Log.e(CLASSNAME, "onSuccess:" + s);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(RongIMClient.ConnectionErrorCode connectionErrorCode) {
|
||||
if (connectionErrorCode.equals(RongIMClient.ConnectionErrorCode.RC_CONN_TOKEN_EXPIRE)) {
|
||||
//从 APP 服务请求新 token,获取到新 token 后重新 connect()
|
||||
Log.e(CLASSNAME, "onError:(从 APP 服务请求新 token)" + RongIMClient.ConnectionErrorCode.RC_CONN_TOKEN_EXPIRE);
|
||||
} else if (connectionErrorCode.equals(RongIMClient.ConnectionErrorCode.RC_CONNECT_TIMEOUT)) {
|
||||
//连接超时,弹出提示,可以引导用户等待网络正常的时候再次点击进行连接
|
||||
Log.e(CLASSNAME, "onError:(连接超时)" + RongIMClient.ConnectionErrorCode.RC_CONNECT_TIMEOUT);
|
||||
} else {
|
||||
//其它业务错误码,请根据相应的错误码作出对应处理。
|
||||
Log.e(CLASSNAME, "onError:(其它业务错误码)" + connectionErrorCode);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDatabaseOpened(RongIMClient.DatabaseOpenStatus databaseOpenStatus) {
|
||||
if (RongIMClient.DatabaseOpenStatus.DATABASE_OPEN_SUCCESS.equals(databaseOpenStatus)) {
|
||||
//本地数据库打开,跳转到会话列表页面
|
||||
Log.e(CLASSNAME, "onDatabaseOpened:(本地数据库打开)" + databaseOpenStatus);
|
||||
} else {
|
||||
//数据库打开失败,可以弹出 toast 提示。
|
||||
Log.e(CLASSNAME, "onDatabaseOpened:(数据库打开失败)" + databaseOpenStatus);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置监听 IM 连接状态
|
||||
* 建议在应用生命周期中设置
|
||||
*/
|
||||
public static void setIMStatusListener() {
|
||||
RongIM.setConnectionStatusListener(connectionStatusListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听 IM 连接状态,可根据连接状态进行不同业务处理
|
||||
*/
|
||||
private static RongIMClient.ConnectionStatusListener connectionStatusListener = new RongIMClient.ConnectionStatusListener() {
|
||||
@Override
|
||||
public void onChanged(ConnectionStatus status) {
|
||||
Log.e(CLASSNAME, "ConnectionStatusListener:(登录状态监听)" + status.getMessage());
|
||||
//开发者需要根据连接状态码,进行不同业务处理
|
||||
switch (status) {
|
||||
//用户主动断开连接的状态,见断开连接
|
||||
case SIGN_OUT:
|
||||
break;
|
||||
//用户账号在其它设备登录,此设备被踢下线
|
||||
case KICKED_OFFLINE_BY_OTHER_CLIENT:
|
||||
break;
|
||||
//连接暂时挂起(多是由于网络问题导致),SDK 会在合适时机进行自动重连
|
||||
case SUSPEND:
|
||||
break;
|
||||
//连接成功
|
||||
case CONNECTED:
|
||||
break;
|
||||
//连接超时,SDK 将停止连接,用户需要做超时处理,再自行调用连接接口进行连接
|
||||
case TIMEOUT:
|
||||
break;
|
||||
//连接中
|
||||
case CONNECTING:
|
||||
break;
|
||||
// 网络不可用
|
||||
case NETWORK_UNAVAILABLE:
|
||||
break;
|
||||
//未连接状态,即应用没有调用过连接方法
|
||||
case UNCONNECTED:
|
||||
|
||||
break;
|
||||
//Token 过期时触发此状态
|
||||
case TOKEN_INCORRECT:
|
||||
break;
|
||||
//用户被开发者后台封禁
|
||||
case CONN_USER_BLOCKED:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 注销登录信息,有新消息时不再收到任何通知提醒
|
||||
*/
|
||||
public static void logoutIM() {
|
||||
RongIM.getInstance().logout();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -29,5 +29,16 @@
|
||||
android:src="@mipmap/icon_back"
|
||||
android:tint="@color/textColor" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/img_more"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_centerVertical="true"
|
||||
android:padding="9dp"
|
||||
android:src="@mipmap/btn_more_black"
|
||||
android:tint="@color/textColor"
|
||||
android:visibility="gone" />
|
||||
|
||||
</RelativeLayout>
|
||||
</FrameLayout>
|
||||
|
||||
BIN
common/src/main/res/mipmap-xxhdpi/btn_more_black.png
Normal file
BIN
common/src/main/res/mipmap-xxhdpi/btn_more_black.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.0 KiB |
Reference in New Issue
Block a user