This commit is contained in:
18401019693
2022-07-21 11:24:15 +08:00
parent 42138777e3
commit e1dbc9d38c
64 changed files with 4785 additions and 915 deletions

View File

@@ -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)'

View File

@@ -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));

View File

@@ -0,0 +1,9 @@
package com.yunbao.common.bean;
import java.io.Serializable;
/**
* 数据类基类实现序列化
*/
public class BaseModel implements Serializable {
}

View File

@@ -0,0 +1,9 @@
package com.yunbao.common.bean;
/**
* 聊天备注信息
*/
public class ChatRemarkModel extends BaseModel {
private String userId;
private String remarks;
}

View 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;
}
}

View 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;
}
}

View 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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View 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);
}
}
}

View File

@@ -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();
}
}

View File

@@ -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));
};
}

View File

@@ -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();
}
}

View File

@@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB