From 6f0f6d3d726932b56bec9c6cc3663fc4a3b776a6 Mon Sep 17 00:00:00 2001 From: LUX-Timber Date: Wed, 3 Apr 2024 16:57:44 +0800 Subject: [PATCH] tag01 --- app/build.gradle | 2 + .../newkeyboard/activity/ApplyActivity.kt | 60 ++++- .../newkeyboard/activity/DetailsActivity.kt | 209 +++++++++++++++++- .../timber/soft/newkeyboard/tools/ImgTools.kt | 3 - app/src/main/res/layout/activity_details.xml | 2 +- app/src/main/res/values/strings.xml | 2 + settings.gradle | 2 + 7 files changed, 264 insertions(+), 16 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index e1cf6a2..8830fcb 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -53,6 +53,8 @@ dependencies { implementation 'com.github.bumptech.glide:glide:4.12.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.12.0' + implementation 'com.github.omicronapps:7-Zip-JBinding-4Android:Release-16.02-2.02' + implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' } \ No newline at end of file diff --git a/app/src/main/java/com/timber/soft/newkeyboard/activity/ApplyActivity.kt b/app/src/main/java/com/timber/soft/newkeyboard/activity/ApplyActivity.kt index 7d8e4cf..4689c2e 100644 --- a/app/src/main/java/com/timber/soft/newkeyboard/activity/ApplyActivity.kt +++ b/app/src/main/java/com/timber/soft/newkeyboard/activity/ApplyActivity.kt @@ -1,9 +1,15 @@ package com.timber.soft.newkeyboard.activity +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent import android.graphics.Color import android.os.Build import android.os.Bundle +import android.provider.Settings import android.view.View +import android.view.inputmethod.InputMethodInfo +import android.view.inputmethod.InputMethodManager import androidx.appcompat.app.AppCompatActivity import com.timber.soft.newkeyboard.databinding.ActivityApplyBinding import com.timber.soft.newkeyboard.tools.StatusBarTools @@ -11,6 +17,7 @@ import com.timber.soft.newkeyboard.tools.StatusBarTools class ApplyActivity : AppCompatActivity() { private lateinit var binding: ActivityApplyBinding + private lateinit var inputManager: InputMethodManager override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -25,12 +32,57 @@ class ApplyActivity : AppCompatActivity() { (View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or View.SYSTEM_UI_FLAG_LAYOUT_STABLE) or View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR window.statusBarColor = Color.TRANSPARENT } - - + inputManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager binding.applyBack.setOnClickListener() { finish() } - - + binding.idStep1.setOnClickListener() { + applyKeyboard() + } + binding.idStep2.setOnClickListener() { + chooseKeyboard() + } } + + override fun onResume() { + super.onResume() + updateUi() + } + + private fun chooseKeyboard() { + inputManager.showInputMethodPicker() + } + + private fun applyKeyboard() { + Intent(Settings.ACTION_INPUT_METHOD_SETTINGS).apply { + startActivity(this) + } + } + + private fun updateUi() { + binding.idStep1.setSelected(isEnable()) + binding.idStep2.setSelected(isChoose()) + } + + private fun isChoose(): Boolean { + Settings.Secure.getString(contentResolver, Settings.Secure.DEFAULT_INPUT_METHOD).let { id -> + return id.startsWith(packageName) + } ?: return false + } + + private fun isEnable(): Boolean { + for (info: InputMethodInfo in inputManager.enabledInputMethodList) { + if (info.id.startsWith(packageName)) { + return true + } + } + return false + } + + inner class StepReceive : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + updateUi() + } + } + } \ No newline at end of file diff --git a/app/src/main/java/com/timber/soft/newkeyboard/activity/DetailsActivity.kt b/app/src/main/java/com/timber/soft/newkeyboard/activity/DetailsActivity.kt index f631092..5b48378 100644 --- a/app/src/main/java/com/timber/soft/newkeyboard/activity/DetailsActivity.kt +++ b/app/src/main/java/com/timber/soft/newkeyboard/activity/DetailsActivity.kt @@ -1,31 +1,48 @@ package com.timber.soft.newkeyboard.activity +import android.content.Context +import android.content.Intent +import android.content.SharedPreferences import android.graphics.Color import android.graphics.drawable.Drawable import android.os.Build import android.os.Bundle +import android.provider.Settings import android.view.View +import android.view.inputmethod.InputMethodInfo +import android.view.inputmethod.InputMethodManager +import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import com.bumptech.glide.Glide import com.bumptech.glide.load.DataSource -import com.bumptech.glide.load.engine.DiskCacheStrategy import com.bumptech.glide.load.engine.GlideException import com.bumptech.glide.load.resource.bitmap.RoundedCorners import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions import com.bumptech.glide.request.RequestListener -import com.bumptech.glide.request.RequestOptions import com.bumptech.glide.request.target.Target import com.timber.soft.newkeyboard.R import com.timber.soft.newkeyboard.databinding.ActivityDetailsBinding import com.timber.soft.newkeyboard.model.DataModel +import com.timber.soft.newkeyboard.tools.AppVal import com.timber.soft.newkeyboard.tools.StatusBarTools +import net.sf.sevenzipjbinding.ArchiveFormat +import net.sf.sevenzipjbinding.SevenZip +import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream +import net.sf.sevenzipjbinding.impl.RandomAccessFileOutStream +import java.io.ByteArrayOutputStream +import java.io.File +import java.io.FileInputStream +import java.io.FileOutputStream +import java.io.InputStream +import java.io.RandomAccessFile class DetailsActivity : AppCompatActivity() { private lateinit var binding: ActivityDetailsBinding + private lateinit var inputManager: InputMethodManager private lateinit var previewUrl: String private lateinit var zipPath: String - + private lateinit var dataModel: DataModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -41,9 +58,14 @@ class DetailsActivity : AppCompatActivity() { window.statusBarColor = Color.TRANSPARENT } - val dataModel = intent.getSerializableExtra("KEY_EXTRA") as DataModel + inputManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager + dataModel = intent.getSerializableExtra("KEY_EXTRA") as DataModel + + previewUrl = dataModel.thumb - zipPath = dataModel.zipUrl + val cacheDir = cacheDir + val dataModelUrl = dataModel.zipUrl + zipPath = "$cacheDir/$dataModelUrl" @@ -89,8 +111,7 @@ class DetailsActivity : AppCompatActivity() { // 淡入动画 .transition(DrawableTransitionOptions.withCrossFade()) // 加载失败占位图 - .error(R.drawable.png_loading_err) - .transform(transformation) + .error(R.drawable.png_loading_err).transform(transformation) .into(binding.themeImage) } catch (e: Exception) { e.printStackTrace() @@ -98,9 +119,181 @@ class DetailsActivity : AppCompatActivity() { } - private fun applyTheme() { + // 检查是否启动键盘并设置 + if (!isEnable() || !isChoose()) { + val intent = Intent(this, ApplyActivity::class.java) + startActivity(intent) + return + } + binding.themeProgressbar.visibility = View.VISIBLE + val file = File(zipPath) + // 判断缓存中是否存在文件 + if (file.exists()) { + val allThemePath: String = getAllThemePath(dataModel.title) + val edit = sp.edit() + edit.run { + putString(AppVal.KEY_ALL_PATH, allThemePath) + apply() + } + } else { + getZipData(dataModel.title, dataModel.zipUrl, this,this::onResult) + } + } + + private fun onResult(isSuccess: Boolean, path: String) { + binding.themeProgressbar.visibility = View.GONE + if (isSuccess) { + val lastIndexOf: Int = path.lastIndexOf(AppVal.res_path) + val substring = path.subSequence(0, lastIndexOf + AppVal.res_path.length).toString() + + val edit = sp.edit() + + edit.run { + putString(AppVal.KEY_ALL_PATH, substring) + apply() + } + + edit.run { + putString(dataModel.title, substring) + apply() + } + + Toast.makeText(this, getString(R.string.succ_apply), Toast.LENGTH_LONG).show() + finish() + } else { + Toast.makeText(this, getString(R.string.fail_apply), Toast.LENGTH_LONG).show() + } + } + + interface ApplyListener { + fun applyListener(isSuccess: Boolean, str: String) + } + + private fun getZipData(title: String, url: String, con: Context, listener: ApplyListener) { + Glide.with(con).asFile().load(url).addListener(object : RequestListener { + override fun onLoadFailed( + e: GlideException?, model: Any?, target: Target, isFirstResource: Boolean + ): Boolean { + listener.applyListener(false, "") + return false + } + + override fun onResourceReady( + resource: File, + model: Any, + target: Target?, + dataSource: DataSource, + isFirstResource: Boolean + ): Boolean { + + val fileInputStream = FileInputStream(resource) + dealFile(title, url, fileInputStream, listener) + return false + } + + }).preload() + } + + private fun dealFile( + title: String, url: String, input: FileInputStream, listener: ApplyListener + ) { + val zipPath = "${cacheDir}/${title}_ZIP" + val unPath = "${cacheDir}/${title}" + + val zipBoolean = writeNewFile(input, zipPath) + val randomAccessFileInStream = + RandomAccessFileInStream(RandomAccessFile(File(zipPath), "r")) + val openInArchive = SevenZip.openInArchive( + ArchiveFormat.SEVEN_ZIP, randomAccessFileInStream + ) + + var out: RandomAccessFileOutStream? = null + + if (zipBoolean) { + try { + var filePath: String = "" + openInArchive.simpleInterface.archiveItems.forEach { item -> + if (!item.isFolder) { + val file = File(unPath, item.path) + out = RandomAccessFileOutStream(RandomAccessFile(file, "rw")) + item.extractSlow(out) + filePath = file.path + } else { + File(unPath, item.path).mkdirs() + } + } + listener.applyListener(true, filePath) + } catch (ex: Exception) { + listener.applyListener(false, "") + + } finally { + openInArchive.close() + randomAccessFileInStream.close() + out?.close() + } + } + } + + private fun writeNewFile(input: InputStream, filePath: String): Boolean { + var stream: FileOutputStream? = null + var outStream: ByteArrayOutputStream? = null + try { + val outStream = ByteArrayOutputStream() + val bytes = ByteArray(4096) + var length = 0 + while (input.read(bytes).also { + length = it + } != -1) { + outStream.write(bytes, 0, length) + } + val file = File(filePath) + if (!file.exists()) { + file.createNewFile() + } + stream = FileOutputStream(file) + stream.run { + write(outStream.toByteArray()) + } + outStream.close() + stream.close() + return true + } catch (ex: Exception) { + outStream?.close() + stream?.close() + return false + } } + private val sp: SharedPreferences = getSharedPreferences( + AppVal.SHARE_NAME, Context.MODE_PRIVATE + ) + + private fun getAllThemePath(zip: String): String { + val result = sp.getString(zip, "") + return result!! + } + + /** + * 检查是否设置键盘 + */ + private fun isChoose(): Boolean { + Settings.Secure.getString(contentResolver, Settings.Secure.DEFAULT_INPUT_METHOD).let { id -> + return id.startsWith(packageName) + } ?: return false + } + + /** + * 检查是否启用键盘 + */ + private fun isEnable(): Boolean { + for (info: InputMethodInfo in inputManager.enabledInputMethodList) { + if (info.id.startsWith(packageName)) { + return true + } + } + return false + } + } \ No newline at end of file diff --git a/app/src/main/java/com/timber/soft/newkeyboard/tools/ImgTools.kt b/app/src/main/java/com/timber/soft/newkeyboard/tools/ImgTools.kt index db6aeb0..fe2215b 100644 --- a/app/src/main/java/com/timber/soft/newkeyboard/tools/ImgTools.kt +++ b/app/src/main/java/com/timber/soft/newkeyboard/tools/ImgTools.kt @@ -2,7 +2,4 @@ package com.timber.soft.newkeyboard.tools object ImgTools { - - - } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_details.xml b/app/src/main/res/layout/activity_details.xml index 4ccf66e..6f74ca4 100644 --- a/app/src/main/res/layout/activity_details.xml +++ b/app/src/main/res/layout/activity_details.xml @@ -53,7 +53,7 @@ android:layout_height="43dp" android:layout_below="@id/theme_image" android:layout_marginStart="15dp" - android:layout_marginTop="26dp" + android:layout_marginTop="64dp" android:layout_marginEnd="15dp" android:background="@drawable/shape_theme_set" android:gravity="center" diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 097193e..415f48c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -9,4 +9,6 @@ Activate Soft Keyboard to enable more features! Step 1: Select Step 2: Enable + Application successful + Application failed, please try again \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index a50dff2..a87dd05 100644 --- a/settings.gradle +++ b/settings.gradle @@ -9,6 +9,7 @@ pluginManagement { } mavenCentral() gradlePluginPortal() + maven { url 'https://jitpack.io' } } } dependencyResolutionManagement { @@ -16,6 +17,7 @@ dependencyResolutionManagement { repositories { google() mavenCentral() + maven { url 'https://jitpack.io' } } }