2023-09-09

【Kotlin】GeckoView 動態顯示本機網頁

參考資料 ----
Match patterns

動機:
因為 GeckoView 的顯示效果比 Android 系統內建 WebView 元件強上許多,所以想探索是否能以 GeckoView 取代 WebView,達到 WebView.loadDataWithBaseURL() 的目的。

先說結論:截至目前為止(2023.09.09), GeckoView 版本為 117.0.20230824132758 之際,
無法實作動態顯示本機網頁,只能顯示靜態網頁,原因在:

GeckoView 目前尚 不支援 url 為 resource://... 的 scheme


所以當您想顯示動態內容網頁,而網頁又引入了 css、javascript... 等檔案,則這些 css、javascript...檔案必須置放在 internet 的網站上,然後呼叫 loadString(html string)。





下面的筆記就先不予理會了...



有時候我們並不是要去下載某個網站的網頁,而是想利用 GeckoView 顯示 HTML+CSS 豐富的版面樣式,要讓 app 和 GeckoView 能互傳訊息,這就要利用 WebExtension(擴充套件) 的功能。

開發工具:Android Studio Chipmunk 2021.2.1 Patch 2

/assets 內建立要置放 javascript 、 CSS 和 WebExtension 的目錄,並將需要的檔案分別置放於內;再建立一個 html 首頁檔,該網頁的 <head> 區塊要引入前述的 javascriptcss

WebExtensionGeckoViewapp 之間扮演重要的角色,是兩者的溝通橋樑。

每建立一個 WebExtensionWebExtension 要有自己的目錄,在本例,我們建立 /assets/messaging/ ,然後每個 WebExtension 要有自己的 manifest.json

manifest.json
  1.  
  2. {
  3. "manifest_version": 2,
  4. "name": "messaging",
  5. "version": "1.0",
  6. "description": "Example messaging web extension.",
  7. "browser_specific_settings": {
  8. "gecko": {
  9. "id": "messaging@example.com"
  10. }
  11. },
  12. "content_scripts": [
  13. {
  14. // "matches": ["*://*.twitter.com/*"],
  15. "matches": ["*://*/*.htm"],
  16. "js": ["messaging.js"]
  17. }
  18. ],
  19. "permissions": [
  20. // "activeTab",
  21. "nativeMessaging",
  22. "nativeMessagingFromContent",
  23. "geckoViewAddons"
  24. ]
  25. }
  26.  


再建立 app 要與 GeckoView 通訊的 javascript 程式,在本例為 background.js
 
background.js
  1.  
  2. // Establish connection with app
  3. let port = browser.runtime.connectNative("browser");
  4. port.onMessage.addListener(response => {
  5. // Let's just echo the message back
  6. port.postMessage(`Received: ${JSON.stringify(response)}`);
  7. });
  8. port.postMessage("Hello from WebExtension!");
  9.  


WWW


index.htm (檔名可自定喔)
  1.  
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  6. <script type="text/javascript" src="./js/jquery-3.5.1.min.js"></script>
  7. <script type="text/javascript" src="./js/jquery-ui-1.8.16.custom.min.js"></script>
  8. <link rel="stylesheet" href="./css/jquery-ui-1.8.16.custom.css">
  9. <style>
  10. img{ max-width:50%; }
  11. .matrix-block { font-size: 150%; text-align: center }
  12. mtable.thin-column-padding > mtr > mtd,
  13. fmath span.thin-column-padding > table > tbody > tr > td
  14. { padding: 0 0.11em !important }
  15. </style>
  16. </head>
  17. <body>
  18. hello
  19. </body>
  20. </html>
  21.  


MainActivity.kt
  1.  
  2. ...
  3. ...
  4.  
  5. import org.mozilla.geckoview.GeckoRuntime;
  6. import org.mozilla.geckoview.GeckoSession;
  7. import org.mozilla.geckoview.GeckoView;
  8.  
  9. class MainActivity : AppCompatActivity() {
  10.  
  11. override fun onCreate(savedInstanceState: Bundle?) {
  12. super.onCreate(savedInstanceState)
  13. setContentView(R.layout.activity_main)
  14.  
  15. var view:GeckoView = findViewById(R.id.geckoview)
  16. val session = GeckoSession()
  17. val runtime = GeckoRuntime.create(this)
  18. session.contentDelegate = object : ContentDelegate {}
  19. if(runtime==null) {
  20. runtime = GeckoRuntime.create(this)
  21. }
  22. session.open(runtime)
  23. view.setSession(session)
  24. session.loadUri(""resource://android/assets/index.htm"") // 先載入首頁,讓 GeckoView 記住相關的設定
  25. // 再載入自定的網頁內容
  26. }
  27. }
  28.  



相關筆記 ----


沒有留言:

張貼留言