Steps:
1. 把 Requirements 都下載安裝好
2. 建立 Cordova Android Project
如果 Cordova projects 放置的位置與 Android App projects 是不同的目錄的話,test_cordova 可以改成與 android app project 相同名稱,這樣會比較好知道 cordova project 是對應到哪個 android project,此外 com.example.hello 也可以改成跟 android app 一樣。
cordova create test_cordova com.example.hello HelloWorld
cordova platform add android
cordova build
在 build 之前可以視情況加入需要的 plugins,例如:
cordova plugin add cordova-plugin-device
cordova plugin add cordova-plugin-x-toast
3. 建立 Android App Project
用預設的即可,有一個 Empty Activity (MainActivity)。
4. 安裝 Cordova Project 環境到 Android Project
Compile Cordova Lib
參考 Android WebViews - Apache Cordova 步驟 1~3,把 cordova-x.x.x.jar 複製到 /libs 之後,編輯 app/build.gradle,加上:
compile files('libs/cordova-x.x.x.jar')
Example:
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile files('libs/cordova-5.2.2.jar')
}
複製依存檔案 (左邊是 Cordova project 的 path,右邊是 Android project 的 path)
www folder
platforms/android/assets/www -> src/main/assets/www
plugins (com/example/hello 以外的目錄,安裝 plugins 多出來的那些)
platforms/android/src/plugin_folder -> src/main/java/
config.xml
platforms/android/res/xml/config.xml -> src/main/res/xml/
然後 sync 一下 Gradle 情報。
5. 建立基本運作 Activity
把 Cordova Webview 嵌入 Android Native App 的基本作業到第四步驟就完成了,接下來可以建立基本運作的 Activity,來測試看看是不是正常運作。
建立以下兩個 Empty Activity: TestCordovaActivity, TestCordovaWithLayoutActivity,然後編輯 java 及 layout 如下:
TestCordovaActivity
public class TestCordovaActivity extends CordovaActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.init();
// Load your application
launchUrl = "file:///android_asset/www/index.html";
loadUrl(launchUrl);
}
}
@Override
public void onDestroy() {
ViewGroup viewGroup = (ViewGroup)this.findViewById(android.R.id.content);
SystemWebView webView = (SystemWebView) viewGroup.getChildAt(0);
viewGroup.removeView(webView);
webView.removeAllViews();
super.onDestroy();
}
TestCordovaWithLayoutActivity
public class TestCordovaWithLayoutActivity extends CordovaActivity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_cordova_with_layout);
super.init();
// Load your application
launchUrl = "file:///android_asset/www/index2.html";
loadUrl(launchUrl);
}
@Override
protected CordovaWebView makeWebView() {
SystemWebView webView = (SystemWebView)findViewById(R.id.cordovaWebView);
return new CordovaWebViewImpl(new SystemWebViewEngine(webView));
}
@Override
protected void createViews() {
// Why are we setting a constant as the ID? This should be investigated
/*
appView.getView().setId(100);
appView.getView().setLayoutParams(new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
setContentView(appView.getView());
*/
if (preferences.contains("BackgroundColor")) {
int backgroundColor = preferences.getInteger("BackgroundColor", Color.BLACK);
// Background of activity:
appView.getView().setBackgroundColor(backgroundColor);
}
appView.getView().requestFocusFromTouch();
}
@Override
public void onDestroy() {
SystemWebView webView = (SystemWebView)findViewById(R.id.cordovaWebView);
((ViewGroup)webView.getParent()).removeView(webView);
webView.removeAllViews();
// If we called webView.destory(), we will get 'mWebViewCore is null' error.
//webView.destroy();
super.onDestroy();
}
}
activity_test_cordova_with_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.fandratec.fssfordksh.TestCordovaWithLayoutActivity">
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:background="#FF0000"
android:textColor="#FFFFFF"
android:gravity="center"
android:text="This is native text view"
/>
<org.apache.cordova.engine.SystemWebView
android:id="@+id/cordovaWebView"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
MainActivity
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void startCordovaActivity(View view) {
Intent intent = new Intent(this, TestCordovaActivity.class);
startActivity(intent);
}
public void startCordovaActivityWithLayout(View view) {
Intent intent = new Intent(this, TestCordovaWithLayoutActivity.class);
startActivity(intent);
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.fandratec.fssfordksh.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
android:id="@+id/textView"/>
<Button
android:text="Start Cordova Activity Without Layout"
android:onClick="startCordovaActivity"
android:layout_width="200dp"
android:layout_height="100dp"
android:id="@+id/button"
android:layout_below="@+id/textView"
android:layout_alignParentStart="true"/>
<Button
android:text="Start Cordova Activity With Layout"
android:onClick="startCordovaActivityWithLayout"
android:layout_width="200dp"
android:layout_height="100dp"
android:layout_below="@+id/button"
android:layout_alignParentStart="true"/>
</RelativeLayout>
以上都弄好後,就可以 run 了。
6. 延伸
如果這個 Android App 要連線到 Internet 或是取得 GPS 座標,記得在 AndroidManifest.xml 加入權限需求宣告,如果沒加上的話會出現錯誤。(例如 loadUrl(REMOTE_URL) 就會直接獲得 "Application 錯誤")
<manifest>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
另外,現在版本的 Cordova project 預設啟用 whitelist 機制,想從 CordovaWebView 連到local (/assets/www) 外的內容並在其中呈現,得在 config.xml 加上設定,要不然會另外呼叫預設瀏覽器:
<widget>
<allow-navigation href="https://YOUR.SITE/*" />
</widget>
References: