0

I need to retrieve user location in different screens of my application. I have written the code to get the location in one of screen activity, however, now I want to get the location in another screen activity too. Is there anything I can do to avoid writing the same code again?

        // variables
        // These variables will be repeated
        LocationProvider locationProvider;
        double latitude;
        double longitude;
        private String userPostcode;
        // ===============

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                      Bundle savedInstanceState) {

        // This code will be repeated
        locationProvider = new LocationProvider(getActivity());
        latitude = locationProvider.getLatitude();
        longitude = locationProvider.getLongitude();
        if (isNetworkAvailable(getContext())) {
            getPostcode();
        } else {
            Toast.makeText(getActivity(), "Internet or GPS is not available. To get the best location one or both of these must be on",
                    Toast.LENGTH_LONG).show();
        }
 // =============
        return inflater.inflate(R.layout.fragment_location, container, false);
    }




      // These two methods will be repeated
        private void getPostcode(){
                    Geocoder geoCoder = new Geocoder(getActivity().getApplicationContext(), Locale.getDefault());
                    List<Address> address = null;

                    if (geoCoder != null) {
                        try {
                            address = geoCoder.getFromLocation(latitude, longitude, 1);
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                        if (address.size() > 0) {
                            userPostcode = address.get(0).getPostalCode();
                        }
                    }
                }


            private boolean isNetworkAvailable(final Context context) {
                    final ConnectivityManager connectivityManager = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
                    return connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isConnected();
                }
    // ====================

If its possible to avoid repeating please can someone show me/show me how it can be done please. I am new to android and might have missed something stupid.

5 Answers 5

1

Add the getPostcode() in a seperate class. You may modify it as followed.

public class Utils {


    public static String getPostcode(Context context, double lat, double lng){
        Geocoder geoCoder = new Geocoder(context, Locale.getDefault());
        List<Address> address = null;

        if (geoCoder != null) {
            try {
                address = geoCoder.getFromLocation(lat, lng, 1);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            if (address.size() > 0) {
                return address.get(0).getPostalCode();
            }
        }
        return null;
    }


    public static boolean isNetworkAvailable(final Context context) {
        final ConnectivityManager connectivityManager = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
        return connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isConnected();
    }
}

in your fragment/activity do this

if(Utils.isNetworkAvailable(this)) {
            String postCode = Utils.getPostcode(this, yourLat, yourLng);
        }

change this to getActivity() if in Fragment.

Sign up to request clarification or add additional context in comments.

15 Comments

IS it possbile to return more then 1 result and then decide later on when calling the method which one to use. for example, I want to return lat and long also
Also, how can I call this in my fragment?
please see the edited post. for fragment you need to use getActivity() and for calling in activity you can simply pass this as context.
Do I need to define the latitude, longitude and userPostcode variables in my "YourClassName" because currently it giving me an error saying these are not foound.
you can define them inside the method. as you will later assign there values to hashMap, and then will get these values from hashMap inside the fragment.
|
1

Methods that just simply return some value, you need to reuse them often and are not tied to any object or state, you can make them static.

Create some kind of utility class. For example

public class Utils {

    public static boolean isNetworkAvailable(final Context context) {
        final ConnectivityManager connectivityManager = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
        return connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isConnected();
    }

    public static String getPostCode(Activity activity) {
        ...
    }
}

Then you can reuse it anywhere you like.

boolean isNetworkAvailable = Utils.isNetworkAvailable(context);

4 Comments

What about the variables I am using within the getPostcode method?
instead of calling getPostcode() you will call userPostCode = Utils.getPostcode(this); if you need to set multiple values in one call I suggest you follow the basic oop principles and create an object representing your data. In you case with String postCode, List<Address> etc
Does this go inside the If statement I have checking if user has i internet? if (isNetworkAvailable(getContext())) {
Also, how is the getPostCode being used?
1

Make new class file and put these below function in that class file

private String getPostcode(Activity activity, Double latitude, Double longitude) {
        String userPostcode = null;
        Geocoder geoCoder = new Geocoder(activity.getApplicationContext(), Locale.getDefault());
        List<Address> address = null;

        if (geoCoder != null) {
            try {
                address = geoCoder.getFromLocation(latitude, longitude, 1);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            if (address.size() > 0) {
                userPostcode = address.get(0).getPostalCode();
            }
        }
        return userPostcode;
    }

    private static boolean isNetworkAvailable(final Context context) {
        final ConnectivityManager connectivityManager = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
        return connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isConnected();
    }

To access these function create the object of that class and call these fucntion

Comments

1

You can create a utility class that does all the location work you want. Pass the activity/context object as a constructor parameter to the utility class. Then use the class methods to get what you want. Look at the following code for the utility class:

public class LocationHelper {
    private double mLatitude;
    private double mLongitude;
    private Context mContext;
    private LocationProvider mLocationProvider;

    // Dont know if you need Activity or Context object.
    // Pass whatever as per requirement
    public LocationHelper(Context context) {
        this.mContext = context;
        initLocation();
    }

    // Set the latitude and longitude here.
    // You can get the latitude and longitude using
    // getter methods.
    private void initLocation() {
        mLocationProvider = new LocationProvider(mContext);
        mLatitude = mLocationProvider.getLatitude();
        mLongitude = mLocationProvider.getLongitude();
    }

    public double getLatitude() {
        return mLatitude;
    }

    public double getLongitude() {
        return mLongitude;
    }

    // Get the post code as a string. Empty if failed to get any.
    public String getPostcode(){
        String userPostcode = "";
        Geocoder geoCoder = new Geocoder(mContext, Locale.getDefault());
        List<Address> address = null;

        //It is a redundant check since it will always be true
        if (geoCoder != null) {
            try {
                address = geoCoder.getFromLocation(mLatitude, mLongitude, 1);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            // Also make sure to put a null check to avoid NullPointerException
            if (address != null && address.size() > 0) {
                userPostcode = address.get(0).getPostalCode();
            }
        }
        return userPostcode;
    }

    //To check if device is offline/online.
    public boolean isNetworkAvailable() {
        final ConnectivityManager connectivityManager = ((ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE));
        return connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isConnected();
    }
}

2 Comments

is the method sNetworkAvailable() being used within this class? or do I need to call it in the fragment where I will be using the getpost?
This implementation requires you to call it in the fragment. If you want to just call one method which does the network check and returns the postCode then you can write a wrapper method in the LocationHelper class.
0

Yes, refractor into a separate class. Or find a way to get the data from one activity to an other. (putExtra(), Singleton, DataBase, SharedPreferences, etc)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.