
Hi developer in this Android tutorial we are sharing How to Download and Install APK Programmatically in android. If you want to make an app and mange app without play store his pass Installing and Update. Hare you can learn an easy way to implementation with full source code.
So Let’s Start on Topic How to Download and Install APK Programmatically in android . I am Using in this example kotlin-android.
Build Gradle dependencies
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.core:core-ktx:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
implementation 'com.google.android.material:material:1.0.0'
}
Step 1 : Create a Android activity with Kotlin Language
Start Android studio and make a project if you have already create that fine. hare we make a button on button click download Apk and Install APK direct.
Step 2 : Create a Kotlin Class with name DownloadController.
class DownloadController(private val context: Context, private val url: String) {
companion object {
private const val FILE_NAME = "CodeplayonApp.apk"
private const val FILE_BASE_PATH = "file://"
private const val MIME_TYPE = "application/vnd.android.package-archive"
private const val PROVIDER_PATH = ".provider"
private const val APP_INSTALL_PATH = "\"application/vnd.android.package-archive\""
}
fun enqueueDownload() {
var destination =
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString() + "/"
destination += FILE_NAME
val uri = Uri.parse("$FILE_BASE_PATH$destination")
val file = File(destination)
if (file.exists()) file.delete()
val downloadManager = context.getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
val downloadUri = Uri.parse(url)
val request = DownloadManager.Request(downloadUri)
request.setMimeType(MIME_TYPE)
request.setTitle(context.getString(R.string.title_file_download))
request.setDescription(context.getString(R.string.downloading))
// set destination
request.setDestinationUri(uri)
showInstallOption(destination, uri)
// Enqueue a new download and same the referenceId
downloadManager.enqueue(request)
Toast.makeText(context, context.getString(R.string.downloading), Toast.LENGTH_LONG)
.show()
}
private fun showInstallOption(
destination: String,
uri: Uri
) {
// set BroadcastReceiver to install app when .apk is downloaded
val onComplete = object : BroadcastReceiver() {
override fun onReceive(
context: Context,
intent: Intent
) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
val contentUri = FileProvider.getUriForFile(
context,
BuildConfig.APPLICATION_ID + PROVIDER_PATH,
File(destination)
)
val install = Intent(Intent.ACTION_VIEW)
install.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
install.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
install.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
install.data = contentUri
context.startActivity(install)
context.unregisterReceiver(this)
// finish()
} else {
val install = Intent(Intent.ACTION_VIEW)
install.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
install.setDataAndType(
uri,
APP_INSTALL_PATH
)
context.startActivity(install)
context.unregisterReceiver(this)
// finish()
}
}
}
context.registerReceiver(onComplete, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE))
}
}
Step 3: Create a Kotlin file for check SelfPermission
fun AppCompatActivity.checkSelfPermissionCompat(permission: String) =
ActivityCompat.checkSelfPermission(this, permission)
fun AppCompatActivity.shouldShowRequestPermissionRationaleCompat(permission: String) =
ActivityCompat.shouldShowRequestPermissionRationale(this, permission)
fun AppCompatActivity.requestPermissionsCompat(
permissionsArray: Array<String>,
requestCode: Int
) {
ActivityCompat.requestPermissions(this, permissionsArray, requestCode)
}
fun View.showSnackbar(msgId: Int, length: Int) {
showSnackbar(context.getString(msgId), length)
}
fun View.showSnackbar(msg: String, length: Int) {
showSnackbar(msg, length, null, {})
}
fun View.showSnackbar(
msgId: Int,
length: Int,
actionMessageId: Int,
action: (View) -> Unit
) {
showSnackbar(context.getString(msgId), length, context.getString(actionMessageId), action)
}
fun View.showSnackbar(
msg: String,
length: Int,
actionMessage: CharSequence?,
action: (View) -> Unit
) {
val snackbar = Snackbar.make(this, msg, length)
if (actionMessage != null) {
snackbar.setAction(actionMessage) {
action(this)
}.show()
}
}
Step 4: In you Main activity where you want to download APK file and Install.
add these flow where you want to download apk file and Install APK in you App. With Leaving your app you can download and install APK file add these code where you want these step .
Main Screen XML Code
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/mainLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.MainActivity">
<Button
android:id="@+id/buttonDownload"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/colorPrimaryDark"
android:minHeight="40dp"
android:text="Download"
android:textAllCaps="false"
android:textColor="@color/colorWhite"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
Main Screen Kotlin Code :
class MainActivity : AppCompatActivity() {
companion object {
const val PERMISSION_REQUEST_STORAGE = 0
}
lateinit var downloadController: DownloadController
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// This apk is taking pagination sample app
val apkUrl = "https://codeplayon.com/source/apk/app-codeplayonApp.apk"
downloadController = DownloadController(this, apkUrl)
buttonDownload.setOnClickListener {
// check storage permission granted if yes then start downloading file
checkStoragePermission()
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
if (requestCode == PERMISSION_REQUEST_STORAGE) {
// Request for camera permission.
if (grantResults.size == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// start downloading
downloadController.enqueueDownload()
} else {
// Permission request was denied.
mainLayout.showSnackbar(R.string.storage_permission_denied, Snackbar.LENGTH_SHORT)
}
}
}
private fun checkStoragePermission() {
// Check if the storage permission has been granted
if (checkSelfPermissionCompat(Manifest.permission.WRITE_EXTERNAL_STORAGE) ==
PackageManager.PERMISSION_GRANTED
) {
// start downloading
downloadController.enqueueDownload()
} else {
// Permission is missing and must be requested.
requestStoragePermission()
}
}
private fun requestStoragePermission() {
if (shouldShowRequestPermissionRationaleCompat(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
mainLayout.showSnackbar(
R.string.storage_access_required,
Snackbar.LENGTH_INDEFINITE, R.string.ok
) {
requestPermissionsCompat(
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
PERMISSION_REQUEST_STORAGE
)
}
} else {
requestPermissionsCompat(
arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
PERMISSION_REQUEST_STORAGE
)
}
}
}
Step 5 : Make a FileProvider XML file in res folder res–>xml–> file_provider_path.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="external"
path="." />
<external-files-path
name="external_files"
path="." />
<files-path
name="files"
path="." />
</paths>
Step 6 : Add File Provider in Your manifist file .
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_provider_paths" />
</provider>
Run you App and Test Happy Coding





