Instala Aplicația programatic pe Android

Am'm a interesat în a ști dacă este posibil să se programatic de a instala un mod dinamic descărcat apk dintr-o aplicație Android personalizat.

Comentarii la întrebare (1)
Soluția

Puteți lansa cu ușurință un magazin play link sau o instala prompt:

Intent promptInstall = new Intent(Intent.ACTION_VIEW)
    .setDataAndType(Uri.parse("content:///path/to/your.apk"), 
                    "application/vnd.android.package-archive");
startActivity(promptInstall); 

sau

Intent goToMarket = new Intent(Intent.ACTION_VIEW)
    .setData(Uri.parse("https://play.google.com/store/apps/details?id=com.package.name"));
startActivity(goToMarket);

Cu toate acestea, nu se poate instala .fișiere apk fără de utilizator's permisiunea explicită; nu excepția cazului în care dispozitivul și programul dvs. este înrădăcinată.

Comentarii (16)
File file = new File(dir, "App.apk");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
startActivity(intent);

Am avut aceeași problemă și, după mai multe încercări, ea a lucrat pentru mine în acest fel. Eu nu't știu de ce, dar setarea de date și de tip în parte greșit intenția mea.

Comentarii (3)

Soluțiile oferite la această întrebare sunt aplicabile `targetSdkVersion modelului de 23 de ani și de mai jos. Pentru Android N, adică API de nivel 24, și mai sus, cu toate acestea, ele nu funcționează și se prăbuși, cu următoarea Excepție:

android.os.FileUriExposedException: file:///storage/emulated/0/... exposed beyond app through Intent.getData()

Acest lucru se datorează faptului că, începând Android 24, Uri pentru abordarea fișierul descărcat-au schimbat. De exemplu, un fișier de instalare numit appName.apk stocate pe extern principal sistem de fișiere a aplicației cu pachetul nume com.exemplu.test ar fi la fel de

file:///depozitare/emulat/0/Android/date/com.exemplu.test/files/appName.apk

pentru API 23` și mai jos, întrucât ceva de genul

content://com.example.test.authorityStr/pathName/Android/data/com.example.test/files/appName.apk

pentru API 24` și mai sus.

Mai multe detalii despre aceasta pot fi găsite aici și nu am de gând să du-te prin ea.

Pentru a răspunde la întrebarea pentru targetSdkVersion` de " 24 " și de mai sus, trebuie să urmați acești pași: Adăugați următoarele la AndroidManifest.xml:



            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/paths"/>

  1. Adăugați următoarele paths.xml dosarul xml folder de pe " res " în src, principale:

<?xml version="1.0" encoding="utf-8"?> <căi xmlns:android="http://schemas.android.com/apk/res/android"> <extern-calea nume="cale" calea="pathValue"/> </căi>

Pe cale este cea prezentată în exemplul de conținutul uri exemplu de mai sus și pathValue este calea reală pe sistemul. Ar fi o idee bună pentru a pune o "." (fără ghilimele) pentru pathValue în cele de mai sus, dacă nu doriți să adăugați orice suplimentare subdirector.

  1. Scrie codul de mai jos pentru a instala apk cu numele `appName.apk pe extern principal sistem de fișiere:

Directorul de fișiere = context.getExternalFilesDir(null); File = new File(director, fileName); Uri fileUri = Uri.fromFile(fișier); dacă (a Construi.VERSIUNE.SDK_INT >= 24) { fileUri = FileProvider.getUriForFile(contextul, contextul.getPackageName(), fișier); } Intenție intenție = new intenție(Intenție.ACTION_VIEW, fileUri); intenție.putExtra(Intenție.EXTRA_NOT_UNKNOWN_SOURCE, true); intenție.setDataAndType(fileUri, "application/vnd.android" + ".pachet-arhiva"); intenție.setFlags(Intenție.FLAG_ACTIVITY_CLEAR_TASK | Intenție.FLAG_ACTIVITY_NEW_TASK); intenție.addFlags(Intenție.FLAG_GRANT_READ_URI_PERMISSION); context.startActivity(intenție); activitate.sosire();

Permisiunea este, de asemenea, necesară atunci când scris la propria aplicație's privată director de pe extern sistem de fișiere.

Am scris un AutoUpdate biblioteca aici în care l-am folosit mai sus.

Comentarii (6)

Ei bine, am săpat mai adânc, și-a găsit surse de PackageInstaller aplicația de la Android Sursă.

https://github.com/android/platform_packages_apps_packageinstaller

De vădită am constatat că este nevoie de permisiunea:

Și procesul efectiv de instalare are loc după confirmarea

Intent newIntent = new Intent();
newIntent.putExtra(PackageUtil.INTENT_ATTR_APPLICATION_INFO, mPkgInfo.applicationInfo);
newIntent.setData(mPackageURI);
newIntent.setClass(this, InstallAppProgress.class);
String installerPackageName = getIntent().getStringExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME);
if (installerPackageName != null) {
   newIntent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, installerPackageName);
}
startActivity(newIntent);
Comentarii (1)

Vreau doar să împărtășesc faptul că mi apk fișier a fost salvat în aplicația mea "de Date" director și că am nevoie pentru a schimba permisiunile pentru fișierul apk pentru a fi ușor de citit, în scopul de a permite ca acesta să fie instalat acel mod, în caz contrar sistemul a fost aruncat "eroare de analiză: Există o Problemă de Analiză Pachetul"; deci, folosind soluție de @Horaceman asta face:

File file = new File(dir, "App.apk");
file.setReadable(true, false);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
startActivity(intent);
Comentarii (1)

Acest lucru poate ajuta la ceilalți o mulțime!

În primul rând:

private static final String APP_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyAppFolderInStorage/";

private void install() {
    File file = new File(APP_DIR + fileName);

    if (file.exists()) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        String type = "application/vnd.android.package-archive";

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            Uri downloadedApk = FileProvider.getUriForFile(getContext(), "ir.greencode", file);
            intent.setDataAndType(downloadedApk, type);
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        } else {
            intent.setDataAndType(Uri.fromFile(file), type);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }

        getContext().startActivity(intent);
    } else {
        Toast.makeText(getContext(), "ّFile not found!", Toast.LENGTH_SHORT).show();
    }
}

În al doilea rând: Pentru android de 7 și de mai sus ar trebui să definească un furnizor în manifest ca de mai jos!


        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/paths" />

În al treilea rând: Definirea path.xml în res/xml folder ca de mai jos! Am'm a utiliza această calea pentru stocare intern, dacă doriți să-l schimbe cu altceva există câteva drum! Puteți merge la acest link: FileProvider

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">


Mai departe: ar trebui să adăugați această permisiune în manifest:

Permite o cerere pentru a solicita instalarea de pachete. Aplicațiile vizează APIs mai mult de 25 trebuie să dețină această permisiune în scopul de a utiliza Intenție.ACTION_INSTALL_PACKAGE.

vă Rugăm să asigurați-vă că furnizorul de autoritățile sunt la fel!


Comentarii (4)

O altă soluție pe care nu't nu necesita hard-cod primirea app și că, prin urmare, este mai sigur:

Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.setData( Uri.fromFile(new File(pathToApk)) );
startActivity(intent);
Comentarii (0)

Da's posibil. Dar pentru asta ai nevoie de telefon pentru a instala surse neverificate. De exemplu, slideMe face asta. Cred că cel mai bun lucru care le puteți face este de a verifica dacă cererea este prezent și trimite o intenție pentru Android Market. ar trebui să utilizați ceva de schema url pentru android Market.

market://details?id=package.name

Eu nu't știu exact cum să-și înceapă activitatea, dar dacă ai începe o activitate cu acest tip de url-ul. Acesta ar trebui să deschidă android market și oferă posibilitatea de a instala aplicații.

Comentarii (1)

L's de remarcat faptul că, dacă utilizați DownloadManager pentru a lovi cu piciorul off descărca, asigurați-vă că să-l salvați într-o locație externă, de exemplu setDestinationInExternalFilesDir(c, null, "<numele tău aici>).apk";. Intenția cu un pachet de tip arhivă nu't par a ca conținut: sistem folosit cu descărcări interne locație, dar nu ca file:. (Încearcă să-și încheie cale internă într-un Fișier obiect și apoi obtinerea calea nu't de lucru, fie, chiar dacă rezultatele într-un fișier:` url, ca aplicație a câștigat't analiza apk; se pare că trebuie să fie extern.)

Exemplu:

int uriIndex = cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI);
String downloadedPackageUriString = cursor.getString(uriIndex);
File mFile = new File(Uri.parse(downloadedPackageUriString).getPath());
Intent promptInstall = new Intent(Intent.ACTION_VIEW)
        .setDataAndType(Uri.fromFile(mFile), "application/vnd.android.package-archive")
        .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
appContext.startActivity(promptInstall);
Comentarii (0)

încercați acest lucru

String filePath = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_FILENAME));
String title = filePath.substring( filePath.lastIndexOf('/')+1, filePath.length() );
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(filePath)), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // without this flag android returned a intent error!
MainActivity.this.startActivity(intent);
Comentarii (0)

Doar o extensie, dacă cineva avea nevoie de o bibliotecă, apoi acest ar putea ajuta. Datorită Raghav

Comentarii (0)

UpdateNode oferă un API pentru Android pentru a instala APK pachete de într-o altă Aplicație.

Puteți defini dvs. de Actualizare on-line și de a integra API în App - asta's a.
În prezent, API este în stare Beta, dar deja puteți face unele teste de tine.

Pe lângă faptul că, UpdateNode oferă, de asemenea, afișarea de mesaje deși sistemul - destul de util dacă vrei să spui ceva important pentru utilizatori.

Eu fac parte dintre client dev team și sunt, folosind cel puțin un mesaj de funcționalitate pentru propria mea Aplicație Android.

Vezi aici o descriere cum pentru a integra API

Comentarii (2)

Mai întâi, adăugați următoarea linie în AndroidManifest.xml :

Apoi, utilizați următorul cod pentru a instala apk:

File sdCard = Environment.getExternalStorageDirectory();
            String fileStr = sdCard.getAbsolutePath() + "/MyApp";// + "app-release.apk";
            File file = new File(fileStr, "TaghvimShamsi.apk");
            Intent promptInstall = new Intent(Intent.ACTION_VIEW).setDataAndType(Uri.fromFile(file),
                    "application/vnd.android.package-archive");
            startActivity(promptInstall);
Comentarii (0)

Nu uita pentru a solicita permisiuni:

android.Manifest.permission.WRITE_EXTERNAL_STORAGE 
android.Manifest.permission.READ_EXTERNAL_STORAGE

Adaugă în AndroidManifest.xml furnizorul și permisiunea:


...

    ...

        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/provider_paths"/>

Creați fișier XML furnizor res/xml/provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">





Folosesc de mai jos exemplu de cod:

   public class InstallManagerApk extends AppCompatActivity {

    static final String NAME_APK_FILE = "some.apk";
    public static final int REQUEST_INSTALL = 0;

     @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // required permission:
        // android.Manifest.permission.WRITE_EXTERNAL_STORAGE 
        // android.Manifest.permission.READ_EXTERNAL_STORAGE

        installApk();

    }

    ...

    /**
     * Install APK File
     */
    private void installApk() {

        try {

            File filePath = Environment.getExternalStorageDirectory();// path to file apk
            File file = new File(filePath, LoadManagerApkFile.NAME_APK_FILE);

            Uri uri = getApkUri( file.getPath() ); // get Uri for  each SDK Android

            Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
            intent.setData( uri );
            intent.setFlags( Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK );
            intent.putExtra(Intent.EXTRA_NOT_UNKNOWN_SOURCE, true);
            intent.putExtra(Intent.EXTRA_RETURN_RESULT, true);
            intent.putExtra(Intent.EXTRA_INSTALLER_PACKAGE_NAME, getApplicationInfo().packageName);

            if ( getPackageManager().queryIntentActivities(intent, 0 ) != null ) {// checked on start Activity

                startActivityForResult(intent, REQUEST_INSTALL);

            } else {
                throw new Exception("don`t start Activity.");
            }

        } catch ( Exception e ) {

            Log.i(TAG + ":InstallApk", "Failed installl APK file", e);
            Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG)
                .show();

        }

    }

    /**
     * Returns a Uri pointing to the APK to install.
     */
    private Uri getApkUri(String path) {

        // Before N, a MODE_WORLD_READABLE file could be passed via the ACTION_INSTALL_PACKAGE
        // Intent. Since N, MODE_WORLD_READABLE files are forbidden, and a FileProvider is
        // recommended.
        boolean useFileProvider = Build.VERSION.SDK_INT >= Build.VERSION_CODES.N;

        String tempFilename = "tmp.apk";
        byte[] buffer = new byte[16384];
        int fileMode = useFileProvider ? Context.MODE_PRIVATE : Context.MODE_WORLD_READABLE;
        try (InputStream is = new FileInputStream(new File(path));
             FileOutputStream fout = openFileOutput(tempFilename, fileMode)) {

            int n;
            while ((n = is.read(buffer)) >= 0) {
                fout.write(buffer, 0, n);
            }

        } catch (IOException e) {
            Log.i(TAG + ":getApkUri", "Failed to write temporary APK file", e);
        }

        if (useFileProvider) {

            File toInstall = new File(this.getFilesDir(), tempFilename);
            return FileProvider.getUriForFile(this,  BuildConfig.APPLICATION_ID, toInstall);

        } else {

            return Uri.fromFile(getFileStreamPath(tempFilename));

        }

    }

    /**
     * Listener event on installation APK file
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if(requestCode == REQUEST_INSTALL) {

            if (resultCode == Activity.RESULT_OK) {
                Toast.makeText(this,"Install succeeded!", Toast.LENGTH_SHORT).show();
            } else if (resultCode == Activity.RESULT_CANCELED) {
                Toast.makeText(this,"Install canceled!", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(this,"Install Failed!", Toast.LENGTH_SHORT).show();
            }

        }

    }

    ...

}
Comentarii (0)

Încercați acest lucru

  • Scrie pe Manifest:

uses-permission android:name="android.permisiunea.INSTALL_PACKAGES" instrumente:ignore="ProtectedPermissions"

Scrie Codul:

File sdCard = Environment.getExternalStorageDirectory();
String fileStr = sdCard.getAbsolutePath() + "/Download";// + "app-release.apk";
File file = new File(fileStr, "app-release.apk");
Intent promptInstall = new Intent(Intent.ACTION_VIEW).setDataAndType(Uri.fromFile(file),
                        "application/vnd.android.package-archive");

startActivity(promptInstall);
Comentarii (1)