Example #1
0
  @Override
  public void initZygote(StartupParam startupParam) throws Throwable {
    sModulePath = startupParam.modulePath;
    sPrefs = new XSharedPreferences(PACKAGE_OWN);
    RomUtils.init(sPrefs);

    logI(TAG, "Version " + BuildConfig.VERSION_NAME + " (" + BuildConfig.VERSION_CODE + ")");
    //noinspection ConstantConditions
    if (BuildConst.BUILD_SERVER_VERSION == 0) {
      logI(
          TAG,
          "Official Build; Release: " + !BuildConfig.DEBUG + " (" + BuildConfig.BUILD_TYPE + ")");
    } else {
      logI(TAG, "Remote Build; Version: " + BuildConst.BUILD_SERVER_VERSION);
    }

    logI(TAG, "ROM type: " + sPrefs.getString("rom", "undefined"));

    if (!sPrefs.getBoolean("can_read_prefs", false)) {
      // With SELinux enforcing, it might happen that we don't have access
      // to the prefs file. Test this by reading a test key that should be
      // set to true. If it is false, we either can't read the file or the
      // user has never opened the preference screen before.
      logW(TAG, "Can't read prefs file, default values will be applied in hooks!");
    }
  }
Example #2
0
  public static void modCode(LoadPackageParam lparam) {
    PaperLogger.log("KyoboLibrary");
    if (pref.getBoolean(prefKey, false) == false) return;

    PaperLogger.log("KyoboLibrary module is active");
    KyoboPlatform.modCode(lparam, packageName);
  }
Example #3
0
  @Override
  public void initZygote(StartupParam startupParam) throws Throwable {
    MODULE_PATH = startupParam.modulePath;
    prefs = new XSharedPreferences(PACKAGE_NAME);

    XposedBridge.log("Hardware: " + Build.HARDWARE);
    XposedBridge.log("Product: " + Build.PRODUCT);
    XposedBridge.log("Device manufacturer: " + Build.MANUFACTURER);
    XposedBridge.log("Device brand: " + Build.BRAND);
    XposedBridge.log("Device model: " + Build.MODEL);
    XposedBridge.log("Is MTK device: " + Utils.isMtkDevice());
    XposedBridge.log("Android SDK: " + Build.VERSION.SDK_INT);
    XposedBridge.log("Android Release: " + Build.VERSION.RELEASE);
    XposedBridge.log("ROM: " + Build.DISPLAY);

    SystemWideResources.initResources(prefs);

    // MTK specific
    if (Utils.isMtkDevice()) {
      ModSignalIconHide.initZygote(prefs);

      if (prefs.getBoolean(GravityBoxSettings.PREF_KEY_FIX_CALLER_ID_PHONE, false)) {
        FixCallerIdPhone.initZygote(prefs);
      }

      if (prefs.getBoolean(GravityBoxSettings.PREF_KEY_FIX_DEV_OPTS, false)) {
        FixDevOptions.initZygote();
      }
    }

    // Common
    FixTraceFlood.initZygote();
    ModVolumeKeySkipTrack.init(prefs);
    ModVolKeyCursor.initZygote(prefs);
    ModCallCard.initZygote();
    ModStatusbarColor.initZygote();
    PhoneWrapper.initZygote();
    ModElectronBeam.initZygote(prefs);
    ModLockscreen.initZygote(prefs);
    ModLowBatteryWarning.initZygote(prefs);
    ModDisplay.initZygote(prefs);
    ModAudio.initZygote(prefs);
    ModHwKeys.initZygote(prefs);
    PatchMasterKey.initZygote();
  }
  public static void doHook(XSharedPreferences prefs, ClassLoader classLoader) {

    XSysUiSmartAlarmPackage.prefs = prefs;
    XSysUiSmartAlarmPackage.classLoader = classLoader;

    if (prefs.getBoolean("hideAlarmClockIcon", false)) {
      hideAlarmIcon();
    }
  }
Example #5
0
  @Override
  public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable {

    switch (lpparam.packageName) {
      case PACKAGE_SETTINGS:
        SettingsHooks.hook(lpparam.classLoader);
        break;
      case PACKAGE_SYSTEMUI:
        SystemUIHooks.hookSystemUI(lpparam.classLoader);
        StatusBarHeaderHooks.hook(lpparam.classLoader);
        NotificationPanelHooks.hook(lpparam.classLoader);
        StackScrollAlgorithmHooks.hook(lpparam.classLoader);
        NotificationHooks.hookSystemUI(lpparam.classLoader);
        RecentsStackHooks.hookSystemUI(lpparam.classLoader);
        RecentsNavigation.hookSystemUI(lpparam.classLoader);
        DoubleTapSwKeys.hook(lpparam.classLoader);
        break;
      case PACKAGE_ANDROID:
        DoubleTapHwKeys.hook(lpparam.classLoader);
        LiveDisplayObserver.hook(lpparam.classLoader);
        PermissionGranter.initAndroid(lpparam.classLoader);
        break;
      case PACKAGE_PHONE:
        EmergencyHooks.hook(lpparam.classLoader);
        break;
      case PACKAGE_OWN:
        XposedHelpers.findAndHookMethod(
            SETTINGS_OWN,
            lpparam.classLoader,
            "isActivated",
            XC_MethodReplacement.returnConstant(true));
        if (!sPrefs.getBoolean("can_read_prefs", false))
          XposedHelpers.findAndHookMethod(
              SETTINGS_OWN,
              lpparam.classLoader,
              "isPrefsFileReadable",
              XC_MethodReplacement.returnConstant(false));
        break;
    }

    // Has to be hooked in every app as every app creates own instances of the Notification.Builder
    NotificationHooks.hook(lpparam.classLoader);

    // This actually is only used in the system process, but every app has access, so just to be
    // sure hook everything
    if (ConfigUtils.qs().enable_qs_editor) {
      try {
        Class<?> classCMStatusBarManager =
            XposedHelpers.findClass("cyanogenmod.app.CMStatusBarManager", lpparam.classLoader);
        XposedBridge.hookAllMethods(
            classCMStatusBarManager, "publishTile", XC_MethodReplacement.DO_NOTHING);
        XposedBridge.hookAllMethods(
            classCMStatusBarManager, "publishTileAsUser", XC_MethodReplacement.DO_NOTHING);
      } catch (Throwable ignore) {
      }
    }
  }
Example #6
0
 public static void setTypeFace(View v) {
   XSharedPreferences pref = new XSharedPreferences("hello.dcsms.omzen");
   pref.makeWorldReadable();
   boolean usecustomfont = pref.getBoolean("CUSTOM_FONT", false);
   if (usecustomfont) {
     Typeface tf =
         Typeface.createFromFile(
             Environment.getExternalStorageDirectory().getAbsolutePath()
                 + "/default_icon"
                 + "/font_satu.ttf");
     ((TextView) v).setTypeface(tf);
   }
 }
Example #7
0
  @Override
  public void handleLoadPackage(LoadPackageParam lpparam) throws Throwable {

    // MTK Specific
    if (Utils.isMtkDevice()) {
      if (lpparam.packageName.equals(ModSignalIconHide.PACKAGE_NAME)) {
        ModSignalIconHide.init(prefs, lpparam.classLoader);
      }

      if (prefs.getBoolean(GravityBoxSettings.PREF_KEY_FIX_CALLER_ID_MMS, false)
          && lpparam.packageName.equals(FixCallerIdMms.PACKAGE_NAME)) {
        FixCallerIdMms.init(prefs, lpparam.classLoader);
      }

      if (prefs.getBoolean(GravityBoxSettings.PREF_KEY_FIX_CALENDAR, false)
          && lpparam.packageName.equals(FixCalendar.PACKAGE_NAME)) {
        FixCalendar.init(prefs, lpparam.classLoader);
      }

      if (prefs.getBoolean(GravityBoxSettings.PREF_KEY_FIX_DATETIME_CRASH, false)
          && lpparam.packageName.equals(FixDateTimeCrash.PACKAGE_NAME)) {
        FixDateTimeCrash.init(prefs, lpparam.classLoader);
      }

      if (prefs.getBoolean(GravityBoxSettings.PREF_KEY_FIX_TTS_SETTINGS, false)
          && lpparam.packageName.equals(FixTtsSettings.PACKAGE_NAME)) {
        FixTtsSettings.init(prefs, lpparam.classLoader);
      }

      if (prefs.getBoolean(GravityBoxSettings.PREF_KEY_FIX_DEV_OPTS, false)
          && lpparam.packageName.equals(FixDevOptions.PACKAGE_NAME)) {
        FixDevOptions.init(prefs, lpparam.classLoader);
      }

      if (prefs.getBoolean(GravityBoxSettings.PREF_KEY_FIX_MMS_WAKELOCK, false)
          && lpparam.packageName.equals(FixMmsWakelock.PACKAGE_NAME)) {
        FixMmsWakelock.init(prefs, lpparam.classLoader);
      }

      if (lpparam.packageName.equals(ModAudioSettings.PACKAGE_NAME)) {
        ModAudioSettings.init(prefs, lpparam.classLoader);
      }

      if (lpparam.packageName.equals(ModCellConnService.PACKAGE_NAME)) {
        ModCellConnService.init(prefs, lpparam.classLoader);
      }
    }

    // Common
    if (lpparam.packageName.equals(ModBatteryStyle.PACKAGE_NAME)) {
      ModBatteryStyle.init(prefs, lpparam.classLoader);
    }

    if (lpparam.packageName.equals(ModLowBatteryWarning.PACKAGE_NAME)) {
      ModLowBatteryWarning.init(prefs, lpparam.classLoader);
    }

    if (lpparam.packageName.equals(ModClearAllRecents.PACKAGE_NAME)) {
      ModClearAllRecents.init(prefs, lpparam.classLoader);
    }

    if (lpparam.packageName.equals(ModRebootMenu.PACKAGE_NAME)) {
      ModRebootMenu.init(prefs, lpparam.classLoader);
    }

    if (lpparam.packageName.equals(ModCallCard.PACKAGE_NAME)) {
      ModCallCard.init(prefs, lpparam.classLoader);
    }

    if (lpparam.packageName.equals(ModQuickSettings.PACKAGE_NAME)) {
      ModQuickSettings.init(prefs, lpparam.classLoader);
    }

    if (lpparam.packageName.equals(ModStatusbarColor.PACKAGE_NAME)) {
      ModStatusbarColor.init(prefs, lpparam.classLoader);
    }

    if (lpparam.packageName.equals(ModCenterClock.PACKAGE_NAME)) {
      ModCenterClock.init(prefs, lpparam.classLoader);
    }

    if (lpparam.packageName.equals(ModPhone.PACKAGE_NAME)) {
      ModPhone.init(prefs, lpparam.classLoader);
    }

    if (lpparam.packageName.equals(ModSettings.PACKAGE_NAME)) {
      ModSettings.init(prefs, lpparam.classLoader);
    }

    if (lpparam.packageName.equals(ModVolumePanel.PACKAGE_NAME)) {
      ModVolumePanel.init(prefs, lpparam.classLoader);
    }

    if (lpparam.packageName.equals(ModPieControls.PACKAGE_NAME)) {
      ModPieControls.init(prefs, lpparam.classLoader);
    }
  }
Example #8
0
  private void patchcode() {
    XSharedPreferences prefs = new XSharedPreferences(XpStatus.PKGNAME, XpStatus.PREF);
    prefs.makeWorldReadable();
    prefs.reload();
    if (!prefs.getBoolean(XpStatus.KEY_REMOVEAD, false)) {
      return;
    }

    if (loadPackageParam.packageName.equals("com.miui.core")) {
      XpUtils.findAndHookMethod(
          "miui.os.SystemProperties",
          loadPackageParam.classLoader,
          "get",
          String.class,
          String.class,
          new XC_MethodHook() {

            protected void afterHookedMethod(MethodHookParam paramAnonymousMethodHookParam)
                throws Throwable {
              if (paramAnonymousMethodHookParam
                  .args[0]
                  .toString()
                  .equals("ro.product.mod_device")) {
                paramAnonymousMethodHookParam.setResult("gemini_global");
              }
            }

            protected void beforeHookedMethod(MethodHookParam paramAnonymousMethodHookParam)
                throws Throwable {
              if (paramAnonymousMethodHookParam
                  .args[0]
                  .toString()
                  .equals("ro.product.mod_device")) {
                paramAnonymousMethodHookParam.setResult("gemini_global");
              }
            }
          });
      return;
    }

    if (loadPackageParam.packageName.equals("com.miui.cleanmaster")) {
      XpUtils.findAndHookMethod(
          "com.miui.optimizecenter.result.DataModel",
          loadPackageParam.classLoader,
          "post",
          Map.class,
          new XC_MethodHook() {
            protected void beforeHookedMethod(MethodHookParam paramAnonymousMethodHookParam)
                throws Throwable {
              paramAnonymousMethodHookParam.setResult("");
            }
          });
      XpUtils.findAndHookMethod(
          "com.miui.optimizecenter.config.MiStat",
          loadPackageParam.classLoader,
          "getChannel",
          new XC_MethodHook() {
            protected void beforeHookedMethod(MethodHookParam paramAnonymousMethodHookParam)
                throws Throwable {
              paramAnonymousMethodHookParam.setResult("international");
            }
          });
      return;
    }

    if (loadPackageParam.packageName.equals("com.miui.video")) {
      XpUtils.findAndHookMethod(
          "com.miui.videoplayer.ads.DynamicAd",
          loadPackageParam.classLoader,
          "replaceList",
          List.class,
          String.class,
          new XC_MethodHook() {
            protected void beforeHookedMethod(MethodHookParam paramAnonymousMethodHookParam)
                throws Throwable {
              paramAnonymousMethodHookParam.args[0] = null;
              paramAnonymousMethodHookParam.args[1] = null;
            }
          });
      XpUtils.findAndHookMethod(
          "com.video.ui.view.AdView",
          loadPackageParam.classLoader,
          "getAdsBlock",
          Context.class,
          XC_MethodReplacement.returnConstant(null));
      Class<?> clsCallback =
          XpUtils.findClass(
              loadPackageParam.classLoader, "com.video.ui.idata.SyncServiceHelper$Callback");
      if (clsCallback != null) {
        XpUtils.findAndHookMethod(
            "com.video.ui.idata.SyncServiceHelper",
            loadPackageParam.classLoader,
            "fetchAds",
            Context.class,
            clsCallback,
            XC_MethodReplacement.returnConstant(null));
      }
      XpUtils.findAndHookMethod(
          "com.video.ui.idata.iDataORM",
          loadPackageParam.classLoader,
          "getBooleanValue",
          Context.class,
          String.class,
          boolean.class,
          new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
              String key = (String) param.args[1];
              if (key.equals("debug_mode")
                  || key.equals("show_first_ads")
                  || key.equals("ads_show_homekey")
                  || key.equals("startup_ads_loop")
                  || key.equals("app_upgrade_splash")) {
                param.setResult(false);
              }
            }

            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
              String key = (String) param.args[1];
              if (key.equals("debug_mode")
                  || key.equals("show_first_ads")
                  || key.equals("ads_show_homekey")
                  || key.equals("startup_ads_loop")
                  || key.equals("app_upgrade_splash")) {
                param.setResult(false);
              }
            }
          });
      XpUtils.findAndHookMethod(
          "com.video.ui.idata.iDataORM",
          loadPackageParam.classLoader,
          "getStringValue",
          Context.class,
          String.class,
          String.class,
          new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
              String key = (String) param.args[1];
              if (key.equals("startup_ads")) {
                param.setResult(null);
              }
            }

            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
              String key = (String) param.args[1];
              if (key.equals("startup_ads")) {
                param.setResult(null);
              }
            }
          });
      return;
    }

    if (loadPackageParam.packageName.equals("com.android.fileexplorer")) {
      XpUtils.findAndHookMethod(
          "com.android.fileexplorer.model.ConfigHelper",
          loadPackageParam.classLoader,
          "isAdEnable",
          Context.class,
          String.class,
          XC_MethodReplacement.returnConstant(false));
      XpUtils.findAndHookMethod(
          "com.android.fileexplorer.model.ConfigHelper",
          loadPackageParam.classLoader,
          "supportAd",
          XC_MethodReplacement.returnConstant(false));
      XpUtils.findAndHookMethod(
          "com.android.fileexplorer.model.ConfigHelper",
          loadPackageParam.classLoader,
          "ifAdShowByCloudForNetwork",
          Context.class,
          String.class,
          XC_MethodReplacement.returnConstant(false));
      XpUtils.findAndHookMethod(
          "com.android.fileexplorer.model.ConfigHelper",
          loadPackageParam.classLoader,
          "getHomePageHotVideoTipSwitch",
          Context.class,
          XC_MethodReplacement.returnConstant(false));
      XpUtils.findAndHookMethod(
          "com.android.fileexplorer.model.ConfigHelper",
          loadPackageParam.classLoader,
          "getHomePageHotVideoTopicUri",
          Context.class,
          XC_MethodReplacement.returnConstant(""));
      XpUtils.findAndHookMethod(
          "com.android.fileexplorer.model.ConfigHelper",
          loadPackageParam.classLoader,
          "getAdStyleName",
          Context.class,
          String.class,
          XC_MethodReplacement.returnConstant(""));
      XpUtils.findAndHookMethod(
          "com.android.fileexplorer.model.ConfigHelper",
          loadPackageParam.classLoader,
          "tryInit",
          Context.class,
          XC_MethodReplacement.returnConstant(false));
      XpUtils.findAndHookMethod(
          "com.android.fileexplorer.model.ConfigHelper",
          loadPackageParam.classLoader,
          "isVideoEnable",
          Context.class,
          XC_MethodReplacement.returnConstant(false));
      XpUtils.findAndHookMethod(
          "com.android.fileexplorer.model.ConfigHelper",
          loadPackageParam.classLoader,
          "isStickerEnable",
          Context.class,
          XC_MethodReplacement.returnConstant(false));
      XpUtils.findAndHookMethod(
          "com.android.fileexplorer.util.XLUtil",
          loadPackageParam.classLoader,
          "isNetworkAvailable",
          Context.class,
          XC_MethodReplacement.returnConstant(false));

      XpUtils.findAndHookMethod(
          "com.xunlei.adlibrary.XunleiADSdk",
          loadPackageParam.classLoader,
          "setup",
          Context.class,
          XC_MethodReplacement.returnConstant(null));
      XpUtils.findAndHookMethod(
          "com.xunlei.adlibrary.analytics.xunlei.AdStatHelper",
          loadPackageParam.classLoader,
          "init",
          Context.class,
          XC_MethodReplacement.returnConstant(null));
      XpUtils.findAndHookMethod(
          "com.android.fileexplorer.video.upload.VideoItemManager",
          loadPackageParam.classLoader,
          "initLoad",
          XC_MethodReplacement.returnConstant(null));
      return;
    }

    if (loadPackageParam.packageName.equals("com.miui.player")) {

      Class<?> clsListener =
          XpUtils.findClass(loadPackageParam.classLoader, "com.android.volley.Response$Listener");
      Class<?> clsErrorListener =
          XpUtils.findClass(
              loadPackageParam.classLoader, "com.android.volley.Response$ErrorListener");
      Class<?> clsAdInfo =
          XpUtils.findClass(loadPackageParam.classLoader, "com.miui.player.util.AdUtils$AdInfo");
      XpUtils.findAndHookMethod(
          "com.miui.player.util.AdUtils",
          loadPackageParam.classLoader,
          "isAdEnable",
          XC_MethodReplacement.returnConstant(false));
      if (clsListener != null && clsErrorListener != null) {
        XpUtils.findAndHookMethod(
            "com.miui.player.util.AdUtils",
            loadPackageParam.classLoader,
            "getPlayAd",
            clsListener,
            clsErrorListener,
            XC_MethodReplacement.returnConstant(null));
      }
      XpUtils.findAndHookMethod(
          "com.miui.player.util.ExperimentsHelper",
          loadPackageParam.classLoader,
          "isAdEnabled",
          XC_MethodReplacement.returnConstant(false));
      if (clsAdInfo != null) {
        XpUtils.findAndHookMethod(
            "com.miui.player.util.AdUtils",
            loadPackageParam.classLoader,
            "handleDeepLinkUrl",
            Activity.class,
            clsAdInfo,
            XC_MethodReplacement.returnConstant(null));
        XpUtils.findAndHookMethod(
            "com.miui.player.util.AdUtils",
            loadPackageParam.classLoader,
            "showAlertAndDownload",
            Activity.class,
            clsAdInfo,
            XC_MethodReplacement.returnConstant(null));
        XpUtils.findAndHookMethod(
            "com.miui.player.util.AdUtils",
            loadPackageParam.classLoader,
            "handleAdClick",
            Activity.class,
            clsAdInfo,
            XC_MethodReplacement.returnConstant(null));
        XpUtils.findAndHookMethod(
            "com.miui.player.util.AdUtils",
            loadPackageParam.classLoader,
            "postPlayAdStat",
            String.class,
            clsAdInfo,
            XC_MethodReplacement.returnConstant(null));
      }
      XpUtils.findAndHookMethod(
          "com.miui.player.phone.view.NowplayingAlbumPage",
          loadPackageParam.classLoader,
          "getPlayAd",
          XC_MethodReplacement.returnConstant(null));
      XpUtils.findAndHookMethod(
          "com.miui.player.util.Configuration",
          loadPackageParam.classLoader,
          "isCmTest",
          XC_MethodReplacement.returnConstant(true));
      XpUtils.findAndHookMethod(
          "com.miui.player.util.Configuration",
          loadPackageParam.classLoader,
          "isCpLogoVisiable",
          XC_MethodReplacement.returnConstant(false));
      return;
    }

    if (loadPackageParam.packageName.equals("com.android.providers.downloads.ui")) {
      XpUtils.findAndHookMethod(
          "com.android.providers.downloads.ui.recommend.config.ADConfig",
          loadPackageParam.classLoader,
          "OSSupportAD",
          new XC_MethodHook() {
            protected void beforeHookedMethod(MethodHookParam paramAnonymousMethodHookParam)
                throws Throwable {
              paramAnonymousMethodHookParam.setResult(false);
            }
          });
      XpUtils.findAndHookMethod(
          "com.android.providers.downloads.ui.utils.BuildUtils",
          loadPackageParam.classLoader,
          "isCmTestBuilder",
          XC_MethodReplacement.returnConstant(true));
      return;
    }

    if (loadPackageParam.packageName.equals("com.miui.weather2")) {
      XpUtils.findAndHookMethod(
          "com.miui.weather2.tools.ToolUtils",
          loadPackageParam.classLoader,
          "checkCommericalStatue",
          Context.class,
          new XC_MethodHook() {
            protected void beforeHookedMethod(MethodHookParam paramAnonymousMethodHookParam)
                throws Throwable {
              paramAnonymousMethodHookParam.setResult(false);
            }
          });
      XpUtils.findAndHookMethod(
          "com.miui.weather2.tools.ToolUtils",
          loadPackageParam.classLoader,
          "canRequestCommercialInfo",
          Context.class,
          XC_MethodReplacement.returnConstant(false));
      XpUtils.findAndHookMethod(
          "com.miui.weather2.tools.ToolUtils",
          loadPackageParam.classLoader,
          "checkCommericalStatue",
          Context.class,
          XC_MethodReplacement.returnConstant(false));
      return;
    }

    if (loadPackageParam.packageName.equals("com.android.quicksearchbox")) {
      XpUtils.findAndHookMethod(
          "com.android.quicksearchbox.ui.LocalListView",
          loadPackageParam.classLoader,
          "updateHotQuery",
          List.class,
          int.class,
          new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
              return null;
            }
          });
      XpUtils.findAndHookMethod(
          "com.android.quicksearchbox.util.HotWordsUtil",
          loadPackageParam.classLoader,
          "setHotQueryView",
          "com.android.quicksearchbox.ui.HotQueryView",
          new XC_MethodHook() {
            protected void beforeHookedMethod(MethodHookParam paramAnonymousMethodHookParam)
                throws Throwable {
              paramAnonymousMethodHookParam.setResult(null);
            }
          });
      return;
    }

    if (loadPackageParam.packageName.equals("com.android.mms")) {
      XpUtils.findAndHookMethod(
          "com.android.mms.ui.MessageUtils",
          loadPackageParam.classLoader,
          "isMessagingTemplateAllowed",
          Context.class,
          new XC_MethodHook() {
            protected void beforeHookedMethod(MethodHookParam paramAnonymousMethodHookParam)
                throws Throwable {
              Context mc = (Context) paramAnonymousMethodHookParam.args[0];
              paramAnonymousMethodHookParam.setResult(
                  !mc.getClass().getName().toLowerCase().contains("app"));
            }
          });
      XpUtils.findAndHookMethod(
          "com.android.mms.ui.SingleRecipientConversationActivity",
          loadPackageParam.classLoader,
          "showMenuMode",
          new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
              return null;
            }
          });
      XpUtils.findAndHookMethod(
          "com.android.mms.util.MiStatSdkHelper",
          loadPackageParam.classLoader,
          "recordBottomMenuShown",
          String.class,
          new XC_MethodReplacement() {
            @Override
            protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
              return null;
            }
          });
    }

    if (loadPackageParam.packageName.equals("com.miui.systemAdSolution")) {
      XpUtils.findAndHookMethod(
          "com.xiaomi.ad.internal.common.b.c",
          loadPackageParam.classLoader,
          "a",
          String.class,
          Context.class,
          XC_MethodReplacement.returnConstant(false));
      XpUtils.findAndHookMethod(
          "com.xiaomi.ad.internal.common.b.c",
          loadPackageParam.classLoader,
          "j",
          Context.class,
          String.class,
          XC_MethodReplacement.returnConstant(false));
      XpUtils.findAndHookMethod(
          "com.xiaomi.ad.internal.common.b.d",
          loadPackageParam.classLoader,
          "m",
          Context.class,
          String.class,
          XC_MethodReplacement.returnConstant(null));
      XpUtils.findAndHookMethod(
          "com.miui.systemAdSolution.landingPage.h",
          loadPackageParam.classLoader,
          "a",
          String.class,
          String.class,
          int.class,
          XC_MethodReplacement.returnConstant(null));
      Class<?> clsB =
          XpUtils.findClass(loadPackageParam.classLoader, "com.xiaomi.ad.internal.pojo.b");
      if (clsB != null) {
        XpUtils.findAndHookMethod(
            "com.xiaomi.ad.internal.server.h",
            loadPackageParam.classLoader,
            "a",
            clsB,
            Bundle.class,
            XC_MethodReplacement.returnConstant(null));
        XpUtils.findAndHookMethod(
            "com.xiaomi.ad.internal.server.h",
            loadPackageParam.classLoader,
            "b",
            clsB,
            Bundle.class,
            XC_MethodReplacement.returnConstant(null));
      }
      XpUtils.findAndHookMethod(
          "com.xiaomi.ad.internal.ui.SplashAdView",
          loadPackageParam.classLoader,
          "onAction",
          String.class,
          XC_MethodReplacement.returnConstant(null));
      return;
    }
  }
Example #9
0
/* Main */
public class Main implements IXposedHookLoadPackage, IXposedHookZygoteInit, IXposedHookInitPackageResources{

    private static String MODULE_PATH = null; //模块所在路径
    private static String PACKAGE_NAME = "com.android.systemui"; //系统UI的包名
    private static String HOOK_CLASS = "com.android.systemui.statusbar.policy.DateView"; //要Hook的Class名
    private static String UPDATE_FUNC = "updateClock"; //更新函数名
    private static String INTENT_SETTING_CHANGED = "de.xiaoxia.xstatusbarlunardate.SETTING_CHANGED"; //更改设置事件
    private static String INTENT_SETTING_TOAST = "de.xiaoxia.xstatusbarlunardate.SETTING_TOAST"; //显示吐司

    /* 初始变量 */
/*    private static String lunarText = "LUNAR"; //记录最后更新时的文字字符串
    private static String lDate = "LAST"; //上次记录的日期
    private static String finalText = "FINALTEXT"; //最终输出的文本
    private static String nDate; //当前状态栏的日期文字*/
    private static String lunarTextToast = ""; //最终输出文本仅节日
    private static Boolean layout_run = false; //判断是否设置过singleLine属性
//    private static TextView mDateView = null; //状态栏日期的 TextView
    private static Set<TextView> mDateViews = new HashSet<>();
    private static Context mContext = null; //显示Toast、注册接收器和获取系统服务所必需的context
    private static Boolean isFest = false; //今天是否为节日的标记
    private static KeyguardManager km = null; //锁屏管理器,用来获取锁屏状态
    private static PowerManager pm = null; //电源管理器,用来获取亮屏状态
    private static Vibrator vibrator = null; //震动
    private static int _notify_times_setting = 0; //记录设置好的提醒次数

    /* 读取设置 */
    //使用Xposed提供的XSharedPreferences方法来读取android内置的SharedPreferences设置
    private final static XSharedPreferences prefs = new XSharedPreferences(Main.class.getPackage().getName());

    /* 将设置保存到变量中,以备后用 */
    protected static Boolean _remove_all = prefs.getBoolean("remove_all", false); //允许布局调整
    protected static Boolean _remove = prefs.getBoolean("remove", false); //删除换行
    protected static Boolean _term = prefs.getBoolean("term", true); //显示节气
    protected static Boolean _fest = prefs.getBoolean("fest", true); //显示农历节日
    protected static Boolean _custom = prefs.getBoolean("custom", false); //显示自定义农历节日
    protected static Boolean _solar = prefs.getBoolean("solar", true); //显示公历节日
    protected static Boolean _solar_custom = prefs.getBoolean("solar_cutom", true); //显示自定义公历节日
    protected static Boolean _breakline = prefs.getBoolean("breakline", true); //另起一行
    protected static Boolean _layout_enable = prefs.getBoolean("layout_enable", false); //允许布局调整
    protected static Boolean _layout_line = prefs.getBoolean("layout_line", false); //允许布局调整单行
    protected static Boolean _layout_width = prefs.getBoolean("layout_width", false); //允许布局调整宽度
    protected static Boolean _layout_height = prefs.getBoolean("layout_height", false); //允许布局调整高度
    protected static Boolean _layout_align = prefs.getBoolean("layout_align", false); //允许布局调整对齐
    protected static String _custom_format = prefs.getString("custom_format", ""); //自定义状态栏字符串
    protected static int _minor = Integer.valueOf(prefs.getString("minor", "1")).intValue(); //小年选项,将字符串型转换为整数型
    protected static int _lang = Integer.valueOf(prefs.getString("lang", "1")).intValue(); //语言选项,将字符串型转换为整数型
    protected static int _format = Integer.valueOf(prefs.getString("format", "1")).intValue(); //显示格式选项,将字符串型转换为整数型
    protected static int _rom = Integer.valueOf(prefs.getString("rom", "1")).intValue(); //系统类型选项,将字符串型转换为整数型

    protected static int _notify = Integer.valueOf(prefs.getString("notify", "1")).intValue(); //通知方法
    protected static int _notify_times = Integer.valueOf(prefs.getString("notify_times", "1")).intValue(); //通知次数
    protected static Boolean _notify_center = prefs.getBoolean("notify_center", false); //通知居中
    protected static Boolean _notify_icon = prefs.getBoolean("notify_icon", false); //显示图标
    protected static Boolean _notify_comp = prefs.getBoolean("notify_comp", false); //兼容性
    protected static Boolean _notify_vibration = prefs.getBoolean("notify_vibration", false); //震动

    protected static Boolean _lockscreen = prefs.getBoolean("lockscreen", false); //开启添加到锁屏
    protected static int _lockscreen_layout = Integer.valueOf(prefs.getString("lockscreen_layout", "1")).intValue(); //锁屏布局,将字符串型转换为整数型
    protected static int _lockscreen_alignment = Integer.valueOf(prefs.getString("lockscreen_alignment", "1")).intValue(); //锁屏对齐,将字符串型转换为整数型
    protected static int _lockscreen_format = Integer.valueOf(prefs.getString("lockscreen_format", "1")).intValue(); //显示格式选项,将字符串型转换为整数型
    protected static String _lockscreen_custom_format = prefs.getString("lockscreen_custom_format", ""); //自定义锁屏字符串

    //读取自定义农历纪念日,并放入到一个数组中
    protected static String[] clf = {
        prefs.getString("custom_lunar_item_0", "").trim(),
        prefs.getString("custom_lunar_item_1", "").trim(),
        prefs.getString("custom_lunar_item_2", "").trim(),
        prefs.getString("custom_lunar_item_3", "").trim(),
        prefs.getString("custom_lunar_item_4", "").trim(),
        prefs.getString("custom_lunar_item_5", "").trim(),
        prefs.getString("custom_lunar_item_6", "").trim(),
        prefs.getString("custom_lunar_item_7", "").trim(),
        prefs.getString("custom_lunar_item_8", "").trim(),
        prefs.getString("custom_lunar_item_9", "").trim(),
        prefs.getString("custom_lunar_item_10", "").trim(),
        prefs.getString("custom_lunar_item_11", "").trim(),
        prefs.getString("custom_lunar_item_12", "").trim(),
        prefs.getString("custom_lunar_item_13", "").trim(),
        prefs.getString("custom_lunar_item_14", "").trim(),
        prefs.getString("custom_lunar_item_15", "").trim(),
        prefs.getString("custom_lunar_item_16", "").trim(),
        prefs.getString("custom_lunar_item_17", "").trim(),
        prefs.getString("custom_lunar_item_18", "").trim(),
        prefs.getString("custom_lunar_item_19", "").trim()
    };
    //读取自定义公历纪念日,并放入到一个数组中
    protected static String[] csf = {
        prefs.getString("custom_solar_item_0", "").trim(),
        prefs.getString("custom_solar_item_1", "").trim(),
        prefs.getString("custom_solar_item_2", "").trim(),
        prefs.getString("custom_solar_item_3", "").trim(),
        prefs.getString("custom_solar_item_4", "").trim(),
        prefs.getString("custom_solar_item_5", "").trim(),
        prefs.getString("custom_solar_item_6", "").trim(),
        prefs.getString("custom_solar_item_7", "").trim(),
        prefs.getString("custom_solar_item_8", "").trim(),
        prefs.getString("custom_solar_item_9", "").trim(),
        prefs.getString("custom_solar_item_10", "").trim(),
        prefs.getString("custom_solar_item_11", "").trim(),
        prefs.getString("custom_solar_item_12", "").trim(),
        prefs.getString("custom_solar_item_13", "").trim(),
        prefs.getString("custom_solar_item_14", "").trim(),
        prefs.getString("custom_solar_item_15", "").trim(),
        prefs.getString("custom_solar_item_16", "").trim(),
        prefs.getString("custom_solar_item_17", "").trim(),
        prefs.getString("custom_solar_item_18", "").trim(),
        prefs.getString("custom_solar_item_19", "").trim()
    };

    //初始化Lunar类
    private static Lunar lunar;

    /* 向Systemui注入图标和字符串资源*/
    private static int ic_toast_bg_fest;
    private static int ic_toast_bg;

    @Override
    public void initZygote(StartupParam startupParam){
        MODULE_PATH = startupParam.modulePath; //获取模块实际路径
    }

    @Override
    public void handleInitPackageResources(InitPackageResourcesParam resparam){
        if (!resparam.packageName.equals(PACKAGE_NAME))
            return; //如果不是UI则跳过

        //这里将自带的图标资源插入到systemui中,并获取到一个资源id
        XModuleResources modRes = XModuleResources.createInstance(MODULE_PATH, resparam.res); //创建一个插入资源的实例
        ic_toast_bg_fest = resparam.res.addResource(modRes, R.drawable.ic_toast_bg_fest);
        ic_toast_bg      = resparam.res.addResource(modRes, R.drawable.ic_toast_bg);
    }

    /* 替换日期函数 */
    @Override
    public void handleLoadPackage(final LoadPackageParam lpparam){
        if(!lpparam.packageName.equals(PACKAGE_NAME))
            return; //如果不是UI则跳过

        lunar = new Lunar(Main._lang); //初始化Lunar类

        _notify_times_setting = _notify_times; //记录提醒次数

        //如果打开了调整布局,则允许进入调整布局步骤
        if(!_layout_enable)
            layout_run = true;

        //根据rom类型选择正确的更新函数
        switch(_rom){
            case 1: break; //原生Android的日起更新函数名
            case 2: UPDATE_FUNC = "a";
                    break; //Miui 4.4 之前的系统更新时间的函数名称为“a”
            case 3: HOOK_CLASS = "com.android.systemui.statusbar.policy.QuickSettingsDateView";
                    break; //Asus Zenfone6
        }

        //勾在com.android.systemui.statusbar.policy.DateView里面的updateClock()之后
        //这的函数可以参考 https://github.com/rovo89/XposedBridge/wiki/Development-tutorial,比较简单
        findAndHookMethod(HOOK_CLASS, lpparam.classLoader, UPDATE_FUNC, new XC_MethodHook() {
            @Override
            //在原函数执行完之后再执行自定义程序
            protected void afterHookedMethod(MethodHookParam param){
                //获取原文字,com.android.systemui.statusbar.policy.DateView类是extends于TextView
                TextView dateView = (TextView) param.thisObject; //获取这个对象
                synchronized (Main.class) {
                    mDateViews.add(dateView);
                }
                mContext = dateView.getContext(); //获取上下文
                if(mContext != null)
                    registerReceiver(mContext); //注册接收器
                setText();//交给setText处理
            }
        });
    }

    /* 获取农历字符串子程序 */
    private void setText(){
        synchronized (Main.class) {
            for (TextView dateView : mDateViews) {
        /* 判断当前日期栏是否包含上次更新后的日期文本
         * 如果当前日期已经改变,则必须重新计算农历
         * 如果当前日期未改变,则只需要重新用已经缓存的文本写入TextView */
                //判断日期是否改变,不改变则不更新内容,改变则重新计算农历
                String nDate = dateView.getText().toString();
                String lDate = (String) XposedHelpers.getAdditionalInstanceField(dateView, "lDate");
                String lunarText = (String) XposedHelpers.getAdditionalInstanceField(dateView, "lunarText");
                String finalText = (String) XposedHelpers.getAdditionalInstanceField(dateView, "finalText");
                if (lunarText == null || !(nDate.contains(lunarText) || finalText == null || nDate.equals(finalText))) {
                    if (lDate == null || !nDate.equals(lDate)) {
                        //获取时间
                        lunar.init();

                        //修正layout的singleLine属性
                        if (!layout_run) {
                            try {
                                //去掉singleLine属性
                                if (_layout_line)
                                    dateView.setSingleLine(false); //去除singleLine属性
                                //去掉align_baseline,并将其设置为center_vertical
                                if (_layout_align) {
                                    //一般机型的状态栏都是RelativeLayout,少数为LinearLayout,但似乎影响不大
                                    RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) dateView.getLayoutParams();
                                    layoutParams.addRule(RelativeLayout.ALIGN_BASELINE, 0); //去除baseline对齐属性
                                    layoutParams.addRule(RelativeLayout.CENTER_VERTICAL); //并将其设置为绝对居中
                                    dateView.setLayoutParams(layoutParams); //设置布局参数
                                }
                                //设置宽度为wrap_content
                                if (_layout_width) {
                                    RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) dateView.getLayoutParams();
                                    layoutParams.width = LayoutParams.WRAP_CONTENT; //取消宽度限制
                                    dateView.setLayoutParams(layoutParams);
                                }
                                //设置高度为wrap_content
                                if (_layout_height) {
                                    RelativeLayout.LayoutParams layoutParams = (RelativeLayout.LayoutParams) dateView.getLayoutParams();
                                    layoutParams.height = LayoutParams.WRAP_CONTENT; //取消高度限制
                                    dateView.setLayoutParams(layoutParams);
                                }
                                layout_run = true; //已经执行过布局的处理步骤,下次不再执行
                            } catch (Throwable t) {
                                XposedBridge.log("xStatusBarLunarDate: Statusbar layout fix error:");
                                XposedBridge.log(t);
                            }
                        }

                        //更新记录的日期
                        XposedHelpers.setAdditionalInstanceField(dateView, "lDate", nDate);
                        //从Lunar类中获得组合好的农历日期字符串(包括各节日)
                        lunarText = lunar.getFormattedDate(_custom_format, _format);
                        XposedHelpers.setAdditionalInstanceField(dateView, "lunarText", lunarText);

                        //重置提醒次数
                        _notify_times = _notify_times_setting;
                        if (_notify > 1) {
                            //当天是否是节日
                            isFest = !"".equals(lunar.getFormattedDate("ff", 5));
                            if ((isFest || _notify == 2) && _lang != 3) {
                                lunarTextToast = nDate.trim().replaceAll("\\n", " ") + "\n" + (_format == 5 ? lunar.getFormattedDate("", 3) : lunarText);
                            } else {
                                lunarTextToast = "";
                            }
                        }
                        //组合最终显示的文字
                        finalText = _remove_all ? lunarText : (_remove ? nDate.trim().replaceAll("[\\n|\\r]", " ") : nDate) + (_breakline ? "\n" : " ") + lunarText;
                        XposedHelpers.setAdditionalInstanceField(dateView, "finalText", finalText);
                    }
                    //向TextView设置显示的最终文字
                    dateView.setText(finalText);
                }
            }
        }
    }

    //震动控制
    private void makeVibration(Context context){
        if(vibrator == null)
            vibrator = (Vibrator)context.getSystemService(Service.VIBRATOR_SERVICE);
        if(isFest && _notify_vibration) //仅当有节日且开启时才震动
            vibrator.vibrate(250);
    }

    //显示 Toast
    private void makeToast(Context context){
        if("".equals(lunarTextToast))
            return;

        try{
            Toast toast = Toast.makeText(context, lunarTextToast, Toast.LENGTH_LONG);
            if(_notify_comp){
                //如果打开了美化
                LinearLayout toastView = (LinearLayout) toast.getView();

                //尝试寻找toastView布局中的textView节点
                TextView toastTextView;
                try{
                    toastTextView = (TextView) toastView.getChildAt(0);
                }catch(Throwable t){
                    try {
                        toastTextView = (TextView) toastView.getChildAt(1);
                    } catch (Throwable tt) {
                        toastTextView = null;
                    }
                }
                if(toastTextView != null){
                    toastTextView.setGravity(Gravity.CENTER_HORIZONTAL); //调整Toast为文字居中
                    toastTextView.setLineSpacing(0, 1.2f); //调整Toast文字行间距为原来的1.2倍
                }

                if(_notify_center)
                    //Toast在屏幕正中显示
                    toast.setGravity(Gravity.CENTER, 0, 0);

                if(_notify_icon){
                    //为Toast加入背景
                    toastView.setBackground((context.getResources().getDrawable(isFest ? ic_toast_bg_fest : ic_toast_bg)));
                    toastView.setGravity(Gravity.CENTER);
                    if(toastTextView != null){
                        toastTextView.setTextColor(0xFF000000);
                        toastTextView.setPadding(0, 15, 0, 0);
                        toastTextView.setShadowLayer(0, 0, 0, 0X00FFFFFF);
                    }
                }
            }
            toast.show();
            makeVibration(context);
        }catch(Throwable t){
            XposedBridge.log("xStatusBarLunarDate: Toast error:");
            XposedBridge.log(t);
        }
    }

    //重置日期记录信息
    private void resetLast(){
        synchronized (Main.class) {
            for (TextView dateView : mDateViews) {
                XposedHelpers.setAdditionalInstanceField(dateView, "lunarText", "RESET");
                XposedHelpers.setAdditionalInstanceField(dateView, "finalText", "RESET");
                XposedHelpers.setAdditionalInstanceField(dateView, "lDate", "RESET");

                //4.4以上有个mLastText储存上次的日期字符串,在此尝试清空它,避免导致文字出现重复等现象
                if(Build.VERSION.SDK_INT >= 19){
                    try{
                        XposedHelpers.setObjectField(dateView, "mLastText", ""); //重置DateView内部日期记录
                    }catch(Throwable t){}
                }
            }
        }
    }

    //注册接收器
    private void registerReceiver(Context context){
        IntentFilter intent = new IntentFilter();
        intent.addAction(Intent.ACTION_USER_PRESENT); //注册解锁屏幕事件
        intent.addAction(Intent.ACTION_SCREEN_ON); //注册亮屏事件
        intent.addAction(Intent.ACTION_DATE_CHANGED); //注册日期变更事件
        intent.addAction(Intent.ACTION_TIMEZONE_CHANGED); //注册时区变更事件
        intent.addAction(INTENT_SETTING_CHANGED); //注册设置变更事件
        intent.addAction(INTENT_SETTING_TOAST); //注册显示Toast事件
        context.registerReceiver(xReceiver, intent);
    }

    //广播接收处理
    private BroadcastReceiver xReceiver = new BroadcastReceiver() {
        @SuppressWarnings("deprecation")
		@Override
        public void onReceive(Context context, Intent intent) {
            context = mContext;

            if(km == null)
                km = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
            if(pm == null)
                pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);

            //Intent事件判断
            if(intent.getAction().equals(INTENT_SETTING_CHANGED)){
                //如果用户更改了设置,从intent中读取更改过的设置
                _remove_all = intent.getExtras().getBoolean("remove_all", _remove_all);
                _remove = intent.getExtras().getBoolean("remove", _remove);
                _term = intent.getExtras().getBoolean("term", _term);
                _fest = intent.getExtras().getBoolean("fest", _fest);
                _custom = intent.getExtras().getBoolean("custom", _custom);
                _solar = intent.getExtras().getBoolean("solar", _solar);
                _solar_custom = intent.getExtras().getBoolean("solar_cutom", _solar_custom);
                _breakline = intent.getExtras().getBoolean("breakline", _breakline);
                _layout_enable = intent.getExtras().getBoolean("layout_enable", _layout_enable);
                _layout_line = intent.getExtras().getBoolean("layout_line", _layout_line);
                _layout_width = intent.getExtras().getBoolean("layout_width", _layout_width);
                _layout_align = intent.getExtras().getBoolean("layout_align", _layout_align);
                _layout_height = intent.getExtras().getBoolean("layout_height", _layout_height);
                _custom_format = intent.getExtras().getString("custom_format", _custom_format);
                _minor = intent.getExtras().getInt("minor", _minor);
                _lang = intent.getExtras().getInt("lang", _lang);
                _format = intent.getExtras().getInt("format", _format);

                _notify = intent.getExtras().getInt("notify", _notify);
                _notify_times_setting = _notify_times = intent.getExtras().getInt("notify_times", _notify_times_setting);
                _notify_center = intent.getExtras().getBoolean("notify_center", _notify_center);
                _notify_icon = intent.getExtras().getBoolean("notify_icon", _notify_icon);
                _notify_comp = intent.getExtras().getBoolean("notify_comp", _notify_comp);
                _notify_vibration = intent.getExtras().getBoolean("notify_vibration", _notify_vibration);

                for(int i = 0; i <= 14; i++){
                    clf[i] = intent.getExtras().getString("custom_lunar_item_" + i, clf[i]);
                    csf[i] = intent.getExtras().getString("custom_solar_item_" + i, csf[i]);
                }

                //重置一些变量
                if(!_layout_enable)
                    layout_run = true;

                resetLast();
                lunar = new Lunar(_lang);
                callUpdateFuncs(); //强制执行日期更新函数
            }else if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)){
                //如果用户亮屏且屏幕处于未解锁状态
                if(!km.inKeyguardRestrictedInputMode() && _notify_times > 0){
                    makeToast(context);
                     _notify_times--;
                }
            }else if(intent.getAction().equals(Intent.ACTION_USER_PRESENT)){
                //如果用户解锁屏幕
                if(_notify_times > 0){
                    makeToast(context);
                    _notify_times--;
                }
            }else if(intent.getAction().equals(Intent.ACTION_DATE_CHANGED)){
                //如果日期变更且用户处于亮屏状态
                resetLast();
                callUpdateFuncs(); //强制执行日期更新函数
                if(pm.isScreenOn() && !km.inKeyguardRestrictedInputMode())
                    makeToast(context);
            }else if (intent.getAction().equals(Intent.ACTION_TIMEZONE_CHANGED)){
                //如果时区变更
                resetLast();
                lunar = new Lunar(_lang);
                callUpdateFuncs(); //强制执行日期更新函数
                makeToast(context);
            }else if(intent.getAction().equals(INTENT_SETTING_TOAST)){
                if(_notify != 2){
                    //改为总是弹出,强制更新,再改回去,强制更新
                    int _notify_temp = _notify; //设置一个临时变量记录初始状态
                    _notify = 2; //设置为总是弹出通知
                    resetLast();
                    callUpdateFuncs(); //强制执行日期更新函数
                    makeToast(context);
                    _notify = _notify_temp; // 吐司通知设置复位到初始状态
                    lunarTextToast = ""; // 清空Toast文字,避免其它情况再次显示
                    resetLast();
                    callUpdateFuncs();
                }else{
                    makeToast(context);
                }
            }
        }
    };

    private void callUpdateFuncs() {
        synchronized (Main.class) {
            for (TextView dateView : mDateViews)
                XposedHelpers.callMethod(dateView, UPDATE_FUNC);
        }
    }
}