2020年4月22日 星期三

Windows 10的Cordova心得

目標

使用 Cordova https://cordova.apache.org/  搭建 Hybrid App

環境

Windows 10

安裝nodejs、git bash

node、npm、git會自動加到windows的環境變數,如果沒有要手動加
git bash裡面也能執行npm、node

安裝cordova

可在git bash上安裝,cmd一樣也會有cordova
$ npm install -g cordova
npm WARN deprecated request@2.88.2: request has been deprecated, see https://github.com/request/request/issues/3142
C:\Users\user\AppData\Roaming\npm\cordova -> C:\Users\user\AppData\Roaming\npm\node_modules\cordova\bin\cordova
+ cordova@9.0.0
added 434 packages from 357 contributors in 90.515s

檢查版本

$ cordova --version
9.0.0 (cordova-lib@9.0.1)

$ npm list -g cordova
C:\Users\user\AppData\Roaming\npm
`-- cordova@9.0.0

升級cordova

$ npm i -g cordova

新建項目

$ cordova create hello com.example.hello HelloWorld

新增平台(browser)

$ cd hello
$ cordova platform add browser
Using cordova-fetch for cordova-browser@^6.0.0
Adding browser project...
Creating Cordova project for cordova-browser:
        Path: C:\Users\user\WebstormProjects\hello\platforms\browser
        Name: HelloWorld
Plugin 'cordova-plugin-whitelist' found in config.xml... Migrating it to package.json
Discovered saved plugin "cordova-plugin-whitelist". Adding it to the project
Installing "cordova-plugin-whitelist" for browser
Adding cordova-plugin-whitelist to package.json

檢查現在設置的平台

(請注意 platform 和 platforms 命令是同義語.)
$ cordova platform ls
Installed platforms:
  browser 6.0.0
Available platforms:
  android ^8.0.0
  electron ^1.0.0
  ios ^5.0.0
  osx ^5.0.0
  windows ^7.0.0

檢查你build 平台時是否滿足要求(requirements)

$  cordova requirements
Requirements check results for browser:

執行

https://www.youtube.com/watch?v=DEDuc4FpYZs  How To Install Apache Cordova On Windows For Beginners
$ cordova run browser
會打開瀏覽器
修改www/index.html後需重新執行 cordova run browser 才生效

在Android上運行

https://www.youtube.com/watch?v=IA3c2lpoOtU&t=373s  Install Cordova, Import to Android studio to Deploy using PhoneGap Cordova Plugin
https://www.youtube.com/watch?v=31kO-qS4qig&t=192s  Setting up/Installing Cordova - Part 1
安裝Android Studio (略)

安裝java JDK


Cordova 只支持 JDK 1.8

https://stackoverflow.com/a/50644399
You may have a version that is greater than 8 but Cordova only supports JDK 1.8. View this link Cordova Documentation
否則在Android Studio run時會報錯
"C:\Program Files\Android\Android Studio\bin\runnerw.exe" C:\Users\user\AppData\Roaming\npm\cordova.cmd run android
Checking Java JDK and Android SDK versions
Requirements check failed for JDK 8 ('1.8.*')! Detected version: 14.0.1

ps. JAVA SE 8 是 LTS版本,官方支持到 2030 年 12 月

設定java環境變數

本機 => 內容 => 進階系統設定 => 環境變數 => 「Path」點兩下編輯 => 新增 C:\Program Files\Java\jdk1.8.0_251\bin
新增使用者變數 JAVA_HOME: C:\Program Files\Java\jdk1.8.0_251
配置完要重新開git bash的session才生效
$ javac -version
javac 1.8.0_251

安裝Android command line tools

到 Android SDK Command Line tools installation page   下載 commandlinetools-win-6200805_latest.zip
新建 C:\android 目錄( ANDROID_HOME ),將 commandlinetools-win-6200805_latest.zip 解壓縮到 C:\android\tools
配置環境變數 ANDROID_HOME :  C:\android  ( 勿設為 C:\android\tools ,否則build時會報這個錯: > Failed to find target with hash string 'android-28' in: C:\android\tools )
設定 Path: %ANDROID_HOME%\tools\bin

安裝Gradle

到 gradle releases page ,下載最新  binary-only 的 Gradle ( gradle-6.3-bin.zip )
解壓縮後將 gradle-6.3 目錄重新命名成 gradle 放到  C:\android\gradle
配置環境變  GRADLE_HOME : C:\android\gradle
設定 Path : %ANDROID_HOME%\gradle\bin

執行 sdkmanager 和 avdmanager 命令

(我在git bash執行)
$ cd /c/android/tools/bin
$ ./sdkmanager.bat --sdk_root=$ANDROID_HOME "build-tools;25.0.3" "emulator" "extras;intel;Hardware_Accelerated_Execution_Manager" "platforms;android-25" "platform-tools" "system-images;android-25;google_apis;x86" --verbose

https://stackoverflow.com/a/60454207  Android Command line tools sdkmanager always shows: Warning: Could not create settings

--sdk_root=$ANDROID_HOME 必須加,否則會報錯:
Warning: Could not create settings
java.lang.IllegalArgumentException


執行完會新增以下資料夾

build-tools - Cordova build Android app使用的工具
emulator - 安卓模擬器,用來預覽你的APP
platforms - Android SDK,以不同版本分開。上面的命令下載了(當時的)最新版本(25)
platform-tools - 管理安卓設備的命令行工具
system-images - 模擬器所需的images

在cmd上就是這樣執行

>sdkmanager --sdk_root=%ANDROID_HOME% --version
3.6.0

$ ./avdmanager.bat -v create avd -n x86 -k "system-images;android-25;google_apis;x86" -g "google_apis"

ps ./sdkmanager.bat 和 ./avdmanager.bat 因為是bat檔不是exe檔,設 Path 後依然沒法在bash全局呼叫

設定環境變數Path

%ANDROID_HOME%\emulator
%ANDROID_HOME%\platform-tools
測試是否正確設置Path
$ adb version
Android Debug Bridge version 1.0.41
Version 29.0.6-6198805
Installed as C:\android\platform-tools\adb.exe

$ gradle -v
Welcome to Gradle 6.3!
...
------------------------------------------------------------
Gradle 6.3
------------------------------------------------------------

Build time:   2020-03-24 19:52:07 UTC
Revision:     bacd40b727b0130eeac8855ae3f9fd9a0b207c60

Kotlin:       1.3.70
Groovy:       2.5.10
Ant:          Apache Ant(TM) version 1.10.7 compiled on September 1 2019
JVM:          1.8.0_251 (Oracle Corporation 25.251-b08)
OS:           Windows 10 10.0 amd64

buid時可能的報錯

File C:\Users\user\.android\repositories.cfg could not be loaded.

https://stackoverflow.com/a/47028911  repositories.cfg could not be loaded in Windows 10 [closed]
建一個空的 repositories.cfg 檔案

Gradle path

Could not find an installed version of Gradle either in Android Studio,
or on your system to install the gradle wrapper. Please include gradle 
in your path, or install Android Studio
Path 設定 gradle\bin 即可

licences have not been accepted

Checking the license for package Android SDK Platform 28 in C:\Users\user\AppData\Local\Android\sdk\licenses
FAILURE: Build failed with an exception.
Warning: License for package Android SDK Platform 28 not accepted.

$ ./sdkmanager.bat --sdk_root=$ANDROID_HOME --licenses 
不要用Android Stuido 的 Cordova Plugins build

創建安卓範例APP

$ cordova create cordova-hello-world
$ cd cordova-hello-world
$ cordova platform add android
$ cordova build
Checking Java JDK and Android SDK versions
ANDROID_SDK_ROOT=undefined (recommended setting)
ANDROID_HOME=C:\android (DEPRECATED)
Starting a Gradle Daemon (subsequent builds will be faster)

BUILD SUCCESSFUL in 27s
1 actionable task: 1 executed
Subproject Path: CordovaLib
Subproject Path: app
...
WARNING: The specified Android SDK Build Tools version (25.0.3) is ignored, as it is below the minimum supported version (28.0.3) for Android Gradle Plugin 3.3.0.
Android SDK Build Tools 28.0.3 will be used.
To suppress this warning, remove "buildToolsVersion '25.0.3'" from your build.gradle file, as each version of the Android Gradle Plugin now has a default version of the build tools.
...
Built the following apk(s):
        C:\Users\user\WebstormProjects\cordova-hello-world\platforms\android\app\build\outputs\apk\debug\app-debug.apk

app-debug.apk 可丟到安卓手機上安裝運行

在模擬器上運行範例APP

到 C:\android\extras\intel\Hardware_Accelerated_Execution_Manager 雙擊 intelhaxm-android.exe 安裝模擬器,然後
$ cordova emulate android
如果報錯 Intel virtualization technology (vt,vt-x) is not enabled ,改在真機上運行

部屬範例APP在你的手機

啟用「開發人員選項」,開啟USB偵錯 (略)
電腦連接上你的手機,允許USB偵錯
用adb令檢查
$ adb devices
List of devices attached
5200d17c4b0845c7        unauthorized => device
部屬APP到你的手機
$ cordova run android
或指定target
$ cordova run android --target=5200d17c4b0845c7

將vue 項目和cordova連結

項目位置
cordova: /c/Users/user/WebstormProjects/cordova-hello-world
vue:/c/Users/user/WebstormProjects/hello-world

如果要使用軟連結

https://askubuntu.com/a/600732  Creating a symlink from one folder to another with different names?
If you want to have a symlink /var/www/html pointing to /home/user/project then you should not have the directory html present beforehand. So, you should only have /var/www and then running the following will create the desired symlink
如果你要將 /var/www/html 做軟連結指向 /home/user/project ,你不應該有 html 目錄。所以你只能有  /var/www 。然後執行這個命令:
$ ln -s /home/user/project /var/www/html

所以,刪除 cordova-hello-world 的 www/ ,然後
$ ln -s /c/Users/user/WebstormProjects/hello-world/dist /c/Users/user/WebstormProjects/cordova-hello-world/www

ps. git bash的軟連結感覺只是複製過去一次。沒法像linux一樣源目錄內容改了後就自動改。最後還是無腦build 出來後複製dist/ 下面檔案過去 www/

安卓上白屏

https://headsigned.com/posts/fixing-blank-screen-on-cordova-phonegap-and-vue/  Fixing blank screen on Cordova/PhoneGap and Vue
因為 Cordova 中檔案是以 file:/// 協議請求,所以跟Vue預設 publicPath '/' 衝突:
<link as="style" href="/css/app.3e7d65e5.css" rel="preload"></link>
<script src="/js/app.85d5fc84.js">
如果配置空字串而不是'/'則是
<link href=css/app.3e7d65e5.css rel=preload as=style>
<script src=js/app.85d5fc84.js>

解法

diff --git a/vue.config.js b/vue.config.js
 module.exports = {
+  publicPath: '',
   chainWebpack: config => {
     config.module.rules.delete('eslint');
   },

router bug

https://stackoverflow.com/a/42300688  vue v2, vue-router and cordova
一樣是因為 "file://" 的關係,導致瀏覽器 history API不作用,所以從router中移除"mode: history"即可
diff --git a/src/router/index.js b/src/router/index.js
 const router = new VueRouter({
-  mode: 'history',
+  // mode: 'history',
   base: process.env.BASE_URL,
   routes
 })

mode:history => http://192.168.1.7:8100/about
非mode:history => http://192.168.1.7:8100/#/about

無法對接口發起請求

用cordova打包出的apk,在部分安卓手機(Samsung J6 2018、Oppo F11 V1)上使用axios無法對接口發起請求,在catch裡面alert出來的error是【Error: Network Error】或【TypeError: Cannot read property 'status' of undefined】,Wireshark抓包也抓不到,但部分安卓手機(Xiaomi-Redmi-5、Vivo X20A)可以

原因

https://stackoverflow.com/a/54752717  Why am I seeing net::ERR_CLEARTEXT_NOT_PERMITTED errors after upgrading to Cordova Android 8?
The default API level in the Cordova Android platform has been upgraded. On an Android 9 device, clear text communication is now disabled by default.
Cordova Android平台的預設API等級已經升級了,在Android 9設備明文通訊(clear text communication)預設被禁用  => https接口估計不受影響
所以Vivo X20A (安卓版本 8.15.1)可以請求,但安卓版本10(Samsung J6 2018、Oppo F11 V1)不行

解法

To allow clear text communication again, set the android:usesCleartextTraffic on your application tag to true:
再次啟用明文通訊(clear text communication),在application標籤中設置android:usesCleartextTraffictrue
明文通訊(clear text communication)就是http,安卓9以上禁用了http,只允許https
cordova專案修改config.xml
diff --git a/config.xml b/config.xml
index 7434b5e..be66291 100644
--- a/config.xml
+++ b/config.xml
@@ -1,6 +1,6 @@
 <?xml version='1.0' encoding='utf-8'?>
-<widget id="io.cordova.hellocordova" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
-    <name>HelloCordova</name>
+<widget id="io.cordova.hellocordova" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
+    <name>HelloCordova2</name>
     <description>
         A sample Apache Cordova application that responds to the deviceready event.
     </description>
@@ -18,6 +18,9 @@
     <allow-intent href="geo:*" />
     <platform name="android">
         <allow-intent href="market:*" />
+        <edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application">
+            <application android:usesCleartextTraffic="true" />
+        </edit-config>
     </platform>
     <platform name="ios">
         <allow-intent href="itms:*" />
...
+   <icon src="res/icon.png" />

在  <platform name="android"> 新增

<edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application">
    <application android:usesCleartextTraffic="true" />
</edit-config>
以修改 platforms/android/app/src/main/AndroidManifest.xml 的manifest.application 新增android:usesCleartextTraffic="true"



<name>HelloCordova2</name>

修改APP的名字

xmlns:android="http://schemas.android.com/apk/res/android"

As noted in the comments, if you have not defined the android XML namespace previously, you will receive an error: unbound prefix during build. This indicates that you need to add it to your widget tag in the same config.xml, like so:
如果你還沒定義android XML命名空間,避免 cordova build 時報 error: unbound prefix 錯誤,需要在config.xmlwidget標籤新增 xmlns:android="http://schemas.android.com/apk/res/android" 

https://github.com/dpa99c/cordova-custom-config/issues/24#issuecomment-172981002  Error parsing XML: unbound prefix when doing cordova build android
ps.
因為加了<tag android:abc>(<application android:usesCleartextTraffic="true" />),如果直接cordova build會報錯(unbound prefix),但是還是會修改 platforms/android/app/src/main/AndroidManifest.xml ,但是 platforms/ 被corodva根目錄gitignore了,你也不會發現有改變(坑)。所以要加 xmlns:android="http://schemas.android.com/apk/res/android" 

<icon src="res/icon.png" />

設定APP的圖標,不設定就是用cordova預設的圖標

iOS打包

$ cordova create hello com.example.hello "HelloWorld"
$ cd hello
$ cordova platform add ios
$ cordova build ios
在模擬器上執行
$ cordova emulate ios
查看到所有可用的目標
$ cordova run ios --list
Available ios devices:
Available ios virtual devices:
Apple-TV-1080p, tvOS 13.4
Apple-TV-4K-4K, tvOS 13.4
Apple-TV-4K-1080p, tvOS 13.4
Apple-Watch-Series-4-40mm, watchOS 6.2
Apple-Watch-Series-4-44mm, watchOS 6.2
Apple-Watch-Series-5-40mm, watchOS 6.2
Apple-Watch-Series-5-44mm, watchOS 6.2
iPhone-8, 13.4
iPhone-8-Plus, 13.4
iPhone-11, 13.4
iPhone-11-Pro, 13.4
iPhone-11-Pro-Max, 13.4
iPhone-SE--2nd-generation-, 13.4
iPad-Pro--9-7-inch-, 13.4
iPad--7th-generation-, 13.4
iPad-Pro--11-inch---2nd-generation-, 13.4
iPad-Pro--12-9-inch---4th-generation-, 13.4
iPad-Air--3rd-generation-, 13.4

生成ipa

https://medium.com/@vosorio/build-ios-ipa-from-cordova-command-line-80f3e1794e0  Cheatsheet: Build IOS ipa from Cordova command line.
cordova build ios 後,打開 Xcode(必須使用Mac,因為只有Xcode能打包)
1. Open the workspace
./platforms/ios/[app_title].xcworkspace/  (./platforms/ios/HelloWorld.xcworkspace/)
2. 在專案preferences中設定簽名(在Xcode先登錄applie 開發者賬號)
















沒有留言:

張貼留言