mirror of
https://github.com/commons-app/apps-android-commons.git
synced 2025-10-27 21:03:54 +01:00
Fix memory leak(s). (#2674)
This commit is contained in:
parent
d1ae88ca8b
commit
351109440f
6 changed files with 24 additions and 37 deletions
|
|
@ -1,6 +1,5 @@
|
||||||
package fr.free.nrw.commons.category;
|
package fr.free.nrw.commons.category;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
|
@ -22,12 +21,10 @@ import fr.free.nrw.commons.R;
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class GridViewAdapter extends ArrayAdapter {
|
public class GridViewAdapter extends ArrayAdapter {
|
||||||
private Context context;
|
|
||||||
private List<Media> data;
|
private List<Media> data;
|
||||||
|
|
||||||
public GridViewAdapter(Context context, int layoutResourceId, List<Media> data) {
|
public GridViewAdapter(Context context, int layoutResourceId, List<Media> data) {
|
||||||
super(context, layoutResourceId, data);
|
super(context, layoutResourceId, data);
|
||||||
this.context = context;
|
|
||||||
this.data = data;
|
this.data = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -81,8 +78,7 @@ public class GridViewAdapter extends ArrayAdapter {
|
||||||
public View getView(int position, View convertView, ViewGroup parent) {
|
public View getView(int position, View convertView, ViewGroup parent) {
|
||||||
|
|
||||||
if (convertView == null) {
|
if (convertView == null) {
|
||||||
LayoutInflater inflater = ((Activity) context).getLayoutInflater();
|
convertView = LayoutInflater.from(getContext()).inflate(R.layout.layout_category_images, null);
|
||||||
convertView = inflater.inflate(R.layout.layout_category_images, null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Media item = data.get(position);
|
Media item = data.get(position);
|
||||||
|
|
@ -102,7 +98,7 @@ public class GridViewAdapter extends ArrayAdapter {
|
||||||
*/
|
*/
|
||||||
private void setAuthorView(Media item, TextView author) {
|
private void setAuthorView(Media item, TextView author) {
|
||||||
if (!TextUtils.isEmpty(item.getCreator())) {
|
if (!TextUtils.isEmpty(item.getCreator())) {
|
||||||
String uploadedByTemplate = context.getString(R.string.image_uploaded_by);
|
String uploadedByTemplate = getContext().getString(R.string.image_uploaded_by);
|
||||||
|
|
||||||
String uploadedBy = String.format(Locale.getDefault(), uploadedByTemplate, item.getCreator());
|
String uploadedBy = String.format(Locale.getDefault(), uploadedByTemplate, item.getCreator());
|
||||||
author.setText(uploadedBy);
|
author.setText(uploadedBy);
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,7 @@ public class ContributionsFragment
|
||||||
@Inject NearbyController nearbyController;
|
@Inject NearbyController nearbyController;
|
||||||
@Inject OkHttpJsonApiClient okHttpJsonApiClient;
|
@Inject OkHttpJsonApiClient okHttpJsonApiClient;
|
||||||
@Inject CampaignsPresenter presenter;
|
@Inject CampaignsPresenter presenter;
|
||||||
|
@Inject LocationServiceManager locationManager;
|
||||||
|
|
||||||
private ArrayList<DataSetObserver> observersWaitingForLoad = new ArrayList<>();
|
private ArrayList<DataSetObserver> observersWaitingForLoad = new ArrayList<>();
|
||||||
private UploadService uploadService;
|
private UploadService uploadService;
|
||||||
|
|
@ -105,8 +106,6 @@ public class ContributionsFragment
|
||||||
private LatLng curLatLng;
|
private LatLng curLatLng;
|
||||||
|
|
||||||
private boolean firstLocationUpdate = true;
|
private boolean firstLocationUpdate = true;
|
||||||
public LocationServiceManager locationManager;
|
|
||||||
|
|
||||||
private boolean isFragmentAttachedBefore = false;
|
private boolean isFragmentAttachedBefore = false;
|
||||||
private View checkBoxView;
|
private View checkBoxView;
|
||||||
private CheckBox checkBox;
|
private CheckBox checkBox;
|
||||||
|
|
@ -496,7 +495,6 @@ public class ContributionsFragment
|
||||||
@Override
|
@Override
|
||||||
public void onResume() {
|
public void onResume() {
|
||||||
super.onResume();
|
super.onResume();
|
||||||
locationManager = new LocationServiceManager(getActivity());
|
|
||||||
|
|
||||||
firstLocationUpdate = true;
|
firstLocationUpdate = true;
|
||||||
locationManager.addLocationListener(this);
|
locationManager.addLocationListener(this);
|
||||||
|
|
@ -546,7 +544,7 @@ public class ContributionsFragment
|
||||||
|
|
||||||
private void checkLocationPermission() {
|
private void checkLocationPermission() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
if (locationManager.isLocationPermissionGranted()) {
|
if (locationManager.isLocationPermissionGranted(requireContext())) {
|
||||||
nearbyNotificationCardView.permissionType = NearbyNotificationCardView.PermissionType.NO_PERMISSION_NEEDED;
|
nearbyNotificationCardView.permissionType = NearbyNotificationCardView.PermissionType.NO_PERMISSION_NEEDED;
|
||||||
locationManager.registerLocationManager();
|
locationManager.registerLocationManager();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -638,8 +636,6 @@ public class ContributionsFragment
|
||||||
getChildFragmentManager().removeOnBackStackChangedListener(this);
|
getChildFragmentManager().removeOnBackStackChangedListener(this);
|
||||||
locationManager.unregisterLocationManager();
|
locationManager.unregisterLocationManager();
|
||||||
locationManager.removeLocationListener(this);
|
locationManager.removeLocationListener(this);
|
||||||
// Try to prevent a possible NPE
|
|
||||||
locationManager.context = null;
|
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
|
|
||||||
if (isUploadServiceConnected) {
|
if (isUploadServiceConnected) {
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ package fr.free.nrw.commons.contributions;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.cursoradapter.widget.CursorAdapter;
|
import androidx.cursoradapter.widget.CursorAdapter;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
@ -20,14 +22,12 @@ class ContributionsListAdapter extends CursorAdapter {
|
||||||
|
|
||||||
private final ContributionDao contributionDao;
|
private final ContributionDao contributionDao;
|
||||||
private UploadService uploadService;
|
private UploadService uploadService;
|
||||||
private Context context;
|
|
||||||
|
|
||||||
public ContributionsListAdapter(Context context,
|
public ContributionsListAdapter(Context context,
|
||||||
Cursor c,
|
Cursor c,
|
||||||
int flags,
|
int flags,
|
||||||
ContributionDao contributionDao) {
|
ContributionDao contributionDao) {
|
||||||
super(context, c, flags);
|
super(context, c, flags);
|
||||||
this.context = context;
|
|
||||||
this.contributionDao = contributionDao;
|
this.contributionDao = contributionDao;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -53,12 +53,12 @@ class ContributionsListAdapter extends CursorAdapter {
|
||||||
new DisplayableContribution.ContributionActions() {
|
new DisplayableContribution.ContributionActions() {
|
||||||
@Override
|
@Override
|
||||||
public void retryUpload() {
|
public void retryUpload() {
|
||||||
ContributionsListAdapter.this.retryUpload(contribution);
|
ContributionsListAdapter.this.retryUpload(view.getContext(), contribution);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteUpload() {
|
public void deleteUpload() {
|
||||||
ContributionsListAdapter.this.deleteUpload(contribution);
|
ContributionsListAdapter.this.deleteUpload(view.getContext(), contribution);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
views.bindModel(context, displayableContribution);
|
views.bindModel(context, displayableContribution);
|
||||||
|
|
@ -68,7 +68,7 @@ class ContributionsListAdapter extends CursorAdapter {
|
||||||
* Retry upload when it is failed
|
* Retry upload when it is failed
|
||||||
* @param contribution contribution to be retried
|
* @param contribution contribution to be retried
|
||||||
*/
|
*/
|
||||||
private void retryUpload(Contribution contribution) {
|
private void retryUpload(@NonNull Context context, Contribution contribution) {
|
||||||
if (NetworkUtils.isInternetConnectionEstablished(context)) {
|
if (NetworkUtils.isInternetConnectionEstablished(context)) {
|
||||||
if (contribution.getState() == STATE_FAILED
|
if (contribution.getState() == STATE_FAILED
|
||||||
&& uploadService!= null) {
|
&& uploadService!= null) {
|
||||||
|
|
@ -87,7 +87,7 @@ class ContributionsListAdapter extends CursorAdapter {
|
||||||
* Delete a failed upload attempt
|
* Delete a failed upload attempt
|
||||||
* @param contribution contribution to be deleted
|
* @param contribution contribution to be deleted
|
||||||
*/
|
*/
|
||||||
private void deleteUpload(Contribution contribution) {
|
private void deleteUpload(@NonNull Context context, Contribution contribution) {
|
||||||
if (NetworkUtils.isInternetConnectionEstablished(context)) {
|
if (NetworkUtils.isInternetConnectionEstablished(context)) {
|
||||||
if (contribution.getState() == STATE_FAILED) {
|
if (contribution.getState() == STATE_FAILED) {
|
||||||
Timber.d("Deleting failed contrib %s", contribution.toString());
|
Timber.d("Deleting failed contrib %s", contribution.toString());
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,8 @@ import android.location.Location;
|
||||||
import android.location.LocationListener;
|
import android.location.LocationListener;
|
||||||
import android.location.LocationManager;
|
import android.location.LocationManager;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
import androidx.core.app.ActivityCompat;
|
import androidx.core.app.ActivityCompat;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
|
@ -26,13 +28,12 @@ public class LocationServiceManager implements LocationListener {
|
||||||
private static final long MIN_LOCATION_UPDATE_REQUEST_TIME_IN_MILLIS = 2 * 60 * 100;
|
private static final long MIN_LOCATION_UPDATE_REQUEST_TIME_IN_MILLIS = 2 * 60 * 100;
|
||||||
private static final long MIN_LOCATION_UPDATE_REQUEST_DISTANCE_IN_METERS = 10;
|
private static final long MIN_LOCATION_UPDATE_REQUEST_DISTANCE_IN_METERS = 10;
|
||||||
|
|
||||||
public Context context;
|
|
||||||
private LocationManager locationManager;
|
private LocationManager locationManager;
|
||||||
private Location lastLocation;
|
private Location lastLocation;
|
||||||
//private Location lastLocationDuplicate; // Will be used for nearby card view on contributions activity
|
//private Location lastLocationDuplicate; // Will be used for nearby card view on contributions activity
|
||||||
private final List<LocationUpdateListener> locationListeners = new CopyOnWriteArrayList<>();
|
private final List<LocationUpdateListener> locationListeners = new CopyOnWriteArrayList<>();
|
||||||
private boolean isLocationManagerRegistered = false;
|
private boolean isLocationManagerRegistered = false;
|
||||||
public Set<Activity> locationExplanationDisplayed = new HashSet<>();
|
private Set<Activity> locationExplanationDisplayed = new HashSet<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new instance of LocationServiceManager.
|
* Constructs a new instance of LocationServiceManager.
|
||||||
|
|
@ -40,7 +41,6 @@ public class LocationServiceManager implements LocationListener {
|
||||||
* @param context the context
|
* @param context the context
|
||||||
*/
|
*/
|
||||||
public LocationServiceManager(Context context) {
|
public LocationServiceManager(Context context) {
|
||||||
this.context = context;
|
|
||||||
this.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
this.locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -57,7 +57,7 @@ public class LocationServiceManager implements LocationListener {
|
||||||
* Returns whether the location permission is granted.
|
* Returns whether the location permission is granted.
|
||||||
* @return true if the location permission is granted
|
* @return true if the location permission is granted
|
||||||
*/
|
*/
|
||||||
public boolean isLocationPermissionGranted() {
|
public boolean isLocationPermissionGranted(@NonNull Context context) {
|
||||||
return ContextCompat.checkSelfPermission(context,
|
return ContextCompat.checkSelfPermission(context,
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
|
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
|
||||||
}
|
}
|
||||||
|
|
@ -101,8 +101,8 @@ public class LocationServiceManager implements LocationListener {
|
||||||
* @return last known LatLng
|
* @return last known LatLng
|
||||||
*/
|
*/
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
public LatLng getLKL() {
|
public LatLng getLKL(@NonNull Context context) {
|
||||||
if (isLocationPermissionGranted()) {
|
if (isLocationPermissionGranted(context)) {
|
||||||
Location lastKL = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
|
Location lastKL = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
|
||||||
if (lastKL == null) {
|
if (lastKL == null) {
|
||||||
lastKL = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
|
lastKL = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
|
||||||
|
|
@ -225,6 +225,7 @@ public class LocationServiceManager implements LocationListener {
|
||||||
*/
|
*/
|
||||||
public void unregisterLocationManager() {
|
public void unregisterLocationManager() {
|
||||||
isLocationManagerRegistered = false;
|
isLocationManagerRegistered = false;
|
||||||
|
locationExplanationDisplayed.clear();
|
||||||
try {
|
try {
|
||||||
locationManager.removeUpdates(this);
|
locationManager.removeUpdates(this);
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException e) {
|
||||||
|
|
|
||||||
|
|
@ -572,7 +572,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
|
||||||
*/
|
*/
|
||||||
private void registerLocationUpdates() {
|
private void registerLocationUpdates() {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
if (locationManager.isLocationPermissionGranted()) {
|
if (locationManager.isLocationPermissionGranted(requireContext())) {
|
||||||
locationManager.registerLocationManager();
|
locationManager.registerLocationManager();
|
||||||
} else {
|
} else {
|
||||||
// Should we show an explanation?
|
// Should we show an explanation?
|
||||||
|
|
@ -666,7 +666,7 @@ public class NearbyFragment extends CommonsDaggerSupportFragment
|
||||||
private void checkLocationPermission() {
|
private void checkLocationPermission() {
|
||||||
Timber.d("Checking location permission");
|
Timber.d("Checking location permission");
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||||
if (locationManager.isLocationPermissionGranted()) {
|
if (locationManager.isLocationPermissionGranted(requireContext())) {
|
||||||
refreshView(LOCATION_SIGNIFICANTLY_CHANGED);
|
refreshView(LOCATION_SIGNIFICANTLY_CHANGED);
|
||||||
} else {
|
} else {
|
||||||
// Should we show an explanation?
|
// Should we show an explanation?
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,6 @@ import timber.log.Timber;
|
||||||
* Custom card view for nearby notification card view on main screen, above contributions list
|
* Custom card view for nearby notification card view on main screen, above contributions list
|
||||||
*/
|
*/
|
||||||
public class NearbyNotificationCardView extends SwipableCardView {
|
public class NearbyNotificationCardView extends SwipableCardView {
|
||||||
|
|
||||||
private Context context;
|
|
||||||
|
|
||||||
private Button permissionRequestButton;
|
private Button permissionRequestButton;
|
||||||
private LinearLayout contentLayout;
|
private LinearLayout contentLayout;
|
||||||
private TextView notificationTitle;
|
private TextView notificationTitle;
|
||||||
|
|
@ -37,21 +34,18 @@ public class NearbyNotificationCardView extends SwipableCardView {
|
||||||
|
|
||||||
public NearbyNotificationCardView(@NonNull Context context) {
|
public NearbyNotificationCardView(@NonNull Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
this.context = context;
|
|
||||||
cardViewVisibilityState = CardViewVisibilityState.INVISIBLE;
|
cardViewVisibilityState = CardViewVisibilityState.INVISIBLE;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public NearbyNotificationCardView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
public NearbyNotificationCardView(@NonNull Context context, @Nullable AttributeSet attrs) {
|
||||||
super(context, attrs);
|
super(context, attrs);
|
||||||
this.context = context;
|
|
||||||
cardViewVisibilityState = CardViewVisibilityState.INVISIBLE;
|
cardViewVisibilityState = CardViewVisibilityState.INVISIBLE;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
public NearbyNotificationCardView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
public NearbyNotificationCardView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||||
super(context, attrs, defStyleAttr);
|
super(context, attrs, defStyleAttr);
|
||||||
this.context = context;
|
|
||||||
cardViewVisibilityState = CardViewVisibilityState.INVISIBLE;
|
cardViewVisibilityState = CardViewVisibilityState.INVISIBLE;
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
@ -60,7 +54,7 @@ public class NearbyNotificationCardView extends SwipableCardView {
|
||||||
* Initializes views and action listeners
|
* Initializes views and action listeners
|
||||||
*/
|
*/
|
||||||
private void init() {
|
private void init() {
|
||||||
View rootView = inflate(context, R.layout.nearby_card_view, this);
|
View rootView = inflate(getContext(), R.layout.nearby_card_view, this);
|
||||||
|
|
||||||
permissionRequestButton = rootView.findViewById(R.id.permission_request_button);
|
permissionRequestButton = rootView.findViewById(R.id.permission_request_button);
|
||||||
contentLayout = rootView.findViewById(R.id.content_layout);
|
contentLayout = rootView.findViewById(R.id.content_layout);
|
||||||
|
|
@ -79,7 +73,7 @@ public class NearbyNotificationCardView extends SwipableCardView {
|
||||||
protected void onAttachedToWindow() {
|
protected void onAttachedToWindow() {
|
||||||
super.onAttachedToWindow();
|
super.onAttachedToWindow();
|
||||||
// If you don't setVisibility after getting layout params, then you will se an empty space in place of nearby NotificationCardView
|
// If you don't setVisibility after getting layout params, then you will se an empty space in place of nearby NotificationCardView
|
||||||
if (((MainActivity)context).defaultKvStore.getBoolean("displayNearbyCardView", true) && this.cardViewVisibilityState == NearbyNotificationCardView.CardViewVisibilityState.READY) {
|
if (((MainActivity)getContext()).defaultKvStore.getBoolean("displayNearbyCardView", true) && this.cardViewVisibilityState == NearbyNotificationCardView.CardViewVisibilityState.READY) {
|
||||||
this.setVisibility(VISIBLE);
|
this.setVisibility(VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
this.setVisibility(GONE);
|
this.setVisibility(GONE);
|
||||||
|
|
@ -88,14 +82,14 @@ public class NearbyNotificationCardView extends SwipableCardView {
|
||||||
|
|
||||||
|
|
||||||
private void setActionListeners() {
|
private void setActionListeners() {
|
||||||
this.setOnClickListener(view -> ((MainActivity)context).viewPager.setCurrentItem(1));
|
this.setOnClickListener(view -> ((MainActivity)getContext()).viewPager.setCurrentItem(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public boolean onSwipe(View view) {
|
@Override public boolean onSwipe(View view) {
|
||||||
view.setVisibility(GONE);
|
view.setVisibility(GONE);
|
||||||
// Save shared preference for nearby card view accordingly
|
// Save shared preference for nearby card view accordingly
|
||||||
((MainActivity) context).defaultKvStore.putBoolean("displayNearbyCardView", false);
|
((MainActivity) getContext()).defaultKvStore.putBoolean("displayNearbyCardView", false);
|
||||||
ViewUtil.showLongToast(context,
|
ViewUtil.showLongToast(getContext(),
|
||||||
getResources().getString(R.string.nearby_notification_dismiss_message));
|
getResources().getString(R.string.nearby_notification_dismiss_message));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue