Skip to content
This repository has been archived by the owner on Jan 16, 2024. It is now read-only.

Commit

Permalink
feat: 存储权限
Browse files Browse the repository at this point in the history
  • Loading branch information
jing332 committed Jan 11, 2024
1 parent c5fd7ab commit 0d6d945
Show file tree
Hide file tree
Showing 10 changed files with 722 additions and 134 deletions.
115 changes: 80 additions & 35 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,55 +4,78 @@ on:
push:
branches:
- "master"
paths:
- "CHANGELOG.md"
paths-ignore:
- "*.md"
- "*.sh"
- "build.yaml"
# - "sync_frp.yaml"

workflow_dispatch:

jobs:
build:
go:
runs-on: ubuntu-latest
strategy:
matrix:
GO_ARCH: [ "386", amd64, arm, arm64 ]
steps:
- uses: actions/checkout@v3

- name: Download AList Source Code
run: |
cd $GITHUB_WORKSPACE/alist-lib/scripts
chmod +x *.sh
./init_alist_core.sh
./init_alist_web.sh
- uses: actions/setup-go@v4
with:
go-version: 1.21.5
cache-dependency-path: ${{ github.workspace }}/alist-lib/go.sum

- name: Build
run: |
cd $GITHUB_WORKSPACE/alist-lib
GOARCH=${{ matrix.GO_ARCH }}
declare -A goarch2cc=( ["arm64"]="aarch64-linux-android32-clang" ["arm"]="armv7a-linux-androideabi32-clang" ["amd64"]="x86_64-linux-android32-clang" ["386"]="i686-linux-android32-clang")
export CC="$ANDROID_NDK_LATEST_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin/${goarch2cc[$GOARCH]}"
declare -A arch2lib=( ["arm64"]="arm64-v8a" ["arm"]="armeabi-v7a" ["amd64"]="x86_64" ["386"]="x86")
export LIB="${arch2lib[$GOARCH]}"
./scripts/install_alist.sh $GOARCH $LIB
- name: Upload to Artifact
uses: actions/upload-artifact@v3
with:
name: "app_libs"
path: "${{ github.workspace }}/app/libs"

android:
runs-on: ubuntu-latest
needs: [ go ]
env:
output: "${{ github.workspace }}/app/build/outputs/apk/release"
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0

- uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 17

- uses: actions/setup-go@v4
with:
go-version: 1.20.3
cache: false
cache-dependency-path: ${{ github.workspace }}/alist-lib/go.sum
- name: Setup Gradle
uses: gradle/gradle-build-action@v2

- uses: actions/cache@v3
name: Cache Go Modules
- name: Download Artifact
uses: actions/download-artifact@v3
with:
path: |
~/.cache/go-build
~/go/pkg/mod
key: go-${{ hashFiles('**/go.sum') }}
restore-keys: |
go-
- name: Build Alist-lib
run: |
cd alist-lib/scripts
chmod +x *.sh
./install_alist.sh
./install_web.sh
go install golang.org/x/mobile/cmd/gomobile@latest
gomobile init
go get golang.org/x/mobile/bind
./install_aar.sh all
- name: Setup Gradle
uses: gradle/gradle-build-action@v2.4.2
name: "app_libs"
path: "${{ github.workspace }}/app/libs"

- name: Init Signature
run: |
Expand All @@ -67,18 +90,40 @@ jobs:
- name: Grant execute permission for gradlew
run: chmod +x gradlew
- name: Build with Gradle
id: gradle
run: ./gradlew assembleRelease -build-cache --parallel --daemon --warning-mode all

- name: Upload missing_rules.txt
if: failure() && steps.gradle.outcome != 'success'
uses: actions/upload-artifact@v3
with:
name: "missing_rules"
path: "${{ github.workspace }}/app/build/outputs/mapping/release/missing_rules.txt"

- name: Init APP Version Name
run: |
echo "ver_name=$(grep -m 1 'versionName' ${{ env.output }}/output-metadata.json | cut -d\" -f4)" >> $GITHUB_ENV
- name: Upload App To Artifact
- name: Upload App To Artifact arm64-v8a
if: success () || failure ()
uses: actions/upload-artifact@v3
with:
name: "AListAndroid-v${{ env.ver_name }}_arm64-v8a"
path: "${{ env.output }}/*-v8a.apk"

- name: Upload App To Artifact arm-v7a
if: success () || failure ()
uses: actions/upload-artifact@v3
with:
name: "AListAndroid-v${{ env.ver_name }}_arm-v7a"
path: "${{ env.output }}/*-v7a.apk"

- name: Upload App To Artifact x86
if: success () || failure ()
uses: actions/upload-artifact@v3
with:
name: "AlistAndroid_${{env.ver_name}}"
path: ${{ env.output }}/*.apk
name: "AListAndroid-v${{ env.ver_name }}_x86"
path: "${{ env.output }}/*_x86.apk"

- uses: softprops/action-gh-release@v0.1.15
with:
Expand Down
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ dependencies {
def accompanistVersion = "0.31.3-beta"
implementation("com.google.accompanist:accompanist-systemuicontroller:${accompanistVersion}")
implementation("com.google.accompanist:accompanist-navigation-animation:${accompanistVersion}")
implementation("com.google.accompanist:accompanist-permissions:${accompanistVersion}")


implementation("androidx.constraintlayout:constraintlayout-compose:1.0.1")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.github.jing332.alistandroid.model

import android.content.Context
import android.content.Intent
import android.graphics.Color
import androidx.core.content.pm.ShortcutInfoCompat
import androidx.core.content.pm.ShortcutManagerCompat
import androidx.core.graphics.drawable.IconCompat
Expand All @@ -21,8 +20,8 @@ object ShortCuts {
private fun buildAlistSwitchShortCutInfo(context: Context): ShortcutInfoCompat {
val msSwitchIntent = buildIntent<SwitchServerActivity>(context)
return ShortcutInfoCompat.Builder(context, "alist_switch")
.setShortLabel(context.getString(R.string.alist_switch))
.setLongLabel(context.getString(R.string.alist_switch))
.setShortLabel(context.getString(R.string.app_switch))
.setLongLabel(context.getString(R.string.app_switch))
.setIcon(IconCompat.createWithResource(context, R.drawable.alist_switch))
.setIntent(msSwitchIntent)
.build()
Expand Down
Original file line number Diff line number Diff line change
@@ -1,53 +1,155 @@
package com.github.jing332.alistandroid.ui.nav.settings

import android.Manifest
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.Settings
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowCircleUp
import androidx.compose.material.icons.filled.ScreenLockPortrait
import androidx.compose.material3.Checkbox
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import com.github.jing332.alistandroid.R
import com.github.jing332.alistandroid.config.AppConfig
import com.github.jing332.alistandroid.ui.MyTools.isIgnoringBatteryOptimizations
import com.github.jing332.alistandroid.ui.MyTools.killBattery
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState

@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun SettingsScreen() {
val context = LocalContext.current
Column(Modifier.statusBarsPadding()) {
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally
) {
DividerPreference {
Text(stringResource(id = R.string.importent_settings))
}

AnimatedVisibility(visible = !context.isIgnoringBatteryOptimizations()) {
BasePreferenceWidget(
onClick = { context.killBattery() },
title = {
Text(
stringResource(R.string.grant_battery_whiltelist),
color = MaterialTheme.colorScheme.error
)
},
subTitle = { Text(stringResource(R.string.grant_battery_whiltelist_desc)) }) {
}
}

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { // A11
var isGranted by remember { mutableStateOf(Environment.isExternalStorageManager()) }
val permissionCheckerObserver = remember {
LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_RESUME) {
isGranted = Environment.isExternalStorageManager()
}
}
}
val lifecycle = LocalLifecycleOwner.current.lifecycle
DisposableEffect(lifecycle, permissionCheckerObserver) {
lifecycle.addObserver(permissionCheckerObserver)
onDispose { lifecycle.removeObserver(permissionCheckerObserver) }
}

BasePreferenceWidget(
onClick = {
context.startActivity(Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION).apply {
setData(Uri.parse("package:${context.packageName}"))
})
},
title = {
Text(
stringResource(id = R.string.all_files_manage_permission),
color = if (isGranted) Color.Companion.Unspecified else MaterialTheme.colorScheme.error,
)
},
subTitle = { Text(stringResource(id = R.string.files_permission_desc)) },
content = {
Checkbox(enabled = false, checked = isGranted, onCheckedChange = {})
})

} else { // < A11
val readPermission =
rememberPermissionState(permission = Manifest.permission.READ_EXTERNAL_STORAGE)
AnimatedVisibility(visible = !readPermission.status.isGranted) {
BasePreferenceWidget(
onClick = { readPermission.launchPermissionRequest() },
title = {
Text(
stringResource(id = R.string.read_external_storage_permission),
color = MaterialTheme.colorScheme.error
)
},
subTitle = { Text(stringResource(id = R.string.files_permission_desc)) }
)
}

val writePermission =
rememberPermissionState(permission = Manifest.permission.WRITE_EXTERNAL_STORAGE)
AnimatedVisibility(visible = !writePermission.status.isGranted) {
BasePreferenceWidget(
onClick = { writePermission.launchPermissionRequest() },
title = {
Text(
stringResource(id = R.string.write_external_storage_permission),
color = MaterialTheme.colorScheme.error
)
},
subTitle = { Text(stringResource(id = R.string.files_permission_desc)) }
)
}
}

}

DividerPreference { Text(text = stringResource(id = R.string.app_switch)) }

var checkUpdate by remember { AppConfig.isAutoCheckUpdate }
PreferenceSwitch(
title = { Text("自动检查更新") },
subTitle = { Text("打开程序主界面时从Github检查更新") },
SwitchPreference(
title = { Text(stringResource(R.string.auto_check_updates)) },
subTitle = { Text(stringResource(R.string.auto_check_updates_desc)) },
checked = checkUpdate,
onCheckedChange = { checkUpdate = it },
icon = {
Icon(Icons.Default.ArrowCircleUp, contentDescription = null)
}
icon = { Icon(Icons.Default.ArrowCircleUp, contentDescription = null) }
)

var enabledWakeLock by remember { AppConfig.enabledWakeLock }
PreferenceSwitch(
title = { Text("唤醒锁") },
subTitle = { Text("打开可防止锁屏后CPU休眠,但在部分系统可能会导致杀后台") },
SwitchPreference(
title = { Text(stringResource(R.string.wake_lock)) },
subTitle = { Text(stringResource(R.string.wake_lock_desc)) },
checked = enabledWakeLock,
onCheckedChange = { enabledWakeLock = it }
onCheckedChange = { enabledWakeLock = it },
icon = { Icon(Icons.Default.ScreenLockPortrait, contentDescription = null) }
)

AnimatedVisibility(visible = !context.isIgnoringBatteryOptimizations()) {
BasePreferenceWidget(
onClick = {
context.killBattery()
},
title = { Text("请求设置电池优化白名单") },
subTitle = { Text("如果程序在后台运行时被系统杀死,可以尝试设置。") }) {

}
}
}
}
Loading

0 comments on commit 0d6d945

Please sign in to comment.