I'm trying to start an activity from an external apk file. The apk file is a simple text display and I download it from an URL into a local mounted directory in /mnt/sdcard/. Everything works fine to that point. Now, I want to start an activity from that file and I'm getting errors. Two types, depending on the Intent construction. Here below are the two implementations with the associated LogCat, the 'targetFilePath' being the same. Case I:
try {
Intent install = new Intent(Intent.ACTION_VIEW)
.setData(Uri.fromFile(new File(targetFilePath)))
.setType("application/vnd.android.package-archive");
startActivity(install);
}
catch (Exception e) {
e.printStackTrace();
Toast.makeText(DownloadFile.this, "apk file launch error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
The Logcat :
08-26 17:03:02.153: I/ActivityManager(59): Starting activity: Intent { act=android.intent.action.VIEW typ=application/vnd.android.package-archive }
08-26 17:03:02.153: W/System.err(390): android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW typ=application/vnd.android.package-archive }
08-26 17:03:02.162: W/System.err(390): at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1408)
08-26 17:03:02.162: W/System.err(390): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1378)
08-26 17:03:02.162: W/System.err(390): at android.app.Activity.startActivityForResult(Activity.java:2817)
08-26 17:03:02.162: W/System.err(390): at android.app.Activity.startActivity(Activity.java:2923)
08-26 17:03:02.162: W/System.err(390): at com.agorasoft.sandbox.DownloadFile$1.onClick(DownloadFile.java:137)
08-26 17:03:02.162: W/System.err(390): at android.view.View.performClick(View.java:2408)
08-26 17:03:02.172: W/System.err(390): at android.view.View$PerformClick.run(View.java:8816)
08-26 17:03:02.172: W/System.err(390): at android.os.Handler.handleCallback(Handler.java:587)
08-26 17:03:02.172: W/System.err(390): at android.os.Handler.dispatchMessage(Handler.java:92)
08-26 17:03:02.172: W/System.err(390): at android.os.Looper.loop(Looper.java:123)
08-26 17:03:02.182: W/System.err(390): at android.app.ActivityThread.main(ActivityThread.java:4627)
08-26 17:03:02.182: W/System.err(390): at java.lang.reflect.Method.invokeNative(Native Method)
08-26 17:03:02.182: W/System.err(390): at java.lang.reflect.Method.invoke(Method.java:521)
08-26 17:03:02.182: W/System.err(390): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-26 17:03:02.182: W/System.err(390): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-26 17:03:02.182: W/System.err(390): at dalvik.system.NativeStart.main(Native Method)
08-26 17:03:21.761: D/SntpClient(59): request time failed: java.net.SocketException: Address family not supported by protocol
Case II:
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri apkUri = Uri.fromFile(new File(targetFilePath));
intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
startActivity(intent);
}
catch (Exception e) {
e.printStackTrace();
Toast.makeText(DownloadFile.this, "apk file launch error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
Parse error pop-up window: There is a problem parsing the package
The LogCat :
08-26 17:09:48.862: W/PackageParser(329): Unable to read AndroidManifest.xml of /mnt/sdcard/Downloads/ApkTest.apk
08-26 17:09:48.862: W/PackageParser(329): java.io.FileNotFoundException: AndroidManifest.xml
08-26 17:09:48.862: W/PackageParser(329): at android.content.res.AssetManager.openXmlAssetNative(Native Method)
08-26 17:09:48.862: W/PackageParser(329): at android.content.res.AssetManager.openXmlBlockAsset(AssetManager.java:485)
08-26 17:09:48.862: W/PackageParser(329): at android.content.res.AssetManager.openXmlResourceParser(AssetManager.java:453)
08-26 17:09:48.862: W/PackageParser(329): at android.content.pm.PackageParser.parsePackage(PackageParser.java:396)
08-26 17:09:48.862: W/PackageParser(329): at com.android.packageinstaller.PackageUtil.getPackageInfo(PackageUtil.java:79)
08-26 17:09:48.862: W/PackageParser(329): at com.android.packageinstaller.PackageInstallerActivity.onCreate(PackageInstallerActivity.java:242)
08-26 17:09:48.862: W/PackageParser(329): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
08-26 17:09:48.862: W/PackageParser(329): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
08-26 17:09:48.862: W/PackageParser(329): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
08-26 17:09:48.862: W/PackageParser(329): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
08-26 17:09:48.862: W/PackageParser(329): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
08-26 17:09:48.862: W/PackageParser(329): at android.os.Handler.dispatchMessage(Handler.java:99)
08-26 17:09:48.862: W/PackageParser(329): at android.os.Looper.loop(Looper.java:123)
08-26 17:09:48.862: W/PackageParser(329): at android.app.ActivityThread.main(ActivityThread.java:4627)
08-26 17:09:48.862: W/PackageParser(329): at java.lang.reflect.Method.invokeNative(Native Method)
08-26 17:09:48.862: W/PackageParser(329): at java.lang.reflect.Method.invoke(Method.java:521)
08-26 17:09:48.862: W/PackageParser(329): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
08-26 17:09:48.862: W/PackageParser(329): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
08-26 17:09:48.862: W/PackageParser(329): at dalvik.system.NativeStart.main(Native Method)
08-26 17:09:48.862: W/PackageInstaller(329): Parse error when parsing manifest. Discontinuing installation
08-26 17:09:49.902: I/ActivityManager(59): Displayed activity com.android.packageinstaller/.PackageInstallerActivity: 1168 ms (total 1168 ms)
Sorry for the lengthy arguments but it seems strange that, first, it doesn't work, then that I have a different behavior for two syntaxes of the intent/install definition. Both the calling application and the apk file have the same SDK target/min versions. No special permission set in the calling application manifest for this chunk of code (do I need any?). Thanks
The docs hold your answer: Intent.setType
This is used to create intents that only specify a type and not data, for example to indicate the type of data to return.
This method automatically clears any data that was previously set (for example by setData(Uri)).
And the docs for Intent.setDataAndType
This method should very rarely be used -- it allows you to override the MIME type that would ordinarily be inferred from the data with your own type given here.
In short, you don't need to specify the type when constructing this intent, it will be inferred from the data itself given the URI.
All of that said, it seems nandeesh's comment is correct - the package you're trying to install looks corrupt. It's also worth noting that if you intend to post this app to the Play Store, apps that download or install other apks are not permitted by the developer agreement.