@aiscene/android 1.6.4 → 1.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ require('../dist/lib/cli.js');
package/bin/yadb ADDED
Binary file
package/dist/es/cli.mjs CHANGED
@@ -932,7 +932,66 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
932
932
  async execYadb(keyboardContent) {
933
933
  await this.ensureYadb();
934
934
  const adb = await this.getAdb();
935
- await adb.shell(`app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "${keyboardContent}"`);
935
+ try {
936
+ const command = `app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "${keyboardContent}"`;
937
+ debugDevice(`Executing YADB input: "${keyboardContent}"`);
938
+ const inputPromise = adb.shell(command);
939
+ const timeoutPromise = new Promise((_, reject)=>setTimeout(()=>reject(new Error('YADB timeout')), 1000));
940
+ await Promise.race([
941
+ inputPromise,
942
+ timeoutPromise
943
+ ]);
944
+ debugDevice(`YADB input completed: "${keyboardContent}"`);
945
+ } catch (error) {
946
+ const isAccessibilityConflict = error?.cause?.stderr?.includes('UiAutomationService') || error?.cause?.stderr?.includes('already registered') || error?.message?.includes('UiAutomationService');
947
+ if (isAccessibilityConflict) {
948
+ debugDevice("YADB failed due to AccessibilityService conflict (likely Appium running), falling back to clipboard method");
949
+ await this.inputViaClipboard(keyboardContent);
950
+ } else 'YADB timeout' === error.message ? debugDevice(`YADB timed out after 2s, assuming input succeeded: "${keyboardContent}"`) : debugDevice(`YADB execution may have completed despite error: ${error}`);
951
+ }
952
+ }
953
+ async inputViaClipboard(text) {
954
+ const adb = await this.getAdb();
955
+ try {
956
+ debugDevice(`Inputting via clipboard: "${text}"`);
957
+ const escapedText = text.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
958
+ const setClipboardCmd = `
959
+ content insert --uri content://settings/system --bind name:s:clipboard_text --bind value:s:"${escapedText}"
960
+ `;
961
+ await adb.shell(setClipboardCmd);
962
+ await sleep(100);
963
+ await adb.shell('input keyevent KEYCODE_PASTE');
964
+ await sleep(100);
965
+ debugDevice(`Clipboard input completed via content provider: "${text}"`);
966
+ } catch (error1) {
967
+ debugDevice(`Content provider clipboard failed, trying clipper app: ${error1}`);
968
+ try {
969
+ const base64Text = Buffer.from(text, 'utf-8').toString('base64');
970
+ await adb.shell(`am broadcast -a clipper.set -e text "${base64Text}"`);
971
+ await sleep(100);
972
+ await adb.shell('input keyevent KEYCODE_PASTE');
973
+ await sleep(100);
974
+ debugDevice(`Clipboard input completed via clipper: "${text}"`);
975
+ } catch (error2) {
976
+ debugDevice(`All clipboard methods failed: ${error2}`);
977
+ const isPureAscii = /^[\x00-\x7F]*$/.test(text);
978
+ if (isPureAscii) {
979
+ debugDevice(`Using ADB inputText for ASCII text: "${text}"`);
980
+ await adb.inputText(text);
981
+ } else await this.inputCharByChar(text);
982
+ }
983
+ }
984
+ }
985
+ async inputCharByChar(text) {
986
+ const adb = await this.getAdb();
987
+ debugDevice(`Inputting character by character (slow method): "${text}"`);
988
+ const chars = Array.from(text);
989
+ for (const char of chars){
990
+ if (' ' === char) await adb.shell('input keyevent KEYCODE_SPACE');
991
+ else await adb.shell(`input text "${char}"`);
992
+ await sleep(50);
993
+ }
994
+ debugDevice("Character-by-character input completed");
936
995
  }
937
996
  async getElementsInfo() {
938
997
  return [];
@@ -1865,7 +1924,7 @@ class AndroidMidsceneTools extends BaseMidsceneTools {
1865
1924
  const tools = new AndroidMidsceneTools();
1866
1925
  runToolsCLI(tools, 'midscene-android', {
1867
1926
  stripPrefix: 'android_',
1868
- version: "1.6.4"
1927
+ version: "1.6.7"
1869
1928
  }).catch((e)=>{
1870
1929
  if (!(e instanceof CLIError)) console.error(e);
1871
1930
  process.exit(e instanceof CLIError ? e.exitCode : 1);
package/dist/es/index.mjs CHANGED
@@ -835,7 +835,66 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
835
835
  async execYadb(keyboardContent) {
836
836
  await this.ensureYadb();
837
837
  const adb = await this.getAdb();
838
- await adb.shell(`app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "${keyboardContent}"`);
838
+ try {
839
+ const command = `app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "${keyboardContent}"`;
840
+ debugDevice(`Executing YADB input: "${keyboardContent}"`);
841
+ const inputPromise = adb.shell(command);
842
+ const timeoutPromise = new Promise((_, reject)=>setTimeout(()=>reject(new Error('YADB timeout')), 1000));
843
+ await Promise.race([
844
+ inputPromise,
845
+ timeoutPromise
846
+ ]);
847
+ debugDevice(`YADB input completed: "${keyboardContent}"`);
848
+ } catch (error) {
849
+ const isAccessibilityConflict = error?.cause?.stderr?.includes('UiAutomationService') || error?.cause?.stderr?.includes('already registered') || error?.message?.includes('UiAutomationService');
850
+ if (isAccessibilityConflict) {
851
+ debugDevice("YADB failed due to AccessibilityService conflict (likely Appium running), falling back to clipboard method");
852
+ await this.inputViaClipboard(keyboardContent);
853
+ } else 'YADB timeout' === error.message ? debugDevice(`YADB timed out after 2s, assuming input succeeded: "${keyboardContent}"`) : debugDevice(`YADB execution may have completed despite error: ${error}`);
854
+ }
855
+ }
856
+ async inputViaClipboard(text) {
857
+ const adb = await this.getAdb();
858
+ try {
859
+ debugDevice(`Inputting via clipboard: "${text}"`);
860
+ const escapedText = text.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
861
+ const setClipboardCmd = `
862
+ content insert --uri content://settings/system --bind name:s:clipboard_text --bind value:s:"${escapedText}"
863
+ `;
864
+ await adb.shell(setClipboardCmd);
865
+ await sleep(100);
866
+ await adb.shell('input keyevent KEYCODE_PASTE');
867
+ await sleep(100);
868
+ debugDevice(`Clipboard input completed via content provider: "${text}"`);
869
+ } catch (error1) {
870
+ debugDevice(`Content provider clipboard failed, trying clipper app: ${error1}`);
871
+ try {
872
+ const base64Text = Buffer.from(text, 'utf-8').toString('base64');
873
+ await adb.shell(`am broadcast -a clipper.set -e text "${base64Text}"`);
874
+ await sleep(100);
875
+ await adb.shell('input keyevent KEYCODE_PASTE');
876
+ await sleep(100);
877
+ debugDevice(`Clipboard input completed via clipper: "${text}"`);
878
+ } catch (error2) {
879
+ debugDevice(`All clipboard methods failed: ${error2}`);
880
+ const isPureAscii = /^[\x00-\x7F]*$/.test(text);
881
+ if (isPureAscii) {
882
+ debugDevice(`Using ADB inputText for ASCII text: "${text}"`);
883
+ await adb.inputText(text);
884
+ } else await this.inputCharByChar(text);
885
+ }
886
+ }
887
+ }
888
+ async inputCharByChar(text) {
889
+ const adb = await this.getAdb();
890
+ debugDevice(`Inputting character by character (slow method): "${text}"`);
891
+ const chars = Array.from(text);
892
+ for (const char of chars){
893
+ if (' ' === char) await adb.shell('input keyevent KEYCODE_SPACE');
894
+ else await adb.shell(`input text "${char}"`);
895
+ await sleep(50);
896
+ }
897
+ debugDevice("Character-by-character input completed");
839
898
  }
840
899
  async getElementsInfo() {
841
900
  return [];
@@ -931,7 +931,66 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
931
931
  async execYadb(keyboardContent) {
932
932
  await this.ensureYadb();
933
933
  const adb = await this.getAdb();
934
- await adb.shell(`app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "${keyboardContent}"`);
934
+ try {
935
+ const command = `app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "${keyboardContent}"`;
936
+ debugDevice(`Executing YADB input: "${keyboardContent}"`);
937
+ const inputPromise = adb.shell(command);
938
+ const timeoutPromise = new Promise((_, reject)=>setTimeout(()=>reject(new Error('YADB timeout')), 1000));
939
+ await Promise.race([
940
+ inputPromise,
941
+ timeoutPromise
942
+ ]);
943
+ debugDevice(`YADB input completed: "${keyboardContent}"`);
944
+ } catch (error) {
945
+ const isAccessibilityConflict = error?.cause?.stderr?.includes('UiAutomationService') || error?.cause?.stderr?.includes('already registered') || error?.message?.includes('UiAutomationService');
946
+ if (isAccessibilityConflict) {
947
+ debugDevice("YADB failed due to AccessibilityService conflict (likely Appium running), falling back to clipboard method");
948
+ await this.inputViaClipboard(keyboardContent);
949
+ } else 'YADB timeout' === error.message ? debugDevice(`YADB timed out after 2s, assuming input succeeded: "${keyboardContent}"`) : debugDevice(`YADB execution may have completed despite error: ${error}`);
950
+ }
951
+ }
952
+ async inputViaClipboard(text) {
953
+ const adb = await this.getAdb();
954
+ try {
955
+ debugDevice(`Inputting via clipboard: "${text}"`);
956
+ const escapedText = text.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
957
+ const setClipboardCmd = `
958
+ content insert --uri content://settings/system --bind name:s:clipboard_text --bind value:s:"${escapedText}"
959
+ `;
960
+ await adb.shell(setClipboardCmd);
961
+ await sleep(100);
962
+ await adb.shell('input keyevent KEYCODE_PASTE');
963
+ await sleep(100);
964
+ debugDevice(`Clipboard input completed via content provider: "${text}"`);
965
+ } catch (error1) {
966
+ debugDevice(`Content provider clipboard failed, trying clipper app: ${error1}`);
967
+ try {
968
+ const base64Text = Buffer.from(text, 'utf-8').toString('base64');
969
+ await adb.shell(`am broadcast -a clipper.set -e text "${base64Text}"`);
970
+ await sleep(100);
971
+ await adb.shell('input keyevent KEYCODE_PASTE');
972
+ await sleep(100);
973
+ debugDevice(`Clipboard input completed via clipper: "${text}"`);
974
+ } catch (error2) {
975
+ debugDevice(`All clipboard methods failed: ${error2}`);
976
+ const isPureAscii = /^[\x00-\x7F]*$/.test(text);
977
+ if (isPureAscii) {
978
+ debugDevice(`Using ADB inputText for ASCII text: "${text}"`);
979
+ await adb.inputText(text);
980
+ } else await this.inputCharByChar(text);
981
+ }
982
+ }
983
+ }
984
+ async inputCharByChar(text) {
985
+ const adb = await this.getAdb();
986
+ debugDevice(`Inputting character by character (slow method): "${text}"`);
987
+ const chars = Array.from(text);
988
+ for (const char of chars){
989
+ if (' ' === char) await adb.shell('input keyevent KEYCODE_SPACE');
990
+ else await adb.shell(`input text "${char}"`);
991
+ await sleep(50);
992
+ }
993
+ debugDevice("Character-by-character input completed");
935
994
  }
936
995
  async getElementsInfo() {
937
996
  return [];
@@ -1868,7 +1927,7 @@ class AndroidMCPServer extends BaseMCPServer {
1868
1927
  constructor(toolsManager){
1869
1928
  super({
1870
1929
  name: '@midscene/android-mcp',
1871
- version: "1.6.4",
1930
+ version: "1.6.7",
1872
1931
  description: 'Control the Android device using natural language commands'
1873
1932
  }, toolsManager);
1874
1933
  }
package/dist/lib/cli.js CHANGED
@@ -947,7 +947,66 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
947
947
  async execYadb(keyboardContent) {
948
948
  await this.ensureYadb();
949
949
  const adb = await this.getAdb();
950
- await adb.shell(`app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "${keyboardContent}"`);
950
+ try {
951
+ const command = `app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "${keyboardContent}"`;
952
+ debugDevice(`Executing YADB input: "${keyboardContent}"`);
953
+ const inputPromise = adb.shell(command);
954
+ const timeoutPromise = new Promise((_, reject)=>setTimeout(()=>reject(new Error('YADB timeout')), 1000));
955
+ await Promise.race([
956
+ inputPromise,
957
+ timeoutPromise
958
+ ]);
959
+ debugDevice(`YADB input completed: "${keyboardContent}"`);
960
+ } catch (error) {
961
+ const isAccessibilityConflict = error?.cause?.stderr?.includes('UiAutomationService') || error?.cause?.stderr?.includes('already registered') || error?.message?.includes('UiAutomationService');
962
+ if (isAccessibilityConflict) {
963
+ debugDevice("YADB failed due to AccessibilityService conflict (likely Appium running), falling back to clipboard method");
964
+ await this.inputViaClipboard(keyboardContent);
965
+ } else 'YADB timeout' === error.message ? debugDevice(`YADB timed out after 2s, assuming input succeeded: "${keyboardContent}"`) : debugDevice(`YADB execution may have completed despite error: ${error}`);
966
+ }
967
+ }
968
+ async inputViaClipboard(text) {
969
+ const adb = await this.getAdb();
970
+ try {
971
+ debugDevice(`Inputting via clipboard: "${text}"`);
972
+ const escapedText = text.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
973
+ const setClipboardCmd = `
974
+ content insert --uri content://settings/system --bind name:s:clipboard_text --bind value:s:"${escapedText}"
975
+ `;
976
+ await adb.shell(setClipboardCmd);
977
+ await (0, core_utils_namespaceObject.sleep)(100);
978
+ await adb.shell('input keyevent KEYCODE_PASTE');
979
+ await (0, core_utils_namespaceObject.sleep)(100);
980
+ debugDevice(`Clipboard input completed via content provider: "${text}"`);
981
+ } catch (error1) {
982
+ debugDevice(`Content provider clipboard failed, trying clipper app: ${error1}`);
983
+ try {
984
+ const base64Text = Buffer.from(text, 'utf-8').toString('base64');
985
+ await adb.shell(`am broadcast -a clipper.set -e text "${base64Text}"`);
986
+ await (0, core_utils_namespaceObject.sleep)(100);
987
+ await adb.shell('input keyevent KEYCODE_PASTE');
988
+ await (0, core_utils_namespaceObject.sleep)(100);
989
+ debugDevice(`Clipboard input completed via clipper: "${text}"`);
990
+ } catch (error2) {
991
+ debugDevice(`All clipboard methods failed: ${error2}`);
992
+ const isPureAscii = /^[\x00-\x7F]*$/.test(text);
993
+ if (isPureAscii) {
994
+ debugDevice(`Using ADB inputText for ASCII text: "${text}"`);
995
+ await adb.inputText(text);
996
+ } else await this.inputCharByChar(text);
997
+ }
998
+ }
999
+ }
1000
+ async inputCharByChar(text) {
1001
+ const adb = await this.getAdb();
1002
+ debugDevice(`Inputting character by character (slow method): "${text}"`);
1003
+ const chars = Array.from(text);
1004
+ for (const char of chars){
1005
+ if (' ' === char) await adb.shell('input keyevent KEYCODE_SPACE');
1006
+ else await adb.shell(`input text "${char}"`);
1007
+ await (0, core_utils_namespaceObject.sleep)(50);
1008
+ }
1009
+ debugDevice("Character-by-character input completed");
951
1010
  }
952
1011
  async getElementsInfo() {
953
1012
  return [];
@@ -1880,7 +1939,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1880
1939
  const tools = new AndroidMidsceneTools();
1881
1940
  (0, cli_namespaceObject.runToolsCLI)(tools, 'midscene-android', {
1882
1941
  stripPrefix: 'android_',
1883
- version: "1.6.4"
1942
+ version: "1.6.7"
1884
1943
  }).catch((e)=>{
1885
1944
  if (!(e instanceof cli_namespaceObject.CLIError)) console.error(e);
1886
1945
  process.exit(e instanceof cli_namespaceObject.CLIError ? e.exitCode : 1);
package/dist/lib/index.js CHANGED
@@ -868,7 +868,66 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
868
868
  async execYadb(keyboardContent) {
869
869
  await this.ensureYadb();
870
870
  const adb = await this.getAdb();
871
- await adb.shell(`app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "${keyboardContent}"`);
871
+ try {
872
+ const command = `app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "${keyboardContent}"`;
873
+ debugDevice(`Executing YADB input: "${keyboardContent}"`);
874
+ const inputPromise = adb.shell(command);
875
+ const timeoutPromise = new Promise((_, reject)=>setTimeout(()=>reject(new Error('YADB timeout')), 1000));
876
+ await Promise.race([
877
+ inputPromise,
878
+ timeoutPromise
879
+ ]);
880
+ debugDevice(`YADB input completed: "${keyboardContent}"`);
881
+ } catch (error) {
882
+ const isAccessibilityConflict = error?.cause?.stderr?.includes('UiAutomationService') || error?.cause?.stderr?.includes('already registered') || error?.message?.includes('UiAutomationService');
883
+ if (isAccessibilityConflict) {
884
+ debugDevice("YADB failed due to AccessibilityService conflict (likely Appium running), falling back to clipboard method");
885
+ await this.inputViaClipboard(keyboardContent);
886
+ } else 'YADB timeout' === error.message ? debugDevice(`YADB timed out after 2s, assuming input succeeded: "${keyboardContent}"`) : debugDevice(`YADB execution may have completed despite error: ${error}`);
887
+ }
888
+ }
889
+ async inputViaClipboard(text) {
890
+ const adb = await this.getAdb();
891
+ try {
892
+ debugDevice(`Inputting via clipboard: "${text}"`);
893
+ const escapedText = text.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
894
+ const setClipboardCmd = `
895
+ content insert --uri content://settings/system --bind name:s:clipboard_text --bind value:s:"${escapedText}"
896
+ `;
897
+ await adb.shell(setClipboardCmd);
898
+ await (0, utils_namespaceObject.sleep)(100);
899
+ await adb.shell('input keyevent KEYCODE_PASTE');
900
+ await (0, utils_namespaceObject.sleep)(100);
901
+ debugDevice(`Clipboard input completed via content provider: "${text}"`);
902
+ } catch (error1) {
903
+ debugDevice(`Content provider clipboard failed, trying clipper app: ${error1}`);
904
+ try {
905
+ const base64Text = Buffer.from(text, 'utf-8').toString('base64');
906
+ await adb.shell(`am broadcast -a clipper.set -e text "${base64Text}"`);
907
+ await (0, utils_namespaceObject.sleep)(100);
908
+ await adb.shell('input keyevent KEYCODE_PASTE');
909
+ await (0, utils_namespaceObject.sleep)(100);
910
+ debugDevice(`Clipboard input completed via clipper: "${text}"`);
911
+ } catch (error2) {
912
+ debugDevice(`All clipboard methods failed: ${error2}`);
913
+ const isPureAscii = /^[\x00-\x7F]*$/.test(text);
914
+ if (isPureAscii) {
915
+ debugDevice(`Using ADB inputText for ASCII text: "${text}"`);
916
+ await adb.inputText(text);
917
+ } else await this.inputCharByChar(text);
918
+ }
919
+ }
920
+ }
921
+ async inputCharByChar(text) {
922
+ const adb = await this.getAdb();
923
+ debugDevice(`Inputting character by character (slow method): "${text}"`);
924
+ const chars = Array.from(text);
925
+ for (const char of chars){
926
+ if (' ' === char) await adb.shell('input keyevent KEYCODE_SPACE');
927
+ else await adb.shell(`input text "${char}"`);
928
+ await (0, utils_namespaceObject.sleep)(50);
929
+ }
930
+ debugDevice("Character-by-character input completed");
872
931
  }
873
932
  async getElementsInfo() {
874
933
  return [];
@@ -962,7 +962,66 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
962
962
  async execYadb(keyboardContent) {
963
963
  await this.ensureYadb();
964
964
  const adb = await this.getAdb();
965
- await adb.shell(`app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "${keyboardContent}"`);
965
+ try {
966
+ const command = `app_process${this.getDisplayArg()} -Djava.class.path=/data/local/tmp/yadb /data/local/tmp com.ysbing.yadb.Main -keyboard "${keyboardContent}"`;
967
+ debugDevice(`Executing YADB input: "${keyboardContent}"`);
968
+ const inputPromise = adb.shell(command);
969
+ const timeoutPromise = new Promise((_, reject)=>setTimeout(()=>reject(new Error('YADB timeout')), 1000));
970
+ await Promise.race([
971
+ inputPromise,
972
+ timeoutPromise
973
+ ]);
974
+ debugDevice(`YADB input completed: "${keyboardContent}"`);
975
+ } catch (error) {
976
+ const isAccessibilityConflict = error?.cause?.stderr?.includes('UiAutomationService') || error?.cause?.stderr?.includes('already registered') || error?.message?.includes('UiAutomationService');
977
+ if (isAccessibilityConflict) {
978
+ debugDevice("YADB failed due to AccessibilityService conflict (likely Appium running), falling back to clipboard method");
979
+ await this.inputViaClipboard(keyboardContent);
980
+ } else 'YADB timeout' === error.message ? debugDevice(`YADB timed out after 2s, assuming input succeeded: "${keyboardContent}"`) : debugDevice(`YADB execution may have completed despite error: ${error}`);
981
+ }
982
+ }
983
+ async inputViaClipboard(text) {
984
+ const adb = await this.getAdb();
985
+ try {
986
+ debugDevice(`Inputting via clipboard: "${text}"`);
987
+ const escapedText = text.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
988
+ const setClipboardCmd = `
989
+ content insert --uri content://settings/system --bind name:s:clipboard_text --bind value:s:"${escapedText}"
990
+ `;
991
+ await adb.shell(setClipboardCmd);
992
+ await (0, core_utils_namespaceObject.sleep)(100);
993
+ await adb.shell('input keyevent KEYCODE_PASTE');
994
+ await (0, core_utils_namespaceObject.sleep)(100);
995
+ debugDevice(`Clipboard input completed via content provider: "${text}"`);
996
+ } catch (error1) {
997
+ debugDevice(`Content provider clipboard failed, trying clipper app: ${error1}`);
998
+ try {
999
+ const base64Text = Buffer.from(text, 'utf-8').toString('base64');
1000
+ await adb.shell(`am broadcast -a clipper.set -e text "${base64Text}"`);
1001
+ await (0, core_utils_namespaceObject.sleep)(100);
1002
+ await adb.shell('input keyevent KEYCODE_PASTE');
1003
+ await (0, core_utils_namespaceObject.sleep)(100);
1004
+ debugDevice(`Clipboard input completed via clipper: "${text}"`);
1005
+ } catch (error2) {
1006
+ debugDevice(`All clipboard methods failed: ${error2}`);
1007
+ const isPureAscii = /^[\x00-\x7F]*$/.test(text);
1008
+ if (isPureAscii) {
1009
+ debugDevice(`Using ADB inputText for ASCII text: "${text}"`);
1010
+ await adb.inputText(text);
1011
+ } else await this.inputCharByChar(text);
1012
+ }
1013
+ }
1014
+ }
1015
+ async inputCharByChar(text) {
1016
+ const adb = await this.getAdb();
1017
+ debugDevice(`Inputting character by character (slow method): "${text}"`);
1018
+ const chars = Array.from(text);
1019
+ for (const char of chars){
1020
+ if (' ' === char) await adb.shell('input keyevent KEYCODE_SPACE');
1021
+ else await adb.shell(`input text "${char}"`);
1022
+ await (0, core_utils_namespaceObject.sleep)(50);
1023
+ }
1024
+ debugDevice("Character-by-character input completed");
966
1025
  }
967
1026
  async getElementsInfo() {
968
1027
  return [];
@@ -1899,7 +1958,7 @@ ${Object.keys(size).filter((key)=>size[key]).map((key)=>` ${key} size: ${size[k
1899
1958
  constructor(toolsManager){
1900
1959
  super({
1901
1960
  name: '@midscene/android-mcp',
1902
- version: "1.6.4",
1961
+ version: "1.6.7",
1903
1962
  description: 'Control the Android device using natural language commands'
1904
1963
  }, toolsManager);
1905
1964
  }
@@ -109,6 +109,16 @@ export declare class AndroidDevice implements AbstractInterface {
109
109
  private resolvePackageName;
110
110
  launch(uri: string): Promise<AndroidDevice>;
111
111
  execYadb(keyboardContent: string): Promise<void>;
112
+ /**
113
+ * 通过剪贴板输入文本(备用方案,当YADB不可用时)
114
+ * 支持中文等非ASCII字符
115
+ */
116
+ private inputViaClipboard;
117
+ /**
118
+ * 逐字符输入文本(最后备用方案)
119
+ * 通过模拟按键输入,支持中文(如果有对应输入法)
120
+ */
121
+ private inputCharByChar;
112
122
  getElementsInfo(): Promise<ElementInfo[]>;
113
123
  getElementsNodeTree(): Promise<any>;
114
124
  getScreenSize(): Promise<{
@@ -108,6 +108,16 @@ declare class AndroidDevice implements AbstractInterface {
108
108
  private resolvePackageName;
109
109
  launch(uri: string): Promise<AndroidDevice>;
110
110
  execYadb(keyboardContent: string): Promise<void>;
111
+ /**
112
+ * 通过剪贴板输入文本(备用方案,当YADB不可用时)
113
+ * 支持中文等非ASCII字符
114
+ */
115
+ private inputViaClipboard;
116
+ /**
117
+ * 逐字符输入文本(最后备用方案)
118
+ * 通过模拟按键输入,支持中文(如果有对应输入法)
119
+ */
120
+ private inputCharByChar;
111
121
  getElementsInfo(): Promise<ElementInfo[]>;
112
122
  getElementsNodeTree(): Promise<any>;
113
123
  getScreenSize(): Promise<{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiscene/android",
3
- "version": "1.6.4",
3
+ "version": "1.6.7",
4
4
  "description": "Android automation library for Midscene",
5
5
  "keywords": [
6
6
  "Android UI automation",
Binary file
@@ -1,2 +0,0 @@
1
- appMetadataVersion=1.1
2
- androidGradlePluginVersion=7.4.2
package/bin/classes.dex DELETED
Binary file
Binary file