Reputation: 367
I am trying to create a mechanism for an app to update itself by downloading and installing a later APK from within the app.
I have an APK located on a server which installs fine if I simply navigate to the URI then open the .apk file. The problem comes when I try to install it programmatically. I get "Parse Error - There was a problem while parsing the package"
The target phone allows install from unknown sources and within AndroidManifest.xml
I request these permissions:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
<uses-permission android:name="android.permission.REQUEST_WRITE_PERMISSION"/>
The code to perform the update has been taken from another thread here on StackOverflow and changed slightly to suit my particular situation.
public class UpdateApp extends AsyncTask<String,Void,Void> {
private Context context;
public void setContext(Context contextf){
context = contextf;
}
@Override
protected Void doInBackground(String... arg0) {
try {
URL url = new URL(arg0[0]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.setDoOutput(true);
conn.connect();
File file = context.getCacheDir();
file.mkdirs();
File outputFile = new File(file, "update.apk");
if(outputFile.exists()){
outputFile.delete();
}
FileOutputStream fos = new FileOutputStream(outputFile);
InputStream is = conn.getInputStream();
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(outputFile), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} catch (Throwable ex) {
Toast.makeText(context, ex.toString(), Toast.LENGTH_LONG).show();
}
return null;
}
}
What can I try in order to understand why the APK is generating an error when installed from within the code but installs without issue when downloaded from the server?
The app is being built for API 23 although it will be required to work with API 24 once complete.
Upvotes: 8
Views: 4086
Reputation: 8552
This works for me on Android 8
startActivity(Intent(Intent.ACTION_VIEW).apply {
type = "application/vnd.android.package-archive"
data = FileProvider.getUriForFile(applicationContext, "$packageName.fileprovider", file)
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
})
Upvotes: 1
Reputation: 5049
You will have to make your cached apk file world-readable.
After is.close();
put
outputFile.setReadable(true, false);
Upvotes: 6