forked from organicmaps/organicmaps
[android][sdk] Create OrganicMaps sdk class
Signed-off-by: Andrei Shkrob <github@shkrob.dev>
This commit is contained in:
parent
466b9365f6
commit
7aad536fbe
14 changed files with 272 additions and 215 deletions
|
@ -25,6 +25,7 @@ set(SRC
|
|||
app/organicmaps/sdk/search/DisplayedCategories.cpp
|
||||
app/organicmaps/sdk/search/SearchEngine.cpp
|
||||
app/organicmaps/sdk/search/SearchRecents.cpp
|
||||
app/organicmaps/sdk/OrganicMaps.cpp
|
||||
app/organicmaps/core/jni_helper.cpp
|
||||
app/organicmaps/core/jni_java_methods.cpp
|
||||
app/organicmaps/core/logging.cpp
|
||||
|
@ -38,7 +39,6 @@ set(SRC
|
|||
app/organicmaps/LocationState.cpp
|
||||
app/organicmaps/Map.cpp
|
||||
app/organicmaps/MapManager.cpp
|
||||
app/organicmaps/MwmApplication.cpp
|
||||
app/organicmaps/routing/RoutingOptions.cpp
|
||||
app/organicmaps/settings/UnitLocale.cpp
|
||||
app/organicmaps/settings/MapLanguageCode.cpp
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
#include "app/organicmaps/Framework.hpp"
|
||||
|
||||
#include "app/organicmaps/platform/AndroidPlatform.hpp"
|
||||
|
||||
#include "app/organicmaps/core/jni_helper.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
// static void nativeSetSettingsDir(String settingsPath);
|
||||
JNIEXPORT void JNICALL
|
||||
Java_app_organicmaps_MwmApplication_nativeSetSettingsDir(JNIEnv * env, jclass clazz, jstring settingsPath)
|
||||
{
|
||||
android::Platform::Instance().SetSettingsDir(jni::ToNativeString(env, settingsPath));
|
||||
}
|
||||
|
||||
// static void nativeInitPlatform(Context context, String apkPath, String storagePath, String privatePath, String tmpPath,
|
||||
// String flavorName, String buildType, boolean isTablet);
|
||||
JNIEXPORT void JNICALL
|
||||
Java_app_organicmaps_MwmApplication_nativeInitPlatform(JNIEnv * env, jclass clazz, jobject context,
|
||||
jstring apkPath, jstring writablePath,
|
||||
jstring privatePath, jstring tmpPath,
|
||||
jstring flavorName, jstring buildType,
|
||||
jboolean isTablet)
|
||||
{
|
||||
android::Platform::Instance().Initialize(env, context, apkPath, writablePath, privatePath, tmpPath,
|
||||
flavorName, buildType, isTablet);
|
||||
}
|
||||
|
||||
// static void nativeInitFramework(@NonNull Runnable onComplete);
|
||||
JNIEXPORT void JNICALL
|
||||
Java_app_organicmaps_MwmApplication_nativeInitFramework(JNIEnv * env, jclass clazz, jobject onComplete)
|
||||
{
|
||||
if (!g_framework)
|
||||
{
|
||||
g_framework = std::make_unique<android::Framework>([onComplete = jni::make_global_ref(onComplete)]()
|
||||
{
|
||||
JNIEnv * env = jni::GetEnv();
|
||||
jmethodID const methodId = jni::GetMethodID(env, *onComplete, "run", "()V");
|
||||
env->CallVoidMethod(*onComplete, methodId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// static void nativeAddLocalization(String name, String value);
|
||||
JNIEXPORT void JNICALL
|
||||
Java_app_organicmaps_MwmApplication_nativeAddLocalization(JNIEnv * env, jclass clazz, jstring name, jstring value)
|
||||
{
|
||||
g_framework->AddString(jni::ToNativeString(env, name),
|
||||
jni::ToNativeString(env, value));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL
|
||||
Java_app_organicmaps_MwmApplication_nativeOnTransit(JNIEnv *, jclass, jboolean foreground)
|
||||
{
|
||||
if (static_cast<bool>(foreground))
|
||||
g_framework->NativeFramework()->EnterForeground();
|
||||
else
|
||||
g_framework->NativeFramework()->EnterBackground();
|
||||
}
|
||||
}
|
56
android/app/src/main/cpp/app/organicmaps/sdk/OrganicMaps.cpp
Normal file
56
android/app/src/main/cpp/app/organicmaps/sdk/OrganicMaps.cpp
Normal file
|
@ -0,0 +1,56 @@
|
|||
#include "app/organicmaps/Framework.hpp"
|
||||
|
||||
#include "app/organicmaps/platform/AndroidPlatform.hpp"
|
||||
|
||||
#include "app/organicmaps/core/jni_helper.hpp"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
// static void nativeSetSettingsDir(String settingsPath);
|
||||
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_OrganicMaps_nativeSetSettingsDir(JNIEnv * env, jclass clazz,
|
||||
jstring settingsPath)
|
||||
{
|
||||
android::Platform::Instance().SetSettingsDir(jni::ToNativeString(env, settingsPath));
|
||||
}
|
||||
|
||||
// static void nativeInitPlatform(Context context, String apkPath, String storagePath, String privatePath, String
|
||||
// tmpPath, String flavorName, String buildType, boolean isTablet);
|
||||
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_OrganicMaps_nativeInitPlatform(
|
||||
JNIEnv * env, jclass clazz, jobject context, jstring apkPath, jstring writablePath, jstring privatePath,
|
||||
jstring tmpPath, jstring flavorName, jstring buildType, jboolean isTablet)
|
||||
{
|
||||
android::Platform::Instance().Initialize(env, context, apkPath, writablePath, privatePath, tmpPath, flavorName,
|
||||
buildType, isTablet);
|
||||
}
|
||||
|
||||
// static void nativeInitFramework(@NonNull Runnable onComplete);
|
||||
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_OrganicMaps_nativeInitFramework(JNIEnv * env, jclass clazz,
|
||||
jobject onComplete)
|
||||
{
|
||||
if (!g_framework)
|
||||
{
|
||||
g_framework = std::make_unique<android::Framework>(
|
||||
[onComplete = jni::make_global_ref(onComplete)]()
|
||||
{
|
||||
JNIEnv * env = jni::GetEnv();
|
||||
jmethodID const methodId = jni::GetMethodID(env, *onComplete, "run", "()V");
|
||||
env->CallVoidMethod(*onComplete, methodId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// static void nativeAddLocalization(String name, String value);
|
||||
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_OrganicMaps_nativeAddLocalization(JNIEnv * env, jclass clazz,
|
||||
jstring name, jstring value)
|
||||
{
|
||||
g_framework->AddString(jni::ToNativeString(env, name), jni::ToNativeString(env, value));
|
||||
}
|
||||
|
||||
JNIEXPORT void JNICALL Java_app_organicmaps_sdk_OrganicMaps_nativeOnTransit(JNIEnv *, jclass, jboolean foreground)
|
||||
{
|
||||
if (static_cast<bool>(foreground))
|
||||
g_framework->NativeFramework()->EnterForeground();
|
||||
else
|
||||
g_framework->NativeFramework()->EnterBackground();
|
||||
}
|
||||
}
|
|
@ -20,10 +20,9 @@ import java.io.IOException;
|
|||
import java.lang.ref.WeakReference;
|
||||
|
||||
import app.organicmaps.background.OsmUploadWork;
|
||||
import app.organicmaps.bookmarks.data.BookmarkManager;
|
||||
import app.organicmaps.display.DisplayManager;
|
||||
import app.organicmaps.downloader.Android7RootCertificateWorkaround;
|
||||
import app.organicmaps.downloader.DownloaderNotifier;
|
||||
import app.organicmaps.display.DisplayManager;
|
||||
import app.organicmaps.location.LocationHelper;
|
||||
import app.organicmaps.location.LocationState;
|
||||
import app.organicmaps.location.SensorHelper;
|
||||
|
@ -31,18 +30,11 @@ import app.organicmaps.location.TrackRecorder;
|
|||
import app.organicmaps.location.TrackRecordingService;
|
||||
import app.organicmaps.maplayer.isolines.IsolinesManager;
|
||||
import app.organicmaps.maplayer.subway.SubwayManager;
|
||||
import app.organicmaps.maplayer.traffic.TrafficManager;
|
||||
import app.organicmaps.routing.NavigationService;
|
||||
import app.organicmaps.routing.RoutingController;
|
||||
import app.organicmaps.sdk.search.SearchEngine;
|
||||
import app.organicmaps.settings.StoragePathManager;
|
||||
import app.organicmaps.sound.TtsPlayer;
|
||||
import app.organicmaps.sdk.OrganicMaps;
|
||||
import app.organicmaps.util.Config;
|
||||
import app.organicmaps.util.ConnectionState;
|
||||
import app.organicmaps.util.SharedPropertiesUtils;
|
||||
import app.organicmaps.util.StorageUtils;
|
||||
import app.organicmaps.util.ThemeSwitcher;
|
||||
import app.organicmaps.util.UiUtils;
|
||||
import app.organicmaps.util.Utils;
|
||||
import app.organicmaps.util.log.Logger;
|
||||
import app.organicmaps.util.log.LogsManager;
|
||||
|
@ -52,6 +44,10 @@ public class MwmApplication extends Application implements Application.ActivityL
|
|||
@NonNull
|
||||
private static final String TAG = MwmApplication.class.getSimpleName();
|
||||
|
||||
@SuppressWarnings("NotNullFieldNotInitialized")
|
||||
@NonNull
|
||||
private OrganicMaps mOrganicMaps;
|
||||
|
||||
@SuppressWarnings("NotNullFieldNotInitialized")
|
||||
@NonNull
|
||||
private SubwayManager mSubwayManager;
|
||||
|
@ -72,9 +68,6 @@ public class MwmApplication extends Application implements Application.ActivityL
|
|||
@NonNull
|
||||
private DisplayManager mDisplayManager;
|
||||
|
||||
private volatile boolean mFrameworkInitialized;
|
||||
private volatile boolean mPlatformInitialized;
|
||||
|
||||
@Nullable
|
||||
private WeakReference<Activity> mTopActivity;
|
||||
|
||||
|
@ -115,6 +108,12 @@ public class MwmApplication extends Application implements Application.ActivityL
|
|||
return mDisplayManager;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public OrganicMaps getOrganicMaps()
|
||||
{
|
||||
return mOrganicMaps;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static MwmApplication from(@NonNull Context context)
|
||||
{
|
||||
|
@ -138,20 +137,12 @@ public class MwmApplication extends Application implements Application.ActivityL
|
|||
|
||||
sInstance = this;
|
||||
|
||||
mOrganicMaps = new OrganicMaps(getApplicationContext());
|
||||
|
||||
LogsManager.INSTANCE.initFileLogging(this);
|
||||
|
||||
Android7RootCertificateWorkaround.initializeIfNeeded(this);
|
||||
|
||||
// Set configuration directory as early as possible.
|
||||
// Other methods may explicitly use Config, which requires settingsDir to be set.
|
||||
final String settingsPath = StorageUtils.getSettingsPath(this);
|
||||
if (!StorageUtils.createDirectory(settingsPath))
|
||||
throw new AssertionError("Can't create settingsDir " + settingsPath);
|
||||
Logger.d(TAG, "Settings path = " + settingsPath);
|
||||
nativeSetSettingsDir(settingsPath);
|
||||
|
||||
Config.init(this);
|
||||
|
||||
ConnectionState.INSTANCE.initialize(this);
|
||||
|
||||
DownloaderNotifier.createNotificationChannel(this);
|
||||
|
@ -166,117 +157,16 @@ public class MwmApplication extends Application implements Application.ActivityL
|
|||
mDisplayManager = new DisplayManager();
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize native core of application: platform and framework.
|
||||
*
|
||||
* @throws IOException - if failed to create directories. Caller must handle
|
||||
* the exception and do nothing with native code if initialization is failed.
|
||||
*/
|
||||
public boolean init(@NonNull Runnable onComplete) throws IOException
|
||||
public boolean initOrganicMaps(@NonNull Runnable onComplete) throws IOException
|
||||
{
|
||||
initNativePlatform();
|
||||
return initNativeFramework(onComplete);
|
||||
return mOrganicMaps.init(() -> {
|
||||
ProcessLifecycleOwner.get().getLifecycle().addObserver(mProcessLifecycleObserver);
|
||||
onComplete.run();
|
||||
});
|
||||
}
|
||||
|
||||
private void initNativePlatform() throws IOException
|
||||
private final LifecycleObserver mProcessLifecycleObserver = new DefaultLifecycleObserver()
|
||||
{
|
||||
if (mPlatformInitialized)
|
||||
return;
|
||||
|
||||
final String apkPath = StorageUtils.getApkPath(this);
|
||||
Logger.d(TAG, "Apk path = " + apkPath);
|
||||
// Note: StoragePathManager uses Config, which requires SettingsDir to be set.
|
||||
final String writablePath = StoragePathManager.findMapsStorage(this);
|
||||
Logger.d(TAG, "Writable path = " + writablePath);
|
||||
final String privatePath = StorageUtils.getPrivatePath(this);
|
||||
Logger.d(TAG, "Private path = " + privatePath);
|
||||
final String tempPath = StorageUtils.getTempPath(this);
|
||||
Logger.d(TAG, "Temp path = " + tempPath);
|
||||
|
||||
// If platform directories are not created it means that native part of app will not be able
|
||||
// to work at all. So, we just ignore native part initialization in this case, e.g. when the
|
||||
// external storage is damaged or not available (read-only).
|
||||
createPlatformDirectories(writablePath, privatePath, tempPath);
|
||||
|
||||
nativeInitPlatform(getApplicationContext(),
|
||||
apkPath,
|
||||
writablePath,
|
||||
privatePath,
|
||||
tempPath,
|
||||
app.organicmaps.BuildConfig.FLAVOR,
|
||||
app.organicmaps.BuildConfig.BUILD_TYPE, UiUtils.isTablet(this));
|
||||
Config.setStoragePath(writablePath);
|
||||
Config.setStatisticsEnabled(SharedPropertiesUtils.isStatisticsEnabled(this));
|
||||
|
||||
mPlatformInitialized = true;
|
||||
Logger.i(TAG, "Platform initialized");
|
||||
}
|
||||
|
||||
private void createPlatformDirectories(@NonNull String writablePath,
|
||||
@NonNull String privatePath,
|
||||
@NonNull String tempPath) throws IOException
|
||||
{
|
||||
SharedPropertiesUtils.emulateBadExternalStorage(this);
|
||||
|
||||
StorageUtils.requireDirectory(writablePath);
|
||||
StorageUtils.requireDirectory(privatePath);
|
||||
StorageUtils.requireDirectory(tempPath);
|
||||
}
|
||||
|
||||
private boolean initNativeFramework(@NonNull Runnable onComplete)
|
||||
{
|
||||
if (mFrameworkInitialized)
|
||||
return false;
|
||||
|
||||
nativeInitFramework(onComplete);
|
||||
|
||||
initNativeStrings();
|
||||
ThemeSwitcher.INSTANCE.initialize(this);
|
||||
SearchEngine.INSTANCE.initialize();
|
||||
BookmarkManager.loadBookmarks();
|
||||
TtsPlayer.INSTANCE.initialize(this);
|
||||
ThemeSwitcher.INSTANCE.restart(false);
|
||||
RoutingController.get().initialize(this);
|
||||
TrafficManager.INSTANCE.initialize();
|
||||
SubwayManager.from(this).initialize();
|
||||
IsolinesManager.from(this).initialize();
|
||||
ProcessLifecycleOwner.get().getLifecycle().addObserver(mProcessLifecycleObserver);
|
||||
|
||||
Logger.i(TAG, "Framework initialized");
|
||||
mFrameworkInitialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void initNativeStrings()
|
||||
{
|
||||
nativeAddLocalization("core_entrance", getString(R.string.core_entrance));
|
||||
nativeAddLocalization("core_exit", getString(R.string.core_exit));
|
||||
nativeAddLocalization("core_my_places", getString(R.string.core_my_places));
|
||||
nativeAddLocalization("core_my_position", getString(R.string.core_my_position));
|
||||
nativeAddLocalization("core_placepage_unknown_place", getString(R.string.core_placepage_unknown_place));
|
||||
nativeAddLocalization("postal_code", getString(R.string.postal_code));
|
||||
nativeAddLocalization("wifi", getString(R.string.category_wifi));
|
||||
}
|
||||
|
||||
public boolean arePlatformAndCoreInitialized()
|
||||
{
|
||||
return mFrameworkInitialized && mPlatformInitialized;
|
||||
}
|
||||
|
||||
static
|
||||
{
|
||||
System.loadLibrary("organicmaps");
|
||||
}
|
||||
|
||||
private static native void nativeSetSettingsDir(String settingsPath);
|
||||
private static native void nativeInitPlatform(Context context, String apkPath, String writablePath,
|
||||
String privatePath, String tmpPath, String flavorName,
|
||||
String buildType, boolean isTablet);
|
||||
private static native void nativeInitFramework(@NonNull Runnable onComplete);
|
||||
private static native void nativeAddLocalization(String name, String value);
|
||||
private static native void nativeOnTransit(boolean foreground);
|
||||
|
||||
private final LifecycleObserver mProcessLifecycleObserver = new DefaultLifecycleObserver() {
|
||||
@Override
|
||||
public void onStart(@NonNull LifecycleOwner owner)
|
||||
{
|
||||
|
@ -334,8 +224,6 @@ public class MwmApplication extends Application implements Application.ActivityL
|
|||
{
|
||||
Logger.d(TAG);
|
||||
|
||||
nativeOnTransit(true);
|
||||
|
||||
mLocationHelper.resumeLocationInForeground();
|
||||
}
|
||||
|
||||
|
@ -343,8 +231,6 @@ public class MwmApplication extends Application implements Application.ActivityL
|
|||
{
|
||||
Logger.d(TAG);
|
||||
|
||||
nativeOnTransit(false);
|
||||
|
||||
OsmUploadWork.startActionUploadOsmChanges(this);
|
||||
|
||||
if (!mDisplayManager.isDeviceDisplayUsed())
|
||||
|
|
|
@ -2,7 +2,6 @@ package app.organicmaps;
|
|||
|
||||
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
|
||||
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
|
||||
import static app.organicmaps.api.Const.EXTRA_PICK_POINT;
|
||||
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
|
@ -146,7 +145,7 @@ public class SplashActivity extends AppCompatActivity
|
|||
boolean asyncContinue = false;
|
||||
try
|
||||
{
|
||||
asyncContinue = app.init(this::processNavigation);
|
||||
asyncContinue = app.initOrganicMaps(this::processNavigation);
|
||||
} catch (IOException error)
|
||||
{
|
||||
showFatalErrorDialog(R.string.dialog_error_storage_title, R.string.dialog_error_storage_message, error);
|
||||
|
|
|
@ -47,7 +47,7 @@ public class OsmUploadWork extends Worker
|
|||
public Result doWork()
|
||||
{
|
||||
final MwmApplication app = MwmApplication.from(mContext);
|
||||
if (!app.arePlatformAndCoreInitialized())
|
||||
if (!app.getOrganicMaps().arePlatformAndCoreInitialized())
|
||||
{
|
||||
Logger.w(TAG, "Application is not initialized, ignoring " + mWorkerParameters);
|
||||
return Result.failure();
|
||||
|
|
|
@ -69,7 +69,7 @@ public abstract class BaseMwmFragmentActivity extends AppCompatActivity
|
|||
setTheme(getThemeResourceId(mThemeName));
|
||||
EdgeToEdge.enable(this, SystemBarStyle.dark(Color.TRANSPARENT));
|
||||
RtlUtils.manageRtl(this);
|
||||
if (!MwmApplication.from(this).arePlatformAndCoreInitialized())
|
||||
if (!MwmApplication.from(this).getOrganicMaps().arePlatformAndCoreInitialized())
|
||||
{
|
||||
final Intent intent = Objects.requireNonNull(getIntent());
|
||||
intent.setComponent(new ComponentName(this, SplashActivity.class));
|
||||
|
|
|
@ -163,7 +163,7 @@ public final class CarAppSession extends Session implements DefaultLifecycleObse
|
|||
mInitFailed = false;
|
||||
try
|
||||
{
|
||||
MwmApplication.from(getCarContext()).init(() -> {
|
||||
MwmApplication.from(getCarContext()).initOrganicMaps(() -> {
|
||||
Config.setFirstStartDialogSeen(getCarContext());
|
||||
if (DownloaderHelpers.isWorldMapsDownloadNeeded())
|
||||
mScreenManager.push(new DownloadMapsScreenBuilder(getCarContext()).setDownloaderType(DownloadMapsScreenBuilder.DownloaderType.FirstLaunch).build());
|
||||
|
|
|
@ -135,7 +135,7 @@ public class TrackRecordingService extends Service implements LocationListener
|
|||
@Override
|
||||
public int onStartCommand(@NonNull Intent intent, int flags, int startId)
|
||||
{
|
||||
if (!MwmApplication.from(this).arePlatformAndCoreInitialized())
|
||||
if (!MwmApplication.from(this).getOrganicMaps().arePlatformAndCoreInitialized())
|
||||
{
|
||||
Logger.w(TAG, "Application is not initialized");
|
||||
stopSelf();
|
||||
|
|
|
@ -201,7 +201,7 @@ public class NavigationService extends Service implements LocationListener
|
|||
return START_NOT_STICKY;
|
||||
}
|
||||
|
||||
if (!MwmApplication.from(this).arePlatformAndCoreInitialized())
|
||||
if (!MwmApplication.from(this).getOrganicMaps().arePlatformAndCoreInitialized())
|
||||
{
|
||||
// The system restarts the service if the app's process has crashed or been stopped. It would be nice to
|
||||
// automatically restore the last route and resume navigation. Unfortunately, the current implementation of
|
||||
|
|
178
android/app/src/main/java/app/organicmaps/sdk/OrganicMaps.java
Normal file
178
android/app/src/main/java/app/organicmaps/sdk/OrganicMaps.java
Normal file
|
@ -0,0 +1,178 @@
|
|||
package app.organicmaps.sdk;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.DefaultLifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.ProcessLifecycleOwner;
|
||||
|
||||
import app.organicmaps.R;
|
||||
import app.organicmaps.bookmarks.data.BookmarkManager;
|
||||
import app.organicmaps.maplayer.isolines.IsolinesManager;
|
||||
import app.organicmaps.maplayer.subway.SubwayManager;
|
||||
import app.organicmaps.maplayer.traffic.TrafficManager;
|
||||
import app.organicmaps.routing.RoutingController;
|
||||
import app.organicmaps.sdk.search.SearchEngine;
|
||||
import app.organicmaps.settings.StoragePathManager;
|
||||
import app.organicmaps.sound.TtsPlayer;
|
||||
import app.organicmaps.util.Config;
|
||||
import app.organicmaps.util.SharedPropertiesUtils;
|
||||
import app.organicmaps.util.StorageUtils;
|
||||
import app.organicmaps.util.ThemeSwitcher;
|
||||
import app.organicmaps.util.UiUtils;
|
||||
import app.organicmaps.util.log.Logger;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public final class OrganicMaps implements DefaultLifecycleObserver
|
||||
{
|
||||
private static final String TAG = OrganicMaps.class.getSimpleName();
|
||||
|
||||
@NonNull
|
||||
private final Context mContext;
|
||||
|
||||
private volatile boolean mFrameworkInitialized;
|
||||
private volatile boolean mPlatformInitialized;
|
||||
|
||||
public OrganicMaps(@NonNull Context context)
|
||||
{
|
||||
mContext = context.getApplicationContext();
|
||||
|
||||
// Set configuration directory as early as possible.
|
||||
// Other methods may explicitly use Config, which requires settingsDir to be set.
|
||||
final String settingsPath = StorageUtils.getSettingsPath(mContext);
|
||||
if (!StorageUtils.createDirectory(settingsPath))
|
||||
throw new AssertionError("Can't create settingsDir " + settingsPath);
|
||||
Logger.d(TAG, "Settings path = " + settingsPath);
|
||||
nativeSetSettingsDir(settingsPath);
|
||||
|
||||
Config.init(mContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize native core of application: platform and framework.
|
||||
*
|
||||
* @throws IOException - if failed to create directories. Caller must handle
|
||||
* the exception and do nothing with native code if initialization is failed.
|
||||
*/
|
||||
public boolean init(@NonNull Runnable onComplete) throws IOException
|
||||
{
|
||||
initNativePlatform();
|
||||
return initNativeFramework(onComplete);
|
||||
}
|
||||
|
||||
public boolean arePlatformAndCoreInitialized()
|
||||
{
|
||||
return mFrameworkInitialized && mPlatformInitialized;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart(@NonNull LifecycleOwner owner)
|
||||
{
|
||||
nativeOnTransit(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop(@NonNull LifecycleOwner owner)
|
||||
{
|
||||
nativeOnTransit(false);
|
||||
}
|
||||
|
||||
private void initNativePlatform() throws IOException
|
||||
{
|
||||
if (mPlatformInitialized)
|
||||
return;
|
||||
|
||||
final String apkPath = StorageUtils.getApkPath(mContext);
|
||||
Logger.d(TAG, "Apk path = " + apkPath);
|
||||
// Note: StoragePathManager uses Config, which requires SettingsDir to be set.
|
||||
final String writablePath = StoragePathManager.findMapsStorage(mContext);
|
||||
Logger.d(TAG, "Writable path = " + writablePath);
|
||||
final String privatePath = StorageUtils.getPrivatePath(mContext);
|
||||
Logger.d(TAG, "Private path = " + privatePath);
|
||||
final String tempPath = StorageUtils.getTempPath(mContext);
|
||||
Logger.d(TAG, "Temp path = " + tempPath);
|
||||
|
||||
// If platform directories are not created it means that native part of app will not be able
|
||||
// to work at all. So, we just ignore native part initialization in this case, e.g. when the
|
||||
// external storage is damaged or not available (read-only).
|
||||
createPlatformDirectories(writablePath, privatePath, tempPath);
|
||||
|
||||
nativeInitPlatform(mContext,
|
||||
apkPath,
|
||||
writablePath,
|
||||
privatePath,
|
||||
tempPath,
|
||||
app.organicmaps.BuildConfig.FLAVOR,
|
||||
app.organicmaps.BuildConfig.BUILD_TYPE, UiUtils.isTablet(mContext));
|
||||
Config.setStoragePath(writablePath);
|
||||
Config.setStatisticsEnabled(SharedPropertiesUtils.isStatisticsEnabled(mContext));
|
||||
|
||||
mPlatformInitialized = true;
|
||||
Logger.i(TAG, "Platform initialized");
|
||||
}
|
||||
|
||||
private boolean initNativeFramework(@NonNull Runnable onComplete)
|
||||
{
|
||||
if (mFrameworkInitialized)
|
||||
return false;
|
||||
|
||||
nativeInitFramework(onComplete);
|
||||
|
||||
initNativeStrings();
|
||||
ThemeSwitcher.INSTANCE.initialize(mContext);
|
||||
SearchEngine.INSTANCE.initialize();
|
||||
BookmarkManager.loadBookmarks();
|
||||
TtsPlayer.INSTANCE.initialize(mContext);
|
||||
ThemeSwitcher.INSTANCE.restart(false);
|
||||
RoutingController.get().initialize(mContext);
|
||||
TrafficManager.INSTANCE.initialize();
|
||||
SubwayManager.from(mContext).initialize();
|
||||
IsolinesManager.from(mContext).initialize();
|
||||
ProcessLifecycleOwner.get().getLifecycle().addObserver(this);
|
||||
|
||||
Logger.i(TAG, "Framework initialized");
|
||||
mFrameworkInitialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
private void createPlatformDirectories(@NonNull String writablePath,
|
||||
@NonNull String privatePath,
|
||||
@NonNull String tempPath) throws IOException
|
||||
{
|
||||
SharedPropertiesUtils.emulateBadExternalStorage(mContext);
|
||||
|
||||
StorageUtils.requireDirectory(writablePath);
|
||||
StorageUtils.requireDirectory(privatePath);
|
||||
StorageUtils.requireDirectory(tempPath);
|
||||
}
|
||||
|
||||
private void initNativeStrings()
|
||||
{
|
||||
nativeAddLocalization("core_entrance", mContext.getString(R.string.core_entrance));
|
||||
nativeAddLocalization("core_exit", mContext.getString(R.string.core_exit));
|
||||
nativeAddLocalization("core_my_places", mContext.getString(R.string.core_my_places));
|
||||
nativeAddLocalization("core_my_position", mContext.getString(R.string.core_my_position));
|
||||
nativeAddLocalization("core_placepage_unknown_place", mContext.getString(R.string.core_placepage_unknown_place));
|
||||
nativeAddLocalization("postal_code", mContext.getString(R.string.postal_code));
|
||||
nativeAddLocalization("wifi", mContext.getString(R.string.category_wifi));
|
||||
}
|
||||
|
||||
private static native void nativeSetSettingsDir(String settingsPath);
|
||||
|
||||
private static native void nativeInitPlatform(Context context, String apkPath, String writablePath,
|
||||
String privatePath, String tmpPath, String flavorName,
|
||||
String buildType, boolean isTablet);
|
||||
|
||||
private static native void nativeInitFramework(@NonNull Runnable onComplete);
|
||||
|
||||
private static native void nativeAddLocalization(String name, String value);
|
||||
|
||||
private static native void nativeOnTransit(boolean foreground);
|
||||
|
||||
static
|
||||
{
|
||||
System.loadLibrary("organicmaps");
|
||||
}
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
package app.organicmaps.settings;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
|
@ -306,9 +305,9 @@ public class StoragePathManager
|
|||
* Checks the currently configured storage first, then scans other storages.
|
||||
* If no map files found uses getDefaultStorage().
|
||||
*/
|
||||
public static String findMapsStorage(@NonNull Application application)
|
||||
public static String findMapsStorage(@NonNull Context context)
|
||||
{
|
||||
StoragePathManager mgr = new StoragePathManager(application);
|
||||
StoragePathManager mgr = new StoragePathManager(context);
|
||||
mgr.scanAvailableStorages();
|
||||
String path;
|
||||
final List<StorageItem> storages = mgr.mStorages;
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package app.organicmaps.util;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
|
@ -91,11 +90,11 @@ public class StorageUtils
|
|||
}
|
||||
|
||||
@NonNull
|
||||
public static String getApkPath(@NonNull Application application)
|
||||
public static String getApkPath(@NonNull Context context)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Utils.getApplicationInfo(application.getPackageManager(), BuildConfig.APPLICATION_ID, 0).sourceDir;
|
||||
return Utils.getApplicationInfo(context.getPackageManager(), BuildConfig.APPLICATION_ID, 0).sourceDir;
|
||||
}
|
||||
catch (final PackageManager.NameNotFoundException e)
|
||||
{
|
||||
|
@ -113,21 +112,21 @@ public class StorageUtils
|
|||
}
|
||||
|
||||
@NonNull
|
||||
public static String getSettingsPath(@NonNull Application application)
|
||||
public static String getSettingsPath(@NonNull Context context)
|
||||
{
|
||||
return addTrailingSeparator(application.getFilesDir().getAbsolutePath());
|
||||
return addTrailingSeparator(context.getFilesDir().getAbsolutePath());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getPrivatePath(@NonNull Application application)
|
||||
public static String getPrivatePath(@NonNull Context context)
|
||||
{
|
||||
return addTrailingSeparator(application.getFilesDir().getAbsolutePath());
|
||||
return addTrailingSeparator(context.getFilesDir().getAbsolutePath());
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String getTempPath(@NonNull Application application)
|
||||
public static String getTempPath(@NonNull Context context)
|
||||
{
|
||||
return addTrailingSeparator(application.getCacheDir().getAbsolutePath());
|
||||
return addTrailingSeparator(context.getCacheDir().getAbsolutePath());
|
||||
}
|
||||
|
||||
public static boolean createDirectory(@NonNull final String path)
|
||||
|
|
|
@ -583,7 +583,7 @@ public class Utils
|
|||
public static void detachFragmentIfCoreNotInitialized(@NonNull Context context,
|
||||
@NonNull Fragment fragment)
|
||||
{
|
||||
if (MwmApplication.from(context).arePlatformAndCoreInitialized())
|
||||
if (MwmApplication.from(context).getOrganicMaps().arePlatformAndCoreInitialized())
|
||||
return;
|
||||
|
||||
FragmentManager manager = fragment.getFragmentManager();
|
||||
|
|
Loading…
Add table
Reference in a new issue