tag01
This commit is contained in:
parent
5d67f8e7ca
commit
6f0f6d3d72
@ -53,6 +53,8 @@ dependencies {
|
|||||||
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
implementation 'com.github.bumptech.glide:glide:4.12.0'
|
||||||
annotationProcessor 'com.github.bumptech.glide:compiler: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'
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,9 +1,15 @@
|
|||||||
package com.timber.soft.newkeyboard.activity
|
package com.timber.soft.newkeyboard.activity
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.provider.Settings
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.inputmethod.InputMethodInfo
|
||||||
|
import android.view.inputmethod.InputMethodManager
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.timber.soft.newkeyboard.databinding.ActivityApplyBinding
|
import com.timber.soft.newkeyboard.databinding.ActivityApplyBinding
|
||||||
import com.timber.soft.newkeyboard.tools.StatusBarTools
|
import com.timber.soft.newkeyboard.tools.StatusBarTools
|
||||||
@ -11,6 +17,7 @@ import com.timber.soft.newkeyboard.tools.StatusBarTools
|
|||||||
class ApplyActivity : AppCompatActivity() {
|
class ApplyActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var binding: ActivityApplyBinding
|
private lateinit var binding: ActivityApplyBinding
|
||||||
|
private lateinit var inputManager: InputMethodManager
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
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
|
(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
|
window.statusBarColor = Color.TRANSPARENT
|
||||||
}
|
}
|
||||||
|
inputManager = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
|
||||||
|
|
||||||
binding.applyBack.setOnClickListener() {
|
binding.applyBack.setOnClickListener() {
|
||||||
finish()
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1,31 +1,48 @@
|
|||||||
package com.timber.soft.newkeyboard.activity
|
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.Color
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
|
import android.provider.Settings
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.view.inputmethod.InputMethodInfo
|
||||||
|
import android.view.inputmethod.InputMethodManager
|
||||||
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.load.DataSource
|
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.engine.GlideException
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||||
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
import com.bumptech.glide.load.resource.drawable.DrawableTransitionOptions
|
||||||
import com.bumptech.glide.request.RequestListener
|
import com.bumptech.glide.request.RequestListener
|
||||||
import com.bumptech.glide.request.RequestOptions
|
|
||||||
import com.bumptech.glide.request.target.Target
|
import com.bumptech.glide.request.target.Target
|
||||||
import com.timber.soft.newkeyboard.R
|
import com.timber.soft.newkeyboard.R
|
||||||
import com.timber.soft.newkeyboard.databinding.ActivityDetailsBinding
|
import com.timber.soft.newkeyboard.databinding.ActivityDetailsBinding
|
||||||
import com.timber.soft.newkeyboard.model.DataModel
|
import com.timber.soft.newkeyboard.model.DataModel
|
||||||
|
import com.timber.soft.newkeyboard.tools.AppVal
|
||||||
import com.timber.soft.newkeyboard.tools.StatusBarTools
|
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() {
|
class DetailsActivity : AppCompatActivity() {
|
||||||
|
|
||||||
private lateinit var binding: ActivityDetailsBinding
|
private lateinit var binding: ActivityDetailsBinding
|
||||||
|
private lateinit var inputManager: InputMethodManager
|
||||||
private lateinit var previewUrl: String
|
private lateinit var previewUrl: String
|
||||||
private lateinit var zipPath: String
|
private lateinit var zipPath: String
|
||||||
|
private lateinit var dataModel: DataModel
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@ -41,9 +58,14 @@ class DetailsActivity : AppCompatActivity() {
|
|||||||
window.statusBarColor = Color.TRANSPARENT
|
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
|
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())
|
.transition(DrawableTransitionOptions.withCrossFade())
|
||||||
// 加载失败占位图
|
// 加载失败占位图
|
||||||
.error(R.drawable.png_loading_err)
|
.error(R.drawable.png_loading_err).transform(transformation)
|
||||||
.transform(transformation)
|
|
||||||
.into(binding.themeImage)
|
.into(binding.themeImage)
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
@ -98,9 +119,181 @@ class DetailsActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun applyTheme() {
|
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<File> {
|
||||||
|
override fun onLoadFailed(
|
||||||
|
e: GlideException?, model: Any?, target: Target<File>, isFirstResource: Boolean
|
||||||
|
): Boolean {
|
||||||
|
listener.applyListener(false, "")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResourceReady(
|
||||||
|
resource: File,
|
||||||
|
model: Any,
|
||||||
|
target: Target<File>?,
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -2,7 +2,4 @@ package com.timber.soft.newkeyboard.tools
|
|||||||
|
|
||||||
object ImgTools {
|
object ImgTools {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -53,7 +53,7 @@
|
|||||||
android:layout_height="43dp"
|
android:layout_height="43dp"
|
||||||
android:layout_below="@id/theme_image"
|
android:layout_below="@id/theme_image"
|
||||||
android:layout_marginStart="15dp"
|
android:layout_marginStart="15dp"
|
||||||
android:layout_marginTop="26dp"
|
android:layout_marginTop="64dp"
|
||||||
android:layout_marginEnd="15dp"
|
android:layout_marginEnd="15dp"
|
||||||
android:background="@drawable/shape_theme_set"
|
android:background="@drawable/shape_theme_set"
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
|
|||||||
@ -9,4 +9,6 @@
|
|||||||
<string name="more_feature">Activate Soft Keyboard to enable more features!</string>
|
<string name="more_feature">Activate Soft Keyboard to enable more features!</string>
|
||||||
<string name="apply_step1_select">Step 1: Select</string>
|
<string name="apply_step1_select">Step 1: Select</string>
|
||||||
<string name="apply_step2_eanble">Step 2: Enable</string>
|
<string name="apply_step2_eanble">Step 2: Enable</string>
|
||||||
|
<string name="succ_apply">Application successful</string>
|
||||||
|
<string name="fail_apply">Application failed, please try again</string>
|
||||||
</resources>
|
</resources>
|
||||||
@ -9,6 +9,7 @@ pluginManagement {
|
|||||||
}
|
}
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
|
maven { url 'https://jitpack.io' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependencyResolutionManagement {
|
dependencyResolutionManagement {
|
||||||
@ -16,6 +17,7 @@ dependencyResolutionManagement {
|
|||||||
repositories {
|
repositories {
|
||||||
google()
|
google()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
|
maven { url 'https://jitpack.io' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user