Browse Source

improve install demo for demonstration

master
wuliang 3 years ago
parent
commit
a648f40576
  1. 1
      app/build.gradle
  2. 1
      app/src/main/AndroidManifest.xml
  3. 162
      app/src/main/java/com/wuliang/xapkinstaller/MainActivity.kt
  4. 4
      app/src/main/res/layout/activity_main.xml

1
app/build.gradle

@ -35,4 +35,5 @@ dependencies {
testImplementation 'junit:junit:4.12'
implementation project(path: ':lib')
implementation "com.liulishuo.okdownload:okdownload:1.0.7"
}

1
app/src/main/AndroidManifest.xml

@ -2,6 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.wuliang.xapkinstaller">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

162
app/src/main/java/com/wuliang/xapkinstaller/MainActivity.kt

@ -1,58 +1,196 @@
package com.wuliang.xapkinstaller
import android.Manifest
import android.content.Context
import android.annotation.SuppressLint
import android.app.ProgressDialog
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.provider.Settings
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.liulishuo.okdownload.DownloadListener
import com.liulishuo.okdownload.DownloadTask
import com.liulishuo.okdownload.core.cause.EndCause
import com.liulishuo.okdownload.core.cause.ResumeFailedCause
import com.liulishuo.okdownload.core.listener.DownloadListener1
import com.liulishuo.okdownload.core.listener.DownloadListener2
import com.liulishuo.okdownload.core.listener.assist.Listener1Assist
import com.wuliang.lib.createXapkInstaller
import java.io.File
import java.lang.Exception
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
class MainActivity : AppCompatActivity() {
private const val PERMISSION_REQUEST_CODE = 99
private const val ACTION_MANAGE_UNKNOWN_APP_SOURCES_REQUEST_CODE = 120
private lateinit var installExecutor: ExecutorService
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
findViewById<TextView>(R.id.install_tv).setOnClickListener {
install()
checkAndInstall()
}
}
private fun checkAndInstall() {
if (Build.VERSION.SDK_INT >= 26) {//8.0
//来判断应用是否有权限安装apk
val installAllowed = packageManager.canRequestPackageInstalls()
//有权限
if (installAllowed) {
//安装apk
install()
} else {
//无权限 申请权限
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.REQUEST_INSTALL_PACKAGES, Manifest.permission.WRITE_EXTERNAL_STORAGE),
99)
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.REQUEST_INSTALL_PACKAGES,
Manifest.permission.WRITE_EXTERNAL_STORAGE
),
PERMISSION_REQUEST_CODE
)
}
} else {//8.0以下
//安装apk
install()
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode != PERMISSION_REQUEST_CODE)
return
grantResults.forEachIndexed { index, grantResult ->
if (grantResult != PackageManager.PERMISSION_GRANTED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (Manifest.permission.REQUEST_INSTALL_PACKAGES == permissions[index]) {
//引导用户去手动开启权限
val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES)
startActivityForResult(
intent,
ACTION_MANAGE_UNKNOWN_APP_SOURCES_REQUEST_CODE
)
}
}
Toast.makeText(this, "权限不足!", Toast.LENGTH_SHORT).show();
return
}
}
install()
}
@SuppressLint("NewApi")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == ACTION_MANAGE_UNKNOWN_APP_SOURCES_REQUEST_CODE) {
if (packageManager.canRequestPackageInstalls()) {
install()
} else {
Toast.makeText(this, "权限不足!", Toast.LENGTH_SHORT).show();
}
}
}
private fun install() {
downloadXapkAndInstall()
}
private fun downloadXapkAndInstall() {
val outputFileDirectory = File(
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).absolutePath +
File.separator + "xapk"
)
if (!outputFileDirectory.exists())
outputFileDirectory.mkdir()
installExecutor = Executors.newSingleThreadExecutor()
installExecutor.execute {
createXapkInstaller(getXapkFilePath())?.installXapk(this@MainActivity)
val outputFileName = "LEGO_CITY.xapk"
val outputFile = File(outputFileDirectory.absolutePath + File.separator + outputFileName)
if (outputFile.exists()) {
doInstall(outputFile.absolutePath)
}
//TODO this is xapk download url
val downloadUrl = ""
val task = DownloadTask.Builder(
downloadUrl,
outputFileDirectory
)
.setFilename(outputFileName)
.build()
val dialog = ProgressDialog(this)
dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL)
dialog.isIndeterminate = false
dialog.setCancelable(false)
dialog.max = 100
dialog.setTitle("正在下载中...")
task.enqueue(object : DownloadListener1() {
override fun taskStart(task: DownloadTask, model: Listener1Assist.Listener1Model) {
dialog.show()
}
override fun progress(task: DownloadTask, currentOffset: Long, totalLength: Long) {
dialog.progress = ((currentOffset / totalLength) * dialog.max).toInt()
}
override fun taskEnd(
task: DownloadTask,
cause: EndCause,
realCause: Exception?,
model: Listener1Assist.Listener1Model
) {
dialog.dismiss()
Toast.makeText(this@MainActivity, "下载完成,开始安装!", Toast.LENGTH_SHORT).show();
doInstall(outputFile.absolutePath)
}
override fun retry(task: DownloadTask, cause: ResumeFailedCause) {
}
override fun connected(
task: DownloadTask,
blockCount: Int,
currentOffset: Long,
totalLength: Long
) {
}
})
}
private fun getXapkFilePath(): String {
return ""
private fun doInstall(xapkFilePath: String) {
val xapkInstaller = createXapkInstaller(xapkFilePath)
if (xapkInstaller == null) {
Toast.makeText(this, "安装xapk失败!", Toast.LENGTH_SHORT).show();
} else {
val installExecutor = Executors.newSingleThreadExecutor()
installExecutor.execute {
xapkInstaller.installXapk(this@MainActivity)
}
}
}
}

4
app/src/main/res/layout/activity_main.xml

@ -6,11 +6,11 @@
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
<Button
android:id="@+id/install_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="安装包含多个apk的xapk"
android:text="下载安装包含多个apk的xapk"
android:textSize="16dp"
android:textColor="#000000"
android:layout_gravity="center" />

Loading…
Cancel
Save