Skip to content

Commit

Permalink
Initialize plugins and custom maps in MapTrek instead of MainActivity (
Browse files Browse the repository at this point in the history
…#193)

This is necessary because MainActivity can be recreated with a saved bundle in two different cases:
- on orientation changes, when only the activity is recreated
- after the process has been killed

In the first case, mMapIndex = application.getExtraMapIndex() worked well,
though in the second case, MapTrek.mExtraMapIndex got cleared and maps from content providers hadn't had any chance to get initialized up to now.

Co-authored-by: Andrey Novikov <[email protected]>
  • Loading branch information
qnga and andreynovikov authored Dec 19, 2023
1 parent 460289b commit 310d5b7
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 9 deletions.
28 changes: 20 additions & 8 deletions app/src/main/java/mobi/maptrek/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
import com.google.android.material.snackbar.BaseTransientBottomBar;
import com.google.android.material.bottomsheet.BottomSheetBehavior;

import androidx.appcompat.app.AppCompatActivity;
import androidx.annotation.StringRes;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.appcompat.widget.ContentFrameLayout;
Expand Down Expand Up @@ -113,6 +114,7 @@
import android.widget.TextView;
import android.widget.Toast;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.oscim.android.canvas.AndroidBitmap;
import org.oscim.backend.CanvasAdapter;
Expand Down Expand Up @@ -234,6 +236,8 @@
import mobi.maptrek.location.INavigationService;
import mobi.maptrek.location.LocationService;
import mobi.maptrek.location.NavigationService;
import mobi.maptrek.plugin.PluginRepository;
import mobi.maptrek.util.ContextUtils;
import mobi.maptrek.util.SafeResultReceiver;
import mobi.maptrek.maps.MapFile;
import mobi.maptrek.maps.MapIndex;
Expand All @@ -256,7 +260,7 @@
import mobi.maptrek.util.SunriseSunset;
import mobi.maptrek.view.Gauge;

public class MainActivity extends BasePluginActivity implements ILocationListener,
public class MainActivity extends AppCompatActivity implements ILocationListener,
DataHolder,
MapHolder,
Map.InputListener,
Expand Down Expand Up @@ -410,6 +414,7 @@ private enum PANEL_STATE {
private WeakReference<SafeResultReceiver> mResultReceiver;

private WaypointBroadcastReceiver mWaypointBroadcastReceiver;
private PluginRepository mPluginRepository;

@SuppressLint({"ShowToast", "UseCompatLoadingForDrawables"})
@Override
Expand All @@ -418,6 +423,7 @@ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

logger.debug("onCreate()");
EventBus.getDefault().register(this);

// Required for transparent status bar
WindowCompat.setDecorFitsSystemWindows(getWindow(), false);
Expand Down Expand Up @@ -474,11 +480,9 @@ protected void onCreate(Bundle savedInstanceState) {
mShieldFactory = application.getShieldFactory();
mOsmcSymbolFactory = application.getOsmcSymbolFactory();

if (savedInstanceState == null) {
initializePlugins();
mMapIndex.initializeOfflineMapProviders();
mMapIndex.initializeOnlineMapProviders();
mPluginRepository = application.getPluginRepository();

if (savedInstanceState == null) {
String language = Configuration.getLanguage();
if (language == null) {
language = resources.getConfiguration().locale.getLanguage();
Expand Down Expand Up @@ -1048,6 +1052,7 @@ protected void onStop() {
protected void onDestroy() {
super.onDestroy();
logger.debug("onDestroy()");
EventBus.getDefault().unregister(this);

long runningTime = (SystemClock.uptimeMillis() - mStartTime) / 60000;
Configuration.updateRunningTime(runningTime);
Expand Down Expand Up @@ -1760,7 +1765,7 @@ private void onMoreClicked() {
}
if (mViews.gaugePanel.hasVisibleGauges() || (mLocationState != LocationState.NORTH && mLocationState != LocationState.TRACK))
menu.removeItem(R.id.actionAddGauge);
java.util.Map<String, Pair<Drawable, Intent>> tools = getPluginsTools();
java.util.Map<String, Pair<Drawable, Intent>> tools = mPluginRepository.getPluginTools();
String[] toolNames = tools.keySet().toArray(new String[0]);
Arrays.sort(toolNames, Collections.reverseOrder(String.CASE_INSENSITIVE_ORDER));
for (String toolName : toolNames) {
Expand Down Expand Up @@ -4079,7 +4084,7 @@ public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
logger.debug("Broadcast: {}", action);
if (WaypointDbDataSource.BROADCAST_WAYPOINTS_MODIFIED.equals(action)) {
sendExplicitBroadcast(WaypointDbDataSource.BROADCAST_WAYPOINTS_MODIFIED);
ContextUtils.sendExplicitBroadcast(MainActivity.this, WaypointDbDataSource.BROADCAST_WAYPOINTS_MODIFIED);
}
if (WaypointDbDataSource.BROADCAST_WAYPOINTS_RESTORED.equals(action)) {
for (Waypoint waypoint : mWaypointDbDataSource.getWaypoints())
Expand Down Expand Up @@ -4626,4 +4631,11 @@ public String getStatsString() {
private double movingAverage(double current, double previous) {
return 0.2 * previous + 0.8 * current;
}
}

@Subscribe
public void onNewPluginEntry(Pair<String, Pair<Drawable, Intent>> entry) {
if (BuildConfig.FULL_VERSION) {
mPluginRepository.addPluginEntry(entry);
}
}
}
17 changes: 16 additions & 1 deletion app/src/main/java/mobi/maptrek/MapTrek.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@
import mobi.maptrek.maps.maptrek.Index;
import mobi.maptrek.maps.maptrek.MapTrekDatabaseHelper;
import mobi.maptrek.maps.maptrek.Tags;
import mobi.maptrek.plugin.PluginRepository;
import mobi.maptrek.util.LongSparseArrayIterator;
import mobi.maptrek.util.NativeMapFilenameFilter;
import mobi.maptrek.util.OsmcSymbolFactory;
Expand Down Expand Up @@ -114,6 +115,7 @@ public class MapTrek extends Application {
private SafeResultReceiver mResultReceiver;
private Waypoint mEditedWaypoint;
private List<MapFile> mBitmapLayerMaps;
private PluginRepository mPluginRepository;

private static final LongSparseArray<MapObject> mapObjects = new LongSparseArray<>();

Expand Down Expand Up @@ -326,8 +328,11 @@ public Index getMapIndex() {
}

public MapIndex getExtraMapIndex() {
if (mExtraMapIndex == null)
if (mExtraMapIndex == null) {
mExtraMapIndex = new MapIndex(this, getExternalFilesDir("maps"));
mExtraMapIndex.initializeOfflineMapProviders();
mExtraMapIndex.initializeOnlineMapProviders();
}
return mExtraMapIndex;
}

Expand All @@ -351,6 +356,16 @@ public OsmcSymbolFactory getOsmcSymbolFactory() {
return mOsmcSymbolFactory;
}

public PluginRepository getPluginRepository() {
if (mPluginRepository == null) {
mPluginRepository = new PluginRepository(this);

if (BuildConfig.FULL_VERSION) {
mPluginRepository.initializePlugins();
}
}
return mPluginRepository;
}

@Nullable
public SafeResultReceiver getResultReceiver() {
Expand Down
94 changes: 94 additions & 0 deletions app/src/main/java/mobi/maptrek/plugin/PluginRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
* Copyright 2022 Andrey Novikov
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

package mobi.maptrek.plugin;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.util.Pair;

import androidx.annotation.NonNull;

import java.util.AbstractMap;
import java.util.HashMap;
import java.util.List;

import mobi.maptrek.util.ContextUtils;

public final class PluginRepository {

private final Context mContext;

// Plugins
private final AbstractMap<String, Intent> mPluginPreferences = new HashMap<>();
private final AbstractMap<String, Pair<Drawable, Intent>> mPluginTools = new HashMap<>();

public PluginRepository(@NonNull Context context) {
mContext = context;
}

public AbstractMap<String, Pair<Drawable, Intent>> getPluginTools() {
return mPluginTools;
}

public AbstractMap<String, Intent> getPluginPreferences() {
return mPluginPreferences;
}

public void addPluginEntry(Pair<String, Pair<Drawable, Intent>> entry) {
mPluginTools.put(entry.first, entry.second);
}

public void initializePlugins() {
PackageManager packageManager = mContext.getPackageManager();
List<ResolveInfo> plugins;

// enumerate initializable plugins
ContextUtils.sendExplicitBroadcast(mContext, "mobi.maptrek.plugins.action.INITIALIZE");

// enumerate plugins with preferences
plugins = packageManager.queryIntentActivities(new Intent("mobi.maptrek.plugins.preferences"), 0);
for (ResolveInfo plugin : plugins) {
Intent intent = new Intent();
intent.setClassName(plugin.activityInfo.packageName, plugin.activityInfo.name);
mPluginPreferences.put(plugin.activityInfo.loadLabel(packageManager).toString(), intent);
}

// enumerate plugins with views
plugins = packageManager.queryIntentActivities(new Intent("mobi.maptrek.plugins.tool"), 0);
for (ResolveInfo plugin : plugins) {
// get menu icon
Drawable icon = null;
try {
Resources resources = packageManager.getResourcesForApplication(plugin.activityInfo.applicationInfo);
int id = resources.getIdentifier("ic_menu_tool", "drawable", plugin.activityInfo.packageName);
if (id != 0)
icon = resources.getDrawable(id, mContext.getTheme());
} catch (Resources.NotFoundException | PackageManager.NameNotFoundException e) {
e.printStackTrace();
}

Intent intent = new Intent();
intent.setClassName(plugin.activityInfo.packageName, plugin.activityInfo.name);
Pair<Drawable, Intent> pair = new Pair<>(icon, intent);
mPluginTools.put(plugin.activityInfo.loadLabel(packageManager).toString(), pair);
}
}
}
38 changes: 38 additions & 0 deletions app/src/main/java/mobi/maptrek/util/ContextUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2022 Andrey Novikov
*
* This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation, either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

package mobi.maptrek.util;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;

import java.util.List;

public class ContextUtils {
public static void sendExplicitBroadcast(Context context, String action) {
PackageManager packageManager = context.getPackageManager();
Intent intent = new Intent(action);
List<ResolveInfo> plugins = packageManager.queryBroadcastReceivers(intent, 0);
for (ResolveInfo plugin : plugins) {
intent = new Intent(action);
intent.setClassName(plugin.activityInfo.packageName, plugin.activityInfo.name);
intent.setFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
context.sendBroadcast(intent);
}
}
}

0 comments on commit 310d5b7

Please sign in to comment.