diff --git a/common/src/main/java/com/yunbao/common/http/CommonHttpUtil.java b/common/src/main/java/com/yunbao/common/http/CommonHttpUtil.java index ccc77a95f..114d2452e 100644 --- a/common/src/main/java/com/yunbao/common/http/CommonHttpUtil.java +++ b/common/src/main/java/com/yunbao/common/http/CommonHttpUtil.java @@ -199,6 +199,15 @@ public class CommonHttpUtil { JSONArray levelArray = obj.getJSONArray("levelanchor_new"); new NewLevelManager(context).UpAnchorDataLevel(levelArray.toJSONString()); } + if (obj.containsKey("apk_ver")) { + IMLoginManager.get(context).setApkVer(obj.getString("apk_ver")); + } + if (obj.containsKey("apk_url")) { + IMLoginManager.get(context).setAPKUrl(obj.getString("apk_url")); + } + if (obj.containsKey("apk_des")) { + IMLoginManager.get(context).setAPKDes(obj.getString("apk_des")); + } } catch (Exception e) { String error = "info[0]:" + info[0] + "\n\n\n" + "Exception:" + e.getClass() + "---message--->" + e.getMessage(); ErrorActivity.forward("GetConfig接口返回数据异常", error); diff --git a/common/src/main/java/com/yunbao/common/manager/IMLoginManager.java b/common/src/main/java/com/yunbao/common/manager/IMLoginManager.java index 17ca385cc..846d7afa0 100644 --- a/common/src/main/java/com/yunbao/common/manager/IMLoginManager.java +++ b/common/src/main/java/com/yunbao/common/manager/IMLoginManager.java @@ -18,6 +18,7 @@ import com.yunbao.common.manager.base.BaseCacheManager; import com.yunbao.common.manager.imrongcloud.MessageIMManager; import com.yunbao.common.manager.imrongcloud.RongcloudIMManager; import com.yunbao.common.utils.SpUtil; +import com.yunbao.common.utils.VersionUtil; import com.yunbao.common.views.floatingview.APPEasyFloat; import org.greenrobot.eventbus.EventBus; @@ -39,6 +40,33 @@ public class IMLoginManager extends BaseCacheManager { private final String IS_HINT = "is_hint"; private final String IS_HINT2 = "is_hint2"; private final String SELECT_CLARITY = "selectClarity"; + private final String APK_VER = "apk_ver"; + private final String APK_URL = "apk_url"; + private final String APK_DES = "apk_des"; + + public void setAPKUrl(String apkUrl) { + put(APK_URL, apkUrl); + } + + public void setAPKDes(String apkDes) { + put(APK_DES, apkDes); + } + + public String getAPKUrl() { + return getString(APK_URL); + } + + public String getAPKDes() { + return getString(APK_DES); + } + + public void setApkVer(String apkVer) { + put(APK_VER, apkVer); + } + + public boolean getApkVerNew() { + return TextUtils.equals(VersionUtil.getVersion(), getString(APK_VER)); + } /** * 设置清晰度 diff --git a/common/src/main/java/com/yunbao/common/views/APKUpdateCustomPopup.java b/common/src/main/java/com/yunbao/common/views/APKUpdateCustomPopup.java new file mode 100644 index 000000000..429be45e7 --- /dev/null +++ b/common/src/main/java/com/yunbao/common/views/APKUpdateCustomPopup.java @@ -0,0 +1,194 @@ +package com.yunbao.common.views; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.os.Build; +import android.os.Handler; +import android.os.Looper; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import androidx.annotation.NonNull; +import androidx.core.content.FileProvider; + +import com.lxj.xpopup.core.CenterPopupView; +import com.yunbao.common.CommonAppConfig; +import com.yunbao.common.R; +import com.yunbao.common.manager.IMLoginManager; +import com.yunbao.common.utils.APKDownloadUtil; +import com.yunbao.common.utils.ToastUtil; +import com.yunbao.common.views.weight.ViewClicksAntiShake; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import okhttp3.Call; +import okhttp3.Callback; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; + +/** + * apk更新弹窗 + */ +public class APKUpdateCustomPopup extends CenterPopupView { + private TextView updateText, versionImmediateUse; + private LinearLayout updateLine; + private ProgressBar progressBar; + private Activity mContext; + + public APKUpdateCustomPopup(@NonNull Activity context) { + super(context); + mContext = context; + } + + // 返回自定义弹窗的布局 + @Override + protected int getImplLayoutId() { + return R.layout.apk_update_custom_popup; + } + + // 执行初始化操作,比如:findView,设置点击,或者任何你弹窗内的业务逻辑 + @Override + protected void onCreate() { + super.onCreate(); + initView(); + initData(); + } + + private void initData() { + + } + + private void initView() { + updateText = findViewById(R.id.update_text); + versionImmediateUse = findViewById(R.id.version_immediate_use); + updateLine = findViewById(R.id.update_line); + progressBar = findViewById(R.id.progressBar); + versionImmediateUse.setVisibility(VISIBLE); + updateLine.setVisibility(GONE); + updateText.setText(IMLoginManager.get(getContext()).getAPKDes()); + ViewClicksAntiShake.clicksAntiShake(versionImmediateUse, new ViewClicksAntiShake.ViewClicksCallBack() { + @Override + public void onViewClicks() { + //不是谷歌 + if (!CommonAppConfig.IS_GOOGLE_PLAY) { + versionImmediateUse.setVisibility(GONE); + updateLine.setVisibility(VISIBLE); + downloadAPK(mContext, IMLoginManager.get(getContext()).getAPKUrl(), new APKDownloadUtil.OnUpdateListener() { + @Override + public void updateFailure(int code, String error) { + ToastUtil.show(error); + } + }); + } else { + Intent i = new Intent(android.content.Intent.ACTION_VIEW); + i.setData(Uri.parse("https://play.google.com/store/apps/details?id=com.pdlive.shayu")); + mContext.startActivity(i); + mContext.finish(); + } + + } + }); + } + + public void downloadAPK(Activity context, String url, APKDownloadUtil.OnUpdateListener listener) { + Request request = new Request.Builder().url(url) + .addHeader("Accept-Encoding", "identity").build(); + File downloadFile = new File(context.getCacheDir(), "update_app.apk"); + try { + if (!downloadFile.exists() + && !downloadFile.createNewFile()) { + return; + } + } catch (IOException e) { + e.printStackTrace(); + } + new OkHttpClient().newCall(request).enqueue(new Callback() { + private Handler handler = new Handler(); + + @Override + public void onFailure(Call call, IOException e) { + // 下载失败 + handler.post(() -> { + listener.updateFailure(-1, e.getMessage()); + dismiss(); + }); + } + + @Override + public void onResponse(Call call, Response response) { + Looper.prepare(); + byte[] buf = new byte[2048]; + int len; + try (InputStream inputStream = response.body().byteStream(); + FileOutputStream outputStream = new FileOutputStream(downloadFile)) { + long total = response.body().contentLength(); + long sum = 0; + while ((len = inputStream.read(buf)) != -1) { + outputStream.write(buf, 0, len); + sum += len; + int progress = (int) (sum * 1.0f / total * 100); + // 下载中 + handler.post(new Runnable() { + @Override + public void run() { + progressBar.setProgress(progress); + } + }); + } + outputStream.flush(); + //启动安装app + installApk(context, downloadFile, context.getPackageName() + ".fileprovider"); + handler.post(() -> dismiss()); + } catch (Exception e) { + e.printStackTrace(); + new Handler().post(() -> { + listener.updateFailure(-1, e.getMessage()); + dismiss(); + }); + } + } + }); + } + + /** + * 安装apk + * + * @param context + * @param file + */ + public void installApk(Context context, File file, String authority) { + Intent intent = getInstallIntent(context, file, authority); + context.startActivity(intent); + } + + /** + * 获取安装Intent + * + * @param context + * @param file + * @param authority + * @return + */ + public Intent getInstallIntent(Context context, File file, String authority) { + Intent intent = new Intent(Intent.ACTION_VIEW); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.addCategory(Intent.CATEGORY_DEFAULT); + Uri uriData; + String type = "application/vnd.android.package-archive"; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); + uriData = FileProvider.getUriForFile(context, authority, file); + } else { + uriData = Uri.fromFile(file); + } + intent.setDataAndType(uriData, type); + return intent; + } +} diff --git a/common/src/main/res/drawable/bg_apk_update_btn.xml b/common/src/main/res/drawable/bg_apk_update_btn.xml new file mode 100644 index 000000000..57831085d --- /dev/null +++ b/common/src/main/res/drawable/bg_apk_update_btn.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/common/src/main/res/drawable/progress_bg.xml b/common/src/main/res/drawable/progress_bg.xml new file mode 100644 index 000000000..97b90eb75 --- /dev/null +++ b/common/src/main/res/drawable/progress_bg.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/common/src/main/res/layout/apk_update_custom_popup.xml b/common/src/main/res/layout/apk_update_custom_popup.xml new file mode 100644 index 000000000..4a4f1f9a7 --- /dev/null +++ b/common/src/main/res/layout/apk_update_custom_popup.xml @@ -0,0 +1,75 @@ + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/common/src/main/res/mipmap-xxhdpi/update_tip_box.png b/common/src/main/res/mipmap-xxhdpi/update_tip_box.png new file mode 100644 index 000000000..7bcfaad41 Binary files /dev/null and b/common/src/main/res/mipmap-xxhdpi/update_tip_box.png differ diff --git a/common/src/main/res/values-en/strings.xml b/common/src/main/res/values-en/strings.xml index 07b3a9a90..47c22d55e 100644 --- a/common/src/main/res/values-en/strings.xml +++ b/common/src/main/res/values-en/strings.xml @@ -994,4 +994,8 @@ Limited ride And limited avatar frame Stick to choice Network prompt The system detects that your network is unstable and insufficient device memory will affect the fluency of your live broadcast. Therefore, it is recommended that you choose fluency and clarity. + check version + Update + Latest Version + updating diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml index 01237fa89..5bc7c5f05 100644 --- a/common/src/main/res/values/strings.xml +++ b/common/src/main/res/values/strings.xml @@ -1014,4 +1014,8 @@ 堅持選擇 網絡提示 系統監測到您的網絡不穩定,設備內存不足將會影響到您的直播流暢度,因此建議您選擇流暢清晰度。 + 检查新版本 + 發現新版本,點此更新 + 已是最新版本 + 更新中 diff --git a/config.gradle b/config.gradle index ac60b7e57..9c0a1cfbb 100644 --- a/config.gradle +++ b/config.gradle @@ -5,7 +5,7 @@ ext { minSdkVersion : 21, targetSdkVersion : 31, versionCode : 402, - versionName : "6.4.7" + versionName : "6.4.6" ] manifestPlaceholders = [ //正式 diff --git a/main/src/main/java/com/yunbao/main/activity/SettingActivity.java b/main/src/main/java/com/yunbao/main/activity/SettingActivity.java index 7d1d599b6..f45bd0653 100644 --- a/main/src/main/java/com/yunbao/main/activity/SettingActivity.java +++ b/main/src/main/java/com/yunbao/main/activity/SettingActivity.java @@ -19,19 +19,18 @@ import androidx.recyclerview.widget.RecyclerView; import com.alibaba.android.arouter.facade.annotation.Route; import com.alibaba.fastjson.JSON; +import com.lxj.xpopup.XPopup; import com.lzf.easyfloat.interfaces.OnPermissionResult; import com.lzf.easyfloat.permission.PermissionUtils; import com.yunbao.common.CommonAppConfig; import com.yunbao.common.Constants; import com.yunbao.common.activity.AbsActivity; import com.yunbao.common.activity.WebViewActivity; -import com.yunbao.common.bean.ConfigBean; import com.yunbao.common.bean.IMLoginModel; import com.yunbao.common.glide.ImgLoader; import com.yunbao.common.http.CommonHttpConsts; import com.yunbao.common.http.CommonHttpUtil; import com.yunbao.common.http.HttpCallback; -import com.yunbao.common.interfaces.CommonCallback; import com.yunbao.common.interfaces.OnItemClickListener; import com.yunbao.common.manager.IMLoginManager; import com.yunbao.common.utils.DialogUitl; @@ -40,6 +39,7 @@ import com.yunbao.common.utils.RouteUtil; import com.yunbao.common.utils.ToastUtil; import com.yunbao.common.utils.VersionUtil; import com.yunbao.common.utils.WordUtil; +import com.yunbao.common.views.APKUpdateCustomPopup; import com.yunbao.common.views.floatingview.APPEasyFloat; import com.yunbao.common.views.weight.ViewClicksAntiShake; import com.yunbao.main.R; @@ -99,6 +99,11 @@ public class SettingActivity extends AbsActivity implements OnItemClickListener< data1.setName(WordUtil.getString(R.string.versions)); list.add(data1); + SettingBean data2 = new SettingBean(); + data2.setId(25); + data2.setName(WordUtil.getString(R.string.check_the_new_version)); + list.add(data2); + SettingBean bean = new SettingBean(); bean.setName(WordUtil.getString(R.string.setting_exit)); bean.setLast(true); @@ -280,6 +285,13 @@ public class SettingActivity extends AbsActivity implements OnItemClickListener< clearCache(position); } else if (bean.getId() == 21) {//清除缓存 startActivity(new Intent(SettingActivity.this, MsgSettActivity.class)); + } else if (bean.getId() == 25) {//版本更新 + if (!IMLoginManager.get(mContext).getApkVerNew()) { + new XPopup.Builder(mContext) + .asCustom(new APKUpdateCustomPopup(mContext)) + .show(); + } + } } else { if (bean.getId() == 17) {//意见反馈要在url上加版本号和设备号 diff --git a/main/src/main/java/com/yunbao/main/adapter/SettingAdapter.java b/main/src/main/java/com/yunbao/main/adapter/SettingAdapter.java index 22e04c560..6ab9de77f 100644 --- a/main/src/main/java/com/yunbao/main/adapter/SettingAdapter.java +++ b/main/src/main/java/com/yunbao/main/adapter/SettingAdapter.java @@ -12,10 +12,9 @@ import androidx.recyclerview.widget.RecyclerView; import com.yunbao.common.Constants; import com.yunbao.common.interfaces.OnItemClickListener; +import com.yunbao.common.manager.IMLoginManager; import com.yunbao.common.utils.DeviceUtils; import com.yunbao.common.utils.LogUtil; -import com.yunbao.common.views.weight.ViewClicksAntiShake; -import com.yunbao.main.BuildConfig; import com.yunbao.main.R; import com.yunbao.main.bean.SettingBean; @@ -47,17 +46,17 @@ public class SettingAdapter extends RecyclerView.Adapter { @Override public void onClick(View v) { - Object tag = v.getTag(); - if (tag != null) { - int position = (int) tag; - SettingBean bean = mList.get(position); - if(bean.getId()==19){ - LogUtil.shareFile(context); - } - if (mOnItemClickListener != null) { - mOnItemClickListener.onItemClick(bean, position); - } + Object tag = v.getTag(); + if (tag != null) { + int position = (int) tag; + SettingBean bean = mList.get(position); + if (bean.getId() == 19) { + LogUtil.shareFile(context); } + if (mOnItemClickListener != null) { + mOnItemClickListener.onItemClick(bean, position); + } + } } @@ -75,7 +74,7 @@ public class SettingAdapter extends RecyclerView.Adapter { @Override public int getItemViewType(int position) { SettingBean bean = mList.get(position); - if (bean.getId() == 19 || bean.getId() == Constants.SETTING_UPDATE_ID || bean.getId() == Constants.SETTING_CLEAR_CACHE) { + if (bean.getId() == 19 || bean.getId() == 25|| bean.getId() == Constants.SETTING_UPDATE_ID || bean.getId() == Constants.SETTING_CLEAR_CACHE) { return VERSION; } else if (bean.isLast()) { return LAST; @@ -147,6 +146,16 @@ public class SettingAdapter extends RecyclerView.Adapter { } else if (bean.getId() == 19) { mText.setText(DeviceUtils.getVersionName(itemView.getContext())); mText.setTextColor(Color.parseColor("#969696")); + } else if (bean.getId() == 25) { + if (IMLoginManager.get(itemView.getContext()).getApkVerNew()) { + mText.setText(itemView.getContext().getString(R.string.latest_version)); + mText.setTextColor(Color.parseColor("#969696")); + + } else { + mText.setText(itemView.getContext().getString(R.string.discover_a_new_version)); + mText.setTextColor(Color.parseColor("#b3d465")); + } + } else { mText.setText(mVersionString); } diff --git a/main/src/main/java/com/yunbao/main/views/MainMeViewHolder.java b/main/src/main/java/com/yunbao/main/views/MainMeViewHolder.java index 3e8df3710..1346e2103 100644 --- a/main/src/main/java/com/yunbao/main/views/MainMeViewHolder.java +++ b/main/src/main/java/com/yunbao/main/views/MainMeViewHolder.java @@ -1,5 +1,6 @@ package com.yunbao.main.views; +import android.annotation.SuppressLint; import android.content.ClipboardManager; import android.content.Context; import android.content.Intent; @@ -38,6 +39,7 @@ import com.yunbao.common.glide.ImgLoader; import com.yunbao.common.http.HttpCallback; import com.yunbao.common.interfaces.CommonCallback; import com.yunbao.common.interfaces.OnItemClickListener; +import com.yunbao.common.manager.IMLoginManager; import com.yunbao.common.utils.RouteUtil; import com.yunbao.common.utils.SVGAViewUtils; import com.yunbao.common.utils.ToastUtil; @@ -99,6 +101,7 @@ public class MainMeViewHolder extends AbsMainViewHolder implements OnItemClickLi private boolean firstInto = true; private Banner banner_me; private LinearLayout lt_advertisement; + private View redPoint; public MainMeViewHolder(Context context, ViewGroup parentView) { super(context, parentView); @@ -109,9 +112,11 @@ public class MainMeViewHolder extends AbsMainViewHolder implements OnItemClickLi return R.layout.view_main_me; } + @SuppressLint("WrongViewCast") @Override public void init() { mAvatar = (ImageView) findViewById(R.id.avatar); + redPoint = findViewById(R.id.red_point); ViewClicksAntiShake.clicksAntiShake(mAvatar, new ViewClicksAntiShake.ViewClicksCallBack() { @Override public void onViewClicks() { @@ -175,6 +180,7 @@ public class MainMeViewHolder extends AbsMainViewHolder implements OnItemClickLi outline.setRoundRect(0, 0, view.getWidth(), view.getHeight(), 10); } }); + redPoint.setVisibility(IMLoginManager.get(mContext).getApkVerNew() ? View.GONE : View.VISIBLE); } @Override @@ -312,7 +318,7 @@ public class MainMeViewHolder extends AbsMainViewHolder implements OnItemClickLi public void onComplete(SVGAVideoEntity videoItem) { SVGADrawable drawable = new SVGADrawable(videoItem); gift_svga.setImageDrawable(drawable); - SVGAViewUtils.playEndClear(gift_svga,false); + SVGAViewUtils.playEndClear(gift_svga, false); } @Override @@ -441,11 +447,11 @@ public class MainMeViewHolder extends AbsMainViewHolder implements OnItemClickLi } else if (bean.getId() == 4) { url = HtmlConfig.SHOP + "?t=" + Math.random() + "&uid=" + CommonAppConfig.getInstance().getUid() + "&token=" + CommonAppConfig.getInstance().getToken(); WebViewActivity.forward(mContext, url); - } else if(bean.getId() == 3) {//我的等级 - Constants.myIntoIndex=2; + } else if (bean.getId() == 3) {//我的等级 + Constants.myIntoIndex = 2; Constants.isTitle = false; ZhuangBanActivity.forward(mContext, url); - }else{ + } else { WebViewActivity.forward(mContext, url); } @@ -462,8 +468,7 @@ public class MainMeViewHolder extends AbsMainViewHolder implements OnItemClickLi mContext.startActivity(new Intent(mContext, EditProfileActivity.class)); } else if (i == R.id.signature) { mContext.startActivity(new Intent(mContext, EditProfileActivity.class)); - } - else if (i == R.id.lt_star_coin) { + } else if (i == R.id.lt_star_coin) { mContext.startActivity(new Intent(mContext, MyWalletActivity.class).putExtra("p", 1)); } else if (i == R.id.btn_coin) { mContext.startActivity(new Intent(mContext, MyWalletActivity.class).putExtra("p", 0)); @@ -483,8 +488,6 @@ public class MainMeViewHolder extends AbsMainViewHolder implements OnItemClickLi } - - } /** diff --git a/main/src/main/res/layout/view_main_me.xml b/main/src/main/res/layout/view_main_me.xml index 6e54a3206..9a0ef092d 100644 --- a/main/src/main/res/layout/view_main_me.xml +++ b/main/src/main/res/layout/view_main_me.xml @@ -476,18 +476,18 @@ android:layout_marginTop="12dp" android:layout_marginRight="15dp" android:background="@drawable/bg_me_data" - android:gravity="center" android:clickable="true" - android:focusableInTouchMode="true" android:focusable="true" + android:focusableInTouchMode="true" + android:gravity="center" android:orientation="horizontal"> @@ -534,10 +534,10 @@ android:layout_width="18dp" android:layout_height="18dp" android:layout_marginRight="30dp" + android:background="@mipmap/icon_more_gray" android:clickable="false" - android:focusableInTouchMode="false" android:focusable="false" - android:background="@mipmap/icon_more_gray" /> + android:focusableInTouchMode="false" /> + +