Skip to content

Commit

Permalink
feat: android target (#2)
Browse files Browse the repository at this point in the history
* feat: android target

* chore: fix doc for android

* support jdk 1.8
  • Loading branch information
Madray Haven committed Feb 17, 2024
1 parent 854ea84 commit 82d3d5d
Show file tree
Hide file tree
Showing 7 changed files with 150 additions and 6 deletions.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ On Mac OS X : ```/Users/<Account>/Library/Application Support/<AppName>```
On Windows XP : ```C:\Documents and Settings\<Account>\Application Data\Local Settings\<AppAuthor>\<AppName>```
On Windows 7 : ```C:\Users\<Account>\AppData\<AppAuthor>\<AppName>```
On Unix/Linux : ```/home/<account>/.local/share/<AppName>```
On Android (internal) : ```/data/user/<uid>/<packageName>```
On Android (external) : ```/storage/emulated/<storageId>/Android/data/<packageName>```

With __Kotlin Multiplatform AppDirs__, you can get the path depending on the runtime platform with the following code.

Expand Down Expand Up @@ -130,6 +132,23 @@ Shared dir: /srv/myapp/1.2.3
- _appAuthor_ parameter is not used on Unix/Linux.
- _roaming_ parameter has no effect on Unix/Linux.

### Output on Android (packageName = ca.gosyer.appdirsm, uid = 0)
```
User data dir: /data/user/0/ca.gosyer.appdirsm/app_data/1.2.3
User data dir (roaming): /data/user/0/ca.gosyer.appdirsm/app_data/1.2.3
User config dir: /data/user/0/ca.gosyer.appdirsm/app_config/1.2.3
User config dir (roaming): /data/user/0/ca.gosyer.appdirsm/app_config/1.2.3
User cache dir: /data/user/0/ca.gosyer.appdirsm/cache/1.2.3
User log dir: /data/user/0/ca.gosyer.appdirsm/app_logs/1.2.3
Site data dir: /storage/emulated/0/Android/data/ca.gosyer.appdirsm/files/data/1.2.3
Site data dir (multi path): /storage/emulated/0/Android/data/ca.gosyer.appdirsm/files/data/1.2.3
Site config dir: /storage/emulated/0/Android/data/ca.gosyer.appdirsm/files/config/1.2.3
Site config dir (multi path): /storage/emulated/0/Android/data/ca.gosyer.appdirsm/files/config/1.2.3
Shared dir: /storage/emulated/0/Android/data/ca.gosyer.appdirsm/files/shared/1.2.3
```

- __AppDirs__ respects [Scoped storage](https://source.android.com/docs/core/storage/scoped) and only accesses the application private directory.

## Bug report, feature request, question

Please create an issue on the [tracker](https://github.com/Syer10/Kotlin-Multiplatform-AppDirs/issues).
Expand Down
38 changes: 33 additions & 5 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,12 @@ import java.util.Properties
plugins {
kotlin("multiplatform") version "1.9.21"
id("com.vanniktech.maven.publish") version "0.25.1"
id("com.android.library") version "8.2.1"
}

group = "ca.gosyer"
version = "1.1.0"

repositories {
mavenCentral()
}

kotlin {
jvm {
compilations.all {
Expand All @@ -28,6 +25,14 @@ kotlin {
linuxArm64()
mingwX64()

androidTarget {
publishLibraryVariants("release")

compilations.all {
kotlinOptions.jvmTarget = "1.8"
}
}

@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)
applyHierarchyTemplate {
common {
Expand Down Expand Up @@ -129,6 +134,18 @@ kotlin {
dependsOn(nativeTest)
dependsOn(windowsTest)
}

// android
val androidMain by getting {
dependsOn(commonMain)
}
val androidInstrumentedTest by getting {
dependencies {
implementation("androidx.test.ext:junit-ktx:1.1.5")
implementation("androidx.test.espresso:espresso-core:3.5.1")
implementation("androidx.test:runner:1.5.2")
}
}
}
}

Expand All @@ -149,4 +166,15 @@ if (signingPropsFile.exists()) {
project.ext.set(key, value)
}
}
}
}

android {
namespace = "ca.gosyer"

sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")

defaultConfig {
compileSdk = 34
minSdk = 21
}
}
3 changes: 3 additions & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,6 @@ SONATYPE_HOST=S01
RELEASE_SIGNING_ENABLED=true

kotlin.native.cacheKind.macosArm64=none

android.useAndroidX=true
android.enableJetifier=true
16 changes: 15 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,2 +1,16 @@
rootProject.name = "Kotlin-Multiplatform-AppDirs"
dependencyResolutionManagement {
repositories {
mavenCentral()
google()
}
}

pluginManagement {
repositories {
mavenCentral()
google()
gradlePluginPortal()
}
}

rootProject.name = "Kotlin-Multiplatform-AppDirs"
13 changes: 13 additions & 0 deletions src/androidMain/kotlin/ca/gosyer/appdirs/AppDirs.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package ca.gosyer.appdirs

import ca.gosyer.appdirs.impl.AndroidAppDirs
import ca.gosyer.appdirs.impl.ContextRef

actual fun AppDirs(
appName: String?,
appAuthor: String?,
vararg extra: String
): AppDirs = AndroidAppDirs(
context = ContextRef,
extra = extra,
)
44 changes: 44 additions & 0 deletions src/androidMain/kotlin/ca/gosyer/appdirs/impl/AndroidAppDirs.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package ca.gosyer.appdirs.impl

import android.content.Context
import ca.gosyer.appdirs.AppDirs
import java.io.File

class AndroidAppDirs(
private val context: Context,
vararg extra: String,
): AppDirs {
private val extras = extra.joinToString(pathSeparator())

override fun getUserDataDir(roaming: Boolean): String {
return getUserDir("data")
}

override fun getUserCacheDir(): String {
return File(context.cacheDir, extras).canonicalPath
}

override fun getUserConfigDir(roaming: Boolean): String {
return getUserDir("config")
}

override fun getUserLogDir(): String {
return getUserDir("logs")
}

private fun getUserDir(type: String, mode: Int = Context.MODE_PRIVATE): String {
return File(context.getDir(type, mode), extras).canonicalPath
}

override fun getSiteDataDir(multiPath: Boolean): String {
return context.getExternalFilesDir("data")!!.canonicalPath
}

override fun getSiteConfigDir(multiPath: Boolean): String {
return context.getExternalFilesDir("config")!!.canonicalPath
}

override fun getSharedDir(): String {
return context.getExternalFilesDir("shared")!!.canonicalPath
}
}
23 changes: 23 additions & 0 deletions src/androidMain/kotlin/ca/gosyer/appdirs/impl/AndroidUtil.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package ca.gosyer.appdirs.impl

import android.app.Application
import android.content.Context
import ca.gosyer.appdirs.AppDirsException
import java.lang.ref.WeakReference

internal actual fun home(): String {
throw UnsupportedOperationException()
}

internal actual fun pathSeparator(): String = "/"

internal actual fun fileSeparator(): String = ":"

private var _Context: WeakReference<Context>? = null
internal val ContextRef: Context get() {
return _Context?.get() ?: throw AppDirsException("In android target, please call Application#attachAppDirs() first!")
}

fun Application.attachAppDirs() {
_Context = WeakReference(this)
}

0 comments on commit 82d3d5d

Please sign in to comment.