Merge remote-tracking branch 'origin/release' into dev

# Conflicts:
#	dependencies.gradle
This commit is contained in:
chenjuntao
2024-04-15 15:13:09 +08:00
66 changed files with 1104 additions and 247 deletions

View File

@ -8,7 +8,7 @@ import com.gh.gamecenter.core.provider.IFlavorProvider
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.TimeUtils
import com.halo.assistant.HaloApp
import com.leon.channel.helper.ChannelReaderUtil
import com.tencent.vasdolly.helper.ChannelReaderUtil
class FlavorProviderImp : IFlavorProvider {

View File

@ -12,7 +12,7 @@ import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.halo.assistant.HaloApp
import com.kwai.monitor.payload.TurboHelper
import com.leon.channel.helper.ChannelReaderUtil
import com.tencent.vasdolly.helper.ChannelReaderUtil
class FlavorProviderImp : IFlavorProvider {

View File

@ -11,6 +11,8 @@
<package android:name="com.lg.vspace" />
</queries>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<!-- 允许应用程序访问网络连接 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允许应用程序写入外部存储如SD卡上写文件 -->
@ -118,10 +120,12 @@
android:label="@string/app_name"
android:largeHeap="true"
android:networkSecurityConfig="@xml/network_security_config"
android:preserveLegacyExternalStorage="true"
android:requestLegacyExternalStorage="true"
android:resizeableActivity="true"
android:theme="@style/AppCompatTheme.APP"
tools:replace="android:name,android:allowBackup"
tools:targetApi="n">
tools:targetApi="r">
<meta-data
android:name="EasyGoClient"

View File

@ -12,13 +12,13 @@ import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.entity.ForumDetailEntity
import com.gh.gamecenter.entity.LocalVideoEntity
import com.gh.gamecenter.entity.QuoteCountEntity
@ -28,7 +28,6 @@ import com.gh.gamecenter.retrofit.service.ApiService
import com.gh.gamecenter.video.upload.OnUploadListener
import com.gh.gamecenter.video.upload.UploadManager
import com.google.gson.JsonObject
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import com.zhihu.matisse.Matisse
import com.zhihu.matisse.internal.utils.PathUtils
@ -62,7 +61,6 @@ abstract class BaseRichEditorViewModel(application: Application) : AndroidViewMo
val TITLE_MIN_LENGTH = 6
val MIN_TEXT_LENGTH = 6
val MAX_TEXT_LENGTH = 10000
val FILE_HOST = "file:///"
var id = ""//视频标记
var videoId = ""//更改封面视频id
val quoteCountEntity = QuoteCountEntity()//数据上报用
@ -129,15 +127,13 @@ abstract class BaseRichEditorViewModel(application: Application) : AndroidViewMo
}
val map = LinkedHashMap<String, String>()
for (key in imageUrlMap.keys) {
val localFileUri = FILE_HOST + key.decodeURI()
// 文件格式为 HEIC 时,使用经 OSS 转码的图片作为预览图片
if (FileUtils.getFileMimeType(getApplication(), key.decodeURI())?.lowercase(Locale.CHINA)?.contains("heic") == true) {
val transformedImgUrl = ImageUtils.getIdealImageUrl(imageUrlMap[key], 5000) ?: ""
map[MD5Utils.getUrlMD5(key)] = transformedImgUrl
mapImages[transformedImgUrl.decodeURI()] = imageUrlMap[key] ?: ""
} else {
map[MD5Utils.getUrlMD5(key)] = localFileUri
map[MD5Utils.getUrlMD5(key)] = imageUrlMap[key] ?: ""
mapImages[TextUtils.htmlEncode(key).decodeURI()] = imageUrlMap[key] ?: ""
}
}

View File

@ -52,6 +52,8 @@ import com.gh.gamecenter.WebActivity;
import com.gh.gamecenter.common.entity.LinkEntity;
import com.gh.gamecenter.common.utils.DarkModeUtils;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.common.utils.NewFlatLogUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.utils.MtaHelper;
@ -69,7 +71,6 @@ import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.vspace.VHelper;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.Utils;
import java.io.File;

View File

@ -0,0 +1,68 @@
package com.gh.common.dialog
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import com.gh.gamecenter.common.databinding.DialogAlertDefaultBinding
import com.lightgame.dialog.BaseDialogFragment
@RequiresApi(Build.VERSION_CODES.R)
class ManagerAllFilesPermissionDialogFragment : BaseDialogFragment() {
private val mBinding by lazy { DialogAlertDefaultBinding.inflate(layoutInflater) }
private var mCallBack: (() -> Unit)? = null
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
return mBinding.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mBinding.run {
titleTv.text = "请求权限"
titleTv.gravity = Gravity.CENTER
contentTv.text = "需要所有文件访问权限,请打开权限设置页面"
confirmTv.setOnClickListener {
val intent = Intent().apply {
action = Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION
data = Uri.fromParts("package", requireContext().packageName, null)
}
requireActivity().startActivityForResult(intent, REQUEST_CODE)
}
cancelTv.setOnClickListener {
dismissAllowingStateLoss()
}
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == REQUEST_CODE && Environment.isExternalStorageManager()) {
mCallBack?.invoke()
dismissAllowingStateLoss()
}
}
companion object {
const val REQUEST_CODE = 1000
@JvmStatic
fun show(activity: AppCompatActivity, callback: () -> Unit) {
ManagerAllFilesPermissionDialogFragment().apply {
mCallBack = callback
}.show(
activity.supportFragmentManager,
ManagerAllFilesPermissionDialogFragment::class.java.name
)
}
}
}

View File

@ -20,15 +20,14 @@ import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor.uiExecutor
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.entity.TrackableEntity
import com.gh.gamecenter.feature.entity.ApkEntity
import com.gh.gamecenter.feature.entity.SimulatorEntity
import com.gh.gamecenter.entity.TrackableEntity
import com.gh.ndownload.NDataChanger
import com.halo.assistant.HaloApp
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import java.lang.ref.WeakReference
import java.text.DecimalFormat

View File

@ -30,7 +30,6 @@ import com.gh.gamecenter.room.AppDatabase
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadDao
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.AppManager
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers

View File

@ -46,7 +46,6 @@ import com.gh.vspace.VHelper
import com.lightgame.download.DownloadConfig
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import java.io.File
import java.util.concurrent.LinkedBlockingQueue

View File

@ -32,7 +32,10 @@ import com.gh.gamecenter.help.HelpAndFeedbackBridge
import com.gh.gamecenter.pkg.PkgHelper
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.*
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadConfig
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.utils.AppManager
import com.lightgame.utils.Utils
import org.greenrobot.eventbus.EventBus

View File

@ -41,7 +41,6 @@ import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.teenagermode.TeenagerModeActivity
import com.gh.vspace.VHelper
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import java.io.File

View File

@ -566,7 +566,7 @@ public class MessageShareUtils {
String path;
// 安卓11无法访问Android/data目录
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
path = Environment.getExternalStorageDirectory().getAbsolutePath() + "/ShareImg/";
path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/ShareImg/";
} else {
path = context.getExternalCacheDir().getPath() + "/ShareImg/";
}

View File

@ -24,7 +24,6 @@ import com.gh.gamecenter.vpn.VpnHelper
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import java.io.File

View File

@ -4,8 +4,12 @@ import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Environment
import android.provider.Settings
import androidx.appcompat.app.AppCompatActivity
import com.gh.common.constant.Config
import com.gh.common.dialog.ManagerAllFilesPermissionDialogFragment
import com.gh.common.util.*
import com.gh.common.util.DirectUtils
import com.gh.common.util.DownloadNotificationHelper
import com.gh.common.util.PackageInstaller
@ -15,6 +19,7 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.SentryHelper
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.xapk.XApkUnZipper
@ -22,10 +27,7 @@ import com.gh.gamecenter.xapk.core.XApkFile
import com.gh.gamecenter.xapk.core.XApkUnZipCallback
import com.gh.gamecenter.xapk.core.XApkUnZipEntry
import com.gh.gamecenter.xapk.core.XApkUnZipOutputFactory
import com.gh.gamecenter.xapk.io.NonSplitApksOutput
import com.gh.gamecenter.xapk.io.OBBFileOutput
import com.gh.gamecenter.xapk.io.SplitApksOutput
import com.gh.gamecenter.xapk.io.XApkFileOutput
import com.gh.gamecenter.xapk.io.*
import com.gh.gamecenter.xapk.pi.IPackageInstaller
import com.gh.ndownload.NDataChanger
import com.halo.assistant.HaloApp
@ -112,19 +114,38 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
return
}
DownloadManager.getInstance().getDownloadEntitySnapshot(downloadEntity.url, downloadEntity.gameId)
?.let {
unzipXapkFile(it)
if (showUnzipToast) {
Utils.toast(mContext, "解压过程请勿退出光环助手!")
if (checkPermission(downloadEntity, showUnzipToast)) {
DownloadManager.getInstance().getDownloadEntitySnapshot(downloadEntity.url, downloadEntity.gameId)
?.let {
unzipXapkFile(it)
if (showUnzipToast) {
Utils.toast(mContext, "解压过程请勿退出光环助手!")
}
}
}
}
} else {
throwExceptionInDebug("如果是Apk包请使用PackageInstaller进行安装")
PackageInstaller.install(mContext, downloadEntity)
}
}
private fun checkPermission(downloadEntity: DownloadEntity, showUnzipToast: Boolean = false): Boolean {
// 安卓11以上系统需要开启所有文件访问权限
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
&& !Environment.isExternalStorageManager()) {
CurrentActivityHolder.getCurrentActivity()?.let {
ManagerAllFilesPermissionDialogFragment.show(it as AppCompatActivity) {
unzipXapkFile(downloadEntity)
if (showUnzipToast) {
Utils.toast(mContext, "解压过程请勿退出光环助手!")
}
}
}
return false
}
return true
}
private fun unzipXapkFile(downloadEntity: DownloadEntity) {
mXApkUnZipper.unzip(
XApkUnZipEntry(

View File

@ -2,15 +2,11 @@ package com.gh.common.xapk
import android.os.Build
import android.os.Environment
import com.gh.gamecenter.common.utils.debounceActionWithInterval
import com.gh.gamecenter.common.utils.getExtension
import com.gh.gamecenter.common.utils.throwException
import com.gh.gamecenter.common.utils.throwExceptionInDebug
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.MD5Utils
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import net.lingala.zip4j.progress.ProgressMonitor
import java.io.File

View File

@ -25,36 +25,44 @@ import com.gh.gamecenter.feature.entity.CustomPageTrackData;
import com.gh.gamecenter.feature.entity.TagStyleEntity;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.common.exposure.ExposureUtils;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.common.history.HistoryHelper;
import com.gh.common.simulator.SimulatorGameManager;
import com.gh.common.util.DataCollectionUtils;
import com.gh.gamecenter.common.utils.DeviceUtils;
import com.gh.common.util.DialogUtils;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.common.util.HomePluggableHelper;
import com.gh.common.util.LunchType;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.base.GlobalActivityManager;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.common.utils.DeviceUtils;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.utils.AppDebugConfig;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.PageSwitchDataHelper;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.core.utils.SentryHelper;
import com.gh.gamecenter.download.DownloadedGameIdAndPackageNameDao;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.entity.GameUpdateEntity;
import com.gh.gamecenter.entity.HomePluggableFilterEntity;
import com.gh.gamecenter.feature.entity.PluginLocation;
import com.gh.gamecenter.eventbus.EBDownloadStatus;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.entity.PluginLocation;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.gamecenter.packagehelper.PackageRepository;
import com.gh.vspace.VHelper;
import com.gh.ndownload.NDataChanger;
import com.gh.ndownload.NDownloadBridge;
import com.gh.ndownload.NDownloadService;
import com.gh.vspace.VHelper;
import com.halo.assistant.HaloApp;
import com.lightgame.download.ConnectionUtils;
import com.lightgame.download.DataWatcher;
@ -63,7 +71,6 @@ import com.lightgame.download.DownloadDao;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import com.lightgame.download.DownloadStatusListener;
import com.lightgame.download.FileUtils;
import com.lightgame.download.HttpDnsManager;
import com.lightgame.utils.Utils;

View File

@ -3,7 +3,9 @@ package com.gh.download
import android.annotation.SuppressLint
import android.text.TextUtils
import com.gh.common.util.*
import com.gh.gamecenter.feature.utils.ConcernUtils
import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.PackageInstaller
import com.gh.common.util.PackageUtils
import com.gh.common.xapk.XapkInstaller
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.common.constant.Constants
@ -18,6 +20,7 @@ import com.gh.gamecenter.core.utils.ThirdPartyPackageHelper
import com.gh.gamecenter.core.utils.UrlFilterUtils
import com.gh.gamecenter.entity.GameDigestEntity
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.utils.ConcernUtils
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.packagehelper.PackageRepository

View File

@ -27,21 +27,13 @@ object ExoCacheManager {
if (NetworkUtils.isWifiConnected(HaloApp.getInstance().application)) {
10 * 1024 * 1024L
} else {
when (NetworkUtils.getMobileNetworkType(HaloApp.getInstance().application)) {
"5G", "4G" -> 10 * 1024 * 1024L
"3G" -> 5 * 1024 * 1024L
else -> 0L
}
10 * 1024 * 1024L
}
} else {
if (NetworkUtils.isWifiConnected(HaloApp.getInstance().application)) {
50 * 1024 * 1024L
} else {
when (NetworkUtils.getMobileNetworkType(HaloApp.getInstance().application)) {
"5G", "4G" -> 20 * 1024 * 1024L
"3G" -> 5 * 1024 * 1024L
else -> 0L
}
20 * 1024 * 1024L
}
}
}

View File

@ -28,7 +28,6 @@ import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.manager.PackagesManager
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.download.FileUtils
import com.lightgame.utils.AppManager
import com.lightgame.utils.Utils

View File

@ -1,12 +1,12 @@
package com.gh.download.server
import com.gh.download.DownloadManager
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.common.utils.FileUtils
import com.gh.gamecenter.common.utils.getMetaExtra
import com.gh.gamecenter.common.utils.toObject
import com.gh.download.DownloadManager
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.halo.assistant.HaloApp
import com.lightgame.download.FileUtils
import fi.iki.elonen.NanoHTTPD
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.schedulers.Schedulers

View File

@ -4,7 +4,7 @@ import com.lg.download.*
import com.lg.ndownload.DownloadConfig
import com.lg.ndownload.DownloadDbManager
import com.lg.ndownload.DownloadQueue
import com.lightgame.download.FileUtils
import com.gh.gamecenter.common.utils.FileUtils
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

View File

@ -79,6 +79,7 @@ import com.gh.gamecenter.common.retrofit.BiResponse;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.DialogHelper;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.NewFlatLogUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.common.utils.ShareUtils;
@ -113,7 +114,6 @@ import com.google.gson.reflect.TypeToken;
import com.halo.assistant.HaloApp;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.Utils;
import com.sina.weibo.sdk.auth.AuthInfo;
import com.sina.weibo.sdk.openapi.IWBAPI;
@ -172,6 +172,8 @@ public class MainActivity extends BaseActivity {
mMainWrapperViewModel = new ViewModelProvider(this, new MainWrapperViewModel.Factory(HaloApp.getInstance()))
.get(MainWrapperViewModel.class);
DisplayUtils.updateGlobalScreen(this);
super.onCreate(savedInstanceState);
setStatusBarColor(Color.TRANSPARENT);

View File

@ -47,7 +47,6 @@ import com.gh.gamecenter.teenagermode.TeenagerModeActivity.Companion.getIntent
import com.gh.vspace.VHelper
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.download.FileUtils
import org.greenrobot.eventbus.EventBus
import java.io.File

View File

@ -23,7 +23,6 @@ import com.gh.gamecenter.entity.ArchiveEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.vspace.VArchiveHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.FileUtils
import org.greenrobot.eventbus.EventBus
class MyArchiveOptionDialogFragment(

View File

@ -28,6 +28,7 @@ import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.entity.IconFloat;
import com.gh.gamecenter.common.utils.DialogHelper;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.common.utils.NewFlatLogUtils;
@ -44,7 +45,6 @@ import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.download.DownloadConfig;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;

View File

@ -36,6 +36,8 @@ data class CommonCollectionEntity(
@Parcelize
data class CommonCollectionContentEntity(
@SerializedName("_id")
private val _id: String? = null,
val title: String = "",
val style: String = "",
val image: String = "",
@ -45,4 +47,8 @@ data class CommonCollectionContentEntity(
var addedContent1: String? = "",
@SerializedName("added_content_2")
var addedContent2: String? = "",
) : Parcelable
) : Parcelable {
val id: String
get() = _id ?: ""
}

View File

@ -134,9 +134,11 @@ class ForumArticleAskListFragment : LazyListFragment<AnswerEntity, ForumArticleA
override fun onLoadRefresh() {
super.onLoadRefresh()
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.GONE
if (::mBinding.isInitialized) {
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.GONE
}
// Fixhttps://sentry.shanqu.cc/organizations/lightgame/issues/288994/?project=22&query=LazyListFragment&statsPeriod=14d
// Fragment在内存泄露的情况下调用requireView()会触发崩溃这里替换为getView()方法
// TODO 解决Fragment内存泄露的问题
@ -145,9 +147,11 @@ class ForumArticleAskListFragment : LazyListFragment<AnswerEntity, ForumArticleA
override fun onLoadDone() {
super.onLoadDone()
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.GONE
if (::mBinding.isInitialized) {
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.GONE
}
view?.setBackgroundColor(Color.TRANSPARENT)
mBaseHandler.postDelayed(Runnable {
tryCatchInRelease {
@ -159,25 +163,31 @@ class ForumArticleAskListFragment : LazyListFragment<AnswerEntity, ForumArticleA
override fun onLoadError() {
super.onLoadError()
mBinding.nestedScrollNoConnection.root.visibility = View.VISIBLE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.GONE
if (::mBinding.isInitialized) {
mBinding.nestedScrollNoConnection.root.visibility = View.VISIBLE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.GONE
}
view?.setBackgroundColor(Color.TRANSPARENT)
}
override fun onLoadEmpty() {
super.onLoadEmpty()
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.VISIBLE
mBinding.nestedScrollDataException.root.visibility = View.GONE
if (::mBinding.isInitialized) {
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.VISIBLE
mBinding.nestedScrollDataException.root.visibility = View.GONE
}
view?.setBackgroundColor(Color.TRANSPARENT)
}
override fun loadNotFound() {
super.loadNotFound()
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.VISIBLE
if (::mBinding.isInitialized) {
mBinding.nestedScrollNoConnection.root.visibility = View.GONE
mBinding.nestedScrollNoneData.root.visibility = View.GONE
mBinding.nestedScrollDataException.root.visibility = View.VISIBLE
}
}
override fun hideRefreshingLayout() {

View File

@ -443,12 +443,13 @@ class GameDetailFragment : BaseLazyFragment(), IScrollable {
.load(R.layout.fragment_gamedetail_skeleton)
.show()
val gameId = args.getString(EntranceConsts.KEY_GAMEID) ?: ""
val factory = GameDetailViewModel.Factory(
HaloApp.getInstance().application,
args.getString(EntranceConsts.KEY_GAMEID),
gameId,
args.getParcelable(GameEntity.TAG)
)
mViewModel = viewModelProviderFromParent(factory)
mViewModel = viewModelProviderFromParent(factory, gameId)
mPackageViewModel = viewModelProvider(PackageViewModel.Factory())
mUserViewModel = viewModelProvider(UserViewModel.Factory(HaloApp.getInstance().application))

View File

@ -123,7 +123,7 @@ class DescFragment: LazyFragment(), IScrollable {
val gameDetailFactory =
GameDetailViewModel.Factory(HaloApp.getInstance().application, mGameEntity?.id, mGameEntity)
val gameDetailViewModel: GameDetailViewModel = viewModelProviderFromParent(gameDetailFactory)
val gameDetailViewModel: GameDetailViewModel = viewModelProviderFromParent(gameDetailFactory, mGameEntity?.id ?: "")
mNewDetailEntity = gameDetailViewModel.gameDetailLiveData.value?.data
val factory = DescViewModel.Factory(HaloApp.getInstance().application, mGameEntity)

View File

@ -20,6 +20,7 @@ import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.databinding.DialogGameDetailMoreBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.gamedetail.GameDetailViewModel
import com.halo.assistant.HaloApp
class GameDetailMoreDialog : BaseDraggableDialogFragment() {
@ -29,7 +30,15 @@ class GameDetailMoreDialog : BaseDraggableDialogFragment() {
private var mGameEntity: GameEntity? = null
private var mShowConcernIcon = false
private var mIsConcerned = false
private val mViewModel: GameDetailViewModel by lazy { viewModelProviderFromParent() }
private val mViewModel: GameDetailViewModel by lazy {
viewModelProviderFromParent(
GameDetailViewModel.Factory(
HaloApp.getInstance().application,
mGameEntity?.id,
mGameEntity
), mGameEntity?.id ?: ""
)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

View File

@ -65,7 +65,7 @@ class FuLiFragment : LazyFragment(), IScrollable {
GameDetailViewModel.Factory(HaloApp.getInstance().application, gameEntity?.id, gameEntity)
shouldScroolToLibao = arguments?.getBoolean(EntranceConsts.KEY_SCROLL_TO_LIBAO) ?: false
mGameDetailViewModel = viewModelProviderFromParent(gameDetailFactory)
mGameDetailViewModel = viewModelProviderFromParent(gameDetailFactory, gameEntity?.id ?: "")
mFuLiViewModel = viewModelProvider()
super.onFragmentFirstVisible()

View File

@ -146,7 +146,7 @@ class ServersCalendarDetailDialog : DialogFragment() {
val serverCalendarList = adapter.selectedServerCalendarList
serverCalendarList.forEachIndexed { index, entity ->
if (index != 0) builder.append("")
builder.append("${entity.getFormatTime("YYYY年MM月dd日")}开服信息有误:${entity.getNote()}")
builder.append("${entity.getFormatTime("yyyy年MM月dd日")}开服信息有误:${entity.getNote()}")
}
HelpAndFeedbackBridge.startSuggestionActivity(
it.context,

View File

@ -32,7 +32,7 @@ class CustomCommonCollectionAdapter(
}
override fun getKey(t: CommonCollectionContentEntity): String {
return t.title
return "${_data.data.layout}-${t.id}"
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CustomCommonCollectionItemViewHolder {

View File

@ -48,7 +48,10 @@ class CustomIconMatrixAdapter(
CustomChildIconMatrixViewHolder(parent.toBinding())
override fun onBindViewHolder(holder: CustomChildIconMatrixViewHolder, position: Int, payloads: MutableList<Any>) {
if (payloads.isNotEmpty()) {
val isRefreshDownloadStatus = payloads.any {
PAYLOAD_REFRESH_GAME_CHANGED == it
}
if (isRefreshDownloadStatus) {
DownloadItemUtils.updateItem(
context,
getItem(position),

View File

@ -746,6 +746,8 @@ abstract class BaseCommentAdapter(
val loginEntrance = if (isVoted) "帖子评论-取消点赞" else "帖子评论-点赞"
binding.likeCountTv.context.ifLogin(loginEntrance) {
if (isVoted) {
viewModel.unLike(comment)
} else {
viewModel.like(comment)
if (viewModel is ArticleDetailViewModel) {
@ -758,8 +760,6 @@ abstract class BaseCommentAdapter(
comment.user.id ?: "", contentType, comment.id
?: "", bbsId, bbsType
)
} else {
viewModel.unLike(comment)
}
}
}

View File

@ -2,7 +2,6 @@ package com.gh.gamecenter.qa.editor
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -11,7 +10,6 @@ import android.widget.TextView
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.gamecenter.R
import com.zhihu.matisse.internal.entity.Album
import java.io.File
class VideoAlbumsAdapter(context: Context) : CursorAdapter(context, null) {
@ -24,6 +22,6 @@ class VideoAlbumsAdapter(context: Context) : CursorAdapter(context, null) {
val album = Album.valueOf(cursor)
view.findViewById<TextView>(R.id.album_name).text = album.getDisplayName(context)
view.findViewById<TextView>(R.id.album_media_count).text = album.count.toString()
view.findViewById<SimpleDraweeView>(R.id.album_cover).setImageURI(Uri.fromFile(File(album.coverPath)))
view.findViewById<SimpleDraweeView>(R.id.album_cover).setImageURI(album.coverUri)
}
}

View File

@ -47,7 +47,6 @@ import com.gh.gamecenter.video.upload.OnUploadListener
import com.gh.gamecenter.video.upload.UploadManager
import com.gh.gamecenter.video.upload.view.VideoFileEntity
import com.gh.gamecenter.video.videomanager.VideoDraftActivity
import com.lightgame.download.FileUtils
import com.lightgame.utils.Util_System_Keyboard
import java.io.File

View File

@ -21,8 +21,8 @@ import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.ndownload.NDataChanger
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.AppManager
import com.gh.gamecenter.common.utils.FileUtils
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers

View File

@ -2,7 +2,6 @@ package com.gh.gamecenter.video.poster.photo
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
@ -11,7 +10,6 @@ import android.widget.TextView
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.gamecenter.R
import com.zhihu.matisse.internal.entity.Album
import java.io.File
class PhotoAlbumsAdapter(context: Context) : CursorAdapter(context, null) {
@ -24,6 +22,6 @@ class PhotoAlbumsAdapter(context: Context) : CursorAdapter(context, null) {
val album = Album.valueOf(cursor)
view.findViewById<TextView>(R.id.album_name).text = album.getDisplayName(context)
view.findViewById<TextView>(R.id.album_media_count).text = album.count.toString()
view.findViewById<SimpleDraweeView>(R.id.album_cover).setImageURI(Uri.fromFile(File(album.coverPath)))
view.findViewById<SimpleDraweeView>(R.id.album_cover).setImageURI(album.coverUri)
}
}

View File

@ -37,7 +37,7 @@ class UploadThread(
override fun run() {
super.run()
val recordDirectory = Environment.getExternalStorageDirectory().absolutePath + "/oss_record/"
val recordDirectory = HaloApp.getInstance().filesDir.absolutePath + "/oss_record/"
val recordDir = File(recordDirectory)
if (!recordDir.exists()) {
recordDir.mkdirs()

View File

@ -53,7 +53,6 @@ import com.gh.gamecenter.video.poster.PosterEditActivity
import com.gh.gamecenter.video.upload.OnUploadListener
import com.gh.gamecenter.video.upload.UploadManager
import com.google.android.flexbox.FlexboxLayout
import com.lightgame.download.FileUtils
import com.lightgame.utils.Util_System_Keyboard
import com.lightgame.utils.Utils
import com.zhihu.matisse.Matisse

View File

@ -19,7 +19,6 @@ import com.lg.download.listener.InnerDownloadListener
import com.lg.ndownload.*
import com.lightgame.download.DownloadDao
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import com.tencent.vasdolly.reader.ChannelReader
import com.tencent.vasdolly.writer.ChannelWriter

View File

@ -14,6 +14,7 @@ import com.gh.common.util.NewFlatLogUtils
import com.gh.download.simple.*
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseBottomDialogFragment
import com.gh.gamecenter.common.utils.FileUtils
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.runOnIoThread
@ -28,7 +29,6 @@ import com.lg.download.DownloadError
import com.lg.download.DownloadStatus
import com.lg.download.httpclient.DefaultHttpClient
import com.lg.ndownload.DownloadConfigBuilder
import com.lightgame.download.FileUtils
import java.io.File
class GAppsDownloadDialogFragment : BaseBottomDialogFragment<DialogGappsDownloadBinding>() {

View File

@ -11,7 +11,7 @@ import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.halo.assistant.HaloApp
import com.leon.channel.helper.ChannelReaderUtil
import com.tencent.vasdolly.helper.ChannelReaderUtil
class FlavorProviderImp : IFlavorProvider {

View File

@ -4,7 +4,7 @@ ext {
compileSdkVersion = 34
minSdkVersion = 16
targetSdkVersion = 28
targetSdkVersion = 30
// application info (每个大版本之间的 versionCode 增加 20)
versionCode = 1050

View File

@ -19,9 +19,10 @@ package com.zhihu.matisse;
import android.content.ContentResolver;
import android.net.Uri;
import android.text.TextUtils;
import androidx.collection.ArraySet;
import android.webkit.MimeTypeMap;
import androidx.collection.ArraySet;
import com.zhihu.matisse.internal.utils.PhotoMetadataUtils;
import java.util.Arrays;
@ -110,10 +111,33 @@ public enum MimeType {
return EnumSet.of(JPEG, PNG, GIF, BMP, WEBP);
}
public static Set<MimeType> ofImage(boolean onlyGif) {
return EnumSet.of(GIF);
}
public static Set<MimeType> ofGif() {
return ofImage(true);
}
public static Set<MimeType> ofVideo() {
return EnumSet.of(MPEG, MP4, QUICKTIME, THREEGPP, THREEGPP2, MKV, WEBM, TS, AVI);
}
public static boolean isImage(String mimeType) {
if (mimeType == null) return false;
return mimeType.startsWith("image");
}
public static boolean isVideo(String mimeType) {
if (mimeType == null) return false;
return mimeType.startsWith("video");
}
public static boolean isGif(String mimeType) {
if (mimeType == null) return false;
return mimeType.equals(MimeType.GIF.toString());
}
private static Set<String> arraySetOf(String... suffixes) {
return new ArraySet<>(Arrays.asList(suffixes));
}

View File

@ -18,9 +18,10 @@ package com.zhihu.matisse.internal.entity;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import android.provider.MediaStore;
import androidx.annotation.Nullable;
import com.zhihu.matisse.R;
@ -43,20 +44,20 @@ public class Album implements Parcelable {
public static final String ALBUM_NAME_ALL = "All";
private final String mId;
private final String mCoverPath;
private final Uri mCoverUri;
private final String mDisplayName;
private long mCount;
Album(String id, String coverPath, String albumName, long count) {
public Album(String id, Uri coverUri, String albumName, long count) {
mId = id;
mCoverPath = coverPath;
mCoverUri = coverUri;
mDisplayName = albumName;
mCount = count;
}
Album(Parcel source) {
private Album(Parcel source) {
mId = source.readString();
mCoverPath = source.readString();
mCoverUri = source.readParcelable(Uri.class.getClassLoader());
mDisplayName = source.readString();
mCount = source.readLong();
}
@ -66,9 +67,10 @@ public class Album implements Parcelable {
* This method is not responsible for managing cursor resource, such as close, iterate, and so on.
*/
public static Album valueOf(Cursor cursor) {
String column = cursor.getString(cursor.getColumnIndex(AlbumLoader.COLUMN_URI));
return new Album(
cursor.getString(cursor.getColumnIndex("bucket_id")),
cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA)),
Uri.parse(column != null ? column : ""),
cursor.getString(cursor.getColumnIndex("bucket_display_name")),
cursor.getLong(cursor.getColumnIndex(AlbumLoader.COLUMN_COUNT)));
}
@ -81,7 +83,7 @@ public class Album implements Parcelable {
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(mId);
dest.writeString(mCoverPath);
dest.writeParcelable(mCoverUri, 0);
dest.writeString(mDisplayName);
dest.writeLong(mCount);
}
@ -90,8 +92,8 @@ public class Album implements Parcelable {
return mId;
}
public String getCoverPath() {
return mCoverPath;
public Uri getCoverUri() {
return mCoverUri;
}
public long getCount() {

View File

@ -55,9 +55,11 @@ public final class SelectionSpec {
public boolean hasInited;
public OnSelectedListener onSelectedListener;
public boolean originalable;
public boolean autoHideToobar;
public int originalMaxSize;
public boolean singleChoiceMode;
public OnCheckedListener onCheckedListener;
public boolean showPreview;
private SelectionSpec() {
}
@ -92,8 +94,10 @@ public final class SelectionSpec {
imageEngine = new PicassoEngine();
hasInited = true;
originalable = false;
autoHideToobar = false;
originalMaxSize = Integer.MAX_VALUE;
singleChoiceMode = false;
showPreview = true;
}
public boolean singleSelectionModeEnabled() {
@ -112,6 +116,10 @@ public final class SelectionSpec {
return showSingleMediaType && MimeType.ofVideo().containsAll(mimeTypeSet);
}
public boolean onlyShowGif() {
return showSingleMediaType && MimeType.ofGif().equals(mimeTypeSet);
}
private static final class InstanceHolder {
private static final SelectionSpec INSTANCE = new SelectionSpec();
}

View File

@ -16,36 +16,55 @@
*/
package com.zhihu.matisse.internal.loader;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.database.MergeCursor;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import androidx.loader.content.CursorLoader;
import com.zhihu.matisse.MimeType;
import com.zhihu.matisse.internal.entity.Album;
import com.zhihu.matisse.internal.entity.SelectionSpec;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* Load all albums (grouped by bucket_id) into a single cursor.
*/
public class AlbumLoader extends CursorLoader {
private static final String COLUMN_BUCKET_ID = "bucket_id";
private static final String COLUMN_BUCKET_DISPLAY_NAME = "bucket_display_name";
public static final String COLUMN_URI = "uri";
public static final String COLUMN_COUNT = "count";
private static final Uri QUERY_URI = MediaStore.Files.getContentUri("external");
private static final String[] COLUMNS = {
MediaStore.Files.FileColumns._ID,
"bucket_id",
"bucket_display_name",
MediaStore.MediaColumns.DATA,
COLUMN_BUCKET_ID,
COLUMN_BUCKET_DISPLAY_NAME,
MediaStore.MediaColumns.MIME_TYPE,
COLUMN_URI,
COLUMN_COUNT};
private static final String[] PROJECTION = {
MediaStore.Files.FileColumns._ID,
"bucket_id",
"bucket_display_name",
MediaStore.MediaColumns.DATA,
COLUMN_BUCKET_ID,
COLUMN_BUCKET_DISPLAY_NAME,
MediaStore.MediaColumns.MIME_TYPE,
"COUNT(*) AS " + COLUMN_COUNT};
private static final String[] PROJECTION_29 = {
MediaStore.Files.FileColumns._ID,
COLUMN_BUCKET_ID,
COLUMN_BUCKET_DISPLAY_NAME,
MediaStore.MediaColumns.MIME_TYPE};
// === params for showSingleMediaType: false ===
private static final String SELECTION =
"(" + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
@ -53,6 +72,11 @@ public class AlbumLoader extends CursorLoader {
+ MediaStore.Files.FileColumns.MEDIA_TYPE + "=?)"
+ " AND " + MediaStore.MediaColumns.SIZE + ">0"
+ ") GROUP BY (bucket_id";
private static final String SELECTION_29 =
"(" + MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
+ " OR "
+ MediaStore.Files.FileColumns.MEDIA_TYPE + "=?)"
+ " AND " + MediaStore.MediaColumns.SIZE + ">0";
private static final String[] SELECTION_ARGS = {
String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE),
String.valueOf(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO),
@ -64,29 +88,58 @@ public class AlbumLoader extends CursorLoader {
MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
+ " AND " + MediaStore.MediaColumns.SIZE + ">0"
+ ") GROUP BY (bucket_id";
private static final String SELECTION_FOR_SINGLE_MEDIA_TYPE_29 =
MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
+ " AND " + MediaStore.MediaColumns.SIZE + ">0";
private static String[] getSelectionArgsForSingleMediaType(int mediaType) {
return new String[]{String.valueOf(mediaType)};
}
// =============================================
// === params for showSingleMediaType: true ===
private static final String SELECTION_FOR_SINGLE_MEDIA_GIF_TYPE =
MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
+ " AND " + MediaStore.MediaColumns.SIZE + ">0"
+ " AND " + MediaStore.MediaColumns.MIME_TYPE + "=?"
+ ") GROUP BY (bucket_id";
private static final String SELECTION_FOR_SINGLE_MEDIA_GIF_TYPE_29 =
MediaStore.Files.FileColumns.MEDIA_TYPE + "=?"
+ " AND " + MediaStore.MediaColumns.SIZE + ">0"
+ " AND " + MediaStore.MediaColumns.MIME_TYPE + "=?";
private static String[] getSelectionArgsForSingleMediaGifType(int mediaType) {
return new String[]{String.valueOf(mediaType), "image/gif"};
}
// =============================================
private static final String BUCKET_ORDER_BY = "datetaken DESC";
private AlbumLoader(Context context, String selection, String[] selectionArgs) {
super(context, QUERY_URI, PROJECTION, selection, selectionArgs, BUCKET_ORDER_BY);
super(
context,
QUERY_URI,
android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q ? PROJECTION : PROJECTION_29,
selection,
selectionArgs,
BUCKET_ORDER_BY
);
}
public static CursorLoader newInstance(Context context) {
String selection;
String[] selectionArgs;
if (SelectionSpec.getInstance().onlyShowImages()) {
selection = SELECTION_FOR_SINGLE_MEDIA_TYPE;
if (SelectionSpec.getInstance().onlyShowGif()) {
selection = android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q ? SELECTION_FOR_SINGLE_MEDIA_GIF_TYPE : SELECTION_FOR_SINGLE_MEDIA_GIF_TYPE_29;
selectionArgs = getSelectionArgsForSingleMediaGifType(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE);
}else if (SelectionSpec.getInstance().onlyShowImages()) {
selection = android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q ? SELECTION_FOR_SINGLE_MEDIA_TYPE : SELECTION_FOR_SINGLE_MEDIA_TYPE_29;
selectionArgs = getSelectionArgsForSingleMediaType(MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE);
} else if (SelectionSpec.getInstance().onlyShowVideos()) {
selection = SELECTION_FOR_SINGLE_MEDIA_TYPE;
selection = android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q ? SELECTION_FOR_SINGLE_MEDIA_TYPE : SELECTION_FOR_SINGLE_MEDIA_TYPE_29;
selectionArgs = getSelectionArgsForSingleMediaType(MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO);
} else {
selection = SELECTION;
selection = android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q ? SELECTION : SELECTION_29;
selectionArgs = SELECTION_ARGS;
}
return new AlbumLoader(context, selection, selectionArgs);
@ -96,20 +149,107 @@ public class AlbumLoader extends CursorLoader {
public Cursor loadInBackground() {
Cursor albums = super.loadInBackground();
MatrixCursor allAlbum = new MatrixCursor(COLUMNS);
int totalCount = 0;
String allAlbumCoverPath = "";
if (albums != null) {
while (albums.moveToNext()) {
totalCount += albums.getInt(albums.getColumnIndex(COLUMN_COUNT));
}
if (albums.moveToFirst()) {
allAlbumCoverPath = albums.getString(albums.getColumnIndex(MediaStore.MediaColumns.DATA));
}
}
allAlbum.addRow(new String[]{Album.ALBUM_ID_ALL, Album.ALBUM_ID_ALL, Album.ALBUM_NAME_ALL, allAlbumCoverPath,
String.valueOf(totalCount)});
return new MergeCursor(new Cursor[]{allAlbum, albums});
if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
int totalCount = 0;
Uri allAlbumCoverUri = null;
MatrixCursor otherAlbums = new MatrixCursor(COLUMNS);
if (albums != null) {
while (albums.moveToNext()) {
long fileId = albums.getLong(albums.getColumnIndex(MediaStore.Files.FileColumns._ID));
long bucketId = albums.getLong(albums.getColumnIndex(COLUMN_BUCKET_ID));
String bucketDisplayName = albums.getString(albums.getColumnIndex(COLUMN_BUCKET_DISPLAY_NAME));
String mimeType = albums.getString(albums.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE));
Uri uri = getUri(albums);
int count = albums.getInt(albums.getColumnIndex(COLUMN_COUNT));
otherAlbums.addRow(new String[]{Long.toString(fileId), Long.toString(bucketId), bucketDisplayName, mimeType, uri.toString(),
String.valueOf(count)});
totalCount += count;
}
if (albums.moveToFirst()) {
allAlbumCoverUri = getUri(albums);
}
}
allAlbum.addRow(new String[]{Album.ALBUM_ID_ALL, Album.ALBUM_ID_ALL, Album.ALBUM_NAME_ALL, null,
allAlbumCoverUri == null ? null : allAlbumCoverUri.toString(),
String.valueOf(totalCount)});
return new MergeCursor(new Cursor[]{allAlbum, otherAlbums});
} else {
int totalCount = 0;
Uri allAlbumCoverUri = null;
// Pseudo GROUP BY
Map<Long, Long> countMap = new HashMap<>();
if (albums != null) {
while (albums.moveToNext()) {
long bucketId = albums.getLong(albums.getColumnIndex(COLUMN_BUCKET_ID));
Long count = countMap.get(bucketId);
if (count == null) {
count = 1L;
} else {
count++;
}
countMap.put(bucketId, count);
}
}
MatrixCursor otherAlbums = new MatrixCursor(COLUMNS);
if (albums != null) {
if (albums.moveToFirst()) {
allAlbumCoverUri = getUri(albums);
Set<Long> done = new HashSet<>();
do {
long bucketId = albums.getLong(albums.getColumnIndex(COLUMN_BUCKET_ID));
if (done.contains(bucketId)) {
continue;
}
long fileId = albums.getLong(albums.getColumnIndex(MediaStore.Files.FileColumns._ID));
String bucketDisplayName = albums.getString(albums.getColumnIndex(COLUMN_BUCKET_DISPLAY_NAME));
String mimeType = albums.getString(albums.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE));
Uri uri = getUri(albums);
long count = countMap.get(bucketId);
otherAlbums.addRow(new String[]{Long.toString(fileId), Long.toString(bucketId), bucketDisplayName, mimeType, uri.toString(),
String.valueOf(count)});
done.add(bucketId);
totalCount += count;
} while (albums.moveToNext());
}
}
allAlbum.addRow(new String[]{Album.ALBUM_ID_ALL, Album.ALBUM_ID_ALL, Album.ALBUM_NAME_ALL, null,
allAlbumCoverUri == null ? null : allAlbumCoverUri.toString(),
String.valueOf(totalCount)});
return new MergeCursor(new Cursor[]{allAlbum, otherAlbums});
}
}
private static Uri getUri(Cursor cursor) {
long id = cursor.getLong(cursor.getColumnIndex(MediaStore.Files.FileColumns._ID));
String mimeType = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE));
Uri contentUri;
if (MimeType.isImage(mimeType)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if (MimeType.isVideo(mimeType)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else {
// ?
contentUri = MediaStore.Files.getContentUri("external");
}
Uri uri = ContentUris.withAppendedId(contentUri, id);
return uri;
}
@Override

View File

@ -19,7 +19,6 @@ import android.content.Context;
import android.content.res.TypedArray;
import android.database.Cursor;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -31,8 +30,6 @@ import com.zhihu.matisse.R;
import com.zhihu.matisse.internal.entity.Album;
import com.zhihu.matisse.internal.entity.SelectionSpec;
import java.io.File;
public class AlbumsAdapter extends CursorAdapter {
private final Drawable mPlaceholder;
@ -69,6 +66,6 @@ public class AlbumsAdapter extends CursorAdapter {
// do not need to load animated Gif
SelectionSpec.getInstance().imageEngine.loadThumbnail(context, context.getResources().getDimensionPixelSize(R
.dimen.media_grid_size), mPlaceholder,
(ImageView) view.findViewById(R.id.album_cover), Uri.fromFile(new File(album.getCoverPath())));
(ImageView) view.findViewById(R.id.album_cover), album.getCoverUri());
}
}

View File

@ -335,12 +335,7 @@ public class MatisseActivity extends AppCompatActivity implements
if (applyFilter != null) {
applyFilter.applyFiltering(this,
mSelectedCollection.asList(),
new ApplyFilter.OnApplyFilterCallBack() {
@Override
public void onApply() {
sendBackResult();
}
});
() -> sendBackResult());
} else {
sendBackResult();
}

View File

@ -51,11 +51,12 @@ import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.common.constant.RouteConsts;
import com.gh.gamecenter.common.eventbus.EBShowDialog;
import com.gh.gamecenter.common.tracker.IBusiness;
import com.gh.gamecenter.common.utils.DarkModeUtils;
import com.gh.gamecenter.common.utils.DialogHelper;
import com.gh.gamecenter.common.utils.EnvHelper;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.common.utils.DarkModeUtils;
import com.gh.gamecenter.common.utils.NewFlatLogUtils;
import com.gh.gamecenter.common.utils.PackageFlavorHelper;
import com.gh.gamecenter.common.utils.SensorsBridge;
@ -71,7 +72,6 @@ import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.core.utils.StringUtils;
import com.lightgame.BaseAppCompatActivity;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.Utils;
import com.tencent.tauth.Tencent;

View File

@ -225,21 +225,8 @@ object MetaUtil {
ConnectivityManager.TYPE_MOBILE -> {
val telephonyManager = application.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
if (telephonyManager.simState != TelephonyManager.SIM_STATE_READY) return "unknown"
when (telephonyManager.networkType) {
// Unknown
TelephonyManager.NETWORK_TYPE_UNKNOWN -> "unknown"
// Cellular Data2G
TelephonyManager.NETWORK_TYPE_EDGE, TelephonyManager.NETWORK_TYPE_GPRS, TelephonyManager.NETWORK_TYPE_CDMA,
TelephonyManager.NETWORK_TYPE_IDEN, TelephonyManager.NETWORK_TYPE_1xRTT -> "2G"
// Cellular Data3G
TelephonyManager.NETWORK_TYPE_UMTS, TelephonyManager.NETWORK_TYPE_HSDPA, TelephonyManager.NETWORK_TYPE_HSPA,
TelephonyManager.NETWORK_TYPE_HSPAP, TelephonyManager.NETWORK_TYPE_HSUPA, TelephonyManager.NETWORK_TYPE_EVDO_0,
TelephonyManager.NETWORK_TYPE_EVDO_A, TelephonyManager.NETWORK_TYPE_EVDO_B -> "3G"
// Cellular Data4G
TelephonyManager.NETWORK_TYPE_LTE -> "4G"
TelephonyManager.NETWORK_TYPE_NR -> "5G"
else -> "unknown"
}
return "MOBILE"
}
else -> "unknown"

View File

@ -2,9 +2,9 @@ package com.gh.gamecenter.common.retrofit;
import android.content.Context;
import com.gh.gamecenter.core.utils.MD5Utils;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.TimestampUtils;
import com.lightgame.download.FileUtils;
import com.gh.gamecenter.core.utils.MD5Utils;
import java.io.File;
import java.io.IOException;

View File

@ -124,41 +124,7 @@ public class DeviceUtils {
if (typeMobile == ConnectivityManager.TYPE_WIFI) {
return "WIFI";
} else if (typeMobile == ConnectivityManager.TYPE_MOBILE) {
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
if (telephonyManager != null) {
int networkType = telephonyManager.getNetworkType();
String status;
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN:
status = "2G";
break;
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
case TelephonyManager.NETWORK_TYPE_EHRPD:
case TelephonyManager.NETWORK_TYPE_HSPAP:
status = "3G";
break;
case TelephonyManager.NETWORK_TYPE_LTE:
status = "4G";
break;
case TelephonyManager.NETWORK_TYPE_NR:
status = "5G";
break;
default:
status = "未知";
break;
}
return status;
}
return "MOBILE";
}
}

View File

@ -0,0 +1,613 @@
package com.gh.gamecenter.common.utils;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.os.StrictMode;
import android.provider.MediaStore;
import androidx.annotation.Nullable;
import org.json.JSONObject;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.UUID;
/**
* @author guanchao wen
* @email shuwoom.wgc@gmail.com
* @modify hzh 2016/03/16
* @update 2015-7-29下午2:26:02
*/
public class FileUtils {
public static String getDownloadPath(Context context, String name) {
return getDownloadDir(context) + File.separator + name;
}
public static String getDownloadDir(Context context) {
String dir;
String baseDir;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
try {
// 在部分设备,可能是使用 sd 卡的设备? getExternalFilesDir 方法返回 null
// 异常时使用备用存储位置作为下载地址
baseDir = context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
} catch (NullPointerException exception) {
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M) {
// Android 6.0 的设备无法直接下载至根目录 Download 文件夹(需要获取外部存储权限)
// 使用 getFilesDir 方法后,默认情况下 PackageInstaller 无法获取直接读取安装 APK
// 一般的处理方式是下载的时候将文件 openFileOutput(APK_FILENAME, Context.MODE_WORLD_READABLE)
// 但因为下载文件由下载模块创建,暂时不做修改,换成在下载完成后调用 file.setReadable(true, false) 使文件可读
baseDir = context.getFilesDir().getAbsolutePath();
} else {
baseDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
}
}
} else {
baseDir = context.getFilesDir().getAbsolutePath();
}
dir = checkDir(baseDir + File.separator + "gh-files");
try {
Runtime.getRuntime().exec("chmod 755 " + dir);
} catch (IOException e) {
e.printStackTrace();
}
return dir;
}
public static boolean isMounted() {
return Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
}
private static String checkDir(String dir) {
File directory = new File(dir);
if (directory.exists() && !directory.isDirectory()) {
directory.delete();
}
if (!directory.exists()) {
directory.mkdirs();
}
return dir;
}
public static String getLogPath(Context context, String name) {
return checkDir(getDir(context, "log")) + File.separator + name;
}
public static String getDir(Context context, String dir) {
if (isMounted()) {
// /storage/emulated/0/Android/data/包名/files
File file = context.getExternalFilesDir(null);
if (file != null) {
return file.getAbsolutePath() + File.separator + dir;
}
}
// /data/data/包名/files
return context.getFilesDir().getAbsolutePath() + File.separator + dir;
}
public static String getPlatformPicDir(Context context) {
return checkDir(getDir(context, "PlatformPic"));
}
public static void deleteFile(String savePath) {
try {
File file = new File(savePath);
if (file.exists()) {
file.delete();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public static void deleteFolder(File folder) {
if (folder != null) {
if (folder.isDirectory()) {
for (File file : folder.listFiles()) {
if (file.isDirectory()) {
deleteFolder(file);
} else {
file.delete();
}
}
}
folder.delete();
}
}
public static boolean isEmptyFile(String path) {
File file = new File(path);
return !(file.exists() && file.length() != 0);
}
public static String isCanDownload(Context context, String size) {
String msg = null;
String packageSizeStr = "";
for (int i = 0; i < size.length(); i++) {
if ((size.charAt(i) >= 48 && size.charAt(i) <= 57) || size.charAt(i) == 46) {
packageSizeStr += size.charAt(i);
}
}
float packageSize = 0;
if (packageSizeStr.length() != 0) {
packageSize = Float.valueOf(packageSizeStr);
}
float freeSpace = getFreeSpaceByPath(getDownloadDir(context));
if (freeSpace < packageSize) {
msg = "手机存储空间不足,无法进行下载!";
}
return msg;
}
public static String isCanDownload(Context context, long size) {
String msg = null;
float freeSpace = getFreeSpaceByPath(getDownloadDir(context));
if (freeSpace < size / 1024f / 1024f) {
msg = "手机存储空间不足,无法进行下载!";
}
return msg;
}
// 返回剩余空间 单位MB
@SuppressWarnings("deprecation")
public static float getFreeSpaceByPath(String path) {
// 部分用 SD卡的老手机会抛出 java.lang.IllegalArgumentException: Invalid path: 的异常
// 出现这异常干脆返回 8192MB 让他下
try {
StatFs statfs = new StatFs(path);
long blockSize = statfs.getBlockSize();
long availableBlocks = statfs.getAvailableBlocks();
return availableBlocks * blockSize / 1024f / 1024f;
} catch (Exception e) {
e.printStackTrace();
return 8192;
}
}
// 下载文件
public static int downloadFile(String url, String savePath) {
DataInputStream dis = null;
FileOutputStream fos = null;
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5 * 1000);
connection.setReadTimeout(5 * 1000);
connection.connect();
int code = connection.getResponseCode();
if (code == 200) {
dis = new DataInputStream(connection.getInputStream());
File file = new File(savePath);
if (file.exists()) {
file.delete();
}
file.getParentFile().mkdir();
file.createNewFile();
fos = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int len;
while ((len = dis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.flush();
}
return code;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dis != null) {
try {
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return -1;
}
// 下载并更新文件 (与上面方法的不同之处是只有在下载完成以后才会更新旧文件)
public static int downloadAndUpdateFile(String url, String savePath) {
DataInputStream dis = null;
FileOutputStream fos = null;
try {
String tempSavePath = savePath + ".tmp";
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod("GET");
connection.setConnectTimeout(5 * 1000);
connection.setReadTimeout(5 * 1000);
connection.connect();
int code = connection.getResponseCode();
if (code == 200) {
dis = new DataInputStream(connection.getInputStream());
File tempFile = new File(tempSavePath);
if (tempFile.exists()) {
tempFile.delete();
}
tempFile.getParentFile().mkdir();
tempFile.createNewFile();
fos = new FileOutputStream(tempFile);
byte[] buffer = new byte[1024];
int len;
while ((len = dis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.flush();
File file = new File(savePath);
if (file.exists()) {
file.delete();
}
tempFile.renameTo(file);
}
return code;
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (dis != null) {
try {
dis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return -1;
}
// 上传文件
public static JSONObject uploadFile(String url, String filePath, String token) {
String end = "\r\n";
String twoHyphens = "--";
String boundary = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
/*
* Output to the connection. Default is false, set to true because
* post method must write something to the connection
*/
connection.setDoOutput(true);
// Read from the connection. Default is true.
connection.setDoInput(true);
// Post cannot use caches
connection.setUseCaches(false);
// Set the post method. Default is GET
connection.setRequestMethod("POST");
connection.setConnectTimeout(5 * 1000);
connection.setReadTimeout(5 * 1000);
// 设置请求属性
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Charset", "UTF-8");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
if (token != null) {
connection.setRequestProperty("TOKEN", token);
}
// 设置StrictMode 否则HTTPURLConnection连接失败因为这是在主进程中进行网络连接
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads().detectDiskWrites().detectNetwork()
.penaltyLog().build());
File file = new File(filePath);
// if (file.exists()) {
// Utils.log("name = " + file.getName());
// Utils.log("length = " + file.length());
// }
// 设置DataOutputStreamgetOutputStream中默认调用connect()
DataOutputStream dos = new DataOutputStream(connection.getOutputStream()); // output
// to the connection
dos.writeBytes(twoHyphens + boundary + end);
dos.writeBytes("Content-Disposition: form-data; "
+ "name=\"Filedata\";filename=\"" + file.getName() + "\"" + end);
dos.writeBytes(end);
// 取得文件的FileInputStream
FileInputStream fStream = new FileInputStream(file);
// 设置每次写入8192bytes
int bufferSize = 8192;
byte[] buffer = new byte[bufferSize]; // 8k
int length;
// 从文件读取数据至缓冲区
while ((length = fStream.read(buffer)) != -1) {
// 将资料写入DataOutputStream中
dos.write(buffer, 0, length);
}
dos.writeBytes(end);
dos.writeBytes(twoHyphens + boundary + twoHyphens + end);
// 关闭流写入的东西自动生成Http正文
fStream.close();
// 关闭DataOutputStream
dos.flush();
dos.close();
InputStream inputStream;
try {
inputStream = connection.getInputStream();
} catch (IOException ioe) {
inputStream = connection.getErrorStream();
}
int ch;
StringBuffer b = new StringBuffer();
while ((ch = inputStream.read()) != -1) {
b.append((char) ch);
}
// 显示网页响应内容
// Utils.log("content = " + b.toString().trim());
int statusCode = connection.getResponseCode();
// Utils.log("statusCode = " + statusCode);
JSONObject response = null;
switch (statusCode) {
case 200:
// {"icon":"http:\/\/gh-test-1.oss-cn-qingdao.aliyuncs.com\/pic\/57e4f4d58a3200042d29492f.jpg"}
response = new JSONObject(b.toString().trim());
response.put("statusCode", 200);
break;
case 403:
response = new JSONObject(b.toString().trim());
response.put("statusCode", 403);
break;
case 401:
response = new JSONObject();
response.put("statusCode", 401);
break;
}
return response;
} catch (Exception e) {
// 显示异常信息
e.printStackTrace();
// Utils.log("Fail:" + e);
}
return null;
}
// 上传文件 realPath:真实路径(防止对文件压缩后filePath路径改变) 提交成功后会返回该路径 以便识别上传文件的身份
public static JSONObject uploadFile(String url, String filePath, String realPath, String token) {
String end = "\r\n";
String twoHyphens = "--";
String boundary = UUID.randomUUID().toString().replaceAll("-", "").substring(0, 16);
try {
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
/*
* Output to the connection. Default is false, set to true because
* post method must write something to the connection
*/
connection.setDoOutput(true);
// Read from the connection. Default is true.
connection.setDoInput(true);
// Post cannot use caches
connection.setUseCaches(false);
// Set the post method. Default is GET
connection.setRequestMethod("POST");
connection.setConnectTimeout(5 * 1000);
connection.setReadTimeout(5 * 1000);
// 设置请求属性
connection.setRequestProperty("Connection", "Keep-Alive");
connection.setRequestProperty("Charset", "UTF-8");
connection.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
if (token != null) {
connection.setRequestProperty("TOKEN", token);
}
// 设置StrictMode 否则HTTPURLConnection连接失败因为这是在主进程中进行网络连接
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
.detectDiskReads().detectDiskWrites().detectNetwork()
.penaltyLog().build());
File file = new File(filePath);
// if (file.exists()) {
// Utils.log("name = " + file.getName());
// Utils.log("length = " + file.length());
// }
// 设置DataOutputStreamgetOutputStream中默认调用connect()
DataOutputStream dos = new DataOutputStream(connection.getOutputStream()); // output
// to the connection
dos.writeBytes(twoHyphens + boundary + end);
dos.writeBytes("Content-Disposition: form-data; "
+ "name=\"Filedata\";filename=\"" + file.getName() + "\"" + end);
dos.writeBytes(end);
// 取得文件的FileInputStream
FileInputStream fStream = new FileInputStream(file);
// 设置每次写入8192bytes
int bufferSize = 8192;
byte[] buffer = new byte[bufferSize]; // 8k
int length;
// 从文件读取数据至缓冲区
while ((length = fStream.read(buffer)) != -1) {
// 将资料写入DataOutputStream中
dos.write(buffer, 0, length);
}
dos.writeBytes(end);
dos.writeBytes(twoHyphens + boundary + twoHyphens + end);
// 关闭流写入的东西自动生成Http正文
fStream.close();
// 关闭DataOutputStream
dos.flush();
dos.close();
InputStream inputStream;
try {
inputStream = connection.getInputStream();
} catch (IOException ioe) {
inputStream = connection.getErrorStream();
}
int ch;
StringBuffer b = new StringBuffer();
while ((ch = inputStream.read()) != -1) {
b.append((char) ch);
}
// 显示网页响应内容
// Utils.log("content = " + b.toString().trim());
int statusCode = connection.getResponseCode();
// Utils.log("statusCode = " + statusCode);
JSONObject response = null;
switch (statusCode) {
case 200:
// {"icon":"http:\/\/gh-test-1.oss-cn-qingdao.aliyuncs.com\/pic\/57e4f4d58a3200042d29492f.jpg"}
response = new JSONObject(b.toString().trim());
response.put("statusCode", 200);
response.put("realPath", realPath);
break;
case 403:
response = new JSONObject(b.toString().trim());
response.put("statusCode", 403);
response.put("realPath", realPath);
break;
case 401:
response = new JSONObject();
response.put("statusCode", 401);
break;
}
return response;
} catch (Exception e) {
// 显示异常信息
e.printStackTrace();
// Utils.log("Fail:" + e);
}
return null;
}
// 读取文件返回byte[]
public static byte[] readFile(File file) {
if (file == null) {
return null;
}
FileInputStream fis = null;
ByteArrayOutputStream bos = null;
try {
fis = new FileInputStream(file);
bos = new ByteArrayOutputStream();
byte[] buffer = new byte[2048];
int len;
while ((len = fis.read(buffer)) != -1) {
bos.write(buffer, 0, len);
}
bos.flush();
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return null;
}
// 根据byte[],保存文件
public static void saveFile(File file, byte[] data) {
if (file == null || data == null) {
return;
}
ByteArrayInputStream bis = null;
FileOutputStream fos = null;
try {
bis = new ByteArrayInputStream(data);
fos = new FileOutputStream(file);
byte[] buffer = new byte[2048];
int len;
while ((len = bis.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
fos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* @param context suggestion application context
* @param filePath file path
* @return A MIME type for the content {category}/{type}
* example: video/mp4
*/
@Nullable
public static String getFileMimeType(Context context, String filePath) {
Uri contentUri = getFileContentUri(context, filePath);
if (contentUri != null) {
return context.getContentResolver().getType(contentUri);
}
return null;
}
@Nullable
public static Uri getFileContentUri(Context context, String filePath) {
Cursor cursor = null;
try {
String absolutePath = new File(filePath).getAbsolutePath();
cursor = context.getContentResolver().query(
MediaStore.Files.getContentUri("external"),
new String[]{MediaStore.Files.FileColumns._ID},
MediaStore.Files.FileColumns.DATA + "=? ",
new String[]{absolutePath}, null);
if (cursor != null && cursor.moveToFirst()) {
int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
cursor.close();
return Uri.withAppendedPath(MediaStore.Files.getContentUri("external"), "" + id);
} else return null;
} catch (Exception ignore) {
} finally {
if (cursor != null) cursor.close();
}
return null;
}
}

View File

@ -94,39 +94,46 @@ public class NetworkUtils {
}
/**
* 获取当前移动网络连接的类型信息(当连接的网络是移动网络时使用)
* 获取当前网络连接的类型信息
*
* @param context 上下文
* @return 当前移动网络连接的类型信息
* @return 当前网络连接的类型信息
*/
public static String getMobileNetworkType(Context context) {
TelephonyManager mTelephonyManager = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
int networkType = mTelephonyManager.getNetworkType();
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN:
return "2G";
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
case TelephonyManager.NETWORK_TYPE_EHRPD:
case TelephonyManager.NETWORK_TYPE_HSPAP:
return "3G";
case TelephonyManager.NETWORK_TYPE_LTE:
return "4G";
case TelephonyManager.NETWORK_TYPE_NR:
return "5G";
default:
return "unknown";
public static String getConnectedType(Context context) {
if (context != null) {
context = context.getApplicationContext();
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager
.getActiveNetworkInfo();
if (mNetworkInfo != null && mNetworkInfo.isAvailable()) {
switch (mNetworkInfo.getType()) {
case ConnectivityManager.TYPE_BLUETOOTH:
return "BLUETOOTH";
case ConnectivityManager.TYPE_DUMMY:
return "DUMMY";
case ConnectivityManager.TYPE_ETHERNET:
return "ETHERNET";
case ConnectivityManager.TYPE_MOBILE:
return "MOBILE";
case ConnectivityManager.TYPE_MOBILE_DUN:
return "MOBILE_DUN";
case ConnectivityManager.TYPE_MOBILE_HIPRI:
return "MOBILE_HIPRI";
case ConnectivityManager.TYPE_MOBILE_MMS:
return "MOBILE_MMS";
case ConnectivityManager.TYPE_MOBILE_SUPL:
return "MOBILE_SUPL";
case ConnectivityManager.TYPE_WIFI:
return "WIFI";
case ConnectivityManager.TYPE_WIMAX:
return "WIMAX";
default:
break;
}
}
}
return "NONE";
}
}

View File

@ -32,6 +32,9 @@ public class DisplayUtils {
public static boolean sShouldUseLegacyMiuiStatusBarMethod = true;
private static int sGlobalScreenWidth = 0;
private static int sGlobalScreenHeight = 0;
/**
* 根据手机的分辨率从 dip(像素) 的单位 转成为 px
*/
@ -296,18 +299,28 @@ public class DisplayUtils {
return false;
}
public static int getScreenWidth() {
WindowManager manager = (WindowManager) HaloApp.getInstance().getSystemService(Context.WINDOW_SERVICE);
public static void updateGlobalScreen(Activity activity) {
WindowManager manager = (WindowManager) activity.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(metrics);
return metrics.widthPixels;
sGlobalScreenWidth = metrics.widthPixels;
sGlobalScreenHeight = metrics.heightPixels;
}
/**
* 如需实时获取屏幕宽度,请传入当前 Activity
*/
@Deprecated
public static int getScreenWidth() {
return sGlobalScreenWidth;
}
/**
* 如需实时获取屏幕高度,请传入当前 Activity
*/
@Deprecated
public static int getScreenHeight() {
WindowManager manager = (WindowManager) HaloApp.getInstance().getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(metrics);
return metrics.heightPixels;
return sGlobalScreenHeight;
}
public static int getScreenWidth(Activity activity) {

View File

@ -11,12 +11,12 @@ import androidx.core.content.ContextCompat;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.feature.HaloApp;
import com.gh.gamecenter.feature.R;
import com.gh.gamecenter.feature.entity.PlatformEntity;
import com.gh.gamecenter.feature.retrofit.RetrofitManager;
import com.lightgame.download.FileUtils;
import org.greenrobot.eventbus.EventBus;

View File

@ -82,7 +82,7 @@ class GameDownloadSettingFragment : ToolbarFragment() {
contentTv.visibility = View.VISIBLE
root.setOnClickListener {
MtaHelper.onEvent("我的光环_设置", "设置功能", "游戏下载目录")
if (TextUtils.isEmpty(dirPath)) dirPath = Environment.getExternalStorageDirectory().path + "/gh-files"
if (TextUtils.isEmpty(dirPath)) dirPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).path + "/gh-files"
startFilePath(dirPath)
}
}

View File

@ -47,7 +47,6 @@ import com.gh.gamecenter.setting.R
import com.gh.gamecenter.setting.databinding.FragmentSettingBinding
import com.gh.gamecenter.setting.view.security.SecurityActivity
import com.gh.gid.GidHelper
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import io.reactivex.Observable
import io.reactivex.ObservableEmitter

View File

@ -15,7 +15,7 @@
<string name="setting_notification_authority_hint">开启后你可以及时收到重要通知</string>
<string name="setting_personal_recommend">个性化推荐</string>
<string name="setting_personal_recommend_hint">开启功能后,您在本应用的使用信息(如下载信息),将用于个性化内容推荐,以提升您在本应用的体验</string>
<string name="setting_download_path_des">…/gh-files</string>
<string name="setting_download_path_des">…/Download/gh-files</string>
<string name="setting_pic_path_des">…/pictures/ghzhushou</string>
<string name="setting_download_path">游戏下载目录</string>
<string name="setting_pic_path">图片保存目录</string>

View File

@ -79,7 +79,7 @@ class ComposeGameDownloadSettingActivity : ComposeBaseActivity() {
SettingItem(
getString(R.string.setting_download_path), content = getString(R.string.setting_download_path_des)
) {
val dirPath = Environment.getExternalStorageDirectory().path + "/gh-files"
val dirPath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).path + "/gh-files"
startFilePath(dirPath)
}
SettingDivider()

View File

@ -55,7 +55,6 @@ import com.gh.gamecenter.setting.compose.ui.component.Space
import com.gh.gamecenter.setting.compose.ui.theme.*
import com.gh.gamecenter.setting.compose.viewmodel.ComposeSettingViewModel
import com.gh.gid.GidHelper
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import io.reactivex.Observable
import io.reactivex.ObservableEmitter

View File

@ -16,7 +16,7 @@
<string name="setting_notification_authority_hint">开启后你可以及时收到重要通知</string>
<string name="setting_personal_recommend">个性化推荐</string>
<string name="setting_personal_recommend_hint">开启功能后,您在本应用的使用信息(如下载信息),将用于个性化内容推荐,以提升您在本应用的体验</string>
<string name="setting_download_path_des">…/gh-files</string>
<string name="setting_download_path_des">…/Download/gh-files</string>
<string name="setting_pic_path_des">…/pictures/ghzhushou</string>
<string name="setting_download_path">游戏下载目录</string>
<string name="setting_pic_path">图片保存目录</string>