核心代码如下,请自取
package cn.yeby.getapk
import android.content.Intent
import android.content.pm.ResolveInfo
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import android.util.Log
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import io.reactivex.Observable
import io.reactivex.ObservableEmitter
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import java.io.*
class MainActivity : AppCompatActivity() {
companion object {
private const val APK = ".apk"
}
private val list = arrayListOf<ResolveInfo>()
private val nameList = arrayListOf<String>()
private val packageNameList = arrayListOf<String>()
private val compositeDisposable = CompositeDisposable()
private lateinit var adapter: ApkAdapter
private lateinit var resolveInfoList: List<ResolveInfo>
private lateinit var backupDir: File
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
backupDir = getExternalFilesDir(null)!!
val tv = findViewById<TextView>(R.id.tv)
val edt = findViewById<EditText>(R.id.edt)
val rc = findViewById<RecyclerView>(R.id.rc)
tv.text = "保存路径:${backupDir.path.replace("/storage/emulated/0/", "")}"
adapter = ApkAdapter(list)
adapter.openLoadAnimation()
adapter.setOnItemChildClickListener { _, _, position -> copyApk(position) }
rc.layoutManager = LinearLayoutManager(this)
rc.adapter = adapter
edt.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {}
override fun afterTextChanged(editable: Editable) {
val key = editable.toString()
list.clear()
for (i in nameList.indices) {
val name = nameList[i]
if (name.contains(key)) {
list.add(resolveInfoList[i])
}
}
for (i in packageNameList.indices) {
val packageName = packageNameList[i]
if (packageName.contains(key)) {
val resolveInfo = resolveInfoList[i]
if (!list.contains(resolveInfo)) {
list.add(resolveInfo)
}
}
}
adapter.notifyDataSetChanged()
}
})
queryApps()
}
//查询已安装的APP
private fun queryApps() {
Observable.create { emitter: ObservableEmitter<Long> ->
val packageManager = this.packageManager
val intent = Intent(Intent.ACTION_MAIN, null)
intent.addCategory(Intent.CATEGORY_LAUNCHER)
list.clear()
resolveInfoList = packageManager.queryIntentActivities(intent, 0)
if (resolveInfoList.isNotEmpty()) {
for (resolveInfo in resolveInfoList) {
list.add(resolveInfo)
nameList.add(resolveInfo.activityInfo.applicationInfo.loadLabel(getPackageManager()).toString())
packageNameList.add(resolveInfo.activityInfo.packageName)
}
}
emitter.onNext(0L)
}.subscribeOn(Schedulers.computation())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<Long> {
override fun onSubscribe(d: Disposable) {
compositeDisposable.add(d)
}
override fun onNext(aLong: Long) {
adapter.notifyDataSetChanged()
}
override fun onError(e: Throwable) {
Log.d("yeby", e.toString())
}
override fun onComplete() {}
})
}
private fun copyApk(position: Int) {
val resolveInfo = list[position]
val activityInfo = resolveInfo.activityInfo
val sourceDir = activityInfo.applicationInfo.sourceDir
val destFile = File(backupDir, activityInfo.packageName + APK)
Observable.create { emitter: ObservableEmitter<String> ->
var input: InputStream? = null
var outputDest: OutputStream? = null
try {
input = FileInputStream(sourceDir)
outputDest = FileOutputStream(destFile)
val buffer = ByteArray(1024)
while (true) {
val bytesRead = input.read(buffer)
if (bytesRead != -1) {
outputDest.write(buffer, 0, bytesRead)
} else {
break
}
}
} finally {
input!!.close()
outputDest!!.close()
}
emitter.onNext("提取成功")
}.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Observer<String> {
override fun onSubscribe(d: Disposable) {
compositeDisposable.add(d)
}
override fun onNext(s: String) {
Toast.makeText(this@MainActivity, s, Toast.LENGTH_SHORT).show()
}
override fun onError(e: Throwable) {
Log.d("yeby", e.toString())
}
override fun onComplete() {}
})
}
override fun onDestroy() {
super.onDestroy()
compositeDisposable.clear()
}
}
网友评论