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
 
{
  "manifest_version": 2,
  "name": "messaging",
  "version": "1.0",
  "description": "Example messaging web extension.",
  "browser_specific_settings": {
    "gecko": {
      "id": "messaging@example.com"
    }
  },
  "content_scripts": [
    {
      // "matches": ["*://*.twitter.com/*"],
      "matches": ["*://*/*.htm"],
      "js": ["messaging.js"]
    }
  ],
  "permissions": [
    // "activeTab",
    "nativeMessaging",
    "nativeMessagingFromContent",
    "geckoViewAddons"
  ]
}
 


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


WWW


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


MainActivity.kt
 
...
...

import org.mozilla.geckoview.GeckoRuntime;
import org.mozilla.geckoview.GeckoSession;
import org.mozilla.geckoview.GeckoView;

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        var view:GeckoView = findViewById(R.id.geckoview)
        val session = GeckoSession()
        val runtime = GeckoRuntime.create(this)
        
        session.contentDelegate = object : ContentDelegate {}
        if(runtime==null) {
            runtime = GeckoRuntime.create(this)
        }
        
        session.open(runtime)
        view.setSession(session)
        session.loadUri(""resource://android/assets/index.htm"")    // 先載入首頁,讓 GeckoView 記住相關的設定
        
        
        // 再載入自定的網頁內容
        
    }
}
 



相關筆記 ----


沒有留言:

張貼留言