Home > Mobile >  How to share the THIS applications base.apk using Intent?
How to share the THIS applications base.apk using Intent?

Time:06-28

I want to share my application using a share button inside it. Once the button is clicked it should get the base.apk from the package manager and then share it using Intents.

Here is what I have so far:

  1. All UI is ready and working

  2. I have the following code to get the app and share it

    try {
         val pm = packageManager
         val ai = pm.getApplicationInfo(packageName, 0)
         val srcFile = File(ai.publicSourceDir)
         val share = Intent()
         share.action = Intent.ACTION_SEND
         share.type = "application/vnd.android.package-archive"
         share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(srcFile))
         startActivity(Intent.createChooser(share, "Sharing"))
      } catch (e: Exception) {
         UtilityMethods(this).toast("Failed To Share The App", "e")
         e.printStackTrace()
      }
    

But I get an error with this procedure.

android.os.FileUriExposedException: file:///data/app/~~BC-clKZDViP_O7n44ooPbQ==/MyAppPublicSourceDirectory/base.apk exposed beyond app through ClipData.Item.getUri()

Is there any help I can get regarding this? I tried a lot of solutions, but they don't work for me.

EDIT:: Updated Code, Copy the base.apk to Downloads Folder and Rename it. Then try to share it (which is where the error invokes from).

try {
                // get the base apk of the app
                val pm = packageManager
                val ai = pm.getApplicationInfo(packageName, 0)
                val srcFile = File(ai.publicSourceDir)

                // save the file in Downloads folder
                val dstFile = File(
                    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
                    "LogsCalculator.apk"
                )
                dstFile.createNewFile()
                val input = FileInputStream(srcFile)
                val output = FileOutputStream(dstFile)
                val buffer = ByteArray(1024)
                var length: Int = input.read(buffer)
                while (length > 0) {
                    output.write(buffer, 0, length)
                    length = input.read(buffer)
                }
                output.flush()
                output.close()
                input.close()

                // share the apk file now
                val intent = Intent(Intent.ACTION_SEND)
                intent.type = "application/vnd.android.package-archive"
                intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(dstFile))
                startActivity(Intent.createChooser(intent, getString(R.string.sharing)))

            } catch (e: Exception) {
                UtilityMethods(this).toast("Failed To Share The App", "e")
                e.printStackTrace()
            }

It Still Does Not Work.

CodePudding user response:

On later API versions, not even backup tools can obtain the APK anymore, therefore the approach is literally pointless. Instead use Firebase Dynamic Links, in order to permit user to user sharing of your application. This way they can install from Google Play Store, instead up installing some APK of unknown origin, which may not update well.

CodePudding user response:

I got the solution.

try {
                // get the base.apk
                val baseApkLocation =
                    applicationContext.packageManager.getApplicationInfo(
                        applicationContext.packageName,
                        PackageManager.GET_META_DATA
                    ).sourceDir
                // get the file
                val baseApk = File(baseApkLocation)

                // the path
                val path = Environment.getExternalStorageDirectory().toString()   "/Download/"
                // make the directory
                val dir = File(path)
                // if the directory doesn't exist, make it
                if (!dir.exists()) {
                    dir.mkdirs()
                }

                // Copy the .apk file to downloads directory
                val destination = File(
                    path   "MyAppName.apk"
                )
                if (destination.exists()) {
                    destination.delete()
                }
                destination.createNewFile()
                val input = FileInputStream(baseApk)
                val output = FileOutputStream(destination)
                val buffer = ByteArray(1024)
                var length: Int = input.read(buffer)
                while (length > 0) {
                    output.write(buffer, 0, length)
                    length = input.read(buffer)
                }
                output.flush()
                output.close()
                input.close()

                // get content uri for the file
                val uri = FileProvider.getUriForFile(
                    this,
                    BuildConfig.APPLICATION_ID   ".provider",
                    destination
                )

                // share the file
                val intent = Intent(Intent.ACTION_SEND)
                intent.type = "application/vnd.android.package-archive"
                intent.putExtra(Intent.EXTRA_STREAM, uri)
                startActivity(Intent.createChooser(intent, getString(R.string.share_app)))

            } catch (e: Exception) {
                Lib(this).toast("Failed To Share The App", "e")
                e.printStackTrace()
            }

Here is how it works

  1. Get the base.apk file of the app from its source dir.

  2. Copy the file to the new location and give it a meaningful name.

  3. Get the content URI of the new file. This is what was missing.

                 // get content uri for the file
                 val uri = FileProvider.getUriForFile(
                     this,
                     BuildConfig.APPLICATION_ID   ".provider",
                     destination
                 )
    
  4. Share the file.

Anyways thanks for all the help.

  • Related