2011-12-12 8 views
5

Próbuję utworzyć aplikację, która automatycznie pobiera apk z określonego serwera i instaluje go w systemie. Mój kod instalacji wygląda następująco, ale nie działa.Zainstaluj apk z innego programu

File f = new File("/mnt/sdcard/download/", "Demo.apk"); 
Log.i("Demo", "f "+f.getAbsoluteFile()); 
Intent intent = new Intent(Intent.ACTION_VIEW); 
intent.setDataAndType(Uri.fromFile(f), "application/vnd.android.package_archive"); 
intent.addFlags(intent.FLAG_ACTIVITY_NEW_TASK); 
m_context.startActivity(intent);    

Czy muszę podać jakiekolwiek prawa do instalacji w Manifest.xml? Wiem, że to pytanie było już wcześniej zadawane, ale żadna z odpowiedzi nie pomogła mi do tej pory.

+1

Jak wspomniałem w mojej odpowiedzi, użyj "package-archive", a nie "package_archive". Mam nadzieję, że to rozwiązuje wyjątek ActivityNotFoundException. – Karthik

Odpowiedz

9

To, co robię w moim przypadku,

Intent intent = new Intent(Intent.ACTION_VIEW); 
intent.setDataAndType(Uri.fromFile(new File(path+"/<application_name>.apk")), "application/vnd.android.package-archive"); 
startActivity(intent); 

I to są uprawnienia ..

<uses-permission android:name="android.permission.INTERNET" /> 
<uses-permission android:name="android.permission.INSTALL_PACKAGES" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
+5

nadal nie działa, uzyskaj ten wyjątek: * E/AndroidRuntime (2216): java.lang.RuntimeException: Nie można rozpocząć działania ComponentInfo {foo.bar/foo.bar.FooActivity}: android.content.ActivityNotFoundException: Nie znaleziono żadnej aktywności uchwyt Intent {act = android.intent.action.VIEW dat = file: ///mnt/sdcard/Demo.apk typ = application/vnd.android.package_archive flg = 0x10000000} * – user932865

+0

nie może być użyty, ponieważ jest przeznaczony do aplikacji systemowych. – CoolMind

3

ja również zrobić

intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

i mój zainstalować lookd tak

intent.setDataAndType(Uri.parse("file://"+path), "application/vnd.android.package-archive"); 

mój path jest ciągiem znaków, jak twój f

+0

plik: // zapisz mi dzień, dziękuję – djdance

0

Trzeba to zrobić

Intent intent = new Intent(Intent.ACTION_VIEW); 
intent.setDataAndType(Uri.fromFile(f), "application/vnd.android.package-archive"); 

W kodzie, trzeba wymienić "package_archive", powinno być "pakiet-archiwum".
Potrzebne będą następujące uprawnienia.

<uses-permission android:name="android.permission.INSTALL_PACKAGES"></uses-permission> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission> 
7

Dzięki za pomoc, w końcu udało się. Udostępniam mój działający kod i działam Manifest.xml.

package test.installer; 
import android.app.Activity; 
import android.content.Intent; 
import android.net.Uri; 
import android.os.Bundle; 
import android.util.Log; 

public class InstallToolActivity extends Activity { 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    Log.i("Demo", "onCreate"); 
    Intent intent = new Intent(Intent.ACTION_VIEW); 
    intent.setDataAndType(Uri.parse("file://"+"/mnt/sdcard/HelloWorld.apk"), "application/vnd.android.package-archive"); 
    intent.addFlags(intent.FLAG_ACTIVITY_NEW_TASK); 
    startActivity(intent); 
    } 
} 

Manifext.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="test.installer" 
android:versionCode="1" 
android:versionName="1.0" > 

<uses-sdk android:minSdkVersion="11" /> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> 
<uses-permission android:name="android.permission.INTERNET"/> 
<uses-permission android:name="android.permission.INSTALL_PACKAGES"/> 
<uses-permission android:name="android.permission.RESTART_PACKAGES"/> 


<application 
    android:icon="@drawable/ic_launcher" 
    android:label="@string/app_name" > 
    <activity 
     android:label="@string/app_name" 
     android:name=".InstallToolActivity" > 
     <intent-filter > 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
</application> 

// Fredrik

+1

Cześć Fredrik, powinienem podziękować za podzielenie się z nami swoim doświadczeniem. Postępowałem zgodnie z dokładnie tymi samymi instrukcjami, ale otrzymuję "Błąd PArser." Jest problem z parsowaniem pakietu. " Próbowałem odnieść się do wielu forów, ale nie było to zbyt pomocne. Każda pomoc jest doceniana. – ayachama

+0

Newbie, czy zrobiłeś postępy w tej sprawie? –

+0

@Newbie Czy korzystasz z tego samego podpisu dla obu programów? A której wersji Androida używasz? – user932865

1

Jeśli Twój targetSdkVersion jest równa lub wyższa niż 24, to trzeba użyć FileProvider wdrożenia dla Androida N i nowsze Wersje Androida.

Oto cała realizacja:

// utility method 
private void openAppInstaller(Context context, File toInstall) { 
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { 
     Uri apkUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", toInstall); 
     Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE); 
     intent.setData(apkUri); 
     intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 
     context.startActivity(intent) 
    } else { 
     Uri apkUri = Uri.fromFile(toInstall); 
     Intent intent = new Intent(Intent.ACTION_VIEW); 
     intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); 
     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
     context.startActivity(intent); 
    } 
} 

Dodaj dostawcę FileProvider do AndroidManifest

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    ... 
    <application 
     ... 
     <provider 
      android:name="android.support.v4.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> 
</manifest> 

I tworzyć provider_paths.xml pod zasobów xml.

<?xml version="1.0" encoding="utf-8"?> 
<paths> 
    <external-path name="external_files" path="."/> 
</paths> 

Więcej informacji o konfiguracji FileProvider można przeczytać here i here.

Wszystkie kredyty idą do @just_user, ponieważ moja odpowiedź oparta jest na his reply.