3232import com .sevtinge .hyperceiler .libhook .base .BaseHook ;
3333import com .sevtinge .hyperceiler .libhook .callback .IMethodHook ;
3434import com .sevtinge .hyperceiler .libhook .utils .hookapi .dexkit .IDexKit ;
35- import com .sevtinge .hyperceiler .libhook .utils .hookapi .tool .EzxHelpUtils ;
3635
3736import org .json .JSONArray ;
3837import org .luckypray .dexkit .DexKitBridge ;
4847import java .lang .reflect .Method ;
4948import java .util .ArrayList ;
5049import java .util .List ;
51- import java .util .Objects ;
5250
5351import io .github .kyuubiran .ezxhelper .xposed .common .HookParam ;
5452
@@ -64,133 +62,126 @@ protected boolean useDexKit() {
6462
6563 @ Override
6664 protected boolean initDexKit () {
67- if (Objects .equals (getPackageName (), "com.miui.phrase" )) {
68- mBuildClipboardJsonMethod = requiredMember ("BuildClipboardJson" , new IDexKit () {
69- @ Override
70- public BaseData dexkit (DexKitBridge bridge ) throws ReflectiveOperationException {
71- MethodData methodData = bridge .findMethod (FindMethod .create ()
72- .matcher (MethodMatcher .create ()
73- .usingStrings ("get savedList size :" )
74- )).singleOrNull ();
75- return methodData ;
76- }
77- });
78- mPhraseMethod = requiredMember ("phrase$1" , new IDexKit () {
79- @ Override
80- public BaseData dexkit (DexKitBridge bridge ) throws ReflectiveOperationException {
81- MethodData methodData = bridge .findMethod (FindMethod .create ()
82- .matcher (MethodMatcher .create ()
83- .declaredClass (ClassMatcher .create ()
84- .usingStrings ("phrase_list" )
85- )
86- .usingStrings ("layout_inflater" )
87- )).singleOrNull ();
88- return methodData ;
89- }
90- });
91- mPhraseEditTextField = requiredMember ("phrase$2" , new IDexKit () {
92- @ Override
93- public BaseData dexkit (DexKitBridge bridge ) throws ReflectiveOperationException {
94- return bridge .findField (FindField .create ()
95- .matcher (FieldMatcher .create ()
96- .declaredClass (ClassMatcher .create ()
97- .usingStrings ("phrase_list" )
98- )
99- .type (EditText .class )
65+ mBuildClipboardJsonMethod = requiredMember ("BuildClipboardJson" , new IDexKit () {
66+ @ Override
67+ public BaseData dexkit (DexKitBridge bridge ) throws ReflectiveOperationException {
68+ MethodData methodData = bridge .findMethod (FindMethod .create ()
69+ .matcher (MethodMatcher .create ()
70+ .usingStrings ("get savedList size :" )
71+ )).singleOrNull ();
72+ return methodData ;
73+ }
74+ });
75+ mPhraseMethod = requiredMember ("phrase$1" , new IDexKit () {
76+ @ Override
77+ public BaseData dexkit (DexKitBridge bridge ) throws ReflectiveOperationException {
78+ MethodData methodData = bridge .findMethod (FindMethod .create ()
79+ .matcher (MethodMatcher .create ()
80+ .declaredClass (ClassMatcher .create ()
81+ .usingStrings ("phrase_list" )
10082 )
101- ).single ();
102- }
103- });
104- }
83+ .usingStrings ("layout_inflater" )
84+ )).singleOrNull ();
85+ return methodData ;
86+ }
87+ });
88+ mPhraseEditTextField = requiredMember ("phrase$2" , new IDexKit () {
89+ @ Override
90+ public BaseData dexkit (DexKitBridge bridge ) throws ReflectiveOperationException {
91+ return bridge .findField (FindField .create ()
92+ .matcher (FieldMatcher .create ()
93+ .declaredClass (ClassMatcher .create ()
94+ .usingStrings ("phrase_list" )
95+ )
96+ .type (EditText .class )
97+ )
98+ ).single ();
99+ }
100+ });
105101 return true ;
106102 }
107103
108104 @ Override
109105 public void init () {
110- try {
111- findAndHookMethod ("android.inputmethodservice.InputMethodModuleManager" , "loadDex" , ClassLoader .class , String .class , new IMethodHook () {
112- @ Override
113- public void after (HookParam param ) {
114- ClassLoader classLoader = (ClassLoader ) param .getArgs ()[0 ];
115- setStaticField (findClass ("com.miui.inputmethod.MiuiClipboardManager" , classLoader ), "MAX_CLIP_CONTENT_SIZE" , Integer .MAX_VALUE );
116- EzxHelpUtils .findAndHookMethod ("com.miui.inputmethod.MiuiClipboardManager" , classLoader , "init" , new IMethodHook () {
117- @ Override
118- public void before (HookParam param ) {
119- setStaticField (findClass ("com.miui.inputmethod.MiuiClipboardManager" , classLoader ), "MAX_CLIP_CONTENT_SIZE" , Integer .MAX_VALUE );
120- }
121-
122- @ Override
123- public void after (HookParam param ) throws Exception {
124- setStaticField (findClass ("com.miui.inputmethod.MiuiClipboardManager" , classLoader ), "MAX_CLIP_CONTENT_SIZE" , Integer .MAX_VALUE );
125- }
126- }
127- );
128- }
106+ hookBuildClipboardJson ();
107+ hookPhraseListLimit ();
108+ hookPhraseEditCharLimit ();
109+ }
110+
111+ /**
112+ * Hook BuildClipboardJson 方法,移除 20 条剪贴板条目限制。
113+ * <p>
114+ * 原始方法会将超过 20 条的旧条目删除,这里重新实现为不限制条数,
115+ * 但保留过期清理逻辑以避免剪贴板 JSON 无限膨胀。
116+ */
117+ private void hookBuildClipboardJson () {
118+ hookMethod (mBuildClipboardJsonMethod , new IMethodHook () {
119+ @ Override
120+ public void before (HookParam param ) {
121+ Object newModel = param .getArgs ()[2 ];
122+ String oldJson = (String ) param .getArgs ()[3 ];
123+
124+ JSONArray jsonArray = new JSONArray ();
125+ ArrayList <Object > list = new ArrayList <>();
126+
127+ if (newModel != null ) {
128+ list .add (newModel );
129129 }
130- );
131- } catch (Exception ignore ) {}
132- if (Objects .equals (getPackageName (), "com.miui.phrase" )) {
133- hookMethod (mBuildClipboardJsonMethod , new IMethodHook () {
134- @ Override
135- public void before (HookParam param ) {
136- Object newModel = param .getArgs ()[2 ];
137- String oldJson = (String ) param .getArgs ()[3 ];
138- Class <?> mgrCls = null ;
139-
140- JSONArray jsonArray = new JSONArray ();
141- ArrayList <Object > list = new ArrayList <>();
142-
143- if (newModel != null ) {
144- list .add (newModel );
145- }
146-
147- if (!TextUtils .isEmpty (oldJson )) {
148- mgrCls = findClass ("com.miui.inputmethod.MiuiClipboardManager" , getClassLoader ());
149- List <?> oldList = (List <?>) callStaticMethod (mgrCls , "jsonToBeanList" , oldJson );
150- list .addAll (oldList );
151- }
152-
153- for (int i = 0 ; i < list .size (); i ++) {
154- Object model = list .get (i );
155- Object jsonObj = callMethod (model , "toJSONObject" );
156- jsonArray .put (jsonObj );
157- }
158-
159- param .setResult (jsonArray .toString ());
130+
131+ if (!TextUtils .isEmpty (oldJson )) {
132+ Class <?> mgrCls = findClass ("com.miui.inputmethod.MiuiClipboardManager" , getClassLoader ());
133+ List <?> oldList = (List <?>) callStaticMethod (mgrCls , "jsonToBeanList" , oldJson );
134+ list .addAll (oldList );
160135 }
161- });
162136
163- // 解除 20 条限制
164- Class <?> InputMethodUtil = findClass ("com.miui.inputmethod.InputMethodUtil" );
165- setStaticField (InputMethodUtil , "sPhraseListSize" , 0 );
166- findAndHookMethod (InputMethodUtil , "queryPhrase" , Context .class , new IMethodHook () {
167- @ Override
168- public void after (HookParam param ) {
169- setStaticField (InputMethodUtil , "sPhraseListSize" , 0 );
137+ for (int i = 0 ; i < list .size (); i ++) {
138+ Object model = list .get (i );
139+ Object jsonObj = callMethod (model , "toJSONObject" );
140+ jsonArray .put (jsonObj );
170141 }
171- });
172142
173- Class <?> AddPhraseActivity = findClass ("com.miui.phrase.AddPhraseActivity" );
174- findAndHookMethod ("com.miui.phrase.PhraseEditActivity" , "onClick" , View .class , new IMethodHook () {
143+ param .setResult (jsonArray .toString ());
144+ }
145+ });
146+ }
147+
148+ /**
149+ * 解除常用语 20 条数量限制
150+ */
151+ private void hookPhraseListLimit () {
152+ Class <?> InputMethodUtil = findClass ("com.miui.inputmethod.InputMethodUtil" );
153+ setStaticField (InputMethodUtil , "sPhraseListSize" , 0 );
154+ findAndHookMethod (InputMethodUtil , "queryPhrase" , Context .class , new IMethodHook () {
155+ @ Override
156+ public void after (HookParam param ) {
157+ setStaticField (InputMethodUtil , "sPhraseListSize" , 0 );
158+ }
159+ });
160+
161+ Class <?> AddPhraseActivity = findClass ("com.miui.phrase.AddPhraseActivity" );
162+ findAndHookMethod ("com.miui.phrase.PhraseEditActivity" , "onClick" , View .class , new IMethodHook () {
163+ @ Override
164+ public void before (HookParam param ) {
165+ Activity activity = (Activity ) param .getThisObject ();
166+ Intent intent = new Intent (activity , AddPhraseActivity );
167+ intent .setAction ("com.miui.intent.action.PHRASE_ADD" );
168+ activity .startActivityForResult (intent , 0 );
169+ param .setResult (null );
170+ }
171+ });
172+ }
173+
174+ /**
175+ * 解除常用语字数限制
176+ */
177+ private void hookPhraseEditCharLimit () {
178+ hookMethod (mPhraseMethod , new IMethodHook () {
175179 @ Override
176- public void before (HookParam param ) {
177- Activity activity = (Activity ) param .getThisObject ();
178- Intent intent = new Intent (activity , AddPhraseActivity );
179- intent .setAction ("com.miui.intent.action.PHRASE_ADD" );
180- activity .startActivityForResult (intent , 0 );
181- param .setResult (null );
182- }
183- });
184-
185- // 解除字数限制
186- hookMethod (mPhraseMethod , new IMethodHook () {
187- @ Override
188- public void after (HookParam param ) {
189- EditText editText = (EditText ) getObjectField (param .getThisObject (), mPhraseEditTextField .getName ());
190- editText .setFilters (new InputFilter []{new InputFilter .LengthFilter (Integer .MAX_VALUE )});
191- }
180+ public void after (HookParam param ) {
181+ EditText editText = (EditText ) getObjectField (param .getThisObject (), mPhraseEditTextField .getName ());
182+ editText .setFilters (new InputFilter []{new InputFilter .LengthFilter (Integer .MAX_VALUE )});
192183 }
193- );
194- }
184+ }
185+ );
195186 }
196187}
0 commit comments