How to Download and Install APK Programmatically in android
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