6

I want to install an apk file from my application.

I have created an app that contains a button, when I click that button then another apk that I have stored in resources folder should be install,
Heres something I have done :

public void onClick(View v) {
    // Intent intent = new Intent("com.google.zxing.client.android.SCAN");
    // intent.setPackage("com.google.zxing.client.android");
    // intent.putExtra("SCAN_MODE", "QR_CODE_MODE");
    // startActivityForResult(intent, 0);
    File file = new File("android.resource://com.app.barcodescanner/raw", "scan.apk");
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
    startActivity(intent);
}

any ideas ?
please help me with this

Pascal MARTIN
  • 395,085
  • 80
  • 655
  • 663
sUrAj
  • 287
  • 2
  • 4
  • 11

5 Answers5

14
Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.fromFile(new File
            (Environment.getExternalStorageDirectory()  + "/barcode.apk")), "application/vnd.android.package-archive");
    startActivity(intent);
Mr.Wizard
  • 24,179
  • 5
  • 44
  • 125
sUrAj
  • 287
  • 2
  • 4
  • 11
2

It probably will not work with an android.resource Uri. Try copying the APK out to external storage and doing the install from there.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • I have a simple question. I downloaded my apk from net and going to update the downloaded apk. Now i would like to know how would i synchronize both, means the progress bar needs to display both the download and upload activity together. Help me in this – AndroidOptimist Mar 04 '14 at 06:28
  • @AndroidOptimist: If "upload activity" really means "update activity", that is not possible. Your process will not be running when your app is being updated. Moreover, your UI will not be visible before the update begins, because the *user* has to start the update and the *user* has to approve the update. – CommonsWare Mar 04 '14 at 12:00
  • @CommonsWare, I have downloaded the new app on external storage and after download with help of `Intent(Intent.ACTION_INSTALL_PACKAGE)` I ask user for installation and it moves the request to default system installer, but before the install option appears it shows **"There was a problem parsing the package"** even when I have allowed all necessary permissions and Allow unknown installation ? – iCantC Nov 06 '19 at 15:17
  • @iCantC: I recommend that you ask a separate Stack Overflow question where you provide a [mcve]. – CommonsWare Nov 06 '19 at 17:57
1

Add this in AndroidManifest.xml file

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

<application>
 <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/provider_paths" />
    </provider>
    </application>

And Create xml file inside your res/xml/provider_paths.xml

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path
        name="files_root"
        path="Android/data/${applicationId}" />
    <external-path
        name="external_files"
        path="." />
</paths>

Final step

Add this in your Activity class

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    Uri uri = FileProvider.getUriForFile(getContext(),
                            getContext().getApplicationContext().getPackageName() + ".provider", new File(Environment.getExternalStorageDirectory() + directory+nameFile));
                    Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
                    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    intent.setDataAndType(uri, "application/vnd.android.package-archive");
                   startActivity(intent);

                } else {
                  Intent intent = new Intent(Intent.ACTION_VIEW);
                    intent.setDataAndType(FileUtils.getFileToUri(this, new File(app.getPath())),
                            "application/vnd.android.package-archive");
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    v.getContext().startActivity(intent);
                }

for more informations see : https://geetmark.com

lookly Dev
  • 325
  • 3
  • 5
0

This might help you. for Android 10 put this in Manifest.xml

android:requestLegacyExternalStorage="true"

       <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>

MainActivity.kt

import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.os.StrictMode
import android.os.StrictMode.VmPolicy
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.FileProvider
import kotlinx.android.synthetic.main.activity_main.*
import java.io.File

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        test.setOnClickListener {
            val arrPerm: ArrayList<String> = ArrayList()
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                arrPerm.add(Manifest.permission.WRITE_EXTERNAL_STORAGE)
            }
            if (arrPerm.isNotEmpty()) {
                var permissions = arrayOfNulls<String>(arrPerm.size)
                permissions = arrPerm.toArray(permissions)
                ActivityCompat.requestPermissions(this, permissions, 1000)
            } else {

                requestapkInstallation()
// FileProvider.getUriForFile(this, applicationContext.packageName + ".provider",File("/storage/emulated/0/Download/test.apk"))
            }
        }
    }

    fun requestapkInstallation() {
        if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.N) {
            val builder = VmPolicy.Builder()
            StrictMode.setVmPolicy(builder.build())
            val fileUri = FileProvider.getUriForFile(
                this,
                applicationContext.packageName + ".provider",
                File(Environment.getExternalStorageDirectory().toString() + "/download/" + "app-debug.apk")
            )
            val intent1 = Intent(Intent.ACTION_VIEW);
            intent1.setDataAndType(
                fileUri,
                "application/vnd.android.package-archive"
            );
            intent1.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent1.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent1.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
            intent1.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
            startActivity(intent1);
        } else {
            val fileUri = FileProvider.getUriForFile(
                this,
                applicationContext.packageName + ".provider",
                File(Environment.getExternalStorageDirectory().toString()+ "/download/" + "app-debug.apk")
            )
            val intent = Intent(Intent.ACTION_VIEW, fileUri)
            intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true)
            intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TASK or Intent.FLAG_ACTIVITY_NEW_TASK
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            intent.setDataAndType(fileUri, "application/vnd.android.package-archive")

            startActivity(intent)
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    when(requestCode)
    {
        1000->{
            if(Manifest.permission.WRITE_EXTERNAL_STORAGE == permissions[0]) {
                if(grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // you now have permission
                    requestapkInstallation()
                }
            }
        }
    }
}

}

Rushi Ayyappa
  • 2,708
  • 2
  • 16
  • 32
0
public void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    File DbFile=new File("mnt/sdcard/HelloAndroid.apk");
    if(!(DbFile.exists()))
    {
        try
        {
            int length = 0;
            DbFile.createNewFile();
            InputStream inputStream = this.getAssets().open("HelloAndroid.apk");
            FileOutputStream fOutputStream = new FileOutputStream(DbFile);
            byte[] buffer = new byte[inputStream.available()];
            while ((length = inputStream.read(buffer)) > 0)
            {
                fOutputStream.write(buffer, 0, length);
            }
            fOutputStream.flush();
            fOutputStream.close();
            inputStream.close();
        }
        catch (Exception ex)
        {
            System.out.println("Error in creating new database at mobile..." + ex);
            ex.printStackTrace();
        }
    }

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.fromFile(new File("/mnt/sdcard/HelloAndroid.apk")), "application/vnd.android.package-archive");
    startActivity(intent);
}

Here i have stored my apk file in assets folder. You can try this.

takrl
  • 6,356
  • 3
  • 60
  • 69
ASH
  • 2,748
  • 2
  • 28
  • 29
  • why not just do `intent.setDataAndType(Uri.fromFile(DbFile)),"application/vnd.android.package-archive")` ? – Pierre Mar 14 '15 at 09:21