post-install Intent to tell OsmAnd to import "installed" OBF
OsmAnd will import map files from a file:// URL pointing to an OBF file, but this currently only works for file:// and not the proper content://. This uses a hack to disable the warning about file:// URIs but only for the final stage of installing the .obf file. Hopefully in the future, this can be changed to use a proper content:// URL as I suggested to them in this merge request: https://github.com/osmandapp/OsmAnd/pull/10043
This commit is contained in:
parent
8cf267ea6c
commit
b316eab85d
@ -569,12 +569,15 @@ public class Apk extends ValueObject implements Comparable<Apk>, Parcelable {
|
||||
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(this.getCanonicalUrl());
|
||||
if (TextUtils.isEmpty(fileExtension)) return path;
|
||||
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
|
||||
String[] mimeType = mimeTypeMap.getMimeTypeFromExtension(fileExtension).split("/");
|
||||
String topLevelType;
|
||||
if (mimeType.length == 0) {
|
||||
topLevelType = "";
|
||||
} else {
|
||||
topLevelType = mimeType[0];
|
||||
String mimeType = mimeTypeMap.getMimeTypeFromExtension(fileExtension);
|
||||
String topLevelType = null;
|
||||
if (!TextUtils.isEmpty(mimeType)) {
|
||||
String[] mimeTypeSections = mimeType.split("/");
|
||||
if (mimeTypeSections.length == 0) {
|
||||
topLevelType = "";
|
||||
} else {
|
||||
topLevelType = mimeTypeSections[0];
|
||||
}
|
||||
}
|
||||
if ("audio".equals(topLevelType)) {
|
||||
path = Environment.getExternalStoragePublicDirectory(
|
||||
|
@ -5,8 +5,12 @@ import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.StrictMode;
|
||||
import android.util.Log;
|
||||
import android.view.ContextThemeWrapper;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.widget.Toast;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
@ -21,6 +25,7 @@ import org.fdroid.fdroid.data.Apk;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class FileInstallerActivity extends FragmentActivity {
|
||||
|
||||
@ -161,12 +166,44 @@ public class FileInstallerActivity extends FragmentActivity {
|
||||
Toast.makeText(this, String.format(this.getString(R.string.app_installed_media), path.toString()),
|
||||
Toast.LENGTH_LONG).show();
|
||||
installer.sendBroadcastInstall(canonicalUri, Installer.ACTION_INSTALL_COMPLETE);
|
||||
postInstall(path);
|
||||
} else {
|
||||
installer.sendBroadcastInstall(canonicalUri, Installer.ACTION_INSTALL_INTERRUPTED);
|
||||
}
|
||||
finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Run any file-type-specific processes after the file has been copied into place.
|
||||
* <p>
|
||||
* When this was written, OsmAnd only supported importing OBF files via a
|
||||
* {@code file:///} URL, so this disables {@link android.os.FileUriExposedException}.
|
||||
*/
|
||||
private void postInstall(File path) {
|
||||
if (path.getName().endsWith(".obf")) {
|
||||
if (Build.VERSION.SDK_INT >= 24) {
|
||||
try {
|
||||
Method m = StrictMode.class.getMethod("disableDeathOnFileUriExposure");
|
||||
m.invoke(null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("obf");
|
||||
intent.setDataAndType(Uri.fromFile(path), mimeType);
|
||||
if (Build.VERSION.SDK_INT >= 23) {
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
}
|
||||
if (intent.resolveActivity(getPackageManager()) != null) {
|
||||
startActivity(intent);
|
||||
} else {
|
||||
Log.i(TAG, "No Activity available to handle " + intent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void uninstallPackage(Apk apk) {
|
||||
if (apk.isMediaInstalled(activity.getApplicationContext())) {
|
||||
File file = apk.getInstalledMediaFile(activity.getApplicationContext());
|
||||
|
@ -2,7 +2,6 @@ package org.fdroid.fdroid.data;
|
||||
|
||||
import android.content.ContextWrapper;
|
||||
import android.os.Environment;
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
@ -58,6 +57,16 @@ public class ApkTest {
|
||||
assertEquals(new File(context.getApplicationInfo().dataDir + "/ota"), path);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMediaInstallPathWithObf() {
|
||||
Apk apk = new Apk();
|
||||
apk.apkName = "Norway_bouvet_europe_2.obf";
|
||||
apk.repoAddress = "https://example.com/fdroid/repo";
|
||||
assertFalse(apk.isApk());
|
||||
File path = apk.getMediaInstallPath(context);
|
||||
assertEquals(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), path);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetMediaInstallPathWithObfZip() throws IOException {
|
||||
Apk apk = new Apk();
|
||||
|
@ -54,5 +54,9 @@ public class ApkCacheTest {
|
||||
new File(cacheDir, "example.com--1/Norway_bouvet_europe_2.obf.zip"),
|
||||
ApkCache.getApkDownloadPath(context,
|
||||
"https://example.com/fdroid/repo/Norway_bouvet_europe_2.obf.zip"));
|
||||
assertEquals("Should work for OBF files also",
|
||||
new File(cacheDir, "example.com--1/Norway_bouvet_europe_2.obf"),
|
||||
ApkCache.getApkDownloadPath(context,
|
||||
"https://example.com/fdroid/repo/Norway_bouvet_europe_2.obf"));
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user