[android] Review fixes

This commit is contained in:
Roman Romanov 2017-04-10 09:38:45 +04:00
parent c8e5145f58
commit bfa6a5ae8b
14 changed files with 179 additions and 126 deletions

View file

@ -252,7 +252,7 @@ android {
android.applicationVariants.all { variant ->
def task = variant.name.capitalize()
project.task(type: Exec, "run${task}", dependsOn: "install${task}") {
commandLine android.getAdbExe(), 'shell', 'am', 'start', '-n', "${applicationId}/com.mapswithme.maps.DownloadResourcesActivity"
commandLine android.getAdbExe(), 'shell', 'am', 'start', '-n', "${applicationId}/com.mapswithme.maps.SplashActivity"
}
variant.outputs.each { output ->

View file

@ -7,38 +7,23 @@ import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import com.mapswithme.maps.ads.LikesManager;
import com.mapswithme.maps.editor.ViralFragment;
import com.mapswithme.maps.location.LocationHelper;
import com.mapswithme.maps.news.BaseNewsFragment;
import com.mapswithme.maps.news.FirstStartFragment;
import com.mapswithme.maps.news.NewsFragment;
import com.mapswithme.util.Counters;
import com.mapswithme.util.PermissionsUtils;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.Utils;
import com.mapswithme.util.concurrency.UiThread;
import com.mapswithme.util.statistics.PushwooshHelper;
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.Manifest.permission.GET_ACCOUNTS;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
public class SplashActivity extends AppCompatActivity
implements BaseNewsFragment.NewsDialogListener
{
public static final String[] PERMISSIONS = new String[]
{
WRITE_EXTERNAL_STORAGE,
ACCESS_COARSE_LOCATION,
ACCESS_FINE_LOCATION,
GET_ACCOUNTS
};
public static final String EXTRA_INTENT = "extra_intent";
private static final String EXTRA_ACTIVITY_TO_START = "extra_activity_to_start";
private static final int REQUEST_PERMISSIONS = 1;
@ -59,7 +44,9 @@ public class SplashActivity extends AppCompatActivity
public void run()
{
init();
// Run delayed task because resumeDialogs() must be called after onPause()
// Run delayed task because resumeDialogs() must see the actual value of mCanceled flag,
// since onPause() callback can be blocked because of UI thread is busy with framework
// initialization.
UiThread.runLater(mFinalTask);
}
};
@ -103,11 +90,11 @@ public class SplashActivity extends AppCompatActivity
{
super.onResume();
mCanceled = false;
mPermissionsGranted = Utils.checkPermissions(this, PERMISSIONS);
mPermissionsGranted = PermissionsUtils.isExternalStorageGranted();
if (!mPermissionsGranted)
{
// TODO requestPermissions after Permissions dialog
ActivityCompat.requestPermissions(this, PERMISSIONS, REQUEST_PERMISSIONS);
PermissionsUtils.requestPermissions(this, REQUEST_PERMISSIONS);
return;
}
@ -180,16 +167,8 @@ public class SplashActivity extends AppCompatActivity
if (grantResults.length == 0)
return;
for (int i = 0; i < permissions.length; i++)
{
int result = grantResults[i];
String permission = permissions[i];
if (permission.equals(WRITE_EXTERNAL_STORAGE) && result == PERMISSION_GRANTED)
{
mPermissionsGranted = true;
break;
}
}
mPermissionsGranted = PermissionsUtils.computePermissionsResult(permissions, grantResults)
.isExternalStorageGranted();
if (mPermissionsGranted)
{

View file

@ -2,9 +2,7 @@ package com.mapswithme.maps.base;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.util.Utils;
public class BaseMwmFragment extends Fragment
@ -14,7 +12,7 @@ public class BaseMwmFragment extends Fragment
public void onAttach(Context context)
{
super.onAttach(context);
Utils.detachFragmentIfInitializing(context, this);
Utils.detachFragmentIfCoreNotInitialized(context, this);
}
@Override

View file

@ -18,6 +18,7 @@ import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
import com.mapswithme.maps.SplashActivity;
import com.mapswithme.util.Config;
import com.mapswithme.util.PermissionsUtils;
import com.mapswithme.util.ThemeUtils;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.Utils;
@ -53,7 +54,7 @@ public class BaseMwmFragmentActivity extends AppCompatActivity
protected void onCreate(@Nullable Bundle savedInstanceState)
{
if (!MwmApplication.get().isPlatformInitialized()
|| !Utils.checkPermissions(this, SplashActivity.PERMISSIONS))
|| !PermissionsUtils.isExternalStorageGranted())
{
super.onCreate(savedInstanceState);
goToSplashScreen();
@ -162,7 +163,7 @@ public class BaseMwmFragmentActivity extends AppCompatActivity
protected void onResume()
{
super.onResume();
if (!Utils.checkPermissions(this, SplashActivity.PERMISSIONS))
if (!PermissionsUtils.isExternalStorageGranted())
{
goToSplashScreen();
return;

View file

@ -2,13 +2,10 @@ package com.mapswithme.maps.base;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.ListFragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
import com.mapswithme.util.UiUtils;
import com.mapswithme.util.Utils;
@ -22,7 +19,7 @@ public abstract class BaseMwmListFragment extends ListFragment
public void onAttach(Context context)
{
super.onAttach(context);
Utils.detachFragmentIfInitializing(context, this);
Utils.detachFragmentIfCoreNotInitialized(context, this);
}
@Override

View file

@ -7,7 +7,6 @@ import android.support.annotation.LayoutRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
@ -15,7 +14,6 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.maps.R;
import com.mapswithme.maps.widget.PlaceholderView;
import com.mapswithme.util.UiUtils;
@ -45,7 +43,7 @@ public abstract class BaseMwmRecyclerFragment extends Fragment
public void onAttach(Context context)
{
super.onAttach(context);
Utils.detachFragmentIfInitializing(context, this);
Utils.detachFragmentIfCoreNotInitialized(context, this);
}
@Override

View file

@ -9,8 +9,6 @@ import android.support.annotation.Nullable;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.util.LocationUtils;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
@ -21,7 +19,6 @@ class AndroidNativeProvider extends BaseLocationProvider
private final static String TAG = AndroidNativeProvider.class.getSimpleName();
private final static String[] TRUSTED_PROVIDERS = { LocationManager.NETWORK_PROVIDER,
LocationManager.GPS_PROVIDER };
private final static Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.LOCATION);
@NonNull
private final LocationManager mLocationManager;
@ -34,6 +31,8 @@ class AndroidNativeProvider extends BaseLocationProvider
mLocationManager = (LocationManager) MwmApplication.get().getSystemService(Context.LOCATION_SERVICE);
}
@SuppressWarnings("MissingPermission")
// A permission is checked externally
@Override
protected void start()
{
@ -55,18 +54,8 @@ class AndroidNativeProvider extends BaseLocationProvider
long interval = LocationHelper.INSTANCE.getInterval();
LOGGER.d(TAG, "Request Android native provider '" + provider
+ "' to get locations at this interval = " + interval + " ms");
mLocationManager.requestLocationUpdates(provider, interval, 0, listener);
mListeners.add(listener);
try
{
mLocationManager.requestLocationUpdates(provider, interval, 0, listener);
}
catch (SecurityException e)
{
LOGGER.e(TAG, "Dynamic permission ACCESS_COARSE_LOCATION/ACCESS_FINE_LOCATION is not granted",
e);
setActive(false);
return;
}
}
LocationHelper.INSTANCE.startSensors();
@ -120,26 +109,20 @@ class AndroidNativeProvider extends BaseLocationProvider
expirationMillis);
}
@SuppressWarnings("MissingPermission")
// A permission is checked externally
@Nullable
private static Location findBestNotExpiredLocation(LocationManager manager, List<String> providers, long expirationMillis)
{
Location res = null;
try
for (final String pr : providers)
{
for (final String pr : providers)
{
final Location last = manager.getLastKnownLocation(pr);
if (last == null || LocationUtils.isExpired(last, last.getTime(), expirationMillis))
continue;
final Location last = manager.getLastKnownLocation(pr);
if (last == null || LocationUtils.isExpired(last, last.getTime(), expirationMillis))
continue;
if (res == null || res.getAccuracy() > last.getAccuracy())
res = last;
}
}
catch (SecurityException e)
{
LOGGER.e(TAG, "Dynamic permission ACCESS_COARSE_LOCATION/ACCESS_FINE_LOCATION is not granted",
e);
if (res == null || res.getAccuracy() > last.getAccuracy())
res = last;
}
return res;
}

View file

@ -123,24 +123,19 @@ class GoogleFusedLocationProvider extends BaseLocationProvider
LocationHelper.INSTANCE.start();
}
@SuppressWarnings("MissingPermission")
// A permission is checked externally
private void requestLocationUpdates()
{
if (!mGoogleApiClient.isConnected())
return;
try
{
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mListener);
LocationHelper.INSTANCE.startSensors();
Location last = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (last != null)
mListener.onLocationChanged(last);
}
catch (SecurityException e)
{
e.printStackTrace();
stop();
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, mListener);
LocationHelper.INSTANCE.startSensors();
Location last = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (last != null)
mListener.onLocationChanged(last);
}
@Override

View file

@ -16,9 +16,11 @@ import com.mapswithme.maps.routing.RoutingController;
import com.mapswithme.util.Config;
import com.mapswithme.util.Listeners;
import com.mapswithme.util.LocationUtils;
import com.mapswithme.util.PermissionsUtils;
import com.mapswithme.util.Utils;
import com.mapswithme.util.log.Logger;
import com.mapswithme.util.log.LoggerFactory;
import com.mapswithme.util.permissions.PermissionsResult;
public enum LocationHelper
{
@ -476,6 +478,12 @@ public enum LocationHelper
mLogger.d(TAG, "startInternal(), current provider is '" + mLocationProvider
+ "' , my position mode = " + LocationState.nameOf(getMyPositionMode())
+ ", mInFirstRun = " + mInFirstRun);
if (!PermissionsUtils.isLocationGranted())
{
mLogger.w(TAG, "Dynamic permission ACCESS_COARSE_LOCATION/ACCESS_FINE_LOCATION is not granted",
new Throwable());
return;
}
checkProviderInitialization();
//noinspection ConstantConditions
mLocationProvider.start();

View file

@ -42,13 +42,6 @@ public class AboutFragment extends BaseSettingsFragment
return R.layout.about;
}
// @Override
// protected BaseShadowController createShadowController()
// {
// clearPaddings();
// return new ScrollViewShadowController((ObservableScrollView) mFrame.findViewById(R.id.content_frame));
// }
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState)
{
@ -127,7 +120,6 @@ public class AboutFragment extends BaseSettingsFragment
case R.id.copyright:
Statistics.INSTANCE.trackEvent(Statistics.EventName.Settings.COPYRIGHT);
AlohaHelper.logClick(AlohaHelper.Settings.COPYRIGHT);
// getSettingsActivity().switchToFragment(CopyrightFragment.class, R.string.copyright);
getSettingsActivity().replaceFragment(CopyrightFragment.class,
getString(R.string.copyright), null);
break;

View file

@ -7,6 +7,7 @@ import android.support.v4.app.Fragment;
import android.support.v7.preference.Preference;
import android.support.v7.preference.PreferenceFragmentCompat;
import android.support.v7.preference.PreferenceScreen;
import android.support.v7.widget.Toolbar;
import android.text.TextUtils;
import com.mapswithme.maps.R;
@ -61,7 +62,8 @@ public class SettingsActivity extends BaseToolbarActivity
{
final int resId = getFragmentContentResId();
if (resId <= 0 || findViewById(resId) == null)
throw new IllegalStateException("Fragment can't be added, since getFragmentContentResId() isn't implemented or returns wrong resourceId.");
throw new IllegalStateException("Fragment can't be added, since getFragmentContentResId() " +
"isn't implemented or returns wrong resourceId.");
String name = fragmentClass.getName();
final Fragment fragment = Fragment.instantiate(this, name, args);
@ -71,10 +73,14 @@ public class SettingsActivity extends BaseToolbarActivity
.commitAllowingStateLoss();
getSupportFragmentManager().executePendingTransactions();
if(title != null)
if (title != null)
{
mLastTitle = getToolbar().getTitle().toString();
getToolbar().setTitle(title);
Toolbar toolbar = getToolbar();
if (toolbar != null && toolbar.getTitle() != null)
{
mLastTitle = toolbar.getTitle().toString();
toolbar.setTitle(title);
}
}
}

View file

@ -0,0 +1,94 @@
package com.mapswithme.util;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import com.mapswithme.maps.MwmApplication;
import com.mapswithme.util.permissions.PermissionsResult;
import java.util.HashMap;
import java.util.Map;
import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.Manifest.permission.GET_ACCOUNTS;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
public final class PermissionsUtils
{
private static final String[] PERMISSIONS = new String[]
{
WRITE_EXTERNAL_STORAGE,
ACCESS_COARSE_LOCATION,
ACCESS_FINE_LOCATION,
GET_ACCOUNTS
};
private PermissionsUtils() {}
@NonNull
public static PermissionsResult computePermissionsResult(@NonNull String[] permissions,
@NonNull int[] grantResults)
{
Map<String, Boolean> result = new HashMap<>();
for (int i = 0; i < permissions.length; i++)
{
result.put(permissions[i], grantResults[i] == PackageManager.PERMISSION_GRANTED);
}
return getPermissionsResult(result);
}
public static boolean isLocationGranted()
{
return checkPermissions().isLocationGranted();
}
public static boolean isExternalStorageGranted()
{
return checkPermissions().isExternalStorageGranted();
}
public static boolean isGetAccountsGranted()
{
return checkPermissions().isGetAccountsGranted();
}
@NonNull
private static PermissionsResult checkPermissions()
{
Context context = MwmApplication.get().getApplicationContext();
Map<String, Boolean> result = new HashMap<>();
for (String permission: PERMISSIONS)
{
result.put(permission,
Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|| context.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED);
}
return getPermissionsResult(result);
}
@NonNull
private static PermissionsResult getPermissionsResult(@NonNull Map<String, Boolean> result)
{
boolean externalStorageGranted = result.containsKey(WRITE_EXTERNAL_STORAGE)
? result.get(WRITE_EXTERNAL_STORAGE) : false;
boolean locationGranted = (result.containsKey(ACCESS_COARSE_LOCATION)
? result.get(ACCESS_COARSE_LOCATION) : false)
|| (result.containsKey(ACCESS_FINE_LOCATION)
? result.get(ACCESS_FINE_LOCATION) : false);
boolean getAccountsGranted = result.containsKey(GET_ACCOUNTS)
? result.get(GET_ACCOUNTS) : false;
return new PermissionsResult(externalStorageGranted, locationGranted, getAccountsGranted);
}
public static void requestPermissions(@NonNull Activity activity, int code)
{
ActivityCompat.requestPermissions(activity, PERMISSIONS, code);
}
}

View file

@ -14,7 +14,6 @@ import android.support.annotation.DimenRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringRes;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.Fragment;
import android.support.v4.app.NavUtils;
import android.support.v7.app.AlertDialog;
@ -43,8 +42,6 @@ import java.util.Currency;
import java.util.Locale;
import java.util.Map;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
public class Utils
{
private static final Logger LOGGER = LoggerFactory.INSTANCE.getLogger(LoggerFactory.Type.MISC);
@ -415,34 +412,8 @@ public class Utils
}
}
public static boolean checkPermissions(@NonNull Activity activity, @NonNull String[] permissions)
{
if (Build.VERSION.SDK_INT >= 23)
{
boolean isGranted = false;
for (String permission: permissions)
{
isGranted = activity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
if (!isGranted)
break;
}
return isGranted;
}
//permission is automatically granted on sdk<23 upon installation
return true;
}
public static boolean isWriteExternalGranted(@NonNull Activity activity)
{
if (Build.VERSION.SDK_INT >= 23)
return activity.checkSelfPermission(WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
return true;
}
public static void detachFragmentIfInitializing(@NonNull Context context,
@NonNull Fragment fragment)
public static void detachFragmentIfCoreNotInitialized(@NonNull Context context,
@NonNull Fragment fragment)
{
if (context instanceof AppCompatActivity && !MwmApplication.get().isPlatformInitialized())
{

View file

@ -0,0 +1,31 @@
package com.mapswithme.util.permissions;
public final class PermissionsResult
{
private final boolean mExternalStorageGranted;
private final boolean mLocationGranted;
private final boolean mGetAccountsGranted;
public PermissionsResult(boolean externalStorageGranted, boolean locationGranted,
boolean getAccountsGranted)
{
mExternalStorageGranted = externalStorageGranted;
mLocationGranted = locationGranted;
mGetAccountsGranted = getAccountsGranted;
}
public boolean isExternalStorageGranted()
{
return mExternalStorageGranted;
}
public boolean isLocationGranted()
{
return mLocationGranted;
}
public boolean isGetAccountsGranted()
{
return mGetAccountsGranted;
}
}