Skip to content

Commit 3299a66

Browse files
committed
Add webkit webview sample
1 parent 7cd91b5 commit 3299a66

38 files changed

+909
-0
lines changed

WebView/WebkitWebView/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# Set Up Instructions
2+
Assuming the GlitchMe site and server is up and running (the glitch me site can
3+
be found [here](https://glitch.com/edit/#!/alder-sunny-bicycle)), this app should
4+
be fairly easy to setup. There is one process that requires ensuring your app
5+
signature is known to the server, which will be in the steps below.
6+
7+
1. Clone this repo anywhere on your machine. Ensure you have AndroidStudio and
8+
all the setup with that is correct (sdk/etc..).
9+
2. Ensure your phone can connect to Android Studio. This often involves ensuring
10+
debug mode is on and adb is installed.
11+
3. Double check there is a 'debug.keystore' file at the root. This is important
12+
as the server expects your app to have the SHA256 from this keystore.
13+
4. 'Run' the app via the 'run' button (the green play triangle).
14+
5. Enjoy!
15+
16+
## Running your own server
17+
If you'd like to manage a server directly, you can choose to Remix this project on glitch.me which
18+
will clone the current project to management under your account. Note that you will likely need to
19+
change the env variables to your app's package name and sha-256 hash, as well as update the
20+
expectedOrigin variables in server.mjs with your updated apk-key-hash (covert your app's sha-256 to
21+
base 64).
22+
23+
# Notice
24+
Please note that accounts created with this sample app are stored on glitch.me. While this does not
25+
impact the security of your Google accounts, please be wary of putting sensitive information in your
26+
username or password fields.
27+
28+
## Known Issues
29+
- We have noticed the GlitchMe service sometimes has reliability issues.
30+
- See status [here](https://status.glitch.com/).
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/build
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
plugins {
2+
id 'com.android.application'
3+
id 'org.jetbrains.kotlin.android'
4+
}
5+
6+
repositories {
7+
google()
8+
mavenCentral()
9+
maven { url 'https://androidx.dev/snapshots/latest/artifacts/repository' }
10+
}
11+
12+
android {
13+
namespace 'com.google.webkit.webviewsample'
14+
compileSdk 35
15+
16+
signingConfigs {
17+
debug {
18+
def keystoreFile = project.rootProject.file('debug.keystore')
19+
if (keystoreFile.exists()) {
20+
storeFile file(keystoreFile.toPath())
21+
} else {
22+
Properties properties = new Properties()
23+
def propertiesFile = project.rootProject.file('local.properties')
24+
if (propertiesFile.exists()) {
25+
properties.load(propertiesFile.newDataInputStream())
26+
storeFile file(properties.getProperty("key_path"))
27+
}
28+
}
29+
}
30+
}
31+
32+
defaultConfig {
33+
applicationId "com.google.webkit.webviewsample"
34+
minSdk 29
35+
targetSdk 34
36+
}
37+
38+
buildTypes {
39+
release {
40+
minifyEnabled false
41+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
42+
}
43+
}
44+
compileOptions {
45+
sourceCompatibility JavaVersion.VERSION_1_8
46+
targetCompatibility JavaVersion.VERSION_1_8
47+
}
48+
kotlinOptions {
49+
jvmTarget = '1.8'
50+
}
51+
buildFeatures {
52+
compose true
53+
}
54+
composeOptions {
55+
kotlinCompilerExtensionVersion '1.5.2'
56+
}
57+
packagingOptions {
58+
resources {
59+
excludes += '/META-INF/{AL2.0,LGPL2.1}'
60+
}
61+
}
62+
}
63+
64+
dependencies {
65+
implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
66+
67+
implementation 'androidx.credentials:credentials-play-services-auth:1.5.0-rc01'
68+
implementation 'androidx.credentials:credentials:1.5.0-rc01'
69+
70+
implementation("androidx.webkit:webkit:1.12.1")
71+
implementation 'androidx.core:core-ktx:1.7.0'
72+
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.3.1'
73+
implementation 'androidx.activity:activity-compose:1.3.1'
74+
implementation "androidx.compose.ui:ui:$compose_ui_version"
75+
implementation "androidx.compose.ui:ui-tooling-preview:$compose_ui_version"
76+
implementation 'androidx.compose.material:material:1.1.1'
77+
78+
testImplementation 'junit:junit:4.13.2'
79+
androidTestImplementation 'androidx.test.ext:junit:1.1.4'
80+
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0'
81+
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_ui_version"
82+
debugImplementation "androidx.compose.ui:ui-tooling:$compose_ui_version"
83+
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_ui_version"
84+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools">
4+
<uses-permission android:name="android.permission.INTERNET" />
5+
<application
6+
android:allowBackup="true"
7+
android:dataExtractionRules="@xml/data_extraction_rules"
8+
android:fullBackupContent="@xml/backup_rules"
9+
android:icon="@mipmap/ic_launcher"
10+
android:label="@string/app_name"
11+
android:supportsRtl="true"
12+
android:theme="@style/Theme.WebViewSample"
13+
tools:targetApi="31">
14+
<activity
15+
android:name="com.google.webkit.webviewsample.MainActivity"
16+
android:exported="true"
17+
android:label="@string/app_name"
18+
android:theme="@style/Theme.WebViewSample">
19+
<intent-filter>
20+
<action android:name="android.intent.action.MAIN" />
21+
22+
<category android:name="android.intent.category.LAUNCHER" />
23+
</intent-filter>
24+
25+
<meta-data
26+
android:name="android.app.lib_name"
27+
android:value="" />
28+
</activity>
29+
</application>
30+
31+
</manifest>
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.google.webkit.webviewsample
2+
3+
import android.os.Bundle
4+
import android.util.Log
5+
import android.webkit.WebView
6+
import androidx.activity.ComponentActivity
7+
import androidx.activity.compose.setContent
8+
import androidx.compose.foundation.layout.fillMaxSize
9+
import androidx.compose.material.MaterialTheme
10+
import androidx.compose.material.Surface
11+
import androidx.compose.ui.Modifier
12+
import androidx.compose.ui.viewinterop.AndroidView
13+
import androidx.webkit.WebSettingsCompat
14+
import androidx.webkit.WebViewFeature
15+
import com.google.webkit.webviewsample.theme.WebViewSampleTheme
16+
17+
18+
/**
19+
* Generates a WebView that uses the Webkit API to handle WebView passkey authentication requests.
20+
*/
21+
class MainActivity : ComponentActivity() {
22+
override fun onCreate(savedInstanceState: Bundle?) {
23+
super.onCreate(savedInstanceState)
24+
setContent {
25+
val url = "https://alder-sunny-bicycle.glitch.me/"
26+
WebViewSampleTheme {
27+
Surface(
28+
modifier = Modifier.fillMaxSize(),
29+
color = MaterialTheme.colors.background
30+
) {
31+
AndroidView(factory = {
32+
WebView(it).apply {
33+
settings.javaScriptEnabled = true
34+
webViewClient = WebViewClientImpl()
35+
}
36+
},
37+
update = { webView ->
38+
run {
39+
webView.loadUrl(url)
40+
if (WebViewFeature.isFeatureSupported(WebViewFeature.WEB_AUTHENTICATION)) {
41+
Log.e("WebViewPasskeyDemo", "WebView supports passkeys.")
42+
WebSettingsCompat.setWebAuthenticationSupport(
43+
webView.settings,
44+
WebSettingsCompat.WEB_AUTHENTICATION_SUPPORT_FOR_APP,
45+
)
46+
Log.e(
47+
"WebViewPasskeyDemo",
48+
"getWebAuthenticationSupport result: " +
49+
WebSettingsCompat.getWebAuthenticationSupport(
50+
webView.settings
51+
),
52+
)
53+
} else {
54+
Log.e(
55+
"WebViewPasskeyDemo",
56+
"WebView does not support passkeys."
57+
)
58+
}
59+
}
60+
})
61+
}
62+
}
63+
}
64+
}
65+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package com.google.webkit.webviewsample
2+
3+
import android.webkit.WebView
4+
import android.webkit.WebViewClient
5+
6+
class WebViewClientImpl : WebViewClient() {
7+
override fun shouldOverrideUrlLoading(view: WebView?, url: String?): Boolean {
8+
return false
9+
}
10+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.google.webkit.webviewsample.theme
2+
3+
import androidx.compose.ui.graphics.Color
4+
5+
val Purple200 = Color(0xFFBB86FC)
6+
val Purple500 = Color(0xFF6200EE)
7+
val Purple700 = Color(0xFF3700B3)
8+
val Teal200 = Color(0xFF03DAC5)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package com.google.webkit.webviewsample.theme
2+
3+
import androidx.compose.foundation.shape.RoundedCornerShape
4+
import androidx.compose.material.Shapes
5+
import androidx.compose.ui.unit.dp
6+
7+
val Shapes = Shapes(
8+
small = RoundedCornerShape(4.dp),
9+
medium = RoundedCornerShape(4.dp),
10+
large = RoundedCornerShape(0.dp)
11+
)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
package com.google.webkit.webviewsample.theme
2+
3+
import androidx.compose.foundation.isSystemInDarkTheme
4+
import androidx.compose.material.MaterialTheme
5+
import androidx.compose.material.darkColors
6+
import androidx.compose.material.lightColors
7+
import androidx.compose.runtime.Composable
8+
9+
private val DarkColorPalette = darkColors(
10+
primary = Purple200,
11+
primaryVariant = Purple700,
12+
secondary = Teal200
13+
)
14+
15+
private val LightColorPalette = lightColors(
16+
primary = Purple500,
17+
primaryVariant = Purple700,
18+
secondary = Teal200
19+
)
20+
21+
@Composable
22+
fun WebViewSampleTheme(
23+
darkTheme: Boolean = isSystemInDarkTheme(),
24+
content: @Composable () -> Unit
25+
) {
26+
val colors = if (darkTheme) {
27+
DarkColorPalette
28+
} else {
29+
LightColorPalette
30+
}
31+
32+
MaterialTheme(
33+
colors = colors,
34+
typography = Typography,
35+
shapes = Shapes,
36+
content = content
37+
)
38+
}

0 commit comments

Comments
 (0)