두 가지 방법을 활용해서 Apk File 을 설치하는 동작을 구현 하려고 합니다. 첫 번째는 asset 으로부터 apk file 을 가져와서 설치하는 것과 두 번째는 SAF 에서 apk file 을 선택해서 설치하는 예제입니다.       1. 예...

[안드로이드] Apk 설치하기 예제 (with kotlin)

 


두 가지 방법을 활용해서 Apk File 을 설치하는 동작을 구현 하려고 합니다.

첫 번째는 asset 으로부터 apk file 을 가져와서 설치하는 것과

두 번째는 SAF 에서 apk file 을 선택해서 설치하는 예제입니다.

 

 

 

1. 예제 다운로드

https://github.com/bictoselfdev/InstallApkEx

 

 

 

2. Apk 설치

(1) 권한 요청

 Apk 설치를 위해 아래와 같이 두 가지 권한 요청이 필요합니다.


AndroidManifest.xml

<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

 

MainActivity.kt

private fun requestPermission(activity: Activity) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
if (!activity.packageManager.canRequestPackageInstalls()) {
val intent = Intent(
Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,
Uri.parse("package:${activity.packageName}")
)
activity.startActivityForResult(intent, 100)
}
}
} catch (e: Exception) {
e.printStackTrace()
}
}

 

 

(2) Apk 설치 요청

권한이 모두 준비되었고 Apk file 의 uri 정보를 알고 있다면,

아래 함수를 호출해서 Apk 설치가 가능합니다.


private fun installApkFile(activity: Activity, uri: Uri?) {

uri?.let {
val intent = Intent(Intent.ACTION_VIEW)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
intent.setDataAndType(it, "application/vnd.android.package-archive")
activity.startActivity(intent)
}
}

 



 

3. Apk File Uri 정보 가져오기

(1) assets 

assets 에 미리 준비된 Apk file 을 내부 저장소에 저장합니다.



MainActivity.kt

private fun saveApkFileFromAssets() {

try {
val inputStream = assets.open("MyApplication.apk")
val outPath = filesDir.absolutePath + "/MyApplication.apk"
val outputStream = FileOutputStream(outPath)
while (true) {
val data = inputStream.read()
if (data == -1) break
outputStream.write(data)
}
inputStream.close()
outputStream.close()
} catch (e: Exception) {
e.printStackTrace()
}
}


apk file 이 내부 저장소에 준비되었다면 provider 를 활용해서

apk file 의 uri 정보를 가져올 수 있습니다.


AndroidManifest.xml

<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:enabled="true"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider" />
</provider>

 

file_provider.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
<!-- 내부 저장소 -->
<files-path
name="files"
path="." />
</paths>

 

MainActivity.kt

private fun getUriByProvider(path: String): Uri? {
var uri: Uri? = null
try {
val file = File(path)
if (file.exists()) {
uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", file)
}
} catch (e: Exception) {
e.printStackTrace()
}
return uri
}

 

 

(2) SAF 으로부터 Uri 정보 가져오기 

준비된 apk file 이 아니라, 사용자가 직접 설치하고 싶은 apk file 을 선택하기 위해 SAF 를 활용합니다.

SAF 으로부터 선택된 apk file 의 uri 정보는 onActivityResult 에서 받을 수 있습니다.


MainActivity.kt

private fun openFileSAF(activity: Activity) {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "application/vnd.android.package-archive"
}

activity.startActivityForResult(intent, requestCodeSAF)
}

 

MainActivity.kt

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)

if (resultCode == RESULT_OK) {

when (requestCode) {
requestCodeSAF -> {
val uri = data?.data
uri?.let { installApkFile(this, it) }
}
}
}
}

 

 

 

[참고자료]

https://codechacha.com/ko/how-to-install-and-uninstall-app-in-android/

 

 

 

0 comments: