Skip to content

Commit 77b5460

Browse files
authored
Merge pull request #2 from lan2015se-collab/codex/apk
Add minimal Android WebView app and GitHub Actions to build debug APK
2 parents b19ac2f + 9e20dce commit 77b5460

11 files changed

Lines changed: 213 additions & 0 deletions

File tree

.github/workflows/build-apk.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Build APK
2+
3+
on:
4+
push:
5+
pull_request:
6+
workflow_dispatch:
7+
8+
jobs:
9+
assemble-debug-apk:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- name: Check out repository
13+
uses: actions/checkout@v4
14+
15+
- name: Set up JDK
16+
uses: actions/setup-java@v4
17+
with:
18+
distribution: temurin
19+
java-version: '17'
20+
21+
- name: Set up Gradle
22+
uses: gradle/actions/setup-gradle@v4
23+
24+
- name: Build debug APK
25+
run: gradle assembleDebug
26+
27+
- name: Upload APK artifact
28+
uses: actions/upload-artifact@v4
29+
with:
30+
name: iwd-debug-apk
31+
path: app/build/outputs/apk/debug/app-debug.apk

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.gradle/
2+
build/
3+
app/build/
4+
local.properties
5+
*.apk
6+
*.aab

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# IWD Web APK
2+
3+
A minimal Android WebView application that embeds `https://iwd.illusd.com/` as an installable APK.
4+
5+
## Download the APK
6+
7+
Every push and pull request runs the **Build APK** GitHub Actions workflow. Open the workflow run and download the `iwd-debug-apk` artifact; it contains `app-debug.apk`.
8+
9+
## Build locally
10+
11+
```bash
12+
gradle assembleDebug
13+
```
14+
15+
The debug APK is generated at `app/build/outputs/apk/debug/app-debug.apk`.

app/build.gradle

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
plugins { id 'com.android.application' }
2+
3+
android {
4+
namespace 'com.illusd.iwdwebapk'
5+
compileSdk 35
6+
7+
defaultConfig {
8+
applicationId 'com.illusd.iwdwebapk'
9+
minSdk 23
10+
targetSdk 35
11+
versionCode 1
12+
versionName '1.0'
13+
}
14+
}

app/src/main/AndroidManifest.xml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
2+
<uses-permission android:name="android.permission.INTERNET" />
3+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
4+
5+
<application
6+
android:allowBackup="true"
7+
android:label="@string/app_name"
8+
android:theme="@style/AppTheme"
9+
android:usesCleartextTraffic="false">
10+
<activity
11+
android:name=".MainActivity"
12+
android:configChanges="keyboardHidden|orientation|screenSize"
13+
android:exported="true">
14+
<intent-filter>
15+
<action android:name="android.intent.action.MAIN" />
16+
<category android:name="android.intent.category.LAUNCHER" />
17+
</intent-filter>
18+
</activity>
19+
</application>
20+
</manifest>
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
package com.illusd.iwdwebapk;
2+
3+
import android.annotation.SuppressLint;
4+
import android.app.Activity;
5+
import android.graphics.Bitmap;
6+
import android.net.http.SslError;
7+
import android.os.Bundle;
8+
import android.view.View;
9+
import android.webkit.SslErrorHandler;
10+
import android.webkit.WebResourceRequest;
11+
import android.webkit.WebSettings;
12+
import android.webkit.WebView;
13+
import android.webkit.WebViewClient;
14+
import android.widget.ProgressBar;
15+
import android.widget.FrameLayout;
16+
17+
public class MainActivity extends Activity {
18+
private WebView webView;
19+
20+
@SuppressLint("SetJavaScriptEnabled")
21+
@Override
22+
protected void onCreate(Bundle savedInstanceState) {
23+
super.onCreate(savedInstanceState);
24+
25+
FrameLayout root = new FrameLayout(this);
26+
webView = new WebView(this);
27+
ProgressBar progressBar = new ProgressBar(this);
28+
FrameLayout.LayoutParams progressParams = new FrameLayout.LayoutParams(
29+
FrameLayout.LayoutParams.WRAP_CONTENT,
30+
FrameLayout.LayoutParams.WRAP_CONTENT
31+
);
32+
progressParams.gravity = android.view.Gravity.CENTER;
33+
34+
root.addView(webView, new FrameLayout.LayoutParams(
35+
FrameLayout.LayoutParams.MATCH_PARENT,
36+
FrameLayout.LayoutParams.MATCH_PARENT
37+
));
38+
root.addView(progressBar, progressParams);
39+
setContentView(root);
40+
41+
WebSettings settings = webView.getSettings();
42+
settings.setJavaScriptEnabled(true);
43+
settings.setDomStorageEnabled(true);
44+
settings.setLoadWithOverviewMode(true);
45+
settings.setUseWideViewPort(true);
46+
settings.setMixedContentMode(WebSettings.MIXED_CONTENT_COMPATIBILITY_MODE);
47+
48+
webView.setWebViewClient(new WebViewClient() {
49+
@Override
50+
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
51+
view.loadUrl(request.getUrl().toString());
52+
return true;
53+
}
54+
55+
@Override
56+
public void onPageStarted(WebView view, String url, Bitmap favicon) {
57+
progressBar.setVisibility(View.VISIBLE);
58+
}
59+
60+
@Override
61+
public void onPageFinished(WebView view, String url) {
62+
progressBar.setVisibility(View.GONE);
63+
}
64+
65+
@Override
66+
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
67+
handler.cancel();
68+
}
69+
});
70+
71+
if (savedInstanceState == null) {
72+
webView.loadUrl(getString(R.string.target_url));
73+
} else {
74+
webView.restoreState(savedInstanceState);
75+
}
76+
}
77+
78+
@Override
79+
protected void onSaveInstanceState(Bundle outState) {
80+
super.onSaveInstanceState(outState);
81+
webView.saveState(outState);
82+
}
83+
84+
@Override
85+
public void onBackPressed() {
86+
if (webView.canGoBack()) {
87+
webView.goBack();
88+
} else {
89+
super.onBackPressed();
90+
}
91+
}
92+
93+
@Override
94+
protected void onDestroy() {
95+
if (webView != null) {
96+
webView.destroy();
97+
}
98+
super.onDestroy();
99+
}
100+
}

app/src/main/res/values/colors.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<resources>
2+
<color name="splash_background">#FFFFFF</color>
3+
</resources>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
<resources>
2+
<string name="app_name">IWD</string>
3+
<string name="target_url">https://iwd.illusd.com/</string>
4+
</resources>

app/src/main/res/values/styles.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<resources>
2+
<style name="AppTheme" parent="android:style/Theme.Material.Light.NoActionBar">
3+
<item name="android:windowLightStatusBar">true</item>
4+
<item name="android:statusBarColor">@color/splash_background</item>
5+
<item name="android:navigationBarColor">@color/splash_background</item>
6+
</style>
7+
</resources>

build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
plugins {
2+
id 'com.android.application' version '8.7.3' apply false
3+
}

0 commit comments

Comments
 (0)