Android?autojs隨時翻譯剪貼板單詞實現示例
使用場景
在看英文的時候, 我們會遇到不懂得單詞, 就需要查閱單詞的意思,
一般步驟是長按出現菜單, 選中單詞, 菜單里有的有翻譯選項, 點擊之后跳轉搜索單詞的頁面,
有的菜單里面沒有翻譯選項, 復制以后, 需要自行打開百度, 或者其他翻譯軟件, 再搜索翻譯
這里面有很多非常干擾我們閱讀的操作, 在app之間跳來跳去, 不爽;
目標
我們今天就做一個, 當長按之后, 選中單詞, 點擊復制, 直接出翻譯的功能
主要功能
監(jiān)聽剪貼板
這個監(jiān)聽剪貼板的功能在高版本安卓是可以實現的, 只是相比于安卓9之前的版本, 步驟復雜一點點,
Google 在近年來一直在打擊第三方應用程序對剪切板的訪問,目的是增強用戶的個人資料安全。 在發(fā)布 Android 10 時就已經禁止后臺應用讀取剪貼板數據。
我的手機是安卓12, 如果我閱讀文章的app在前臺, autojs在后臺肯定 是讀取不到剪貼板內容的
在autojs的菜單中, 有一個前臺服務, 打開之后, 回到手機桌面, 測試讀取剪貼板, 內容為空, 讀取不到
懸浮窗算前臺嗎?
前臺服務不行的話, 我們用懸浮窗試試, 懸浮窗算前臺嗎?
試試就知道了
let w = floaty.window( <vertical> <button id="readClipboard" text="讀取剪貼板" w="auto" /> </vertical> ); w.readClipboard.click(() => { let content = getClip(); toastLog(content); }); setInterval(() => {}, 1000);
經過測試, toast氣泡內容為空, 證明懸浮窗不算安卓所說的前臺,
焦點
查閱了一番教程之后, 說安卓10獲取剪貼板要獲取焦點,
那么我們就給按鈕申請焦點試試
w.readClipboard.click(() => { // 申請焦點 w.requestFocus(); setTimeout(() => { let content = getClip(); toastLog(content); }, 500); });
焦點申請了, 第一次點擊沒有獲取到剪貼板內容, 之后的點擊都獲取到了剪貼板內容
時差
再次查閱資料, 說申請焦點以后, 還要等一下再獲取剪貼板, 那我們就等一下
w.readClipboard.click((view) => { log(view.text()); // 申請焦點 w.requestFocus(); setTimeout(() => { let content = getClip(); toastLog(content); }, 500); });
這下測試就正常了, 第一次點擊也可以獲取到剪貼板內容,
這里有個問題, 我們申請了焦點, 用完之后應該去除焦點
w.readClipboard.click((view) => { w.requestFocus(); setTimeout(() => { let content = getClip(); toastLog(content); w.disableFocus(); }, 500); });
監(jiān)聽剪貼板
獲取剪貼板內容解決了, 怎么監(jiān)聽呢?
開一個定時器, 每隔一會讀取一下剪貼板,
我們的目的是翻譯單詞, 不想等太久, 所以用300ms, 大家可以自行修改時間
切換焦點的問題
頻繁切換焦點, 當我們要聊天界面有輸入框出現的時候, 焦點會在懸浮窗和聊天輸入框之間頻繁切換,
甚至無法操作界面, 因此我們要增加一個停止切換焦點的功能, 以便我們可以正常打字聊天輸入文字
必須用懸浮窗獲取剪貼板內容嗎
不想用懸浮窗, 也可以試試adb, 手機用usb連接電腦, 然后執(zhí)行下面的命令
adb -d shell appops set org.autojs.autojspro SYSTEM_ALERT_WINDOW allow; adb -d shell pm grant org.autojs.autojspro android.permission.READ_LOGS; adb shell am force-stop org.autojs.autojspro;
實測, 這個方法沒用, 所以, 必須用懸浮窗.
不過那個scrcpy投屏軟件就可以直接獲取剪貼板, 有經驗的大佬可以去看看研究下scrcpy的代碼
翻譯單詞
翻譯單詞可以用在線的百度, 有道, 也可以用離線的詞典.
百度和有道都有免費額度,
百度
免費調用量:標準版免費調用量由不限額度改為5萬字符/月
有道
每小時1000次免費訪問,超過訪問次數后會進行封禁暫停服務,1小時后會自然恢復。
每個平臺都要申請自己的key, 這里以有道為例
這是有道的官網
更換自己的秘鑰和應用id
var appKey = "xxxxxxxxxxxxxxx";// 應用id var key = "xxxxxxxxxxxxxxx"; // 秘鑰 var salt = "" + new Date().getTime(); var curtime = Math.round(new Date().getTime() / 1000); var query = "upvote"; var from = "en"; var to = "zh-CHS"; var str1 = appKey + truncate(query) + salt + curtime + key; var sign = $crypto.digest(str1, "SHA-256", { output: "hex" }); let url = "https://openapi.youdao.com/api"; let data = { q: query, appKey: appKey, salt: salt, from: from, to: to, sign: sign, signType: "v3", curtime: curtime, }; let r = http.post(url, data); let info = r.body.json(); let translation = info.translation; let explains = info.basic ? info.basic.explains.join("\n") : ""; log(translation + "\n" + explains); /* -------------------------------------------------------------------------- */ function truncate(q) { var len = q.length; log("len = " + len); if (len <= 20) return q; let r = q.substring(0, 10) + len + q.substring(len - 10, len); log(r); return r; }
返回的主要信息
upvote
vt. (線上)贊同,點贊
n. (線上)有利的投票
懸浮窗顯示翻譯內容
顯示單詞, 翻譯, 再加一個關閉按鈕
let info = `vt. (線上)贊同,點贊 n. (線上)有利的投票`; setInterval(() => {}, 1000); let w = floaty.window( <vertical bg="#adb5bd" padding="8"> <horizontal h="wrap_content"> <text>upvote</text> <text layout_weight="1" gravity="right"> X </text> </horizontal> <text id="info" textColor="#ffffff" textSize="16sp" /> </vertical> ); w.info.setText(info);
給懸浮窗加上觸摸移動
//記錄按鍵被按下時的觸摸坐標 var x = 0, y = 0; //記錄按鍵被按下時的懸浮窗位置 var windowX, windowY; w.move.setOnTouchListener(function (view, event) { switch (event.getAction()) { case event.ACTION_DOWN: x = event.getRawX(); y = event.getRawY(); windowX = w.getX(); windowY = w.getY(); return true; case event.ACTION_MOVE: //移動手指時調整懸浮窗位置 w.setPosition(windowX + (event.getRawX() - x), windowY + (event.getRawY() - y)); return true; case event.ACTION_UP: return true; } return true; });
觸摸移動效果
添加記憶懸浮窗位置的功能
也許你想要自己調整懸浮窗, 到自己覺得舒服的位置, 那么每次移動懸浮窗后, 就記住懸浮窗左上角的坐標,
下次顯示, 也顯示到這個位置
這個記憶位置的動作放在松開手指的事件(ACTION_UP)里面做
case event.ACTION_UP: storage.put("windowX", w.getX()); storage.put("windowY", w.getY()); return true;
之后如果要顯示懸浮窗, 就先讀取位置信息, 再設置懸浮窗位置
let windowX = storage.get("windowX", 0); let windowY = storage.get("windowY", 0); w.setPosition(windowX, windowY);
停止切換焦點
這個停止切換焦點, 需要用另外一個懸浮窗來控制, 就用那個切換焦點的來做
懸浮窗按鈕點擊有兩個, 功能分別是
- 停止切換焦點
- 退出腳本
let w = floaty.window( <vertical bg="#adb5bd" w="32dp" padding="3"> <text id="focus" w="*" h="36dp" gravity="center" textSize="20dp"> 焦 </text> <View bg="#000000" h="1px"></View> <text id="exit" w="*" h="36dp" gravity="center" textSize="20dp"> 退 </text> </vertical> );
這個懸浮窗默認放在右側邊緣
w.setPosition(-6666, -6666); ui.post(function () { let windowWidth = w.getWidth(); let windowHeight = w.getHeight(); let deviceWidth = device.width; let deviceHeight = device.height; // 懸浮窗放到右側邊緣 w.setPosition(deviceWidth - windowWidth, (deviceHeight - windowHeight) / 2); }, 300);
工作狀態(tài)我們用文字的顏色來表示
- 白色, 工作中, 白天工作的意思
- 黑色, 休息, 晚上睡覺
如果焦, 這個字是白色, 那么就是切換焦點一致在進行, 如果焦點擊以后變成黑色, 就是說切換焦點不工作了;
退, 表示退出腳本的意思
let focus = true; w.focus.click(() => { focus = !focus; if (focus) { w.focus.attr("textColor", "#ffffff"); } else { w.focus.attr("textColor", "#000000"); } }); w.exit.click(() => { engines.myEngine().forceStop(); });
同時, 這個foucus變量, 應當可以控制是否切換焦點, 在這之前, 還有一個問題要確定,
什么時候觸發(fā)翻譯指令, 顯示懸浮窗
這里的觸發(fā)指令設置為, 腳本開始獲取一次剪貼板內容,
如果循環(huán)獲取剪貼板內容和之前的內容不一樣, 那么就觸發(fā)翻譯指令, 顯示懸浮窗
ui.post(function () { w2.requestFocus(); setTimeout(() => { clipboardContent = getClip(); w2.disableFocus(); /* -------------------------------------------------------------------------- */ intervalID = setInterval(function () { if (!focus) { return; } w2.requestFocus(); setTimeout(() => { let currentClipboardContent = getClip(); w2.disableFocus(); if (currentClipboardContent !== clipboardContent) { clipboardContent = currentClipboardContent; let info = translate(clipboardContent); showInfo(info); } }, 100); }, 300); }, 1000); });
切換焦點, 影響長按復制單詞
實際使用發(fā)現, 如果頻繁切換焦點, 那么長按菜單都出不來, 因此, 不可以頻繁切換焦點,
基于這個原因, 翻譯的時機要改一下, 改為當用戶主動點擊按鈕, 再去讀取剪貼板
這個主要是修改右側按鈕的點擊事件, 點擊按鈕后讀取剪貼板內容, 再進行翻譯, 顯示懸浮窗
最終效果展示
點擊右側按鈕, 譯, 顯示翻譯結果
環(huán)境
設備: 小米11Pro
Android版本: 12
Autojs版本: 9.2.10
以上就是Android autojs隨時翻譯剪貼板單詞實現示例的詳細內容,更多關于Android autojs 剪貼板翻譯的資料請關注腳本之家其它相關文章!
相關文章
Android studio無法創(chuàng)建類和接口和提示問題的完美解決辦法
這篇文章主要介紹了Android studio無法創(chuàng)建類和接口和提示問題解決辦法,內容比較簡單,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2018-04-04解決Android studio 3.6.1 出現Cause: unable to find valid certifi
這篇文章主要介紹了Android studio 3.6.1 出現Cause: unable to find valid certification path to requested target 報錯的問題及解決方法,需要的朋友可以參考下2020-03-03android LinearLayout和RelativeLayout組合實現精確布局方法介紹
用android LinearLayout和RelativeLayout實現精確布局此方法適合很適合新人看2012-11-11Android項目實戰(zhàn)(二十八):使用Zxing實現二維碼及優(yōu)化實例
這篇文章主要介紹了Android項目實戰(zhàn)(二十八):使用Zxing實現二維碼及優(yōu)化實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2016-11-11