diff --git a/app/src/main/java/com/gh/common/util/Extensions.kt b/app/src/main/java/com/gh/common/util/Extensions.kt index 027b3e7db4..8570c598e5 100644 --- a/app/src/main/java/com/gh/common/util/Extensions.kt +++ b/app/src/main/java/com/gh/common/util/Extensions.kt @@ -130,11 +130,13 @@ fun String.fromHtml(): Spanned { return Html.fromHtml(this) } +// 完全地清除所有 Html 格式 fun String.clearHtmlFormatCompletely(): String { return Html.fromHtml(this).toString().replace('\n', 32.toChar()) .replace(160.toChar(), 32.toChar()).replace(65532.toChar(), 32.toChar()).trim { it <= ' ' } } +// 如果该字符串长度超过固定长度的话,从头开始截取固定长度并返回 fun String.subStringIfPossible(length: Int): String { return if (this.length > length) { this.substring(0, length) diff --git a/app/src/main/java/com/gh/common/util/PackageUtils.java b/app/src/main/java/com/gh/common/util/PackageUtils.java index 72a5bbbbdd..206a21f72b 100644 --- a/app/src/main/java/com/gh/common/util/PackageUtils.java +++ b/app/src/main/java/com/gh/common/util/PackageUtils.java @@ -371,6 +371,25 @@ public class PackageUtils { return jsonArray; } + public static JSONObject getAppBasicInfoByPackageName(String packageName) { + JSONObject jsonObject = new JSONObject(); + + try { + PackageInfo packageInfo = HaloApp.getInstance().getApplication().getPackageManager().getPackageInfo(packageName, + PackageManager.COMPONENT_ENABLED_STATE_DEFAULT); + if ((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { + jsonObject.put("name", packageInfo.applicationInfo.toString()); + jsonObject.put("package", packageName); + jsonObject.put("version", packageInfo.versionName); + } + return jsonObject; + } catch (JSONException | NameNotFoundException e) { + e.printStackTrace(); + return jsonObject; + } + } + + /* * 启动应用 */ diff --git a/app/src/main/java/com/gh/common/util/SpUtils.kt b/app/src/main/java/com/gh/common/util/SpUtils.kt index 905eea916c..de1f3f8463 100644 --- a/app/src/main/java/com/gh/common/util/SpUtils.kt +++ b/app/src/main/java/com/gh/common/util/SpUtils.kt @@ -45,6 +45,16 @@ object SPUtils { return sp.getInt(key, defaultValue) } + @JvmStatic + fun getLong(key: String, defaultValue: Long): Long { + return sp.getLong(key, defaultValue) + } + + @JvmStatic + fun setLong(key: String, value: Long) { + return sp.edit().putLong(key, value).apply() + } + @JvmStatic fun setBoolean(key: String, value: Boolean) { sp.edit().putBoolean(key, value).apply() diff --git a/app/src/main/java/com/gh/gamecenter/MainActivity.java b/app/src/main/java/com/gh/gamecenter/MainActivity.java index f5db512e96..30da612f7d 100644 --- a/app/src/main/java/com/gh/gamecenter/MainActivity.java +++ b/app/src/main/java/com/gh/gamecenter/MainActivity.java @@ -1,5 +1,6 @@ package com.gh.gamecenter; +import android.annotation.SuppressLint; import android.app.Dialog; import android.app.NotificationManager; import android.arch.lifecycle.ViewModelProviders; @@ -72,6 +73,7 @@ import com.gh.gamecenter.manager.UserManager; import com.gh.gamecenter.normal.NormalFragment; import com.gh.gamecenter.packagehelper.PackageViewModel; import com.gh.gamecenter.qa.AskFragment; +import com.gh.gamecenter.retrofit.BiResponse; import com.gh.gamecenter.retrofit.Response; import com.gh.gamecenter.retrofit.RetrofitManager; import com.gh.gamecenter.suggest.SuggestType; @@ -92,6 +94,7 @@ import com.tencent.bugly.crashreport.CrashReport; import org.greenrobot.eventbus.EventBus; import org.greenrobot.eventbus.Subscribe; import org.greenrobot.eventbus.ThreadMode; +import org.jetbrains.annotations.NotNull; import org.json.JSONObject; import java.io.BufferedReader; @@ -816,17 +819,11 @@ public class MainActivity extends BaseActivity { } } } - - // 更新已安装游戏 - RetrofitManager.getInstance(MainActivity.this).getApi() - .postPackage(UserManager.getInstance().getUserId(), packageName) - .subscribeOn(Schedulers.io()) - .observeOn(Schedulers.io()) - .subscribe(new Response<>()); } }); } + postNewlyInstalledApp(packageName); } if ("卸载".equals(busFour.getType())) { mPackageViewModel.addUninstalledGame(packageName); @@ -847,16 +844,58 @@ public class MainActivity extends BaseActivity { } // 更新已安装游戏 - RetrofitManager.getInstance(this).getApi() - .deletePackage(UserManager.getInstance().getUserId(), packageName) - .subscribeOn(Schedulers.io()) - .observeOn(Schedulers.io()) - .subscribe(new Response<>()); + deleteInstalledPackage(packageName); } DataCollectionUtils.uploadInorunstall(this, busFour.getType(), busFour.getPackageName()); } + @SuppressLint("CheckResult") + private void postNewlyInstalledApp(String packageName) { + + JSONObject packageObject = PackageUtils.getAppBasicInfoByPackageName(packageName); + + RequestBody requestBody = RequestBody.create(MediaType.parse("application/json"), + packageObject.toString()); + + // 更新已安装游戏 + RetrofitManager.getInstance(MainActivity.this).getApi() + .postNewlyInstalledApp(HaloApp.getInstance().getGid(), requestBody) + .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.io()) + .subscribe(new BiResponse() { + @Override + public void onSuccess(ResponseBody data) { + // do nothing + } + + @Override + public void onFailure(@NotNull Exception exception) { + exception.printStackTrace(); + } + }); + } + + @SuppressLint("CheckResult") + private void deleteInstalledPackage(String packageName) { + // 删除已安装游戏 + RetrofitManager.getInstance(MainActivity.this).getApi() + .deleteInstalledApp(HaloApp.getInstance().getGid(), packageName) + .subscribeOn(Schedulers.io()) + .observeOn(Schedulers.io()) + .subscribe(new BiResponse() { + @Override + public void onSuccess(ResponseBody data) { + // do nothing + } + + @Override + public void onFailure(@NotNull Exception exception) { + exception.printStackTrace(); + } + }); + } + // 接收登录和登出更新事件统计的 Meta @Subscribe(threadMode = ThreadMode.MAIN) public void onEventMainThread(EBReuse reuse) { diff --git a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt index f2b8c7b861..918efe3215 100644 --- a/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt +++ b/app/src/main/java/com/gh/gamecenter/packagehelper/PackageRepository.kt @@ -1,5 +1,6 @@ package com.gh.gamecenter.packagehelper +import android.annotation.SuppressLint import android.arch.lifecycle.MutableLiveData import android.preference.PreferenceManager import android.text.TextUtils @@ -13,6 +14,7 @@ import com.gh.gamecenter.manager.FilterManager import com.gh.gamecenter.manager.PackagesManager import com.gh.gamecenter.packagehelper.PackageRepository.gameInstalled import com.gh.gamecenter.packagehelper.PackageRepository.gameUpdate +import com.gh.gamecenter.retrofit.BiResponse import com.gh.gamecenter.retrofit.ObservableUtil import com.gh.gamecenter.retrofit.Response import com.gh.gamecenter.retrofit.RetrofitManager @@ -21,6 +23,9 @@ import com.lightgame.utils.Utils import com.tencent.bugly.beta.tinker.TinkerManager.getApplication import io.reactivex.android.schedulers.AndroidSchedulers import io.reactivex.schedulers.Schedulers +import okhttp3.MediaType +import okhttp3.RequestBody +import okhttp3.ResponseBody import retrofit2.HttpException /** @@ -40,6 +45,8 @@ object PackageRepository { private val mApi = RetrofitManager.getInstance(mApplication).api private val mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(mApplication) + private const val LAST_UPLOAD_APPLIST_TIME = "last_upload_applist_time" + private val mInstalledPkgList = ArrayList() val gameUpdateLiveData = MutableLiveData>() @@ -100,15 +107,39 @@ object PackageRepository { } /** - * 上传已安装的应用数据 + * 上传已安装的应用数据,data 后台和 api 后台数据独立 */ + @SuppressLint("CheckResult") private fun uploadAppList() { - //检查是否符合应用上报周期 - val time = mSharedPreferences.getLong("last_upload_applist_time", 0) - //一周为一个周期 + // 检查是否符合应用上报周期, 用的不同 SP 不冲突 + val time = mSharedPreferences.getLong(LAST_UPLOAD_APPLIST_TIME, 0) + val lastUploadTime = SPUtils.getLong(LAST_UPLOAD_APPLIST_TIME, 0) + + // 上传到 data 后台一周一个周期 if (Utils.getTime(mApplication) - time >= 604800L) { DataCollectionUtils.uploadAppList(mApplication, PackageUtils.getAppList(mApplication)) } + + // 上传到 api 后台一天一个周期 + if (Utils.getTime(mApplication) - lastUploadTime >= (3600 * 24)) { + + val appList = PackageUtils.getAppList(mApplication) + + val requestBody = RequestBody.create(MediaType.parse("application/json"), + appList.toString()) + + RetrofitManager.getInstance(mApplication).api.putInstalledApps(HaloApp.getInstance().gid, requestBody) + .subscribeOn(Schedulers.io()) + .subscribe(object: BiResponse() { + override fun onSuccess(data: ResponseBody) { + SPUtils.setLong(LAST_UPLOAD_APPLIST_TIME, System.currentTimeMillis() / 1000) + } + + override fun onFailure(exception: Exception) { + exception.printStackTrace() + } + }) + } } /** diff --git a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java index b0650760a7..c0bc11c9a5 100644 --- a/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java +++ b/app/src/main/java/com/gh/gamecenter/retrofit/service/ApiService.java @@ -439,26 +439,6 @@ public interface ApiService { @GET("users/{user_id}/follows/games") Observable> getConcern(@Path("user_id") String user_id); - /** - * 添加已安装游戏 - */ - @Headers({"Content-Type: application/json", "Accept: application/json"}) - @POST("users/{user_id}/packages/{package_name}") - Observable postPackage(@Path("user_id") String user_id, @Path("package_name") String package_name); - - /** - * 删除已安装游戏 - */ - @DELETE("users/{user_id}/packages/{package_name}") - Observable deletePackage(@Path("user_id") String user_id, @Path("package_name") String package_name); - - /** - * 整体更新设备已安装游戏 - */ - @Headers({"Content-Type: application/json", "Accept: application/json"}) - @PUT("users/{user_id}/packages") - Observable putPackage(@Path("user_id") String user_id, @Body RequestBody body); - /*********** CommentService ************/ @@ -1709,4 +1689,27 @@ public interface ApiService { @Path("comment_id") String commitId); + /** + * 本设备新增了一个应用 + * + * @param deviceId gid + */ + @POST("devices/{device_id}/applications") + Single postNewlyInstalledApp(@Path("device_id") String deviceId, @Body RequestBody body); + + /** + * 本设备删除了一个应用 + * + * @param deviceId gid + */ + @DELETE("devices/{device_id}/applications/{package_name}") + Single deleteInstalledApp(@Path("device_id") String deviceId, @Path("package_name") String packageName); + + /** + * 将本色被所有已安装应用(除系统应用外)提交给后台 + * + * @param deviceId gid + */ + @PUT("devices/{device_id}/applications") + Single putInstalledApps(@Path("device_id") String deviceId, @Body RequestBody body); } \ No newline at end of file