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:
All UI is ready and working
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%3D%3D/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.
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
Get the base.apk file of the app from its source dir.
Copy the file to the new location and give it a meaningful name.
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
)
Share the file.
Anyways thanks for all the help.