19 Commits

Author SHA1 Message Date
Max
515912b40a chore:调整jvm配置(解决butterknife导致打包失败问题) 2024-06-11 11:12:25 +08:00
Max
bf492ed403 同步PIKO修复bug(fix:修复相亲房送礼导致闭麦、结束导致闭麦问题(只是临时补救,具体看注释)
fix:移除BaseRoomFragment中更新麦克风状态的某些判断(isNoProhibitMic),不知道之前为何加这段判断,但这段判断风险较大,某些情况导致麦克风状态一直显示未关闭(去掉后经测试验收,未发现问题)
)
2024-05-15 10:25:03 +08:00
Max
5ea7426e7d fix:替换新用户打招呼弹窗的图片 2024-04-19 11:48:01 +08:00
Max
013ed0a39d fix:修复文件上传回调不在主线程导致的上传特权卡流程失败问题(文件上传统一回调主线程) 2024-04-09 15:00:10 +08:00
Max
1e80959db6 fix:修复发布动态上传失败后子线程回调更新UI导致崩溃问题 2024-04-03 11:19:10 +08:00
Max
06f31c3e9c fix:技能卡-声音秀增加权限申请逻辑 2024-03-28 19:13:24 +08:00
Max
1bb3bb1c3e feat:新增荣誉渠道 2024-03-28 12:00:55 +08:00
Max
3d478a5017 feat:增加debug环境是否混淆配置 2024-03-27 19:34:06 +08:00
Max
d329c97f03 feat:移除个人主页-公会icon 2024-03-27 19:27:42 +08:00
Max
d1fd822c42 feat:完成补填邀请码功能 2024-03-27 19:27:42 +08:00
Max
f86fea11b8 feat:完成补填邀请码UI部分 2024-03-27 19:27:41 +08:00
Max
e707da25a8 feat:适配网页实名认证的权限申请 2024-03-27 19:27:41 +08:00
Max
4af7fcf877 feat:文件上传支持自定义域名替换 2024-03-27 19:25:36 +08:00
Max
0695a74520 feat:新增渠道:fir 2024-03-18 18:44:30 +08:00
Max
fced114686 feat:移除AVRoomActivity中的全服礼物飘屏逻辑到BaseActivity 2024-03-18 14:44:44 +08:00
Max
3181a115d8 feat:同步peko完成礼物飘窗UI优化(同步peko:去掉普通礼物飘窗) 2024-03-18 14:44:43 +08:00
Max
4c48bef21b feat:移除七牛云,改用腾讯COS 2024-03-18 14:43:56 +08:00
Max
60d274c79a feat:客服中心改为私聊 2024-03-14 14:31:12 +08:00
Max
a48440209a fix:修复首页默认选中Tab-bug 2024-03-13 17:39:25 +08:00
82 changed files with 2245 additions and 1954 deletions

View File

@@ -156,12 +156,13 @@ android {
}
debug {
println("minifyEnabled = " + minify_enabled)
buildConfigField "String", "BASE_URL", "\"http://beta.api.nnbc123.cn/\""
buildConfigField "String", "WEB_URL", "\"http://beta.api.nnbc123.cn\""
buildConfigField "String", "BASE_URL_DEBUG", "BASE_URL"
buildConfigField "String", "BASE_URL_STAGING", "\"https://api.nnbc123.cn/\""
buildConfigField "String", "BASE_URL_RELEASE", "\"https://api.nnbc123.cn/\""
minifyEnabled false
minifyEnabled minify_enabled.toBoolean() // 是否混淆
shrinkResources false
signingConfig signingConfigs.v2
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
@@ -185,6 +186,11 @@ android {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
fir {
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
}
mlq {
ndk {
abiFilters 'x86'
@@ -215,6 +221,11 @@ android {
abiFilters 'arm64-v8a'
}
}
rongyao {
ndk {
abiFilters 'arm64-v8a'
}
}
kuaishou_01 {
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'

View File

@@ -501,7 +501,7 @@ public class MainActivity extends BaseMvpActivity<IMainView, MainPresenter>
getMvpPresenter().exitRoom();
QuickPassLoginAct.start(MainActivity.this);
PmDialogShowMrg.get().onLogout();
CustomerServerHelper.logout();
// CustomerServerHelper.logout();
}
public void onNeedLogin() {
@@ -657,7 +657,7 @@ public class MainActivity extends BaseMvpActivity<IMainView, MainPresenter>
onTabClick(mCurrentTabType);
CustomerServerHelper.onLoginInfoUpdate(UserUtils.getUserInfo());
// CustomerServerHelper.onLoginInfoUpdate(UserUtils.getUserInfo());
}

View File

@@ -307,7 +307,7 @@ public class XChatApplication extends BaseApp {
// 集成测试
UMConfigure.setLogEnabled(BuildConfig.DEBUG);
} else {
CustomerServerHelper.init(instance, null);
// CustomerServerHelper.init(instance, null);
}
LogUtils.d("init time = " + (System.currentTimeMillis() - startTime) + "ms");

View File

@@ -2,15 +2,12 @@ package com.nnbc123.app.avroom.activity;
import static android.view.View.VISIBLE;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_ALL_SERVICE_GIFT;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_HEADER_TYPE_GIFT;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_LUCKY_GIFT;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_LUCKY_GIFT_SERVER_NOTIFY;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_ROOM_PK;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_ROOM_PK_NOTIFY;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.graphics.drawable.Drawable;
@@ -65,10 +62,6 @@ import com.nnbc123.app.ui.user.UserInfoActivity;
import com.nnbc123.app.ui.utils.ImageLoadUtils;
import com.nnbc123.app.ui.webview.CommonWebViewActivity;
import com.nnbc123.app.ui.widget.NobleOpenNoticeView;
import com.nnbc123.app.ui.widget.dialog.AllServiceGiftDialog;
import com.nnbc123.app.ui.widget.dialog.AllServiceGiftLevelOneDialog;
import com.nnbc123.app.ui.widget.dialog.AllServiceGiftLevelThreeDialog;
import com.nnbc123.app.ui.widget.dialog.AllServiceGiftLevelTwoDialog;
import com.nnbc123.app.ui.widget.dialog.MonsterDialog;
import com.nnbc123.app.ui.widget.marqueeview.Utils;
import com.nnbc123.app.utils.UserUtils;
@@ -92,7 +85,6 @@ import com.nnbc123.core.monsterhunting.bean.MonsterHuntingResult;
import com.nnbc123.core.monsterhunting.bean.MonsterInfo;
import com.nnbc123.core.monsterhunting.bean.MonsterProtocol;
import com.nnbc123.core.monsterhunting.manager.MonsterDataManager;
import com.nnbc123.core.noble.AllServiceGiftProtocol;
import com.nnbc123.core.noble.NobleInfo;
import com.nnbc123.core.noble.NobleResourceType;
import com.nnbc123.core.noble.NobleUtil;
@@ -119,7 +111,6 @@ import com.nnbc123.core.utils.LogUtils;
import com.nnbc123.core.utils.StringUtils;
import com.nnbc123.library.base.factory.CreatePresenter;
import com.nnbc123.library.rxbus.RxBus;
import com.nnbc123.library.utils.JavaUtil;
import com.nnbc123.library.utils.SingleToastUtil;
import com.nnbc123.library.utils.UIUtils;
import com.opensource.svgaplayer.SVGADrawable;
@@ -137,7 +128,6 @@ import java.lang.ref.WeakReference;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
@@ -197,8 +187,6 @@ public class AVRoomActivity extends BaseMvpActivity<IAvRoomView, AvRoomPresenter
/*********************************显示全服礼物***************************************/
private GiftBroadcastObserver giftObserver;
private Dialog giftDialog;
private LinkedList<AllServiceGiftProtocol.DataBean> giftList;
private boolean isResume = true;
@Nullable
private SingleRoomTipDialog singleRoomTipDialog;
@@ -501,9 +489,6 @@ public class AVRoomActivity extends BaseMvpActivity<IAvRoomView, AvRoomPresenter
super.onResume();
AvRoomDataManager.get().roomNoDestory = true;
registerGiftBroadcastMessage(true);
if (giftList != null) {
giftList.clear();
}
isResume = true;
}
@@ -904,12 +889,6 @@ public class AVRoomActivity extends BaseMvpActivity<IAvRoomView, AvRoomPresenter
monsterDialog.dismiss();
monsterDialog = null;
}
if (giftDialog != null && giftDialog.isShowing()) {
giftDialog.setOnDismissListener(null);
giftDialog.dismiss();
giftDialog = null;
}
if (limitEnterRoomHelper != null) {
limitEnterRoomHelper.release();
}
@@ -1190,30 +1169,6 @@ public class AVRoomActivity extends BaseMvpActivity<IAvRoomView, AvRoomPresenter
if (baseProtocol == null) return;
switch (baseProtocol.getFirst()) {
case CUSTOM_MSG_HEADER_TYPE_GIFT:
if (!isValid()) return;
if (giftList == null) {
giftList = new LinkedList<>();
}
int second2 = baseProtocol.getSecond();
AllServiceGiftProtocol.DataBean data = JSON.parseObject(String.valueOf(baseProtocol.getData()), AllServiceGiftProtocol.DataBean.class);
if (data == null || data.getGiftUrl() == null || data.isCeremonyGift())
return;
giftList.add(data);
if (second2 == CUSTOM_MSG_ALL_SERVICE_GIFT) {
if (giftDialog != null && giftDialog.isShowing()) {
// 如果当前以及有礼物弹窗在展示,则需要等到他 dismiss 后再显示下一个
AllServiceGiftProtocol.DataBean dataBean = giftList.peekFirst();
if (dataBean != null) {
return;
} else {
giftDialog.dismiss();
}
} else {
showGiftDialog();
}
}
break;
case CUSTOM_MSG_LUCKY_GIFT:
if (baseProtocol.getSecond() == CUSTOM_MSG_LUCKY_GIFT_SERVER_NOTIFY) {
RoomReceivedLuckyGiftAttachment attachment = new RoomReceivedLuckyGiftAttachment(CUSTOM_MSG_LUCKY_GIFT_SERVER_NOTIFY);
@@ -1236,39 +1191,6 @@ public class AVRoomActivity extends BaseMvpActivity<IAvRoomView, AvRoomPresenter
}
}
private void showGiftDialog() {
if (giftList.size() == 0) return;
giftDialog = generateAllServiceGiftDialog(this, giftList.peekFirst());
giftDialog.setOnDismissListener(dialog -> {
giftList.pollFirst();
AllServiceGiftProtocol.DataBean dataBean = giftList.peekFirst();
if (dataBean != null) {
if (isValid()) {
showGiftDialog();
} else {
giftList.clear();
}
}
});
giftDialog.show();
}
private AllServiceGiftDialog generateAllServiceGiftDialog(Context context, AllServiceGiftProtocol.DataBean dataBean) {
switch (JavaUtil.str2int(dataBean.getLevelNum())) {
default:
case AllServiceGiftDialog.ALL_SERVICE_GIFT_LEVEL_1:
return new AllServiceGiftLevelOneDialog(context, dataBean);
case AllServiceGiftDialog.ALL_SERVICE_GIFT_LEVEL_2:
return new AllServiceGiftLevelTwoDialog(context, dataBean);
case AllServiceGiftDialog.ALL_SERVICE_GIFT_LEVEL_3:
return new AllServiceGiftLevelThreeDialog(context, dataBean);
}
}
@Override
protected void onPause() {
super.onPause();

View File

@@ -677,14 +677,7 @@ open class BaseRoomFragment<V : IBaseRoomView?, P : BaseRoomPresenter<V>?> :
} else {
val roomQueueInfo = AvRoomDataManager.get()
.getRoomQueueMemberInfoByAccount(myUid.toString())
if (roomQueueInfo?.mChatRoomMember?.isNoProhibitMic == true && roomQueueInfo.mRoomMicInfo?.isMicMute == false) {
bottomView.setMicBtnEnable(true)
if (AudioEngineManager.get().isMute) {
bottomView.setMicBtnOpen(false)
} else {
bottomView.setMicBtnOpen(true)
}
} else if (roomQueueInfo?.mChatRoomMember != null
if (roomQueueInfo?.mChatRoomMember != null
&& myUid.toString() == roomQueueInfo.mChatRoomMember.account
&& roomQueueInfo.mRoomMicInfo?.isMicMute == true
) {

View File

@@ -125,59 +125,6 @@ public class GiftEffectView extends RelativeLayout implements SVGACallback {
giftInfo = giftEffectInfo.getGift();
}
if (giftInfo != null) {
int totalCoin = giftInfo.getGoldPrice() * giftEffectInfo.getGiftNum() * giftEffectInfo.getTargetUsers().size();
if (totalCoin >= 520 &&
giftEffectInfo.getGiftReceiveType() != GiftEffectInfo.GIFT_RECEIVE_TYPE_LUCKY
&& !AvRoomDataManager.get().isSelfGamePlaying()) {//礼物栏
ImageLoadUtils.loadImage(benefactorAvatar.getContext(), giftEffectInfo.getAvatar(), benefactorAvatar);
ImageLoadUtils.loadImage(giftImg.getContext(), giftInfo.getGiftUrl(), giftImg);
benefactorNick.setText(giftEffectInfo.getNick());
giftNumber.setText("X" + giftEffectInfo.getGiftNum());
giftName.setText(giftInfo.getGiftName());
container.setVisibility(VISIBLE);
if (giftEffectInfo.getGiftReceiveType() == GiftEffectInfo.GIFT_RECEIVE_TYPE_SINGLE) {
GiftReceiver giftReceiver = giftEffectInfo.getTargetUsers().get(0);
ImageLoadUtils.loadAvatar(receiverAvatar.getContext(), giftReceiver.getAvatar(), receiverAvatar);
receiverNick.setText(giftReceiver.getNick());
} else if (giftEffectInfo.getGiftReceiveType() == GiftEffectInfo.GIFT_RECEIVE_TYPE_ALL) {
receiverAvatar.setImageResource(R.mipmap.app_logo);
receiverNick.setText("全麦");
} else if (giftEffectInfo.getGiftReceiveType() == GiftEffectInfo.GIFT_RECEIVE_TYPE_MULTI) {
receiverAvatar.setImageResource(R.mipmap.app_logo);
StringBuilder sb = new StringBuilder();
for (GiftReceiver targetUser : giftEffectInfo.getTargetUsers()) {
RoomQueueInfo roomQueueInfo = AvRoomDataManager.get().getRoomQueueMemberInfoByAccount(targetUser.getUid() + "");
if (roomQueueInfo == null) continue;
sb.append(roomQueueInfo.mRoomMicInfo.getPosition() + 1).append("").append(",");
}
if (sb.length() > 0) {
sb.replace(sb.lastIndexOf(","), sb.length(), "");
}
receiverNick.setText(sb.toString());
}
Animation operatingAnim = AnimationUtils.loadAnimation(getContext(), R.anim.light_bg_rotate_anim);
LinearInterpolator lin = new LinearInterpolator();
operatingAnim.setInterpolator(lin);
giftLightBg.setAnimation(operatingAnim);
final Point center = new Point();
center.x = ResolutionUtils.getScreenWidth(getContext()) / 2;
ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(container, "translationX", -UIUtil.dip2px(getContext(), 400), center.x - container.getWidth() / 2).setDuration(500);
objectAnimator.setInterpolator(new AccelerateDecelerateInterpolator());
objectAnimator.start();
ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(container, "alpha", 0.0F, 1.0F).setDuration(500);
objectAnimator1.setInterpolator(new AccelerateDecelerateInterpolator());
objectAnimator1.start();
if (totalCoin < 4999) {
imgBg.setImageResource(R.drawable.icon_gift_effect_bg_1);
} else if (totalCoin < 9999) {
imgBg.setImageResource(R.drawable.icon_gift_effect_bg_2);
} else {
imgBg.setImageResource(R.drawable.icon_gift_effect_bg_3);
}
}
effectHandler.sendEmptyMessageDelayed(0, 6000);
if (giftInfo.getOtherViewType() == 1 && !TextUtils.isEmpty(giftInfo.getViewUrl())) {
drawVAPEffect(giftInfo.getViewUrl());

View File

@@ -4,6 +4,7 @@ import static com.nnbc123.core.Constants.DEBUG_MAX_UID;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MESS_HEAD_NOBLE;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MESS_SUB_OPENNOBLE;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MESS_SUB_RENEWNOBLE;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_ALL_SERVICE_GIFT;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_HEADER_TYPE_GIFT;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_RED_PACKAGE;
import static com.nnbc123.core.im.custom.bean.CustomAttachment.CUSTOM_MSG_SUB_RED_PACKAGE_RECEIVE_ALL_DIAMOND;
@@ -13,6 +14,7 @@ import static com.nnbc123.library.utils.UIUtils.getActivityByContext;
import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
@@ -69,7 +71,7 @@ import com.nnbc123.app.ui.login.LoginPhoneActivity;
import com.nnbc123.app.ui.pay.ChargeActivity;
import com.nnbc123.app.ui.setting.ResetPasswordActivity;
import com.nnbc123.app.ui.widget.DefaultToolBar;
import com.nnbc123.app.ui.widget.dialog.AllServiceGiftLevelCeremonyDialog;
import com.nnbc123.app.ui.widget.dialog.AllServiceGiftLevelDialog;
import com.nnbc123.app.ui.widget.dialog.AllServiceVipLevelUPDialog;
import com.nnbc123.app.ui.widget.dialog.GameInviteDialog;
import com.nnbc123.app.ui.widget.dialog.OpenNobleGlobalNoticeDialog;
@@ -114,6 +116,7 @@ import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import io.reactivex.Observable;
@@ -134,7 +137,7 @@ public abstract class BaseActivity extends RxAppCompatActivity
*/
protected static final String STATUS_TAG = "STATUS_TAG";
protected final RxPermissions rxPermissions = new RxPermissions(this);
public final RxPermissions rxPermissions = new RxPermissions(this);
protected TitleBar mTitleBar;
protected DefaultToolBar mToolBar;
protected CompositeDisposable mCompositeDisposable;
@@ -145,6 +148,8 @@ public abstract class BaseActivity extends RxAppCompatActivity
private OpenNobleGlobalNoticeDialog mNoticeDialog;
private boolean isShowingChargeDialog;
private Dialog giftDialog;
private LinkedList<AllServiceGiftProtocol.DataBean> giftList;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -340,7 +345,14 @@ public abstract class BaseActivity extends RxAppCompatActivity
mNoticeDialog.dismiss();
mNoticeDialog = null;
}
if (giftDialog != null && giftDialog.isShowing()) {
giftDialog.setOnDismissListener(null);
giftDialog.dismiss();
giftDialog = null;
}
if (giftList != null) {
giftList.clear();
}
super.onDestroy();
LogUtil.i(this.getClass().getName(), "onDestroy");
/* ImageLoadUtils.clearMemory(this);*/
@@ -508,7 +520,6 @@ public abstract class BaseActivity extends RxAppCompatActivity
.compose(bindUntilEvent(ActivityEvent.PAUSE))
.observeOn(AndroidSchedulers.mainThread())
.subscribe(this::onRoomEventReceived);
}
@Override
@@ -930,15 +941,53 @@ public abstract class BaseActivity extends RxAppCompatActivity
UserUtils.getUserInfo() == null)
return;
AllServiceGiftProtocol.DataBean data = JSON.parseObject(String.valueOf(baseProtocol.getData()), AllServiceGiftProtocol.DataBean.class);
if (data == null || data.getGiftUrl() == null || !data.isCeremonyGift())
if (data == null || data.getGiftUrl() == null)
return;
new AllServiceGiftLevelCeremonyDialog(context, data).show();
if (giftList == null) {
giftList = new LinkedList<>();
}
int second2 = baseProtocol.getSecond();
if (second2 == CUSTOM_MSG_ALL_SERVICE_GIFT) {
giftList.add(data);
if (giftDialog != null && giftDialog.isShowing()) {
// 如果当前以及有礼物弹窗在展示,则需要等到他 dismiss 后再显示下一个
AllServiceGiftProtocol.DataBean dataBean = giftList.peekFirst();
if (dataBean != null) {
return;
} else {
giftDialog.dismiss();
}
} else {
showGiftDialog();
}
}
break;
default:
break;
}
}
private void showGiftDialog() {
if (giftList.size() == 0) return;
giftDialog = generateAllServiceGiftDialog(this, giftList.peekFirst());
giftDialog.setOnDismissListener(dialog -> {
giftList.pollFirst();
AllServiceGiftProtocol.DataBean dataBean = giftList.peekFirst();
if (dataBean != null) {
if (isValid()) {
showGiftDialog();
} else {
giftList.clear();
}
}
});
giftDialog.show();
}
private AllServiceGiftLevelDialog generateAllServiceGiftDialog(Context context, AllServiceGiftProtocol.DataBean dataBean) {
return new AllServiceGiftLevelDialog(context, dataBean);
}
public void onGrabApprenticesEvent(GrabApprenticesEvent event) {
if (!isTopActivity()) return;
if (dialog != null && dialog.isAdded()) {

View File

@@ -30,10 +30,10 @@ import com.nnbc123.app.home.activity.VisitorListActivity
import com.nnbc123.app.home.adapter.MeCenterAdapter
import com.nnbc123.app.home.helper.BannerHelper
import com.nnbc123.app.home.helper.OpenRoomHelper
import com.nnbc123.app.qiyukefu.CustomerServerHelper
import com.nnbc123.app.skill.activity.SkillHomeActivity
import com.nnbc123.app.skill.activity.SkillHomeActivity.Companion.start
import com.nnbc123.app.support.LevelIconHelper
import com.nnbc123.app.ui.im.avtivity.NimP2PMessageActivity
import com.nnbc123.app.ui.patriarch.PatriarchModeActivity
import com.nnbc123.app.ui.pay.ChargeActivity
import com.nnbc123.app.ui.relation.AttentionListActivity
@@ -439,7 +439,8 @@ class MeFragment : BaseFragment(), View.OnClickListener {
UriProvider.getTutuRealNamePage()
)
R.id.tv_me_service -> {
CustomerServerHelper.contactCustomerServer(mContext)
NimP2PMessageActivity.start(requireContext(), "200014")
// CustomerServerHelper.contactCustomerServer(mContext)
}
R.id.tv_user_id -> {
mUserInfo?.let {

View File

@@ -106,7 +106,7 @@ class HomeFragment : BaseBindingFragment<HomeFragmentBinding>() {
})
InitialModel.get().cacheInitInfo?.defaultTab?.let {
val tab = it - 1
if (it >= 0 && it < tagList.size) {
if (tab >= 0 && tab < tagList.size) {
mBinding.viewPager.currentItem = tab
}
}

View File

@@ -1,11 +1,22 @@
package com.nnbc123.app.skill
import android.Manifest
import android.annotation.SuppressLint
import android.content.Intent
import android.net.Uri
import android.provider.Settings
import androidx.core.util.Consumer
import com.nnbc123.app.R
import com.nnbc123.app.base.BaseActivity
import com.nnbc123.app.common.permission.PermissionHelper.isAllGranted
import com.nnbc123.app.skill.dialog.SkillSelectionDialog
import com.nnbc123.app.skill.repository.SkillDataManager
import com.nnbc123.app.skill.repository.SkillModel
import com.nnbc123.app.skill.widget.*
import com.nnbc123.app.ui.widget.dialog.CommonTipDialog
import com.nnbc123.app.ui.widget.dialog.RequestPermissionPromptDialog
import com.nnbc123.app.ui.widget.dialog.RequestPermissionPromptDialog.Companion.dismissCurrentDialog
import com.nnbc123.app.ui.widget.dialog.RequestPermissionPromptDialog.Companion.isNeedPrompt
import com.nnbc123.core.file.FileModel
import com.nnbc123.core.skill.entity.PropRefEntity
import com.nnbc123.core.skill.entity.PropsEntity
@@ -13,6 +24,7 @@ import com.nnbc123.core.skill.entity.SkillPostServerEntity
import com.nnbc123.core.skill.entity.SkillPropertyEntity
import com.nnbc123.core.skill.event.SkillEvent
import com.nnbc123.core.utils.toast
import com.nnbc123.library.utils.ResUtil
import org.greenrobot.eventbus.EventBus
import java.io.File
@@ -198,4 +210,53 @@ class SkillDataDelegate(private val skillView: SkillCardView, private val activi
activity.toast(th.message)
})
}
override fun requestMicPermissions(consumer: Consumer<Boolean>) {
super.requestMicPermissions(consumer)
val permissions = arrayOf(
Manifest.permission.RECORD_AUDIO,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
)
val sb = StringBuffer()
sb.append("1.").append(ResUtil.getString(R.string.permission_denied_tips_mic))
.append("\n2.").append(ResUtil.getString(R.string.permission_denied_tips_image))
val tips = sb.toString()
if (isNeedPrompt()
&& !isAllGranted(activity.rxPermissions, *permissions)
) {
RequestPermissionPromptDialog(activity, tips).show()
}
activity.checkPermission(Consumer<Boolean> { isGranted: Boolean ->
dismissCurrentDialog()
if (isGranted) {
consumer.accept(true)
} else {
consumer.accept(false)
showPermissionDeniedTipsDialog(tips)
}
}, *permissions)
}
private fun showPermissionDeniedTipsDialog(message: String) {
val mPrivacyDialog = CommonTipDialog(activity)
mPrivacyDialog.setTipMsg(message)
mPrivacyDialog.setOkText("去设置")
mPrivacyDialog.setOnActionListener(
object : CommonTipDialog.OnActionListener {
override fun onOk() {
//同意跳到应用详情页面
val packageUri = Uri.parse("package:" + activity.packageName)
val intent = Intent(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
packageUri
)
activity.startActivityForResult(
intent, 0
)
}
}
)
mPrivacyDialog.show()
}
}

View File

@@ -1,5 +1,6 @@
package com.nnbc123.app.skill.widget
import androidx.core.util.Consumer
import com.nnbc123.core.skill.entity.PropRefEntity
import java.io.File
@@ -31,6 +32,7 @@ interface ItemEventListener {
fun onItemClick(item: SkillItem) {}
fun onRecordSuccess(audioFile: File?, duration: Int) {}
fun onDeleteRecordClick() {}
fun requestMicPermissions(consumer: Consumer<Boolean>) {}
}

View File

@@ -3,6 +3,7 @@ package com.nnbc123.app.skill.widget
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import androidx.core.util.Consumer
import com.netease.nim.uikit.common.util.sys.ScreenUtil
import com.netease.nimlib.sdk.media.record.RecordType
import com.nnbc123.app.R
@@ -12,6 +13,7 @@ import com.nnbc123.app.databinding.LayoutSkillAudioBinding
import com.nnbc123.app.ui.widget.dialog.CommonTipDialog
import com.nnbc123.core.utils.TextUtils
import com.nnbc123.core.utils.toast
import com.tbruyelle.rxpermissions2.RxPermissions
import java.io.File
class RecordIResourceItem(private val itemAttribute: ItemAttribute) : SkillItem,
@@ -119,6 +121,13 @@ class RecordIResourceItem(private val itemAttribute: ItemAttribute) : SkillItem,
setItemByState(RECORD_STATE_READY)
}
override fun onClickRecord() {
itemAttribute.itemEventListener?.requestMicPermissions {
if (it) {
binding.recordView.startRecord()
}
}
}
/**
* 根据状态设置View

View File

@@ -50,7 +50,7 @@ class TimerRecorderView(context: Context, @Nullable attrs: AttributeSet?, defSty
setOnClickListener {
when (state) {
STATE_PAUSED -> {
startRecord()
recordListener?.onClickRecord()
}
STATE_PLAYED -> {
endAudioRecord(false)
@@ -82,7 +82,7 @@ class TimerRecorderView(context: Context, @Nullable attrs: AttributeSet?, defSty
//开始录制
private fun startRecord() {
fun startRecord() {
if (audioMessageHelper == null) {
val options = NimUIKitImpl.getOptions()
options.audioRecordMaxTime = recordDuration
@@ -175,5 +175,6 @@ class TimerRecorderView(context: Context, @Nullable attrs: AttributeSet?, defSty
fun onRecordCancel()
fun onRecordSuccess(file: File?)
fun onRecordFail()
fun onClickRecord()
}
}

View File

@@ -9,8 +9,11 @@ import android.text.SpannableString;
import android.text.TextUtils;
import android.view.View;
import androidx.core.util.Consumer;
import androidx.databinding.DataBindingUtil;
import com.nnbc123.app.ui.setting.invite.InviteInputConfirmDialog;
import com.nnbc123.app.ui.setting.invite.InviteInputDialog;
import com.nnbc123.core.UriProvider;
import com.nnbc123.core.auth.AuthModel;
import com.nnbc123.core.auth.event.LogoutEvent;
@@ -55,6 +58,8 @@ public class SettingActivity extends BaseActivity implements View.OnClickListene
private ActivitySettingBinding settingBinding;
private WithdrawInfo withdrawInfos;
private InviteInputDialog inviteInputDialog;
private InviteInputConfirmDialog inviteInputConfirmDialog;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -76,6 +81,7 @@ public class SettingActivity extends BaseActivity implements View.OnClickListene
protected void onDestroy() {
super.onDestroy();
EventBus.getDefault().unregister(this);
dismissInviteDialog();
}
@SuppressLint("CheckResult")
@@ -232,6 +238,9 @@ public class SettingActivity extends BaseActivity implements View.OnClickListene
case R.id.rly_permission:
PermissionGuideActivity.Companion.start(context);
break;
case R.id.layout_invite_code:
showInviteInputDialog();
break;
}
}
@@ -285,7 +294,11 @@ public class SettingActivity extends BaseActivity implements View.OnClickListene
} else {
settingBinding.tvPayModify.setText("修改");
}
if (cacheLoginUserInfo.isCanRefillInviteCode()) {
settingBinding.layoutInviteCode.setVisibility(View.VISIBLE);
} else {
settingBinding.layoutInviteCode.setVisibility(View.GONE);
}
}
public static class MissingPermissionException extends RuntimeException {
@@ -311,5 +324,60 @@ public class SettingActivity extends BaseActivity implements View.OnClickListene
finish();
}
public void showInviteInputDialog(){
inviteInputDialog = new InviteInputDialog(this);
inviteInputDialog.setOnNext(new Consumer<String>() {
@Override
public void accept(String s) {
showInviteInputConfirmDialog(s);
}
});
inviteInputDialog.show();
}
public void showInviteInputConfirmDialog(String code) {
inviteInputConfirmDialog = new InviteInputConfirmDialog(this, code);
inviteInputConfirmDialog.setOnNext(new Consumer<String>() {
@Override
public void accept(String s) {
inviteInputConfirmDialog.dismiss();
submitInviteCode(s);
}
});
inviteInputConfirmDialog.show();
}
private void dismissInviteDialog() {
if (inviteInputDialog != null && inviteInputDialog.isShowing()) {
inviteInputDialog.dismiss();
}
if (inviteInputConfirmDialog != null && inviteInputConfirmDialog.isShowing()) {
inviteInputConfirmDialog.dismiss();
}
}
private void submitInviteCode(String code) {
getDialogManager().showProgressDialog(this);
Disposable d = UserModel.get().refillInviteCode(code)
.compose(bindToLifecycle())
.subscribe(info -> {
getDialogManager().dismissDialog();
if (info.isSuccess()) {
dismissInviteDialog();
toast(R.string.invite_input_fill_in_success);
settingBinding.layoutInviteCode.setVisibility(View.GONE);
} else {
String message = info.getMessage();
if (message != null) {
toast(message);
}
// INVITE_CODE_DEVICE_DUPLICATED(211185,"该设备已填写过邀请码"),
// TIME_OUT_TO_REFILL_INVITE_CODE(211186,"超出补充填时间,无法补填邀请码"),
if (info.getCode() == 211185 || info.getCode() == 211186) {
settingBinding.layoutInviteCode.setVisibility(View.GONE);
dismissInviteDialog();
}
}
});
}
}

View File

@@ -0,0 +1,57 @@
package com.nnbc123.app.ui.setting.invite
import android.content.Context
import android.graphics.Typeface
import android.os.Bundle
import android.view.Gravity
import android.view.WindowManager
import android.widget.TextView
import androidx.core.util.Consumer
import com.chuhai.utils.ktx.getColorById
import com.chuhai.utils.spannable.SpannableTextBuilder
import com.nnbc123.app.R
import com.nnbc123.app.databinding.InviteInputConfirmDialogBinding
import com.nnbc123.app.ui.widget.dialog.BaseDialog
import com.nnbc123.app.utils.SpannableBuilder
import java.time.format.TextStyle
/**
* Created by Max on 2024/3/25 20:05
* Desc:
**/
class InviteInputConfirmDialog(context: Context, val code: String) :
BaseDialog(context, R.style.dialog) {
var onNext: Consumer<String>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setCancelable(false)
val binding = InviteInputConfirmDialogBinding.inflate(layoutInflater)
setContentView(binding.root)
window?.attributes?.let {
it.width = WindowManager.LayoutParams.MATCH_PARENT
it.height = WindowManager.LayoutParams.WRAP_CONTENT
window?.attributes = it
}
SpannableTextBuilder(binding.tvTitle).appendText(context.getString(R.string.invite_input_confirm_title))
.appendText(
text = context.getString(R.string.invite_input_confirm_format).format(code),
textColor = context.getColorById(R.color.color_2B2D33)
)
.appendText("?").apply()
SpannableTextBuilder(binding.tvTips).appendText(context.getString(R.string.invite_input_tips3))
.appendText(
text = "1次",
textSize = 16,
textStyle = Typeface.BOLD,
textColor = context.getColorById(R.color.color_theme)
).apply()
binding.tvCancel.setOnClickListener {
dismiss()
}
binding.tvSave.setOnClickListener {
onNext?.accept(code)
}
}
}

View File

@@ -0,0 +1,49 @@
package com.nnbc123.app.ui.setting.invite
import android.content.Context
import android.os.Bundle
import android.view.View
import android.view.WindowManager
import androidx.core.util.Consumer
import com.chuhai.utils.ktx.setOnInputChangedListener
import com.nnbc123.app.R
import com.nnbc123.app.databinding.InviteInputDialogBinding
import com.nnbc123.app.ui.widget.dialog.BaseDialog
/**
* Created by Max on 2024/3/25 20:05
* Desc:
**/
class InviteInputDialog(context: Context) : BaseDialog(context, R.style.dialog) {
var onNext: Consumer<String>? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding = InviteInputDialogBinding.inflate(layoutInflater)
setContentView(binding.root)
window?.attributes?.let {
it.width = WindowManager.LayoutParams.MATCH_PARENT
it.height = WindowManager.LayoutParams.WRAP_CONTENT
window?.attributes = it
}
binding.etCode.setOnInputChangedListener {
resetSaveBtn(binding)
true
}
binding.tvSave.setOnClickListener {
onNext?.accept(binding.etCode.text.toString().trim())
}
resetSaveBtn(binding)
}
private fun resetSaveBtn(binding: InviteInputDialogBinding) {
if (binding.etCode.length() > 0) {
binding.tvSave.isEnabled = true
binding.tvSave.setBackgroundResource(R.drawable.shape_theme_26)
} else {
binding.tvSave.isEnabled = false
binding.tvSave.setBackgroundResource(R.drawable.shape_33ffda24_26)
}
}
}

View File

@@ -154,16 +154,6 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
if (userId != AuthModel.get().getCurrentUid() && !VipHelper.isHideLookUser()) {
UserModel.get().visitUserDetail(userId).subscribe();
}
viewModel.getHallData().observe(this, clanAndHallInfo -> {
if (clanAndHallInfo != null && clanAndHallInfo.getClan() != null && clanAndHallInfo.getClan().getId() != 0) {
mBinding.tvHallDesc.setVisibility(View.VISIBLE);
mBinding.tvHallDesc.setOnClickListener(v -> {
ModuleClanActivity.start(context, userId);
});
} else {
mBinding.tvHallDesc.setVisibility(View.GONE);
}
});
if (userId != AuthModel.get().getCurrentUid()) {
ViewGroup.MarginLayoutParams layoutParams = (ViewGroup.MarginLayoutParams) mBinding.viewPager.getLayoutParams();
@@ -177,7 +167,6 @@ public class UserInfoActivity extends BaseBindingActivity<ActivityUserInfoBindin
protected void onResume() {
super.onResume();
viewModel.getUserInfoDetail();
viewModel.getUserHallAndClan();
viewModel.getUserSkillData(viewModel.getUserId());
}

View File

@@ -1,5 +1,6 @@
package com.nnbc123.app.ui.webview;
import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
@@ -13,6 +14,7 @@ import android.os.Bundle;
import android.os.Handler;
import android.text.TextUtils;
import android.view.View;
import android.webkit.PermissionRequest;
import android.webkit.SslErrorHandler;
import android.webkit.ValueCallback;
import android.webkit.WebBackForwardList;
@@ -31,6 +33,9 @@ import com.google.gson.Gson;
import com.netease.nim.uikit.StatusBarUtil;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.netease.nim.uikit.common.util.string.StringUtil;
import com.nnbc123.app.common.permission.PermissionHelper;
import com.nnbc123.app.ui.widget.dialog.RequestPermissionPromptDialog;
import com.nnbc123.library.utils.ResUtil;
import com.orhanobut.logger.Logger;
import com.trello.rxlifecycle3.android.ActivityEvent;
import com.nnbc123.app.R;
@@ -221,6 +226,8 @@ public class CommonWebViewActivity extends BaseActivity implements ShareDialog.O
jsInterface.setPosition(mPosition);
webView.addJavascriptInterface(jsInterface, "androidJsObj");
webView.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
// 允许自动播放
webView.getSettings().setMediaPlaybackRequiresUserGesture(false);
webView.setWebViewClient(new WebViewClient() {
@@ -312,6 +319,35 @@ public class CommonWebViewActivity extends BaseActivity implements ShareDialog.O
//获取webviewtitle作为titlebar的title
wvcc = new WebChromeClient() {
@Override
public void onPermissionRequest(PermissionRequest request) {
String tips = null;
String[] permissions = null;
for (String item : request.getResources()) {
if (item != null && item.equals(PermissionRequest.RESOURCE_VIDEO_CAPTURE)) {
tips = ResUtil.getString(R.string.permission_denied_tips_camera);
permissions = new String[]{Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO};
}
}
if (permissions == null) {
request.grant(request.getResources());
return;
}
if (RequestPermissionPromptDialog.Companion.isNeedPrompt()
&& !PermissionHelper.INSTANCE.isAllGranted(rxPermissions, permissions)) {
new RequestPermissionPromptDialog(context, tips).show();
}
checkPermission(isGranted -> {
RequestPermissionPromptDialog.Companion.dismissCurrentDialog();
if (isGranted) {
request.grant(request.getResources());
} else {
request.deny();
}
}, permissions);
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);

View File

@@ -0,0 +1,105 @@
package com.nnbc123.app.ui.widget.dialog
import android.content.Context
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.Window
import android.view.WindowManager
import androidx.databinding.DataBindingUtil
import com.chuhai.utils.ktx.singleClick
import com.nnbc123.app.R
import com.nnbc123.app.avroom.activity.AVRoomActivity
import com.nnbc123.app.databinding.AllServiceGiftGoRoomTipsDialogBinding
import com.nnbc123.app.public_chat_hall.activity.PublicChatHallHomeActivity
import com.nnbc123.core.initial.InitialModel
import com.nnbc123.library.common.util.SPUtils
import com.nnbc123.library.utils.JavaUtil
/**
* Created by Max on 2023/10/30 10:29
* Desc:跳转房间提示
**/
class AllServiceGiftGoRoomTipsDialog(
context: Context,
private val roomName: String,
private val roomId: Long
) :
BaseDialog(context, R.style.dialog) {
private var binding: AllServiceGiftGoRoomTipsDialogBinding? = null
companion object {
/**
* 是否需要提示前往房间
*/
fun isNeedTips(): Boolean {
return !SPUtils.getBoolean("all_service_gift_go_room_no_tips", false)
}
/**
* 忽略提示/不在提示
*/
private fun ignoreTips() {
SPUtils.putBoolean("all_service_gift_go_room_no_tips", true)
}
}
private var isCheck: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setCancelable(false)
requestWindowFeature(Window.FEATURE_NO_TITLE)
val inflate =
LayoutInflater.from(context)
.inflate(R.layout.all_service_gift_go_room_tips_dialog, null)
setContentView(inflate.rootView)
binding = DataBindingUtil.bind(inflate)
binding?.tvRoomName?.text = roomName
binding?.ivCheckbox?.setOnClickListener {
updateCheckbox(!isCheck)
}
binding?.tvTips?.setOnClickListener {
updateCheckbox(!isCheck)
}
binding?.tvGo?.singleClick {
if (isCheck) {
ignoreTips()
}
if (roomId == JavaUtil.str2long(InitialModel.get().publicChatHallUid)) {
PublicChatHallHomeActivity.openPublicChatHallPage(context)
} else {
AVRoomActivity.start(context, roomId)
}
dismiss()
}
binding?.tvCancel?.singleClick {
if (isCheck) {
ignoreTips()
}
dismiss()
}
updateCheckbox(false)
}
override fun onStart() {
super.onStart()
this.window?.attributes?.let {
it.width = WindowManager.LayoutParams.MATCH_PARENT
it.height = WindowManager.LayoutParams.WRAP_CONTENT
it.gravity = Gravity.CENTER
window?.attributes = it
}
}
private fun updateCheckbox(isCheck: Boolean) {
this.isCheck = isCheck
if (isCheck) {
binding?.ivCheckbox?.setImageResource(R.drawable.base_ic_checkbox_selected)
} else {
binding?.ivCheckbox?.setImageResource(R.drawable.base_ic_checkbox_unselected)
}
}
}

View File

@@ -1,77 +0,0 @@
package com.nnbc123.app.ui.widget.dialog;
import android.content.Context;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import androidx.databinding.DataBindingUtil;
import com.nnbc123.core.manager.AvRoomDataManager;
import com.nnbc123.core.noble.AllServiceGiftProtocol;
import com.nnbc123.app.R;
import com.nnbc123.app.avroom.activity.AVRoomActivity;
import com.nnbc123.app.databinding.DialogGiftAllServiceCeremonyBinding;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
/**
* Created by MadisonRong on 11/05/2018.
*/
public class AllServiceGiftLevelCeremonyDialog extends AllServiceGiftDialog {
private DialogGiftAllServiceCeremonyBinding binding;
public AllServiceGiftLevelCeremonyDialog(Context context, AllServiceGiftProtocol.DataBean dataBean) {
super(context, R.style.FullScreenDialog, dataBean);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
View inflate = LayoutInflater.from(getContext()).inflate(R.layout.dialog_gift_all_service_ceremony, null);
setContentView(inflate.getRootView());
setCancelable(true);
setCanceledOnTouchOutside(true);
binding = DataBindingUtil.bind(inflate);
Window window = getWindow();
Point point = new Point();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
WindowManager.LayoutParams windowParams = window.getAttributes();
windowParams.width = WindowManager.LayoutParams.MATCH_PARENT;
windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.dimAmount = 0.0f;
windowParams.gravity = Gravity.TOP;
windowParams.x = 0;
windowParams.y = 0;
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.setAttributes(windowParams);
window.setWindowAnimations(R.style.anim_fade);
window.getWindowManager().getDefaultDisplay().getSize(point);
}
if (dataBean != null) {
// 设置定时器
Observable.timer((long) dataBean.getNotifyStaySecond(), TimeUnit.SECONDS)
.subscribe(aLong -> {
dismiss();
});
binding.setGiftBean(dataBean);
binding.tvGoRoom.setVisibility(dataBean.getRoomUid() == 0
|| (AvRoomDataManager.get().mCurrentRoomInfo != null && dataBean.getRoomUid() == AvRoomDataManager.get().mCurrentRoomInfo.getUid())
? View.GONE : View.VISIBLE);
binding.tvGoRoom.setOnClickListener(view -> AVRoomActivity.start(getContext(), dataBean.getRoomUid()));
}
}
}

View File

@@ -0,0 +1,191 @@
package com.nnbc123.app.ui.widget.dialog
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.ViewConfiguration
import android.view.Window
import android.view.WindowManager
import android.widget.TextView
import androidx.core.view.isVisible
import androidx.databinding.DataBindingUtil
import com.chuhai.utils.ktx.getColorById
import com.chuhai.utils.ktx.singleClick
import com.chuhai.utils.spannable.SpannableTextBuilder
import com.nnbc123.app.R
import com.nnbc123.app.avroom.activity.AVRoomActivity
import com.nnbc123.app.databinding.DialogGiftAllServiceLevelBinding
import com.nnbc123.app.public_chat_hall.activity.PublicChatHallHomeActivity
import com.nnbc123.core.initial.InitialModel
import com.nnbc123.core.noble.AllServiceGiftProtocol
import com.nnbc123.library.utils.JavaUtil
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import java.util.concurrent.TimeUnit
/**
* Created by Max on 2023/10/27 18:42
* Desc:全服礼物弹窗
**/
class AllServiceGiftLevelDialog : BaseDialog {
private var data: AllServiceGiftProtocol.DataBean? = null
private var binding: DialogGiftAllServiceLevelBinding? = null
private var disposable: Disposable? = null
companion object {
private var marqueeError = false
}
constructor(context: Context?, data: AllServiceGiftProtocol.DataBean) : super(
context, R.style.FullScreenDialog
) {
this.data = data
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
requestWindowFeature(Window.FEATURE_NO_TITLE)
val inflate =
LayoutInflater.from(context).inflate(R.layout.dialog_gift_all_service_level, null)
setContentView(inflate.rootView)
setCancelable(true)
setCanceledOnTouchOutside(true)
binding = DataBindingUtil.bind(inflate)
val window = window
if (window != null) {
window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val windowParams = window.attributes
windowParams.width = WindowManager.LayoutParams.MATCH_PARENT
//MATCH_PARENT会挡住键盘
// wrap_parent在小米8又会截掉一点在华为测试关闭按钮点击不到
//暂时找不到原因,
windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT
windowParams.dimAmount = 0.0f
windowParams.gravity = Gravity.TOP
windowParams.x = 0
windowParams.y = 0
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL)
window.attributes = windowParams
window.setWindowAnimations(R.style.anim_left)
}
val data = this.data
val binding = this.binding
if (data != null && binding != null) {
init(data, binding)
} else {
dismiss()
}
}
private fun init(
data: AllServiceGiftProtocol.DataBean,
binding: DialogGiftAllServiceLevelBinding
) {
binding.ivAvatar.singleClick {
goRoom(data)
}
binding.tvRoomGo.singleClick {
goRoom(data)
}
binding.giftBean = data
if ((data.giftNum) <= 1) {
binding.tvCount.text = ""
} else {
binding.tvCount.text = "X${data.giftNum}"
}
SpannableTextBuilder(binding.tvMessage)
.appendText(
data.sendUserNick,
binding.tvMessage.context.getColorById(R.color.color_FFE468)
)
.appendText(
" 送给 ",
binding.tvMessage.context.getColorById(R.color.white)
)
.appendText(
data.recvUserNick + " ",
binding.tvMessage.context.getColorById(R.color.color_FFE468)
)
.appendText(
data.giftName,
binding.tvMessage.context.getColorById(R.color.white)
).apply()
when (data.levelNum.toIntOrNull()) {
2 -> {
binding.ivAvatarBg.setImageResource(R.drawable.all_service_gift_bg_avatar_2)
binding.layoutRoot.setBackgroundResource(R.drawable.all_service_gift_bg_2)
binding.tvRoomGo.setBackgroundResource(R.drawable.all_service_gift_bg_room_go2)
}
3 -> {
binding.ivAvatarBg.setImageResource(R.drawable.all_service_gift_bg_avatar_3)
binding.layoutRoot.setBackgroundResource(R.drawable.all_service_gift_bg_3)
binding.tvRoomGo.setBackgroundResource(R.drawable.all_service_gift_bg_room_go3)
}
else -> {
binding.ivAvatarBg.setImageDrawable(null)
binding.layoutRoot.setBackgroundResource(R.drawable.all_service_gift_bg_1)
binding.tvRoomGo.setBackgroundResource(R.drawable.all_service_gift_bg_room_go1)
}
}
setupTextMarquee(binding.tvMessage)
disposable = Observable.timer(data.notifyStaySecond.toLong(), TimeUnit.SECONDS)
.subscribe { dismiss() }
binding.groupRoom.isVisible = data.roomUid != 0L
}
/**
* 添加跑马灯
* 以及反射一些参数影响跑马灯
*/
private fun setupTextMarquee(view: TextView) {
view.isSelected = true
if (marqueeError) {
return
}
try {
val configuration = ViewConfiguration.get(
context
)
val claz: Class<*> = configuration.javaClass
val field = claz.getDeclaredField("mFadingMarqueeEnabled")
field.isAccessible = true
field[configuration] = true
} catch (e: Exception) {
e.printStackTrace()
marqueeError = true
}
}
private fun goRoom(
data: AllServiceGiftProtocol.DataBean
) {
if (data.roomUid <= 0L) {
// 非房间场景送的礼物
return
}
if (AllServiceGiftGoRoomTipsDialog.isNeedTips()) {
AllServiceGiftGoRoomTipsDialog(context, data.roomTitle ?: "", data.roomUid).show()
} else {
if (data.roomUid == JavaUtil.str2long(InitialModel.get().publicChatHallUid)) {
PublicChatHallHomeActivity.openPublicChatHallPage(context)
} else {
AVRoomActivity.start(context, data.roomUid)
}
}
}
override fun dismiss() {
super.dismiss()
if (disposable?.isDisposed != true) {
disposable?.dispose()
}
disposable = null
}
}

View File

@@ -1,85 +0,0 @@
package com.nnbc123.app.ui.widget.dialog;
import android.content.Context;
import androidx.databinding.DataBindingUtil;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.nnbc123.app.R;
import com.nnbc123.app.avroom.activity.AVRoomActivity;
import com.nnbc123.app.databinding.DialogGiftAllServiceLevelOneBinding;
import com.nnbc123.app.public_chat_hall.activity.PublicChatHallHomeActivity;
import com.nnbc123.core.initial.InitialModel;
import com.nnbc123.core.noble.AllServiceGiftProtocol;
import com.nnbc123.core.statistic.StatisticManager;
import com.nnbc123.core.statistic.protocol.StatisticsProtocol;
import com.nnbc123.library.utils.JavaUtil;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
/**
* Created by MadisonRong on 11/05/2018.
*/
public class AllServiceGiftLevelOneDialog extends AllServiceGiftDialog {
private DialogGiftAllServiceLevelOneBinding binding;
public AllServiceGiftLevelOneDialog(Context context, AllServiceGiftProtocol.DataBean dataBean) {
super(context, R.style.FullScreenDialog, dataBean);
giftLevel = ALL_SERVICE_GIFT_LEVEL_1;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
View inflate = LayoutInflater.from(getContext()).inflate(R.layout.dialog_gift_all_service_level_one, null);
setContentView(inflate.getRootView());
setCancelable(true);
setCanceledOnTouchOutside(true);
binding = DataBindingUtil.bind(inflate);
Window window = getWindow();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
WindowManager.LayoutParams windowParams = window.getAttributes();
windowParams.width = WindowManager.LayoutParams.MATCH_PARENT;
//MATCH_PARENT会挡住键盘
// wrap_parent在小米8又会截掉一点在华为测试关闭按钮点击不到
//暂时找不到原因,
windowParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.dimAmount = 0.0f;
windowParams.gravity = Gravity.TOP;
windowParams.x = 0;
windowParams.y = 0;
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.setAttributes(windowParams);
window.setWindowAnimations(R.style.anim_left);
}
if (dataBean != null) {
binding.getRoot().setOnClickListener(v -> {
if (dataBean.getRoomUid() == JavaUtil.str2long(InitialModel.get().getPublicChatHallUid())) {
PublicChatHallHomeActivity.openPublicChatHallPage(getContext());
} else {
AVRoomActivity.start(getContext(), dataBean.getRoomUid());
}
StatisticManager.Instance().onEvent(StatisticsProtocol.FULL_GIFT_WATCHING, "全服礼物-前往围观计数");
});
Observable.timer((long) dataBean.getNotifyStaySecond(), TimeUnit.SECONDS)
.subscribe(aLong -> {
dismiss();
});
binding.setGiftBean(dataBean);
}
binding.ivCloseDialogOne.setOnClickListener(v -> dismiss());
}
}

View File

@@ -1,92 +0,0 @@
package com.nnbc123.app.ui.widget.dialog;
import android.content.Context;
import androidx.databinding.DataBindingUtil;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.nnbc123.app.R;
import com.nnbc123.app.avroom.activity.AVRoomActivity;
import com.nnbc123.app.databinding.DialogGiftAllServiceLevelThreeBinding;
import com.nnbc123.app.public_chat_hall.activity.PublicChatHallHomeActivity;
import com.nnbc123.core.initial.InitialModel;
import com.nnbc123.core.noble.AllServiceGiftProtocol;
import com.nnbc123.core.statistic.StatisticManager;
import com.nnbc123.core.statistic.protocol.StatisticsProtocol;
import com.nnbc123.library.utils.JavaUtil;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
/**
* Created by MadisonRong on 11/05/2018.
*/
public class AllServiceGiftLevelThreeDialog extends AllServiceGiftDialog {
private DialogGiftAllServiceLevelThreeBinding binding;
private float screenWidth;
public AllServiceGiftLevelThreeDialog(Context context, AllServiceGiftProtocol.DataBean dataBean) {
super(context, R.style.FullScreenDialog, dataBean);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
View inflate = LayoutInflater.from(getContext()).inflate(R.layout.dialog_gift_all_service_level_three, null);
setContentView(inflate.getRootView());
setCancelable(true);
setCanceledOnTouchOutside(true);
binding = DataBindingUtil.bind(inflate);
Window window = getWindow();
Point point = new Point();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
WindowManager.LayoutParams windowParams = window.getAttributes();
windowParams.width = WindowManager.LayoutParams.MATCH_PARENT;
windowParams.height =WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.dimAmount = 0.0f;
windowParams.gravity = Gravity.TOP;
windowParams.x = 0;
windowParams.y = 0;
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.setAttributes(windowParams);
window.setWindowAnimations(R.style.anim_fade);
window.getWindowManager().getDefaultDisplay().getSize(point);
screenWidth = point.x;
}
if (dataBean != null) {
binding.giftClose.setOnClickListener(v -> {
dismiss();
});
binding.getRoot().setOnClickListener(v -> {
if (dataBean.getRoomUid() == JavaUtil.str2long(InitialModel.get().getPublicChatHallUid())) {
PublicChatHallHomeActivity.openPublicChatHallPage(getContext());
} else {
AVRoomActivity.start(getContext(), dataBean.getRoomUid());
}
StatisticManager.Instance().onEvent(StatisticsProtocol.FULL_GIFT_WATCHING, "全服礼物-前往围观计数");
});
// 设置定时器
Observable.timer((long) dataBean.getNotifyStaySecond(), TimeUnit.SECONDS)
.subscribe(aLong -> {
dismiss();
});
binding.setGiftBean(dataBean);
binding.tvRoomId.setVisibility(dataBean.getRoomUid() == 0 ? View.GONE : View.VISIBLE);
}
}
}

View File

@@ -1,88 +0,0 @@
package com.nnbc123.app.ui.widget.dialog;
import android.content.Context;
import androidx.databinding.DataBindingUtil;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import com.nnbc123.app.R;
import com.nnbc123.app.avroom.activity.AVRoomActivity;
import com.nnbc123.app.databinding.DialogGiftAllServiceLevelTwoBinding;
import com.nnbc123.app.public_chat_hall.activity.PublicChatHallHomeActivity;
import com.nnbc123.core.initial.InitialModel;
import com.nnbc123.core.noble.AllServiceGiftProtocol;
import com.nnbc123.core.statistic.StatisticManager;
import com.nnbc123.core.statistic.protocol.StatisticsProtocol;
import com.nnbc123.library.utils.JavaUtil;
import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
/**
* Created by MadisonRong on 11/05/2018.
*/
public class AllServiceGiftLevelTwoDialog extends AllServiceGiftDialog {
private DialogGiftAllServiceLevelTwoBinding binding;
private float screenWidth;
public AllServiceGiftLevelTwoDialog(Context context, AllServiceGiftProtocol.DataBean dataBean) {
super(context, R.style.FullScreenDialog, dataBean);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
View inflate = LayoutInflater.from(getContext()).inflate(R.layout.dialog_gift_all_service_level_two, null);
setContentView(inflate.getRootView());
setCancelable(true);
setCanceledOnTouchOutside(true);
binding = DataBindingUtil.bind(inflate);
Window window = getWindow();
Point point = new Point();
if (window != null) {
window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
WindowManager.LayoutParams windowParams = window.getAttributes();
windowParams.width = WindowManager.LayoutParams.MATCH_PARENT;
windowParams.height =WindowManager.LayoutParams.WRAP_CONTENT;
windowParams.dimAmount = 0.0f;
windowParams.gravity = Gravity.TOP;
windowParams.x = 0;
windowParams.y = 0;
window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL);
window.setAttributes(windowParams);
window.setWindowAnimations(R.style.anim_left);
window.getWindowManager().getDefaultDisplay().getSize(point);
screenWidth = point.x;
}
if (dataBean != null) {
binding.getRoot().setOnClickListener(v -> {
if (dataBean.getRoomUid() == JavaUtil.str2long(InitialModel.get().getPublicChatHallUid())) {
PublicChatHallHomeActivity.openPublicChatHallPage(getContext());
} else {
AVRoomActivity.start(getContext(), dataBean.getRoomUid());
}
StatisticManager.Instance().onEvent(StatisticsProtocol.FULL_GIFT_WATCHING, "全服礼物-前往围观计数");
});
// 设置定时器
Observable.timer((long) (dataBean.getNotifyStaySecond()), TimeUnit.SECONDS)
.subscribe(aLong -> dismiss());
binding.setGiftBean(dataBean);
}
binding.ivCloseDialogTwo.setOnClickListener(v -> dismiss());
}
}

View File

@@ -31,7 +31,7 @@ class RequestPermissionPromptDialog(context: Context, private val message: Strin
* 是否需要展示权限申请说明
*/
fun isNeedPrompt(): Boolean {
return (BasicConfig.INSTANCE.channel == "huawei")
return (BasicConfig.INSTANCE.channel == "huawei") || (BasicConfig.INSTANCE.channel == "rongyao")
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF283889" />
<stroke
android:width="1dp"
android:color="#FF66B5FF" />
<corners android:radius="8.5dp" />
</shape>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FF49157D" />
<stroke
android:width="1dp"
android:color="#FFFE9FFF" />
<corners android:radius="8.5dp" />
</shape>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#87152D" />
<stroke
android:width="1dp"
android:color="#FFED77" />
<corners android:radius="8.5dp" />
</shape>

View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="20dp"
android:height="20dp"
android:viewportWidth="20"
android:viewportHeight="20">
<path
android:pathData="M12.528,0.898L18.773,5.98C19.55,6.611 20,7.558 20,8.557L20,16.009C20,18.213 18.209,20 16,20L15,20C14.264,20 13.667,19.403 13.667,18.667L13.667,14.346L13.667,14.346C13.667,13.269 12.811,12.391 11.742,12.352L11.667,12.35L8.333,12.35C7.254,12.35 6.374,13.204 6.335,14.271L6.333,14.346L6.333,18.667C6.333,19.403 5.736,20 5,20L4,20L4,20C1.791,20 0,18.213 0,16.009L0,8.557C0,7.558 0.45,6.611 1.227,5.98L7.472,0.898C8.944,-0.299 11.056,-0.299 12.528,0.898Z"
android:strokeWidth="1"
android:fillColor="#FFFFFF"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

View File

@@ -0,0 +1,18 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:viewportWidth="14"
android:viewportHeight="14">
<path
android:pathData="M7,7m-7,0a7,7 0,1 1,14 0a7,7 0,1 1,-14 0"
android:strokeWidth="1"
android:fillColor="#141414"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
<path
android:pathData="M3.576,6.612C3.792,6.373 4.161,6.353 4.4,6.569L6.381,8.353L9.867,4.483C10.098,4.226 10.493,4.205 10.75,4.436C11.006,4.667 11.027,5.062 10.796,5.319L6.948,9.592L6.937,9.604C6.932,9.61 6.926,9.617 6.92,9.623C6.705,9.862 6.336,9.882 6.097,9.666L3.619,7.436C3.38,7.22 3.361,6.851 3.576,6.612Z"
android:strokeWidth="1"
android:fillColor="#FFFFFF"
android:fillType="evenOdd"
android:strokeColor="#00000000"/>
</vector>

View File

@@ -0,0 +1,12 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="14dp"
android:height="14dp"
android:viewportWidth="14"
android:viewportHeight="14">
<path
android:pathData="M7,7m-6.5,0a6.5,6.5 0,1 1,13 0a6.5,6.5 0,1 1,-13 0"
android:strokeWidth="1"
android:fillColor="#00000000"
android:strokeColor="#B3B3C3"
android:fillType="evenOdd"/>
</vector>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="26dp"/>
<solid android:color="#33FFDA24"/>
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="21dp"/>
<solid android:color="#FFE6E6F0"/>
</shape>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="8dp"/>
<solid android:color="#F3F5FA"/>
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="21dp"/>
<solid android:color="@color/color_theme"/>
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="26dp"/>
<solid android:color="@color/color_theme"/>
</shape>

View File

@@ -308,6 +308,35 @@
android:textColor="@color/text_title_282828"
android:textSize="14sp" />
<LinearLayout
android:id="@+id/layout_invite_code"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="@{click}"
android:orientation="vertical"
android:visibility="gone"
tools:visibility="visible">
<View
android:layout_width="match_parent"
android:layout_height="1px"
android:layout_marginStart="@dimen/dp_15"
android:layout_marginEnd="15dp"
android:background="@color/line_353548" />
<TextView
android:id="@+id/tv_invite_code"
android:layout_width="match_parent"
android:layout_height="50dp"
android:drawableEnd="@drawable/arrow_right"
android:gravity="center_vertical"
android:paddingLeft="@dimen/dp_15"
android:paddingRight="@dimen/dp_15"
android:text="@string/text_setting_invite_code"
android:textColor="@color/text_title_282828"
android:textSize="14sp" />
</LinearLayout>
<View
android:layout_width="match_parent"
android:layout_height="10dp"

View File

@@ -232,16 +232,6 @@
android:orientation="horizontal"
app:layout_constraintTop_toBottomOf="@id/ll_id">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/tv_hall_desc"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginEnd="@dimen/dp_4"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_userinfo_hall"
tools:visibility="visible" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv_user_level"
android:layout_width="wrap_content"

View File

@@ -0,0 +1,116 @@
<?xml version="1.0" encoding="utf-8"?>
<layout>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="28dp"
android:background="@drawable/shape_white_20dp_round"
android:paddingBottom="24dp">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/all_service_gift_room_go_title"
android:textColor="@color/color_1F1B4F"
android:textSize="18dp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tv_go_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/all_service_gift_room_go_tips"
android:textColor="@color/color_1F1B4F"
android:textSize="14dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<TextView
android:id="@+id/tv_room_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="2dp"
android:gravity="center_horizontal"
android:textColor="@color/color_9168FA"
android:textSize="14dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_go_tips"
tools:text="Name" />
<ImageView
android:id="@+id/iv_checkbox"
android:layout_width="22dp"
android:layout_height="22dp"
android:layout_marginTop="13dp"
android:scaleType="center"
android:src="@drawable/base_ic_checkbox_unselected"
app:layout_constraintEnd_toStartOf="@id/tv_tips"
app:layout_constraintHorizontal_chainStyle="packed"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_room_name" />
<TextView
android:id="@+id/tv_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:includeFontPadding="false"
android:text="@string/all_service_gift_room_go_ignore"
android:textColor="@color/color_B3B3C3"
android:textSize="12dp"
app:layout_constraintBottom_toBottomOf="@id/iv_checkbox"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/iv_checkbox"
app:layout_constraintTop_toTopOf="@id/iv_checkbox" />
<TextView
android:id="@+id/tv_cancel"
android:layout_width="0dp"
android:layout_height="42dp"
android:layout_marginStart="28dp"
android:layout_marginTop="19dp"
android:layout_marginEnd="7.5dp"
android:background="@drawable/shape_e6e6f0_21"
android:gravity="center"
android:text="@string/all_service_gift_room_go_cancel"
android:textColor="@color/white"
android:textSize="16dp"
app:layout_constraintEnd_toStartOf="@id/tv_go"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/iv_checkbox" />
<TextView
android:id="@+id/tv_go"
android:layout_width="0dp"
android:layout_height="42dp"
android:layout_marginStart="7.5dp"
android:layout_marginEnd="28dp"
android:background="@drawable/shape_theme_21"
android:gravity="center"
android:text="@string/all_service_gift_room_go_go"
android:textColor="@color/color_333333"
android:textSize="16dp"
app:layout_constraintBottom_toBottomOf="@id/tv_cancel"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_cancel"
app:layout_constraintTop_toTopOf="@id/tv_cancel" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>
</layout>

View File

@@ -1,130 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="giftBean"
type="com.nnbc123.core.noble.AllServiceGiftProtocol.DataBean" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:paddingTop="30dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/all_service_gift_ceremony_background"
android:gravity="center_vertical"
android:orientation="horizontal">
<TextView
android:id="@+id/benefactor_nick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="35dp"
android:ellipsize="end"
android:gravity="center"
android:maxEms="5"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.sendUserNick}"
android:textColor="#FBC200"
android:textSize="12dp"
tools:ignore="SpUsage"
tools:text="宫泽艾里斯-宫泽艾里斯-宫泽艾里斯" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/benefactor_avatar"
avatarUrl="@{giftBean.sendUserAvatar}"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="2dp"
app:cborder_color="#FFEB71"
app:cborder_width="1dp"
tools:src="@drawable/default_avatar" />
<TextView
android:id="@+id/give_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:text="送给"
android:textColor="@color/white"
android:textSize="12dp" />
<TextView
android:id="@+id/receiver_nick"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:ellipsize="end"
android:gravity="center"
android:maxEms="5"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.recvUserNick}"
android:textColor="#FBC200"
android:textSize="12dp"
tools:text="梅利奥达斯-梅利奥达斯-梅利奥达斯" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/receiver_avatar"
avatarUrl="@{giftBean.recvUserAvatar}"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginStart="2dp"
app:cborder_color="#FFEB71"
app:cborder_width="1dp"
tools:src="@drawable/default_avatar" />
<TextView
android:id="@+id/gift_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:gravity="center"
android:text="@{giftBean.giftName}"
android:textColor="#80F9FF"
android:textSize="12dp"
android:textStyle="bold"
tools:ignore="SpUsage"
tools:text="神邸荣光" />
<ImageView
android:id="@+id/gift_img"
nomalUrl="@{giftBean.giftUrl}"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_gravity="center"
android:layout_marginStart="2dp" />
<TextView
android:id="@+id/gift_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="2dp"
android:gravity="center"
android:text="@{@string/x + giftBean.giftNum}"
android:textColor="#80F9FF"
android:textSize="12dp"
android:textStyle="bold"
tools:ignore="SpUsage"
tools:text="x1" />
<ImageView
android:id="@+id/tv_go_room"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_5"
android:src="@drawable/all_service_gift_ceremony_go_to" />
</LinearLayout>
</FrameLayout>
</layout>

View File

@@ -0,0 +1,167 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="giftBean"
type="com.nnbc123.core.noble.AllServiceGiftProtocol.DataBean" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingTop="20dp">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/layout_root"
android:layout_width="match_parent"
android:layout_height="0dp"
android:background="@drawable/all_service_gift_bg_1"
app:layout_constraintDimensionRatio="h,375:69"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/iv_avatar_bg"
android:layout_width="0dp"
android:layout_height="match_parent"
app:layout_constraintBottom_toBottomOf="@id/iv_avatar"
app:layout_constraintDimensionRatio="w,89:69"
app:layout_constraintEnd_toEndOf="@id/iv_avatar"
app:layout_constraintStart_toStartOf="@id/iv_avatar"
app:layout_constraintTop_toTopOf="@id/iv_avatar"
tools:background="@color/black" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/line_content_start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.0586" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/iv_avatar"
avatarUrl="@{giftBean.sendUserAvatar}"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="w,1:1"
app:layout_constraintHeight_percent="0.6376"
app:layout_constraintStart_toStartOf="@id/line_content_start"
app:layout_constraintTop_toTopOf="parent"
tools:src="@drawable/default_avatar" />
<TextView
android:id="@+id/tv_message"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="13dp"
android:layout_marginEnd="4.5dp"
android:ellipsize="marquee"
android:focusable="true"
android:focusableInTouchMode="true"
android:includeFontPadding="false"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:textColor="@color/white"
android:textSize="14dp"
app:layout_constraintBottom_toTopOf="@id/tv_room_name"
app:layout_constraintEnd_toStartOf="@id/iv_gift"
app:layout_constraintStart_toEndOf="@id/iv_avatar"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="XXX 送给 XXX XXXX" />
<TextView
android:id="@+id/tv_room_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="2.5dp"
android:layout_marginTop="5dp"
android:layout_marginEnd="4.5dp"
android:includeFontPadding="false"
android:singleLine="true"
android:text="@{giftBean.roomTitle}"
android:textColor="@color/white"
android:textSize="12dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/tv_room_go"
app:layout_constraintStart_toEndOf="@id/iv_room"
app:layout_constraintTop_toBottomOf="@id/tv_message"
tools:text="X1111111111111111111" />
<TextView
android:id="@+id/tv_room_go"
android:layout_width="wrap_content"
android:layout_height="19dp"
android:layout_marginEnd="2dp"
android:background="@drawable/all_service_gift_bg_room_go1"
android:gravity="center"
android:paddingHorizontal="7.5dp"
android:singleLine="true"
android:text="@string/all_service_gift_room_go"
android:textColor="@color/white"
android:textSize="10dp"
app:layout_constraintBottom_toBottomOf="@id/tv_room_name"
app:layout_constraintEnd_toStartOf="@id/iv_gift"
app:layout_constraintTop_toTopOf="@id/tv_room_name" />
<ImageView
android:id="@+id/iv_room"
android:layout_width="12dp"
android:layout_height="12dp"
android:src="@drawable/all_service_gift_ic_room"
app:layout_constraintBottom_toBottomOf="@id/tv_room_name"
app:layout_constraintStart_toStartOf="@id/tv_message"
app:layout_constraintTop_toTopOf="@id/tv_room_name" />
<ImageView
android:id="@+id/iv_gift"
nomalUrl="@{giftBean.giftUrl}"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginEnd="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintDimensionRatio="w,1:1"
app:layout_constraintEnd_toStartOf="@id/tv_count"
app:layout_constraintHeight_percent="0.9275"
app:layout_constraintTop_toTopOf="parent"
tools:background="@color/black" />
<androidx.constraintlayout.widget.Guideline
android:id="@+id/line_content_end"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintGuide_percent="0.9413" />
<TextView
android:id="@+id/tv_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:maxWidth="180dp"
android:singleLine="true"
android:textColor="@color/color_FFE468"
android:textSize="16dp"
android:textStyle="italic|bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@id/line_content_end"
app:layout_constraintTop_toTopOf="parent"
tools:text="X10000" />
<androidx.constraintlayout.widget.Group
android:id="@+id/group_room"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="gone"
app:constraint_referenced_ids="tv_room_name,tv_room_go,iv_room"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>

View File

@@ -1,177 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="giftBean"
type="com.nnbc123.core.noble.AllServiceGiftProtocol.DataBean" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
tools:background="@color/black">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:background="@drawable/all_service_gift_level_one_background">
<RelativeLayout
android:id="@+id/benefactor_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="13dp"
android:layout_marginTop="37dp">
<RelativeLayout
android:id="@+id/benefactor_avatar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/benefactor_avatar_background"
android:layout_width="51dp"
android:layout_height="51dp"
android:layout_centerInParent="true"
android:src="@drawable/all_service_gift_avatar_level_one_background" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/benefactor_avatar"
avatarUrl="@{giftBean.sendUserAvatar}"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
tools:src="@drawable/default_avatar" />
</RelativeLayout>
<TextView
android:id="@+id/benefactor_nick"
android:layout_width="66.5dp"
android:layout_height="16.5dp"
android:layout_below="@id/benefactor_avatar_layout"
android:layout_centerHorizontal="true"
android:layout_marginTop="-8dp"
android:background="@drawable/all_service_gift_nick_one_background"
android:ellipsize="end"
android:gravity="center"
android:maxLength="6"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.sendUserNick}"
android:textColor="#FF2F0060"
android:textSize="10dp"
tools:ignore="SpUsage"
tools:text="宫泽艾里斯宫泽艾里斯-宫泽艾里斯" />
</RelativeLayout>
<ImageView
android:id="@+id/give_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="13dp"
android:layout_marginTop="56dp"
android:layout_marginEnd="13dp"
android:layout_toEndOf="@id/benefactor_container"
android:src="@drawable/all_service_gift_give_level_1" />
<RelativeLayout
android:id="@+id/receiver_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="37dp"
android:layout_toEndOf="@id/give_text">
<RelativeLayout
android:id="@+id/receiver_avatar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/receiver_avatar_background"
android:layout_width="51dp"
android:layout_height="51dp"
android:layout_centerInParent="true"
android:src="@drawable/all_service_gift_avatar_level_one_background" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/receiver_avatar"
avatarUrl="@{giftBean.recvUserAvatar}"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
tools:src="@drawable/default_avatar" />
</RelativeLayout>
<TextView
android:id="@+id/receiver_nick"
android:layout_width="66.5dp"
android:layout_height="16.5dp"
android:layout_below="@id/receiver_avatar_layout"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-8dp"
android:background="@drawable/all_service_gift_nick_one_background"
android:ellipsize="end"
android:gravity="center"
android:maxLength="6"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.recvUserNick}"
android:textColor="#FF2F0060"
android:textSize="10dp"
tools:text="梅利奥达斯-梅利奥达斯-梅利奥达斯" />
</RelativeLayout>
<ImageView
android:id="@+id/gift_img"
nomalUrl="@{giftBean.giftUrl}"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:layout_marginStart="@dimen/dp_15"
android:layout_marginTop="37dp"
android:layout_toEndOf="@+id/receiver_container" />
<TextView
android:id="@+id/gift_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_6"
android:layout_marginTop="53dp"
android:layout_toEndOf="@+id/gift_img"
android:gravity="center"
android:includeFontPadding="false"
android:text="@{@string/x + giftBean.giftNum}"
android:textColor="#FFFEF563"
android:textSize="20dp"
tools:ignore="SpUsage"
tools:text="x1314" />
</RelativeLayout>
<ImageView
android:id="@+id/iv_close_dialog_one"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="13dp"
android:layout_marginEnd="10dp"
android:src="@drawable/ic_close_all_server_one" />
</FrameLayout>
</layout>

View File

@@ -1,192 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="giftBean"
type="com.nnbc123.core.noble.AllServiceGiftProtocol.DataBean" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
tools:background="@color/black">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="15dp"
android:layout_marginEnd="15dp"
android:background="@drawable/all_service_gift_level_three_background">
<TextView
android:id="@+id/tv_room_id"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="8dp"
android:gravity="center"
android:text="@{@string/click_go + giftBean.roomErbanNo}"
android:textColor="@color/white"
android:textSize="10dp"
tools:ignore="SpUsage"
tools:text="ID:1234567" />
<RelativeLayout
android:id="@+id/benefactor_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="17dp"
android:layout_marginTop="56dp">
<RelativeLayout
android:id="@+id/benefactor_avatar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/benefactor_avatar_background"
android:layout_width="51dp"
android:layout_height="51dp"
android:layout_centerInParent="true"
android:src="@drawable/all_service_gift_avatar_level_one_background" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/benefactor_avatar"
avatarUrl="@{giftBean.sendUserAvatar}"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
tools:src="@drawable/default_avatar" />
</RelativeLayout>
<TextView
android:id="@+id/benefactor_nick"
android:layout_width="67.5dp"
android:layout_height="16.5dp"
android:layout_below="@id/benefactor_avatar_layout"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-8dp"
android:background="@drawable/all_service_gift_nick_two_background"
android:ellipsize="end"
android:gravity="center"
android:maxLength="6"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.sendUserNick}"
android:textColor="@color/white"
android:textSize="10dp"
tools:ignore="SpUsage"
tools:text="宫泽艾里斯宫泽艾里斯-宫泽艾里斯" />
</RelativeLayout>
<ImageView
android:id="@+id/give_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="13dp"
android:layout_marginTop="56dp"
android:layout_marginEnd="13dp"
android:layout_toEndOf="@id/benefactor_container"
android:src="@drawable/all_service_gift_give_level_1" />
<RelativeLayout
android:id="@+id/receiver_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="56dp"
android:layout_toEndOf="@id/give_text">
<RelativeLayout
android:id="@+id/receiver_avatar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/receiver_avatar_background"
android:layout_width="51dp"
android:layout_height="51dp"
android:layout_centerInParent="true"
android:src="@drawable/all_service_gift_avatar_level_one_background" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/receiver_avatar"
avatarUrl="@{giftBean.recvUserAvatar}"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
tools:src="@drawable/default_avatar" />
</RelativeLayout>
<TextView
android:id="@+id/receiver_nick"
android:layout_width="67.5dp"
android:layout_height="16.5dp"
android:layout_below="@id/receiver_avatar_layout"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-8dp"
android:background="@drawable/all_service_gift_nick_two_background"
android:ellipsize="end"
android:gravity="center"
android:maxLength="6"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.recvUserNick}"
android:textColor="@color/white"
android:textSize="10dp"
tools:text="梅利奥达斯梅利奥达斯-梅利奥达斯" />
</RelativeLayout>
<ImageView
android:id="@+id/gift_img"
nomalUrl="@{giftBean.giftUrl}"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:layout_marginStart="15dp"
android:layout_marginTop="56dp"
android:layout_toEndOf="@+id/receiver_container" />
<TextView
android:id="@+id/gift_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_6"
android:layout_marginTop="75dp"
android:layout_toEndOf="@+id/gift_img"
android:gravity="center"
android:includeFontPadding="false"
android:text="@{@string/x + giftBean.giftNum}"
android:textColor="#FFFEF563"
android:textSize="20dp"
tools:ignore="SpUsage"
tools:text="x1314" />
</RelativeLayout>
<ImageView
android:id="@+id/gift_close"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginEnd="@dimen/dp_10"
android:layout_marginTop="34dp"
android:src="@drawable/ic_close_all_server_one" />
</FrameLayout>
</layout>

View File

@@ -1,178 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<data>
<variable
name="giftBean"
type="com.nnbc123.core.noble.AllServiceGiftProtocol.DataBean" />
</data>
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
tools:background="@color/black">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginEnd="10dp"
android:background="@drawable/all_service_gift_level_two_background">
<RelativeLayout
android:id="@+id/benefactor_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="17dp"
android:layout_marginTop="34dp">
<RelativeLayout
android:id="@+id/benefactor_avatar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/benefactor_avatar_background"
android:layout_width="51dp"
android:layout_height="51dp"
android:layout_centerInParent="true"
android:src="@drawable/all_service_gift_avatar_level_one_background" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/benefactor_avatar"
avatarUrl="@{giftBean.sendUserAvatar}"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
tools:src="@drawable/default_avatar" />
</RelativeLayout>
<TextView
android:id="@+id/benefactor_nick"
android:layout_width="67.5dp"
android:layout_height="16.5dp"
android:layout_below="@id/benefactor_avatar_layout"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-8dp"
android:background="@drawable/all_service_gift_nick_two_background"
android:ellipsize="end"
android:gravity="center"
android:maxLength="6"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.sendUserNick}"
android:textColor="@color/white"
android:textSize="10dp"
tools:ignore="SpUsage"
tools:text="宫泽艾里斯宫泽艾里斯-宫泽艾里斯" />
</RelativeLayout>
<ImageView
android:id="@+id/give_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginStart="13dp"
android:layout_marginTop="53dp"
android:layout_marginEnd="13dp"
android:layout_toEndOf="@id/benefactor_container"
android:src="@drawable/all_service_gift_give_level_1" />
<RelativeLayout
android:id="@+id/receiver_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginTop="34dp"
android:layout_toEndOf="@id/give_text">
<RelativeLayout
android:id="@+id/receiver_avatar_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true">
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/receiver_avatar_background"
android:layout_width="51dp"
android:layout_height="51dp"
android:layout_centerInParent="true"
android:src="@drawable/all_service_gift_avatar_level_two_background" />
<com.nnbc123.app.common.widget.CircleImageView
android:id="@+id/receiver_avatar"
avatarUrl="@{giftBean.recvUserAvatar}"
android:layout_width="44dp"
android:layout_height="44dp"
android:layout_centerInParent="true"
android:layout_centerHorizontal="true"
tools:src="@drawable/default_avatar" />
</RelativeLayout>
<TextView
android:id="@+id/receiver_nick"
android:layout_width="67.5dp"
android:layout_height="16.5dp"
android:layout_below="@id/receiver_avatar_layout"
android:layout_centerHorizontal="true"
android:layout_gravity="center_horizontal"
android:layout_marginTop="-8dp"
android:background="@drawable/all_service_gift_nick_two_background"
android:ellipsize="end"
android:gravity="center"
android:maxLength="6"
android:maxLines="1"
android:singleLine="true"
android:text="@{giftBean.recvUserNick}"
android:textColor="@color/white"
android:textSize="10dp"
tools:text="梅利奥达斯梅利奥达斯-梅利奥达斯" />
</RelativeLayout>
<ImageView
android:id="@+id/gift_img"
nomalUrl="@{giftBean.giftUrl}"
android:layout_width="60dp"
android:layout_height="60dp"
android:layout_gravity="center"
android:layout_marginStart="15dp"
android:layout_marginTop="34dp"
android:layout_toEndOf="@+id/receiver_container" />
<TextView
android:id="@+id/gift_number"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_6"
android:layout_marginTop="53dp"
android:layout_toEndOf="@+id/gift_img"
android:gravity="center"
android:includeFontPadding="false"
android:text="@{@string/x + giftBean.giftNum}"
android:textColor="#FFFEF563"
android:textSize="20dp"
tools:ignore="SpUsage"
tools:text="x1314" />
</RelativeLayout>
<ImageView
android:id="@+id/ivCloseDialogTwo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="end"
android:layout_marginTop="10dp"
android:layout_marginEnd="11dp"
android:src="@drawable/ic_close_all_server_one" />
</FrameLayout>
</layout>

View File

@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="34dp"
android:background="@drawable/shape_white_20dp_round">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:textColor="#2B2D33"
android:textSize="14dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:text="@string/invite_input_confirm_format" />
<TextView
android:id="@+id/tv_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:text="@string/invite_input_tips3"
android:textColor="#2B2D33"
android:textSize="14dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<TextView
android:id="@+id/tv_cancel"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginStart="22dp"
android:layout_marginTop="28dp"
android:layout_marginBottom="24dp"
android:background="@drawable/shape_33ffda24_26"
android:gravity="center"
android:text="@string/cancel"
android:textColor="#2B2D33"
android:textSize="14dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/tv_save"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_tips" />
<TextView
android:id="@+id/tv_save"
android:layout_width="0dp"
android:layout_height="40dp"
android:layout_marginStart="15dp"
android:layout_marginEnd="22dp"
android:background="@drawable/shape_theme_26"
android:gravity="center"
android:text="@string/dialog_privilege_15"
android:textColor="#2B2D33"
android:textSize="14dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/tv_cancel"
app:layout_constraintTop_toBottomOf="@id/tv_tips" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

View File

@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="34dp"
android:background="@drawable/shape_white_20dp_round">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:text="@string/invite_input_title"
android:textColor="#2B2D33"
android:textSize="16dp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/et_code"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_marginHorizontal="26dp"
android:layout_marginTop="26dp"
android:background="@drawable/shape_f3f5fa_8dp"
android:digits="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"
android:gravity="center"
android:hint="@string/invite_input_hint"
android:maxLength="10"
android:singleLine="true"
android:textColor="#878B9C"
android:textColorHint="#878B9C"
android:textSize="14dp"
app:layout_constraintTop_toBottomOf="@id/tv_title" />
<TextView
android:id="@+id/tv_tips_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="28dp"
android:text="@string/invite_input_tips"
android:textColor="#2B2D33"
android:textSize="14dp"
app:layout_constraintStart_toStartOf="@id/et_code"
app:layout_constraintTop_toBottomOf="@id/et_code" />
<TextView
android:id="@+id/tv_tips"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/invite_input_tips2"
android:textColor="#A2A7B8"
android:textSize="12dp"
app:layout_constraintStart_toStartOf="@id/tv_tips_title"
app:layout_constraintTop_toBottomOf="@id/tv_tips_title" />
<TextView
android:id="@+id/tv_save"
android:layout_width="match_parent"
android:layout_height="40dp"
android:layout_marginHorizontal="32dp"
android:layout_marginTop="16dp"
android:layout_marginBottom="24dp"
android:background="@drawable/shape_theme_26"
android:gravity="center"
android:text="@string/dialog_privilege_15"
android:textColor="#2B2D33"
android:textSize="14dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tv_tips" />
</androidx.constraintlayout.widget.ConstraintLayout>
</FrameLayout>

View File

@@ -7,6 +7,7 @@
<color name="color_male">@color/color_529EF2</color>
<color name="color_female">@color/color_FC588F</color>
<color name="color_theme">#FFDA24</color>
<color name="transparent">#00000000</color>
<!-- 透明度参考表
@@ -631,4 +632,7 @@
<color name="color_FFF265">#FFFFF265</color>
<color name="color_5CEFFF">#FF5CEFFF</color>
<color name="color_7F8494">#7F8494</color>
<color name="color_FFE468">#FFFFE468</color>
<color name="color_1F1B4F">#1F1B4F</color>
<color name="color_9168FA">#9168FA</color>
</resources>

View File

@@ -680,6 +680,7 @@
<string name="text_setting_pay_password">支付密码</string>
<string name="text_setting_feedback">我要反馈</string>
<string name="text_setting_black_management">黑名单管理</string>
<string name="text_setting_invite_code">填写邀请码</string>
<string name="text_setting_community_norms">社区规范</string>
<string name="text_setting_contact_us">联系官方</string>
<string name="text_setting_help">帮助</string>
@@ -991,5 +992,21 @@
<string name="diamond_inning">%d钻/局</string>
<string name="permission_denied_tips_mic">为了实现连麦及语音输入等功能,请您允许应用向您获取“麦克风”权限</string>
<string name="permission_denied_tips_image">访问你的本地内容,以能正常使用图片上传、视频发送等应用功能</string>
<string name="permission_denied_tips_camera">用于拍摄更新个人头像、发布动态、与客服反馈问题时进行照片和视频的拍摄录制</string>
<string name="permission_denied_tips_camera">用于拍摄更新个人头像、发布动态、实名认证、与客服反馈问题时进行照片和视频的拍摄录制</string>
<string name="all_service_gift_room_go">去围观</string>
<string name="all_service_gift_room_go_title">前往围观</string>
<string name="all_service_gift_room_go_tips">是否离开当前房间前往</string>
<string name="all_service_gift_room_go_ignore">下次不再出现此提示</string>
<string name="all_service_gift_room_go_cancel">留在这</string>
<string name="all_service_gift_room_go_go">立即前往</string>
<string name="invite_input_title">填写邀请码</string>
<string name="invite_input_hint">请输入要填写的邀请码</string>
<string name="invite_input_tips">填写说明:</string>
<string name="invite_input_tips2">请填写邀请人的邀请码;\n邀请码只能填写一次请勿随意填写</string>
<string name="invite_input_confirm_title">确认填写 </string>
<string name="invite_input_confirm_format">邀请码【%s】</string>
<string name="invite_input_tips3">注意邀请码只能填写 </string>
<string name="invite_input_fill_in_success">填写成功</string>
</resources>

View File

@@ -38,6 +38,8 @@ public class CustomItem implements Parcelable, Serializable {
*/
private int fileType;
private String format;
private int width;
private int height;
public CustomItem(String path, int fileType) {
this(path, fileType, "jpeg");
@@ -50,12 +52,16 @@ public class CustomItem implements Parcelable, Serializable {
this.path = path;
this.fileType = fileType;
this.format = format;
this.width = 0;
this.height = 0;
}
protected CustomItem(Parcel in) {
this.path = in.readString();
this.fileType = in.readInt();
this.format = in.readString();
this.width = in.readInt();
this.height = in.readInt();
}
public boolean isImage() {
@@ -104,6 +110,22 @@ public class CustomItem implements Parcelable, Serializable {
this.format = format;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
@Override
public int describeContents() {
return 0;
@@ -114,5 +136,7 @@ public class CustomItem implements Parcelable, Serializable {
dest.writeString(this.path);
dest.writeInt(this.fileType);
dest.writeString(this.format);
dest.writeInt(this.width);
dest.writeInt(this.height);
}
}

View File

@@ -22,6 +22,7 @@ import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.MediaStore;
import androidx.annotation.Nullable;
import com.zhihu.matisse.MimeType;
@@ -46,8 +47,10 @@ public class Item implements Parcelable {
public final Uri uri;
public final long size;
public final long duration; // only for video, in ms
public final int width;
public final int height;
private Item(long id, String mimeType, long size, long duration) {
private Item(long id, String mimeType, long size, long duration,int width,int height) {
this.id = id;
this.mimeType = mimeType;
Uri contentUri;
@@ -62,14 +65,18 @@ public class Item implements Parcelable {
this.uri = ContentUris.withAppendedId(contentUri, id);
this.size = size;
this.duration = duration;
this.width = width;
this.height = height;
}
public Item(String mimeType, Uri uri, long size, long duration) {
public Item(String mimeType, Uri uri, long size, long duration, int width, int height) {
this.id = 1;
this.mimeType = mimeType;
this.uri = uri;
this.size = size;
this.duration = duration;
this.width = width;
this.height = height;
}
private Item(Parcel source) {
@@ -78,13 +85,44 @@ public class Item implements Parcelable {
uri = source.readParcelable(Uri.class.getClassLoader());
size = source.readLong();
duration = source.readLong();
width = source.readInt();
height = source.readInt();
}
public static Item valueOf(Cursor cursor) {
return new Item(cursor.getLong(cursor.getColumnIndex(MediaStore.Files.FileColumns._ID)),
cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE)),
cursor.getLong(cursor.getColumnIndex(MediaStore.MediaColumns.SIZE)),
cursor.getLong(cursor.getColumnIndex("duration")));
return new Item(getCursorLong(cursor, MediaStore.Files.FileColumns._ID, 0),
getCursorString(cursor, MediaStore.MediaColumns.MIME_TYPE, ""),
getCursorLong(cursor, MediaStore.MediaColumns.SIZE, 0),
getCursorLong(cursor, "duration", 0),
getCursorInt(cursor, MediaStore.MediaColumns.WIDTH, 0),
getCursorInt(cursor, MediaStore.MediaColumns.HEIGHT, 0));
}
private static long getCursorLong(Cursor cursor, String key, long defaultValue) {
int index = cursor.getColumnIndex(key);
long value = defaultValue;
if (index >= 0) {
value = cursor.getLong(index);
}
return value;
}
private static String getCursorString(Cursor cursor, String key, String defaultValue) {
int index = cursor.getColumnIndex(key);
String value = defaultValue;
if (index >= 0) {
value = cursor.getString(index);
}
return value;
}
private static int getCursorInt(Cursor cursor, String key, int defaultValue) {
int index = cursor.getColumnIndex(key);
int value = defaultValue;
if (index >= 0) {
value = cursor.getInt(index);
}
return value;
}
@Override
@@ -99,6 +137,8 @@ public class Item implements Parcelable {
dest.writeParcelable(uri, 0);
dest.writeLong(size);
dest.writeLong(duration);
dest.writeInt(width);
dest.writeInt(height);
}
public Uri getContentUri() {
@@ -134,7 +174,9 @@ public class Item implements Parcelable {
&& (uri != null && uri.equals(other.uri)
|| (uri == null && other.uri == null))
&& size == other.size
&& duration == other.duration;
&& duration == other.duration
&& width == other.width
&& height == other.height;
}
@Override
@@ -147,6 +189,8 @@ public class Item implements Parcelable {
result = 31 * result + uri.hashCode();
result = 31 * result + Long.valueOf(size).hashCode();
result = 31 * result + Long.valueOf(duration).hashCode();
result = 31 * result + Integer.valueOf(width).hashCode();
result = 31 * result + Integer.valueOf(height).hashCode();
return result;
}
}

View File

@@ -39,6 +39,8 @@ public class AlbumMediaLoader extends CursorLoader {
MediaStore.MediaColumns.DISPLAY_NAME,
MediaStore.MediaColumns.MIME_TYPE,
MediaStore.MediaColumns.SIZE,
MediaStore.MediaColumns.WIDTH,
MediaStore.MediaColumns.HEIGHT,
"duration"};
// === params for album ALL && showSingleMediaType: false ===
@@ -143,7 +145,7 @@ public class AlbumMediaLoader extends CursorLoader {
return result;
}
MatrixCursor dummy = new MatrixCursor(PROJECTION);
dummy.addRow(new Object[]{Item.ITEM_ID_CAPTURE, Item.ITEM_DISPLAY_NAME_CAPTURE, "", 0, 0});
dummy.addRow(new Object[]{Item.ITEM_ID_CAPTURE, Item.ITEM_DISPLAY_NAME_CAPTURE, "", 0, 0, 0, 0});
return new MergeCursor(new Cursor[]{dummy, result});
}

View File

@@ -165,6 +165,9 @@ public class SelectedItemCollection {
CustomItem customItem = new CustomItem();
customItem.setPath(PathUtils.getPath(mContext, item.getContentUri()));
customItem.setFileType(item.isGif() ? 1 : 0);
customItem.setWidth(item.width);
customItem.setHeight(item.height);
customItem.setFormat(item.mimeType);
paths.add(customItem);
}
return paths;

View File

@@ -21,6 +21,8 @@ import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.net.Uri;
@@ -250,6 +252,9 @@ public class MatisseActivity extends AppCompatActivity implements
for (Item item : selected) {
selectedUris.add(item.getContentUri());
CustomItem customItem = new CustomItem();
customItem.setFormat(item.mimeType);
customItem.setWidth(item.width);
customItem.setHeight(item.height);
customItem.setFileType(item.isGif() ? 1 : 0);
customItem.setPath(PathUtils.getPath(this, item.getContentUri()));
selectedPaths.add(customItem);
@@ -280,6 +285,7 @@ public class MatisseActivity extends AppCompatActivity implements
CustomItem customItem = new CustomItem();
customItem.setFileType(0);
customItem.setPath(path);
trySetImageInfo(customItem);
selectedPath.add(customItem);
Intent result = new Intent();
result.putParcelableArrayListExtra(EXTRA_RESULT_SELECTION, selected);
@@ -298,6 +304,9 @@ public class MatisseActivity extends AppCompatActivity implements
ArrayList<CustomItem> selectedPath = new ArrayList<>(1);
Item item = selected.get(0);
CustomItem customItem = new CustomItem();
customItem.setFormat(item.mimeType);
customItem.setWidth(item.width);
customItem.setHeight(item.height);
customItem.setFileType(2);
customItem.setPath(item.uri.toString());
selectedPath.add(customItem);
@@ -309,6 +318,26 @@ public class MatisseActivity extends AppCompatActivity implements
}
}
// 补充图片信息
private void trySetImageInfo(CustomItem customItem) {
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap bitmap = BitmapFactory.decodeFile(customItem.getPath(), options);
if (customItem.getWidth() <= 0) {
customItem.setWidth(options.outWidth);
}
if (customItem.getHeight() <= 0) {
customItem.setHeight(options.outHeight);
}
if (customItem.getFormat() == null || customItem.getFormat().length() == 0) {
customItem.setFormat(options.outMimeType);
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void updateBottomToolbar() {
int selectedCount = mSelectedCollection.count();
if (selectedCount == 0) {

View File

@@ -48,9 +48,9 @@ public class PublishPresenter extends BaseMvpPresenter<IPublishView> {
private MiniWorldChooseInfo miniWorldChooseInfo = new MiniWorldChooseInfo();
public void publishDy(List<String> list, long worldId, String content, boolean isOriginalImage) {
public void publishDy(List<DynamicMedia> list, long worldId, String content, boolean isOriginalImage) {
publishBody = new PublishBody();
List<String> uploadList = new ArrayList<>(list);
List<DynamicMedia> uploadList = new ArrayList<>(list);
int type = ListUtils.isListEmpty(uploadList) ? 0 : 2;
publishBody.setType(type);
publishBody.setUid(AuthModel.get().getCurrentUid());
@@ -77,7 +77,7 @@ public class PublishPresenter extends BaseMvpPresenter<IPublishView> {
});
}
private Single<String> uploadImage(List<String> imagePaths) {
private Single<String> uploadImage(List<DynamicMedia> imagePaths) {
upload(imagePaths);
return Single.create(emitter ->
mImageUploadSubscribe = Observable.interval(500, TimeUnit.MILLISECONDS)
@@ -91,22 +91,34 @@ public class PublishPresenter extends BaseMvpPresenter<IPublishView> {
}));
}
private void upload(List<String> imagePaths) {
private void upload(List<DynamicMedia> imagePaths) {
if (imagePaths == null || imagePaths.size() == 0) {
return;
}
String file = imagePaths.get(0);
DynamicMedia item = imagePaths.get(0);
String file = item.getLocalFilePath();
Single.create((SingleOnSubscribe<String>) e -> {
long fileLength = JXFileUtils.getFileLength(file);
LogUtil.print("文件大小:" + fileLength);
String compressFile = null;
if (!isOriginalImage && fileLength > ImageUploadConfig.MAX_FILE_SIZE) {
compressFile = JXImageUtils.compressImagePxAndQuality(
JXImageUtils.CompressResult result = JXImageUtils.compressImagePxAndQuality(
file, DirectoryHelper.get().getDynamicDir(),
"dynamic_" + System.currentTimeMillis() + ".jpg",
ImageUploadConfig.EXPECT_MIN_WIDTH,
ImageUploadConfig.EXPECT_COMPRESS_SIZE);
if (result != null) {
compressFile = result.getPath();
if (result.getWidth() > 0 && item.getWidth() != result.getWidth()) {
item.setWidth(result.getWidth());
}
if (result.getHeight() > 0 && item.getHeight() != result.getHeight()) {
item.setHeight(result.getHeight());
}
if (result.getFormat() != null) {
item.setFormat(result.getFormat());
}
}
LogUtil.print("压缩后:" + compressFile);
}
if (!TextUtils.isEmpty(compressFile)) {
@@ -118,21 +130,22 @@ public class PublishPresenter extends BaseMvpPresenter<IPublishView> {
}
})
.compose(RxHelper.handleSchedulers())
.flatMap((Function<String, SingleSource<DynamicMedia>>)
path -> FileModel.get().uploadFileReturnImageInfo(path))
.flatMap((Function<String, SingleSource<String>>)
path -> FileModel.get().uploadFile(path))
.compose(bindUntilEvent(PresenterEvent.DESTROY))
.subscribe(new DontWarnObserver<DynamicMedia>() {
.subscribe(new DontWarnObserver<String>() {
@Override
public void acceptThrowable(DynamicMedia media, Throwable throwable) {
super.acceptThrowable(media, throwable);
public void acceptThrowable(String url, Throwable throwable) {
super.acceptThrowable(url, throwable);
if (throwable != null) {
if (mImageUploadSubscribe != null) {
mImageUploadSubscribe.dispose();
}
dealUploadFileError(throwable);
} else {
LogUtil.print("上传成功:", media);
publishBody.addDynamicMedia(media);
item.setResUrl(url);
LogUtil.print("上传成功:", item);
publishBody.addDynamicMedia(item);
imagePaths.remove(0);
upload(imagePaths);
}

View File

@@ -337,7 +337,7 @@ public class PublishActivity extends BaseMvpActivity<IPublishView, PublishPresen
tvPublish.setEnabled(false);
getDialogManager().showProgressDialog(context);
getMvpPresenter().publishDy(
ObjectTypeHelper.customToStringList(uploadList),
ObjectTypeHelper.customToMediaList(uploadList),
getMvpPresenter().getWorldId(), etContent.getText().toString(), isOriginalImage);
}
@@ -442,6 +442,7 @@ public class PublishActivity extends BaseMvpActivity<IPublishView, PublishPresen
public void onPublishFailed(Throwable throwable) {
getDialogManager().dismissDialog();
toast(throwable.getMessage());
updatePublishStatus();
}
@Override

View File

@@ -22,6 +22,22 @@ public class ObjectTypeHelper {
return resultList;
}
public static List<DynamicMedia> customToMediaList(List<CustomItem> paramsList) {
List<DynamicMedia> resultList = new ArrayList<>();
if (paramsList == null) {
return resultList;
}
for (CustomItem item : paramsList) {
DynamicMedia media = new DynamicMedia();
media.setLocalFilePath(item.getPath());
media.setWidth(item.getWidth());
media.setHeight(item.getHeight());
media.setFormat(item.getFormat());
resultList.add(media);
}
return resultList;
}
public static List<CustomItem> stringToCustomList(List<String> paramsList) {
List<CustomItem> resultList = new ArrayList<>();
if (paramsList == null) {
@@ -40,6 +56,8 @@ public class ObjectTypeHelper {
}
for (DynamicMedia media : paramsList) {
CustomItem item = new CustomItem();
item.setWidth(media.getWidth());
item.setHeight(media.getHeight());
item.setPath(media.getResUrl());
item.setFileType(CustomItem.UNKOWN);
if (media.isJpgOrPng()) {

View File

@@ -100,6 +100,7 @@ dependencies {
api 'com.alipay.sdk:alipaysdk-android:+@aar'
api 'com.qcloud.cos:cos-android:5.9.23'
}
repositories {
mavenCentral()

View File

@@ -2158,6 +2158,9 @@ public final class IMNetEaseManager {
PkModel.get().syncPkList(userInfo, chatRoomMember.getGroupType());
noticePKInfo();
int oldMicPosition = AvRoomDataManager.get().getMicPosition(AuthModel.get().getCurrentUid());
boolean oldIsOnMic = AvRoomDataManager.get().isOwnerOnMic();
int size = mMicQueueMemberMap.size();
if (size > 0) {
for (int j = 0; j < size; j++) {
@@ -2201,7 +2204,14 @@ public final class IMNetEaseManager {
//开麦
AudioEngineManager.get().setRole(Constants.CLIENT_ROLE_BROADCASTER);
if (!roomQueueInfo.mChatRoomMember.isNoProhibitMic()) {
AudioEngineManager.get().setMute(roomQueueInfo.mRoomMicInfo.isMicMute() || AvRoomDataManager.get().mIsNeedOpenMic);
/*
修复相亲房自动闭麦bug
原因:相亲房的某些麦位状态更新,走的是上麦通道,导致默认闭麦了
临时解决:若是相亲房且之前在麦或麦位没变化->不做闭麦操作
*/
if (!AvRoomDataManager.get().isDatingMode() || (AvRoomDataManager.get().isDatingMode() && (!oldIsOnMic || oldMicPosition != micPosition))) {
AudioEngineManager.get().setMute(roomQueueInfo.mRoomMicInfo.isMicMute() || AvRoomDataManager.get().mIsNeedOpenMic);
}
}
}
noticeUpMic(Integer.parseInt(key), chatRoomMember.getAccount());

View File

@@ -2,22 +2,19 @@ package com.nnbc123.core.file;
import android.text.TextUtils;
import com.netease.nim.uikit.common.util.log.LogUtil;
import com.qiniu.android.common.FixedZone;
import com.qiniu.android.storage.Configuration;
import com.qiniu.android.storage.UploadManager;
import com.chuhai.utils.AppUtils;
import com.chuhai.utils.PathUtils;
import com.nnbc123.core.file.cos.CosClient;
import com.nnbc123.core.file.cos.CosToken;
import com.nnbc123.core.base.BaseModel;
import com.nnbc123.core.bean.response.ServiceResult;
import com.nnbc123.core.community.bean.DynamicMedia;
import com.nnbc123.core.exception.ErrorThrowable;
import com.nnbc123.core.utils.net.RxHelper;
import com.nnbc123.library.net.rxnet.RxNet;
import org.json.JSONObject;
import java.io.File;
import java.util.UUID;
import io.reactivex.Single;
import io.reactivex.android.schedulers.AndroidSchedulers;
import retrofit2.http.GET;
public class FileModel extends BaseModel implements IFileModel {
@@ -27,119 +24,50 @@ public class FileModel extends BaseModel implements IFileModel {
}
private FileModel() {
Configuration config = new Configuration.Builder()
.zone(FixedZone.zone2) // 设置区域不指定会自动选择。指定不同区域的上传域名、备用域名、备用IP。
.build();
uploadManager = new UploadManager(config);
}
public static FileModel get() {
return Helper.INSTANCE;
}
private UploadManager uploadManager;
private final Api api = RxNet.create(Api.class);
private CosToken cosToken;
private Single<CosToken> getCosToken() {
if (cosToken != null && cosToken.isValid()) {
return Single.just(cosToken);
} else {
return api.getCosToken().compose(RxHelper.handleSchedulers())
.compose(RxHelper.handleBeanData()).map(cosToken -> {
FileModel.get().cosToken = cosToken;
return cosToken;
});
}
}
@Override
public Single<String> uploadFile(String path) {
File file;
if (TextUtils.isEmpty(path) || !((file = new File(path)).exists())) {
return Single.error(new ErrorThrowable(path + " 为空或者该文件不存在!"));
}
File finalFile = file;
return api.getUploadToken()
.compose(RxHelper.handleSchedulers())
.compose(RxHelper.handleBeanData())
.flatMap(uploadToken -> Single.create(singleEmitter ->
uploadManager.put(finalFile, uploadToken.getKey(), uploadToken.getToken(),
(key, info, response) -> {
if (info.isOK()) {
try {
String imgUrl = response.getString("path");
singleEmitter.onSuccess(imgUrl);
} catch (Exception e) {
singleEmitter.onError(e);
}
} else {
singleEmitter.onError(new Throwable(info.error));
}
}, null)));
String outName = UUID.randomUUID().toString() + PathUtils.INSTANCE.getSuffixType(finalFile.getName());
return getCosToken().flatMap(token -> CosClient.INSTANCE.upload(AppUtils.getApp(), finalFile, outName, token).map(cosXmlResult -> cosXmlResult.accessUrl))
.observeOn(AndroidSchedulers.mainThread());
}
@Override
public Single<DynamicMedia> uploadFileReturnImageInfo(String path) {
return uploadFileReturnImageInfo(path, null);
}
@Override
public Single<DynamicMedia> uploadFileReturnImageInfo(String path, String qiniuName) {
File file;
if (TextUtils.isEmpty(path) || !((file = new File(path)).exists())) {
return Single.error(new ErrorThrowable(path + " 为空或者该文件不存在!"));
}
File finalFile = file;
return api.getUploadToken()
.compose(RxHelper.handleSchedulers())
.compose(RxHelper.handleBeanData())
.flatMap(uploadToken -> Single.create(singleEmitter ->
uploadManager.put(finalFile, uploadToken.getKey(), uploadToken.getToken(),
(key, info, response) -> {
if (info.isOK()) {
try {
LogUtil.print("上传成功");
LogUtil.print(response);
DynamicMedia media = responseToMeia(response);
if (media != null) {
singleEmitter.onSuccess(media);
return;
}
} catch (Exception e) {
e.printStackTrace();
}
singleEmitter.onError(new Throwable("qiniu json error"));
} else {
singleEmitter.onError(new Throwable(info.error));
}
}, null)));
}
@Override
public Single<String> downloadFile(String url) {
return null;
}
private DynamicMedia responseToMeia(JSONObject response) {
DynamicMedia media = new DynamicMedia();
try {
String imgNamePath = response.getString("path");
media.setResUrl(imgNamePath);
} catch (Exception ex) {
ex.printStackTrace();
return null;
}
try {
media.setFormat(response.getString("format"));
media.setWidth(response.getInt("w"));
media.setHeight(response.getInt("h"));
} catch (Exception ex) {
ex.printStackTrace();
}
LogUtil.print("七牛上传", media);
return media;
}
interface Api {
/**
* 获取钱包
*
* @return
*/
@GET("/qiniu/upload/getUploadToken")
Single<ServiceResult<UploadToken>> getUploadToken();
@GET("/tencent/cos/getToken")
Single<ServiceResult<CosToken>> getCosToken();
}
}

View File

@@ -23,8 +23,4 @@ public interface IFileModel extends IModel {
*/
Single<String> downloadFile(String url);
Single<DynamicMedia> uploadFileReturnImageInfo(String path);
Single<DynamicMedia> uploadFileReturnImageInfo(String path, String qiniuName);
}

View File

@@ -1,71 +0,0 @@
package com.nnbc123.core.file;
public class UploadToken {
private String key;
private String token;
//<editor-fold defaultstate="collapsed" desc="delombok">
@SuppressWarnings("all")
public UploadToken() {
}
@SuppressWarnings("all")
public String getKey() {
return this.key;
}
@SuppressWarnings("all")
public String getToken() {
return this.token;
}
@SuppressWarnings("all")
public void setKey(final String key) {
this.key = key;
}
@SuppressWarnings("all")
public void setToken(final String token) {
this.token = token;
}
@Override
@SuppressWarnings("all")
public boolean equals(final Object o) {
if (o == this) return true;
if (!(o instanceof UploadToken)) return false;
final UploadToken other = (UploadToken) o;
if (!other.canEqual((Object) this)) return false;
final Object this$key = this.getKey();
final Object other$key = other.getKey();
if (this$key == null ? other$key != null : !this$key.equals(other$key)) return false;
final Object this$token = this.getToken();
final Object other$token = other.getToken();
if (this$token == null ? other$token != null : !this$token.equals(other$token)) return false;
return true;
}
@SuppressWarnings("all")
protected boolean canEqual(final Object other) {
return other instanceof UploadToken;
}
@Override
@SuppressWarnings("all")
public int hashCode() {
final int PRIME = 59;
int result = 1;
final Object $key = this.getKey();
result = result * PRIME + ($key == null ? 43 : $key.hashCode());
final Object $token = this.getToken();
result = result * PRIME + ($token == null ? 43 : $token.hashCode());
return result;
}
@Override
@SuppressWarnings("all")
public String toString() {
return "UploadToken(key=" + this.getKey() + ", token=" + this.getToken() + ")";
}
//</editor-fold>
}

View File

@@ -0,0 +1,131 @@
package com.nnbc123.core.file.cos
import android.content.Context
import android.net.Uri
import android.util.Log
import com.nnbc123.core.Env
import com.tencent.cos.xml.CosXmlService
import com.tencent.cos.xml.CosXmlServiceConfig
import com.tencent.cos.xml.exception.CosXmlClientException
import com.tencent.cos.xml.exception.CosXmlServiceException
import com.tencent.cos.xml.listener.CosXmlResultListener
import com.tencent.cos.xml.model.CosXmlRequest
import com.tencent.cos.xml.model.CosXmlResult
import com.tencent.cos.xml.transfer.COSXMLUploadTask
import com.tencent.cos.xml.transfer.TransferConfig
import com.tencent.cos.xml.transfer.TransferManager
import io.reactivex.Single
import java.io.File
/**
* Created by Max on 2024/1/16 11:09
* Desc:
**/
object CosClient {
private var cosXmlClient: CosXmlService? = null
private var credentialProvider: CosCredentialProvider? = null
private fun getCosXmlClient(context: Context, token: CosToken): CosXmlService {
var client = this.cosXmlClient
if (client != null && credentialProvider != null) {
credentialProvider?.updateCredentials(token.toCredential())
return client
}
// 创建 CosXmlServiceConfig 对象,根据需要修改默认的配置参数
val serviceConfig: CosXmlServiceConfig = CosXmlServiceConfig.Builder()
.setRegion(token.region)
.isHttps(true) // 使用 HTTPS 请求, 默认为 HTTP 请求
.builder()
val credentials = token.toCredential()
credentialProvider = CosCredentialProvider(credentials)
// 初始化 COS Service获取实例
client = CosXmlService(
context,
serviceConfig, credentialProvider
)
cosXmlClient = client
return client
}
/**
* 上传文件
* @param outName 远端文件名
*/
fun upload(
context: Context,
file: File,
outName: String,
token: CosToken
): Single<CosXmlResult> {
if (Env.isDebug()) {
Log.e("CosClient", "upload file:${file.absolutePath} outName:${outName}")
}
return Single.create {
uploadFile(context, file, outName, token).apply {
setCosXmlResultListener(object : CosXmlResultListener {
override fun onSuccess(request: CosXmlRequest?, result: CosXmlResult) {
transformDomain(result, token)
if (Env.isDebug()) {
Log.e("CosClient", "upload onSuccess result:${result.accessUrl}")
}
it.onSuccess(result)
}
override fun onFail(
request: CosXmlRequest?,
clientException: CosXmlClientException?,
serviceException: CosXmlServiceException?
) {
if (Env.isDebug()) {
Log.e("CosClient", "upload onFail clientException:$clientException")
Log.e("CosClient", "upload onFail serviceException:$serviceException")
}
it.onError(CosException(clientException, serviceException))
}
})
}
}
}
private fun transformDomain(result: CosXmlResult, token: CosToken) {
try {
if (result.accessUrl.isNullOrEmpty()) {
return
}
if (token.customDomain.isNullOrEmpty()) {
return
}
val newUri = Uri.parse(token.customDomain)
result.accessUrl = Uri.parse(result.accessUrl).buildUpon().scheme(newUri.scheme)
.authority(newUri.authority).build().toString()
} catch (e: Exception) {
e.printStackTrace()
}
}
/**
* 上传文件
* @param outName 远端文件名
*/
private fun uploadFile(
context: Context,
file: File,
outName: String,
token: CosToken
): COSXMLUploadTask {
val cosXmlService = getCosXmlClient(context, token)
// 初始化 TransferConfig这里使用默认配置如果需要定制请参考 SDK 接口文档
val transferConfig = TransferConfig.Builder().build()
// 初始化 TransferManager
val transferManager = TransferManager(
cosXmlService,
transferConfig
)
return transferManager.upload(
token.bucket, outName,
file.absolutePath, null
)
}
}

View File

@@ -0,0 +1,20 @@
package com.nnbc123.core.file.cos
import com.tencent.qcloud.core.auth.BasicLifecycleCredentialProvider
import com.tencent.qcloud.core.auth.QCloudLifecycleCredentials
/**
* Created by Max on 2024/1/16 11:28
* Desc:
**/
class CosCredentialProvider(private var credentials: QCloudLifecycleCredentials) :
BasicLifecycleCredentialProvider() {
fun updateCredentials(credentials: QCloudLifecycleCredentials) {
this.credentials = credentials
}
override fun fetchNewCredentials(): QCloudLifecycleCredentials {
return credentials
}
}

View File

@@ -0,0 +1,21 @@
package com.nnbc123.core.file.cos
import com.tencent.cos.xml.exception.CosXmlClientException
import com.tencent.cos.xml.exception.CosXmlServiceException
/**
* Created by Max on 2024/1/16 15:49
* Desc:
**/
class CosException : Exception {
var clientException: CosXmlClientException? = null
var serviceException: CosXmlServiceException? = null
constructor(
clientException: CosXmlClientException?,
serviceException: CosXmlServiceException?
) : super(clientException ?: serviceException) {
this.clientException = clientException
this.serviceException = serviceException
}
}

View File

@@ -0,0 +1,44 @@
package com.nnbc123.core.file.cos
import com.nnbc123.core.utils.CurrentTimeUtils
import com.tencent.qcloud.core.auth.QCloudLifecycleCredentials
import com.tencent.qcloud.core.auth.SessionQCloudCredentials
/**
* Created by Max on 2024/1/16 11:44
* Desc:
**/
data class CosToken(
val secretId: String?,
val secretKey: String?,
val sessionToken: String?,
val bucket: String?,
val region: String?,
val startTime: Long?,
val expireTime: Long?,
val customDomain: String?
) {
/**
* 是否有效
*/
fun isValid(): Boolean {
if (expireTime == null) {
return false
}
val currentTime = CurrentTimeUtils.getCurrentTime() / 1000
// 预留一点安全时长
var safeTime = 30
if (safeTime >= (expireTime - (startTime ?: 0))) {
safeTime = 0
}
return currentTime <= (expireTime - safeTime)
}
fun toCredential(): QCloudLifecycleCredentials {
return SessionQCloudCredentials(
secretId ?: "", secretKey ?: "",
sessionToken ?: "", startTime ?: 0, expireTime ?: 0
)
}
}

View File

@@ -239,6 +239,8 @@ public interface IUserModel extends IModel {
Single<ServiceResult> deleteInRoomRecord(@Nullable String roomUid);
Single<ServiceResult> refillInviteCode(@Nullable String inviteCode);
/**
* 随机头像昵称开关
*/

View File

@@ -793,6 +793,12 @@ public final class UserModel extends BaseModel implements IUserModel {
.compose(RxHelper.handleSchAndExce());
}
@Override
public Single<ServiceResult> refillInviteCode(@Nullable String inviteCode) {
return api.refillInviteCode(inviteCode)
.compose(RxHelper.handleSchAndExce());
}
/**
* 随机头像昵称开关
*/
@@ -1106,5 +1112,9 @@ public final class UserModel extends BaseModel implements IUserModel {
@GET("/uservisitrecord/visitUserList")
Single<ServiceResult<List<VisitorInfo>>> getVisitorUserList(@Query("pageNum") int pageNum,
@Query("pageSize") int pageSize);
@FormUrlEncoded
@POST("/inviteCode/refillInviteCode")
Single<ServiceResult<String>> refillInviteCode(@Field("inviteCode") String inviteCode);
}
}

View File

@@ -228,6 +228,17 @@ public class UserInfo implements Serializable {
private boolean voicePlaying;
private boolean lock;
// 是否可以补填邀请码
private boolean canRefillInviteCode;
public boolean isCanRefillInviteCode() {
return canRefillInviteCode;
}
public void setCanRefillInviteCode(boolean canRefillInviteCode) {
this.canRefillInviteCode = canRefillInviteCode;
}
public boolean isLock() {
return lock;
}

View File

@@ -1,10 +0,0 @@
package com.nnbc123.core.utils;
/**
* create by lvzebiao @2019/11/20
*/
public class UploadUtils {
}

View File

@@ -2,6 +2,8 @@ package com.nnbc123.core.community.bean;
import android.text.TextUtils;
import kotlin.jvm.Transient;
/**
* create by lvzebiao @2019/11/21
*/
@@ -21,6 +23,17 @@ public class DynamicMedia {
private int width;
private int height;
@Transient
private String localFilePath;
public String getLocalFilePath() {
return localFilePath;
}
public void setLocalFilePath(String localFilePath) {
this.localFilePath = localFilePath;
}
/**
* 是否是网络图片
* @return -
@@ -38,14 +51,14 @@ public class DynamicMedia {
if (TextUtils.isEmpty(format)) {
return false;
}
return format.toLowerCase().equals("jpeg") || format.toLowerCase().equals("jpg") || format.toLowerCase().equals("png");
return format.toLowerCase().contains("jpeg") || format.toLowerCase().contains("jpg") || format.toLowerCase().contains("png");
}
public boolean isGif() {
if (TextUtils.isEmpty(format)) {
return false;
}
return format.toLowerCase().equals("gif");
return format.toLowerCase().contains("gif");
}
//<editor-fold defaultstate="collapsed" desc="delombok">

View File

@@ -6,8 +6,11 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx4096m -XX:MaxPermSize=2048m
org.gradle.daemon=true
org.gradle.jvmargs=-Xmx4096m \
--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
@@ -28,5 +31,6 @@ COMPILE_SDK_VERSION=32
MIN_SDK_VERSION=21
TARGET_SDK_VERSION=32
version_name=2.0.0
version_code=2000
version_name=2.1.6
version_code=2106
minify_enabled=false

View File

@@ -116,8 +116,6 @@ dependencies {
api "com.orhanobut:logger:${loggerVersion}"
api "com.qiniu:qiniu-android-sdk:${qiniu}"
api "org.greenrobot:eventbus:${eventbusVersion}"
api "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"

View File

@@ -19,6 +19,7 @@ import android.graphics.RectF;
import android.media.ExifInterface;
import android.util.Log;
import com.nnbc123.library.utils.LogUtil;
import com.nnbc123.library.utils.StringUtils;
import com.nnbc123.library.utils.file.JXFileUtils;
@@ -690,78 +691,79 @@ public class JXImageUtils {
return baos.toByteArray();
}
public static CompressResult compressImagePxAndQuality(String inPath, File outDir, String outFileName, int expectWidth, long expectSize) {
try {
if (outDir == null) {
return null;
}
if (!outDir.exists()) {
//创建目录
outDir.mkdirs();
}
if (!outDir.exists()) {
return null;
}
public static String compressImagePxAndQuality(String inPath, File outDir, String outFileName, int expectWidth, long expectSize) {
try {
if (outDir == null) {
return null;
}
if (!outDir.exists()) {
//创建目录
outDir.mkdirs();
}
if (!outDir.exists()) {
return null;
}
//读取原图的旋转角度,并写入到压缩图片中
ExifInterface exif = new ExifInterface(inPath);
String orientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
LogUtil.print("原图:" + inPath);
// LogUtil.print("原图旋转角度:" + getPicRotate(inPath));
//读取原图的旋转角度,并写入到压缩图片中
ExifInterface exif = new ExifInterface(inPath);
String orientation = exif.getAttribute(ExifInterface.TAG_ORIENTATION);
LogUtil.print("原图:" + inPath);
LogUtil.print("原图旋转角度:" + getPicRotate(inPath));
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inPreferredConfig = Config.RGB_565;
bmOptions.inSampleSize = getExpectInSampleSize(inPath, expectWidth);
Bitmap bitmap = BitmapFactory.decodeFile(inPath, bmOptions);
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inPreferredConfig = Config.RGB_565;
bmOptions.inSampleSize = getExpectInSampleSize(inPath, expectWidth);
Bitmap bitmap = BitmapFactory.decodeFile(inPath, bmOptions);
LogUtil.print("宽高," + bitmap.getWidth() + "," + bitmap.getHeight());
LogUtil.print("宽高," + bitmap.getWidth() + "," + bitmap.getHeight());
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int options = 100;
int minQuality = 20;
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//质量压缩方法把压缩后的数据存放到baos中 (100表示不压缩0表示压缩到最小)
Log.e("mouse_debug", "压缩前质量:" + baos.toByteArray().length);
while (baos.toByteArray().length > expectSize) {//循环判断如果压缩后图片是否大于指定大小,大于继续压缩
baos.reset();//重置baos即让下一次的写入覆盖之前的内容
options -= 5;//图片质量每次减少5
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int options = 100;
int minQuality = 20;
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//质量压缩方法把压缩后的数据存放到baos中 (100表示不压缩0表示压缩到最小)
Log.e("mouse_debug", "压缩前质量:" + baos.toByteArray().length);
while (baos.toByteArray().length > expectSize) {//循环判断如果压缩后图片是否大于指定大小,大于继续压缩
baos.reset();//重置baos即让下一次的写入覆盖之前的内容
options -= 5;//图片质量每次减少5
if (options <= minQuality) options = minQuality;//如果图片质量小于5为保证压缩后的图片质量图片最底压缩质量为5
LogUtil.print("压缩参数:" + options);
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//将压缩后的图片保存到baos中
if (options == minQuality) break;//如果图片的质量已降到最低则,不再进行压缩
}
if (!bitmap.isRecycled()) {
bitmap.recycle();//回收内存中的图片
}
if (options <= minQuality) options = minQuality;//如果图片质量小于5为保证压缩后的图片质量图片最底压缩质量为5
LogUtil.print("压缩参数:" + options);
bitmap.compress(Bitmap.CompressFormat.JPEG, options, baos);//将压缩后的图片保存到baos中
if (options == minQuality) break;//如果图片的质量已降到最低则,不再进行压缩
}
if (!bitmap.isRecycled()) {
bitmap.recycle();//回收内存中的图片
}
File thumbnailFile = new File(outDir, outFileName);
if (thumbnailFile.exists()) {
thumbnailFile.delete();
}
thumbnailFile.createNewFile();
FileOutputStream fos = new FileOutputStream(thumbnailFile);//将压缩后的图片保存的本地上指定路径中
fos.write(baos.toByteArray());
fos.flush();
fos.close();
if (thumbnailFile.exists()) {
String compressPath = thumbnailFile.getPath();
if (orientation != null) {
exif = new ExifInterface(compressPath);
exif.setAttribute(ExifInterface.TAG_ORIENTATION, orientation);
exif.saveAttributes();
}
LogUtil.print("压缩图旋转角度:" + getPicRotate(compressPath));
return compressPath;
}
} catch (Exception ex) {
Log.e("mouse_debug", "压缩失败...");
ex.printStackTrace();
} catch (OutOfMemoryError error) {
LogUtil.print("压缩图片OOM了");
}
return null;
}
File thumbnailFile = new File(outDir, outFileName);
if (thumbnailFile.exists()) {
thumbnailFile.delete();
}
thumbnailFile.createNewFile();
FileOutputStream fos = new FileOutputStream(thumbnailFile);//将压缩后的图片保存的本地上指定路径中
fos.write(baos.toByteArray());
fos.flush();
fos.close();
if (thumbnailFile.exists()) {
String compressPath = thumbnailFile.getPath();
exif = new ExifInterface(compressPath);
if (orientation != null) {
exif.setAttribute(ExifInterface.TAG_ORIENTATION, orientation);
exif.saveAttributes();
}
int width = exif.getAttributeInt(ExifInterface.TAG_IMAGE_WIDTH, 0);
int height = exif.getAttributeInt(ExifInterface.TAG_IMAGE_LENGTH, 0);
// LogUtil.print("压缩图旋转角度:" + getPicRotate(compressPath));
return new CompressResult(compressPath, width, height, "image/jpeg");
}
} catch (Exception ex) {
Log.e("mouse_debug", "压缩失败...");
ex.printStackTrace();
} catch (OutOfMemoryError error) {
LogUtil.print("压缩图片OOM了");
}
return null;
}
public static int getExpectInSampleSize(String path, int expectWidth) {
//先获取图片旋转角度如果是90或者270°则以高作为参考值否则以宽作为参考值
@@ -814,5 +816,33 @@ public class JXImageUtils {
return degree;
}
public static class CompressResult {
private String path;
private int width;
private int height;
private String format;
public CompressResult(String path, int width, int height, String format) {
this.path = path;
this.width = width;
this.height = height;
this.format = format;
}
public String getPath() {
return path;
}
public int getWidth() {
return width;
}
public int getHeight() {
return height;
}
public String getFormat() {
return format;
}
}
}

View File

@@ -5,8 +5,9 @@ import android.net.Uri;
import android.os.Environment;
import android.text.TextUtils;
import androidx.core.text.TextUtilsCompat;
import com.nnbc123.library.utils.FP;
import com.qiniu.android.utils.StringUtils;
import com.nnbc123.library.common.application.BaseApp;
import com.nnbc123.library.common.util.Logger;
@@ -877,41 +878,4 @@ public class FileHelper {
}
return content;
}
/**
* 文件转换成字符串
*
* @param filePath 文件路径
* @return 字符串内容
*/
public static String getTxtFileContent(String filePath) {
String content = "";
if (!StringUtils.isNullOrEmpty(filePath)) {
File file = new File(filePath);
if (file.isFile()) {
FileInputStream inputStream = null;
try {
inputStream = new FileInputStream(file);
String line;
StringBuilder sb = new StringBuilder();
BufferedReader buffReader = new BufferedReader(new InputStreamReader(inputStream));
while ((line = buffReader.readLine()) != null) {
sb.append(line).append("\n");
}
content = sb.toString();
} catch (Exception e) {
Logger.error(TAG, "getTxtFileContent read fail, e = " + e);
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (Exception ignore) {
}
}
}
}
}
return content;
}
}

View File

@@ -45,451 +45,475 @@ import java.io.File
* 路径 工具类 By https://github.com/Blankj/AndroidUtilCode -> PathUtils.java
* Created by Max on 2018/12/12.
*/
class PathUtils private constructor() {
init {
throw UnsupportedOperationException("u can't instantiate me...")
object PathUtils {
/**
* Return the path of /system.
*
* @return the path of /system
*/
val rootPath: String
get() = Environment.getRootDirectory().absolutePath
/**
* Return the path of /data.
*
* @return the path of /data
*/
val dataPath: String
get() = Environment.getDataDirectory().absolutePath
/**
* Return the path of /cache.
*
* @return the path of /cache
*/
val downloadCachePath: String
get() = Environment.getDownloadCacheDirectory().absolutePath
/**
* Return the path of /data/data/package.
*
* @return the path of /data/data/package
*/
fun getInternalAppDataPath(application: Application): String {
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
application.applicationInfo.dataDir
} else application.dataDir.absolutePath
}
companion object {
/**
* Return the path of /system.
*
* @return the path of /system
*/
val rootPath: String
get() = Environment.getRootDirectory().absolutePath
/**
* Return the path of /data/data/package/code_cache.
*
* @return the path of /data/data/package/code_cache
*/
fun getInternalAppCodeCacheDir(application: Application): String {
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
application.applicationInfo.dataDir + "/code_cache"
} else application.codeCacheDir.absolutePath
}
/**
* Return the path of /data.
*
* @return the path of /data
*/
val dataPath: String
get() = Environment.getDataDirectory().absolutePath
/**
* Return the path of /data/data/package/cache.
*
* @return the path of /data/data/package/cache
*/
fun getInternalAppCachePath(application: Application): String {
return application.cacheDir.absolutePath
}
/**
* Return the path of /cache.
*
* @return the path of /cache
*/
val downloadCachePath: String
get() = Environment.getDownloadCacheDirectory().absolutePath
/**
* Return the path of /data/data/package/databases.
*
* @return the path of /data/data/package/databases
*/
fun getInternalAppDbsPath(application: Application): String {
return application.applicationInfo.dataDir + "/databases"
}
/**
* Return the path of /data/data/package.
*
* @return the path of /data/data/package
*/
fun getInternalAppDataPath(application: Application): String {
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
application.applicationInfo.dataDir
} else application.dataDir.absolutePath
}
/**
* Return the path of /data/data/package/databases/name.
*
* @param name The name of database.
* @return the path of /data/data/package/databases/name
*/
fun getInternalAppDbPath(application: Application, name: String?): String {
return application.getDatabasePath(name).absolutePath
}
/**
* Return the path of /data/data/package/code_cache.
*
* @return the path of /data/data/package/code_cache
*/
fun getInternalAppCodeCacheDir(application: Application): String {
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
application.applicationInfo.dataDir + "/code_cache"
} else application.codeCacheDir.absolutePath
}
/**
* Return the path of /data/data/package/files.
*
* @return the path of /data/data/package/files
*/
fun getInternalAppFilesPath(application: Application): String {
return application.filesDir.absolutePath
}
/**
* Return the path of /data/data/package/cache.
*
* @return the path of /data/data/package/cache
*/
fun getInternalAppCachePath(application: Application): String {
return application.cacheDir.absolutePath
}
/**
* Return the path of /data/data/package/shared_prefs.
*
* @return the path of /data/data/package/shared_prefs
*/
fun getInternalAppSpPath(application: Application): String {
return application.applicationInfo.dataDir + "shared_prefs"
}
/**
* Return the path of /data/data/package/databases.
*
* @return the path of /data/data/package/databases
*/
fun getInternalAppDbsPath(application: Application): String {
return application.applicationInfo.dataDir + "/databases"
}
/**
* Return the path of /data/data/package/no_backup.
*
* @return the path of /data/data/package/no_backup
*/
fun getInternalAppNoBackupFilesPath(application: Application): String {
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
application.applicationInfo.dataDir + "no_backup"
} else application.noBackupFilesDir.absolutePath
}
/**
* Return the path of /data/data/package/databases/name.
*
* @param name The name of database.
* @return the path of /data/data/package/databases/name
*/
fun getInternalAppDbPath(application: Application, name: String?): String {
return application.getDatabasePath(name).absolutePath
}
/**
* Return the path of /storage/emulated/0.
*
* @return the path of /storage/emulated/0
*/
val externalStoragePath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStorageDirectory().absolutePath
/**
* Return the path of /data/data/package/files.
*
* @return the path of /data/data/package/files
*/
fun getInternalAppFilesPath(application: Application): String {
return application.filesDir.absolutePath
}
/**
* Return the path of /storage/emulated/0/Music.
*
* @return the path of /storage/emulated/0/Music
*/
val externalMusicPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MUSIC
).absolutePath
/**
* Return the path of /data/data/package/shared_prefs.
*
* @return the path of /data/data/package/shared_prefs
*/
fun getInternalAppSpPath(application: Application): String {
return application.applicationInfo.dataDir + "shared_prefs"
}
/**
* Return the path of /storage/emulated/0/Podcasts.
*
* @return the path of /storage/emulated/0/Podcasts
*/
val externalPodcastsPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PODCASTS
).absolutePath
/**
* Return the path of /data/data/package/no_backup.
*
* @return the path of /data/data/package/no_backup
*/
fun getInternalAppNoBackupFilesPath(application: Application): String {
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
application.applicationInfo.dataDir + "no_backup"
} else application.noBackupFilesDir.absolutePath
}
/**
* Return the path of /storage/emulated/0/Ringtones.
*
* @return the path of /storage/emulated/0/Ringtones
*/
val externalRingtonesPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_RINGTONES
).absolutePath
/**
* Return the path of /storage/emulated/0.
*
* @return the path of /storage/emulated/0
*/
val externalStoragePath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStorageDirectory().absolutePath
/**
* Return the path of /storage/emulated/0/Alarms.
*
* @return the path of /storage/emulated/0/Alarms
*/
val externalAlarmsPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_ALARMS
).absolutePath
/**
* Return the path of /storage/emulated/0/Music.
*
* @return the path of /storage/emulated/0/Music
*/
val externalMusicPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MUSIC
).absolutePath
/**
* Return the path of /storage/emulated/0/Notifications.
*
* @return the path of /storage/emulated/0/Notifications
*/
val externalNotificationsPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_NOTIFICATIONS
).absolutePath
/**
* Return the path of /storage/emulated/0/Podcasts.
*
* @return the path of /storage/emulated/0/Podcasts
*/
val externalPodcastsPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PODCASTS
).absolutePath
/**
* Return the path of /storage/emulated/0/Pictures.
*
* @return the path of /storage/emulated/0/Pictures
*/
val externalPicturesPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES
).absolutePath
/**
* Return the path of /storage/emulated/0/Ringtones.
*
* @return the path of /storage/emulated/0/Ringtones
*/
val externalRingtonesPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_RINGTONES
).absolutePath
/**
* Return the path of /storage/emulated/0/Movies.
*
* @return the path of /storage/emulated/0/Movies
*/
val externalMoviesPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
).absolutePath
/**
* Return the path of /storage/emulated/0/Alarms.
*
* @return the path of /storage/emulated/0/Alarms
*/
val externalAlarmsPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_ALARMS
).absolutePath
/**
* Return the path of /storage/emulated/0/Download.
*
* @return the path of /storage/emulated/0/Download
*/
val externalDownloadsPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS
).absolutePath
/**
* Return the path of /storage/emulated/0/Notifications.
*
* @return the path of /storage/emulated/0/Notifications
*/
val externalNotificationsPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_NOTIFICATIONS
).absolutePath
/**
* Return the path of /storage/emulated/0/DCIM.
*
* @return the path of /storage/emulated/0/DCIM
*/
val externalDcimPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM
).absolutePath
/**
* Return the path of /storage/emulated/0/Pictures.
*
* @return the path of /storage/emulated/0/Pictures
*/
val externalPicturesPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES
).absolutePath
/**
* Return the path of /storage/emulated/0/Movies.
*
* @return the path of /storage/emulated/0/Movies
*/
val externalMoviesPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_MOVIES
).absolutePath
/**
* Return the path of /storage/emulated/0/Download.
*
* @return the path of /storage/emulated/0/Download
*/
val externalDownloadsPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOWNLOADS
).absolutePath
/**
* Return the path of /storage/emulated/0/DCIM.
*
* @return the path of /storage/emulated/0/DCIM
*/
val externalDcimPath: String?
get() = if (isExternalStorageDisable) null else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DCIM
).absolutePath
/**
* Return the path of /storage/emulated/0/Documents.
*
* @return the path of /storage/emulated/0/Documents
*/
val externalDocumentsPath: String?
get() {
if (isExternalStorageDisable) return null
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
Environment.getExternalStorageDirectory().absolutePath + "/Documents"
} else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOCUMENTS
).absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package.
*
* @return the path of /storage/emulated/0/Android/data/package
*/
fun getExternalAppDataPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.externalCacheDir?.parentFile?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/cache.
*
* @return the path of /storage/emulated/0/Android/data/package/cache
*/
fun getExternalAppCachePath(application: Application): String? {
return if (isExternalStorageDisable) null else application.externalCacheDir?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files.
*
* @return the path of /storage/emulated/0/Android/data/package/files
*/
fun getExternalAppFilesPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(null)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Music.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Music
*/
fun getExternalAppMusicPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_MUSIC
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Podcasts.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Podcasts
*/
fun getExternalAppPodcastsPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_PODCASTS
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Ringtones.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Ringtones
*/
fun getExternalAppRingtonesPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_RINGTONES
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Alarms.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Alarms
*/
fun getExternalAppAlarmsPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_ALARMS
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Notifications.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Notifications
*/
fun getExternalAppNotificationsPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_NOTIFICATIONS
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Pictures.
*
* @return path of /storage/emulated/0/Android/data/package/files/Pictures
*/
fun getExternalAppPicturesPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_PICTURES
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Movies.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Movies
*/
fun getExternalAppMoviesPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_MOVIES
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Download.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Download
*/
fun getExternalAppDownloadPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_DOWNLOADS
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/DCIM.
*
* @return the path of /storage/emulated/0/Android/data/package/files/DCIM
*/
fun getExternalAppDcimPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_DCIM
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Documents.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Documents
*/
fun getExternalAppDocumentsPath(application: Application): String? {
/**
* Return the path of /storage/emulated/0/Documents.
*
* @return the path of /storage/emulated/0/Documents
*/
val externalDocumentsPath: String?
get() {
if (isExternalStorageDisable) return null
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
application.getExternalFilesDir(null)?.absolutePath + "/Documents"
} else application.getExternalFilesDir(
Environment.getExternalStorageDirectory().absolutePath + "/Documents"
} else Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOCUMENTS
)?.absolutePath
).absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/obb/package.
*
* @return the path of /storage/emulated/0/Android/obb/package
*/
fun getExternalAppObbPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.obbDir.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package.
*
* @return the path of /storage/emulated/0/Android/data/package
*/
fun getExternalAppDataPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.externalCacheDir?.parentFile?.absolutePath
}
private val isExternalStorageDisable: Boolean
private get() = Environment.MEDIA_MOUNTED != Environment.getExternalStorageState()
/**
* Return the path of /storage/emulated/0/Android/data/package/cache.
*
* @return the path of /storage/emulated/0/Android/data/package/cache
*/
fun getExternalAppCachePath(application: Application): String? {
return if (isExternalStorageDisable) null else application.externalCacheDir?.absolutePath
}
/**
* 判断sub是否在parent之下的文件或子文件夹<br></br>
*
* @param parent
* @param sub
* @return
*/
fun isSub(parent: File, sub: File): Boolean {
return try {
sub.absolutePath.startsWith(parent.absolutePath)
} catch (e: Exception) {
false
}
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files.
*
* @return the path of /storage/emulated/0/Android/data/package/files
*/
fun getExternalAppFilesPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(null)?.absolutePath
}
/**
* 获取子绝对路径与父绝对路径的相对路径
*
* @param parentPath
* @param subPath
* @return
*/
fun getRelativePath(parentPath: String?, subPath: String?): String? {
return try {
if (parentPath == null || subPath == null) {
return null
}
if (subPath.startsWith(parentPath)) {
subPath.substring(parentPath.length)
} else {
null
}
} catch (e: Exception) {
null
}
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Music.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Music
*/
fun getExternalAppMusicPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_MUSIC
)?.absolutePath
}
/**
* 拼接两个路径
*
* @param pathA 路径A
* @param pathB 路径B
* @return 拼接后的路径
*/
fun plusPath(pathA: String?, pathB: String?): String? {
if (pathA == null) {
return pathB
}
if (pathB == null) {
return pathA
}
return plusPathNotNull(pathA, pathB)
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Podcasts.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Podcasts
*/
fun getExternalAppPodcastsPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_PODCASTS
)?.absolutePath
}
/**
* 拼接两个路径
*
* @param pathA 路径A
* @param pathB 路径B
* @return 拼接后的路径
*/
fun plusPathNotNull(pathA: String, pathB: String): String {
val pathAEndSeparator = pathA.endsWith(File.separator)
val pathBStartSeparator = pathB.startsWith(File.separator)
return if (pathAEndSeparator && pathBStartSeparator) {
pathA + pathB.substring(1)
} else if (pathAEndSeparator || pathBStartSeparator) {
pathA + pathB
} else {
pathA + File.separator + pathB
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Ringtones.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Ringtones
*/
fun getExternalAppRingtonesPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_RINGTONES
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Alarms.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Alarms
*/
fun getExternalAppAlarmsPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_ALARMS
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Notifications.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Notifications
*/
fun getExternalAppNotificationsPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_NOTIFICATIONS
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Pictures.
*
* @return path of /storage/emulated/0/Android/data/package/files/Pictures
*/
fun getExternalAppPicturesPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_PICTURES
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Movies.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Movies
*/
fun getExternalAppMoviesPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_MOVIES
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Download.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Download
*/
fun getExternalAppDownloadPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_DOWNLOADS
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/DCIM.
*
* @return the path of /storage/emulated/0/Android/data/package/files/DCIM
*/
fun getExternalAppDcimPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.getExternalFilesDir(
Environment.DIRECTORY_DCIM
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/data/package/files/Documents.
*
* @return the path of /storage/emulated/0/Android/data/package/files/Documents
*/
fun getExternalAppDocumentsPath(application: Application): String? {
if (isExternalStorageDisable) return null
return if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
application.getExternalFilesDir(null)?.absolutePath + "/Documents"
} else application.getExternalFilesDir(
Environment.DIRECTORY_DOCUMENTS
)?.absolutePath
}
/**
* Return the path of /storage/emulated/0/Android/obb/package.
*
* @return the path of /storage/emulated/0/Android/obb/package
*/
fun getExternalAppObbPath(application: Application): String? {
return if (isExternalStorageDisable) null else application.obbDir.absolutePath
}
private val isExternalStorageDisable: Boolean
private get() = Environment.MEDIA_MOUNTED != Environment.getExternalStorageState()
/**
* 判断sub是否在parent之下的文件或子文件夹<br></br>
*
* @param parent
* @param sub
* @return
*/
fun isSub(parent: File, sub: File): Boolean {
return try {
sub.absolutePath.startsWith(parent.absolutePath)
} catch (e: Exception) {
false
}
}
/**
* 获取子绝对路径与父绝对路径的相对路径
*
* @param parentPath
* @param subPath
* @return
*/
fun getRelativePath(parentPath: String?, subPath: String?): String? {
return try {
if (parentPath == null || subPath == null) {
return null
}
if (subPath.startsWith(parentPath)) {
subPath.substring(parentPath.length)
} else {
null
}
} catch (e: Exception) {
null
}
}
/**
* 拼接两个路径
*
* @param pathA 路径A
* @param pathB 路径B
* @return 拼接后的路径
*/
fun plusPath(pathA: String?, pathB: String?): String? {
if (pathA == null) {
return pathB
}
if (pathB == null) {
return pathA
}
return plusPathNotNull(pathA, pathB)
}
/**
* 拼接两个路径
*
* @param pathA 路径A
* @param pathB 路径B
* @return 拼接后的路径
*/
fun plusPathNotNull(pathA: String, pathB: String): String {
val pathAEndSeparator = pathA.endsWith(File.separator)
val pathBStartSeparator = pathB.startsWith(File.separator)
return if (pathAEndSeparator && pathBStartSeparator) {
pathA + pathB.substring(1)
} else if (pathAEndSeparator || pathBStartSeparator) {
pathA + pathB
} else {
pathA + File.separator + pathB
}
}
/**
* 获取后缀名称
* @param path 路径
* @return 后缀格式 .mp4 .gif 等
*/
fun getSuffixType(path: String): String? {
if (path.isEmpty()) {
return null
}
val dotIndex = path.indexOfLast {
'.' == it
}
val separatorIndex = path.indexOfLast {
'/' == it
}
if (dotIndex >= 0 && dotIndex > separatorIndex) {
val suffix = path.substring(dotIndex)
val askIndex = suffix.indexOfLast {
'?' == it
}
return if (askIndex >= 0) {
suffix.substring(0, askIndex)
} else {
suffix
}
}
return null
}
}

View File

@@ -1,25 +0,0 @@
package com.chuhai.utils
import android.os.SystemClock
/**
* Created by Max on 2023/10/24 15:11
* Desc:服务器时间
*/
object ServiceTime {
// 服务器时间与系统开机时间的时差
private var serviceTimeDiff: Long? = null
val time
get() = if (serviceTimeDiff == null) System.currentTimeMillis()
else SystemClock.elapsedRealtime() + serviceTimeDiff!!
/**
* 刷新服务器时间
*/
fun refreshServiceTime(time: Long) {
//serviceTimeDiff = 服务器时间 - 此刻系统启动时间
serviceTimeDiff = time - SystemClock.elapsedRealtime()
}
}