1. Download our Official Android App: Forums for Android!

Where should LocationManager be placed in MVP?

Discussion in 'Android Development' started by twopelu, Oct 29, 2018.

  1. twopelu

    twopelu Lurker
    Thread Starter
    Rank:
    None
    Points:
    5
    Posts:
    7
    Joined:
    Oct 29, 2018

    Oct 29, 2018
    7
    0
    5
    Im refactoring my messy Activity code to a MVP architecture, but Im not sure where to put LocationManager and permission checks...any help please? Thanks, Dani

     

    Advertisement

  2. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,656
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,656
    11,072
    1,988
    Male
    Software developer
    South West of England
    The logical place for that would be in the model, which contains the business logic, and database access components.
     
  3. twopelu

    twopelu Lurker
    Thread Starter
    Rank:
    None
    Points:
    5
    Posts:
    7
    Joined:
    Oct 29, 2018

    Oct 29, 2018
    7
    0
    5
    Thanks form your response!

    Thats what I did at first time, the only problem I see is that the Model gets coupled with permissions API of Android SDK and you have to provide methods in all layers of the MVP to show and check permissions, isnt it? Any way to gently solve this?
     
  4. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,656
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,656
    11,072
    1,988
    Male
    Software developer
    South West of England
    Sometimes a consequence of having a layered architecture, is the need for 'pass through' methods. But without seeing your code, I can't really say anything very specific. Can you provide some sample code to illustrate the problems you're having?
     
  5. twopelu

    twopelu Lurker
    Thread Starter
    Rank:
    None
    Points:
    5
    Posts:
    7
    Joined:
    Oct 29, 2018

    Oct 29, 2018
    7
    0
    5
    Yes of course, I don't have the code now at home but I will try to give you a specific example of the problem I'm facing with the MVP:

    LocationManager requires to check location permissions just before calling the method (or supress warning with annotation), so the decision on where to put it in the MVP is not straightforward.

    This code used to be in my Activity and worked fine having the Context and all the SDK Android imports available:

    1. Inside onCreate() method of the Activity I ask for permissions:

    Code (Java):
    1. private void checkPermissions() {
    2.         Log.i(TAG, "ACCESS_FINE_LOCATION check");
    3.         if (ContextCompat.checkSelfPermission(this,
    4.                 Manifest.permission.ACCESS_FINE_LOCATION)
    5.                 != PackageManager.PERMISSION_GRANTED) {
    6.             Log.i(TAG, "ACCESS_FINE_LOCATION request");
    7.             if (ActivityCompat.shouldShowRequestPermissionRationale(this,
    8.                     Manifest.permission.ACCESS_FINE_LOCATION)) {
    9.                 showRequestPermission(REQUEST_CODE_LOCATION);
    10.             } else {
    11.                 ActivityCompat.requestPermissions(this,
    12.                         new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
    13.                         REQUEST_CODE_LOCATION);
    14.             }
    15.         } else {
    16.             Log.i(TAG, "ACCESS_FINE_LOCATION granted");
    17.         }
    18. }
    2. The callback returns the result of the permission check later:

    Code (Java):
    1. @Override
    2.     public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    3.         switch (requestCode) {
    4.             case REQUEST_CODE_LOCATION: {
    5.                 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    6.                     Log.i(TAG, "ACCESS_FINE_LOCATION granted");
    7.  
    8.                     if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
    9.                         if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
    10.                             Log.i(TAG, "GPS provider enabled");
    11.                         } else {
    12.                             Log.i(TAG, "GPS provider disabled");
    13.                         }
    14.  
    15.                         Log.i(TAG, "Listening to location updates...");
    16.                         locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 10, locationListener);
    17.                     }
    18.                 } else {
    19.                     Log.i(TAG, "ACCESS_FINE_LOCATION denied");
    20.                 }
    21.                 return;
    22.             }
    23.         }
    24.     }
    When triying to deocuple things with MVP architecture I decided leaving the permissions-related code in the Activity and moving LocationManager to the Model (is that even a good decision? what other choices are?):

    Code (Java):
    1. if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
    2.            Log.i(TAG, "Listening to location updates...");
    3.            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME, MIN_DISTANCE, locationListener);
    4. }
    To avoid checking permissions in the Model I have to: 1) provide a pass-through methods in the Presenter so that the View can call the requestLocation() of the Model when the permission is granted and 2) either supress warnings (Annotation) or wrap with a try-catch in the requestLocation() call in the Model to avoid compilation error.

    I have considered aadding pass-through methods to check permissions, moving permissions and LocationManager to the Presenter, encapsulate LocationManager with a Helper class and some others options, but none of them feel good to me. It ends up being everything coupled with Android SDK and / or with dirty interfaces for the VMP layers.

    Code (Java):
    1. try {
    2.            Log.i(TAG, "Listening to location updates...");
    3.            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME, MIN_DISTANCE, locationListener);
    4. } catch (SecurityException se) {
    5.            se.printStackTrace();
    6. }
    The decision on where to put the permissions-realated code, how to manage permissions in Presenter and Model and where to put the calls to Android SDK services or managers seems to be a bit arbitrary depending on which article / post you read. Also, some of them say that no Android SDK code or imports can be placed in Presenter or Model in the benefit of testability (or purity), but I find that the result is lots of boilerplate and pass-through methods.

    To be honest, I have not been able to find two articles / posts that are consistent with the approach on how to handle these things in MVP and none of them cover the problem in detail ("it depends"). The Android Developers page does not give any guidance on this either... :-(

    P.S. Thanks for your help and apologies for the long post! ;-)
     
  6. twopelu

    twopelu Lurker
    Thread Starter
    Rank:
    None
    Points:
    5
    Posts:
    7
    Joined:
    Oct 29, 2018

    Oct 29, 2018
    7
    0
    5
  7. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,656
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,656
    11,072
    1,988
    Male
    Software developer
    South West of England
    I'm not really surprised you haven't found much guidance on this, because I've looked for exactly the kind of information you require, and found it lacking. Basically, this isn't an exact science, and there are a multitude of different ways you can structure your code.
    Rather than get hung up on patterns - and honestly, if you're tying yourself in knots trying to massage the code into a prescribed architectural pattern, then that leads me to question if it's the right approach.
    I tend to apply some basic principles when I'm trying to come up with a software architecture:

    - I try to write my code in such a way that it makes testing easy. Testing is a much neglected part of software development, and quite often it's not done properly.
    - Program to the interface. Interfaces are a great way of decoupling your classes, and providing lots of flexibility in your design.
    - Keep things cohesive. That means not mixing a lot of different functionality in the same class. If a class is called DBHelper, then it should only be concerned with database stuff.
    - Aim for loose coupling - that is all about reducing the dependencies between classes. There's a great pattern that can help you with this, it's called 'Dependency Injection'.

    But really, Android apps are heavily UI based, so a lot time your code revolves around Activities, and responding to user input. With the apps I've built, I didn't really feel the need to construct a complicated architecture.

    When you say you moved the LocationManager to the 'model', what do you mean by that? What constitutes the 'model' in your application?
    Maybe if you placed your code in a Github repo we could get some more context around the code fragments you've presented. Because it's a little difficult to visualise the full picture.

    Note: I just saw your most recent post while writing this response. I'll have a look at the article.
     
    twopelu likes this.
  8. twopelu

    twopelu Lurker
    Thread Starter
    Rank:
    None
    Points:
    5
    Posts:
    7
    Joined:
    Oct 29, 2018

    Oct 29, 2018
    7
    0
    5
    Thanks again! Yes, I will try to share the code tomorrow so you can see the whole thing.

    And many thanks for your useful advice also, I totally agree, I think I should be more pragmatic and less purist with this hehe.

    I have a background (+10 years) in Java with similar architecture patterns, in those cases a simple MVC with DI fits perfectly.

    But in this case with Android it all feels a bit akward hehe :-S
     
  9. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,656
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,656
    11,072
    1,988
    Male
    Software developer
    South West of England
    I think some applications fit so naturally with MVC. Web applications in particular were made for that pattern, no question about it.
    But do put your code up on Github, and if I get some time, I'll look over it.
     
  10. twopelu

    twopelu Lurker
    Thread Starter
    Rank:
    None
    Points:
    5
    Posts:
    7
    Joined:
    Oct 29, 2018

    Oct 29, 2018
    7
    0
    5
    The Model in my app is only a class that stores some values in memory, such as the current location and a list of alerts, and encapsulates the calls to LocationManager. Here is where the coupling with Android SDK ocurrs. The Model has a reference to the Presenter to notify changes in data that have to be represented on the View (in my case, the Activity).
     
  11. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,656
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,656
    11,072
    1,988
    Male
    Software developer
    South West of England
    Ah right, I see what you mean. Yes I sometimes found myself passing around references to a Context (Activity) in another class, so it could update the UI. I was never totally comfortable with that approach, but I just lived with it, as I couldn't really see a cleaner way of doing it.
     
    twopelu likes this.
  12. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,656
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,656
    11,072
    1,988
    Male
    Software developer
    South West of England
  13. twopelu

    twopelu Lurker
    Thread Starter
    Rank:
    None
    Points:
    5
    Posts:
    7
    Joined:
    Oct 29, 2018

    Oct 29, 2018
    7
    0
    5

Share This Page

Loading...