user7025727
user7025727

Reputation: 1

Wait for Retrofit API to update before creating Android fragment view

I'm trying to use geolocation to get the lat/lon coordinates and use them to fetch weather data using an API, but the android view finishes before it can update the coordinates. It ends up using 0.0 by default, and that gets passed into the API link. What method could I use to either force the thread to wait or perhaps update the view once the coordinates are returned?

public class Frag1 extends Fragment  {
    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";
    OnHeadlineSelectedListener callback;
    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    private OnFragmentInteractionListener mListener;

    private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
    private static final String COURSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION;
    private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
    private Boolean mLocationPermissionsGranted = false;
    private FusedLocationProviderClient mFusedLocationProviderClient;
    public Button sendButton;
    TextView  description, tempTextView, cityNameTextView, humidityTextView, pressureTextView, windSpeedTextView;;
    private WebView MapsView;

    ImageView weatherIcon;

    public Frag1() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment Frag1.
     */
    // TODO: Rename and change types and number of parameters
    public static Frag1 newInstance(String param1, String param2) {
        Frag1 fragment = new Frag1();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);

        }


    }

    public void setOnHeadlineSelectedListener(OnHeadlineSelectedListener callback) {
        this.callback = callback;
    }
    // This interface can be implemented by the Activity, parent Fragment,
    // or a separate test implementation.
    public interface OnHeadlineSelectedListener {

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View v = inflater.inflate(R.layout.fragment_frag1, container, false);
        sendButton = v.findViewById(R.id.sendButton);
        pressureTextView = v.findViewById(R.id.pressureTextView);
        windSpeedTextView = v.findViewById(R.id.windSpeedTextView);
        humidityTextView = v.findViewById(R.id.humidityTextView);
        cityNameTextView = v.findViewById(R.id.cityNameTextView);
        description = v.findViewById(R.id.descriptionTextView);
        tempTextView = v.findViewById(R.id.tempTextView);

        ((MainActivity)getActivity()).getLocationPermission();
        ((MainActivity)getActivity()).getDeviceLocation();

        //final WeatherForcast forcast = retrofit.create(WeatherForcast.class);

        return v;
    }

    // TODO: Rename method, update argument and hook method into UI event
    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onViewCreated(@NonNull final View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl("https://api.openweathermap.org")
                .addConverterFactory(JacksonConverterFactory.create())
                .build();
        final WeatherService service = retrofit.create(WeatherService.class);
            Call<WeatherOutputData> callRequest = service.getWeatherInfo(Double.toString(lat), Double.toString(lon), "imperial", "API_ID");

            callRequest.enqueue(new Callback<WeatherOutputData>() {
                @Override
                public void onResponse(Call<WeatherOutputData> call, Response<WeatherOutputData> response) {
                    WeatherOutputData data = response.body();

                    cityNameTextView.setText(data.getName());
                    tempTextView.setText(data.getMain().getTemp() + "°F");
                    description.setText("Clouds: " + data.getWeather().get(0).getDescription());
                    humidityTextView.setText("Humidity: " + data.getMain().getHumidity() + "%");
                    pressureTextView.setText("Pressure: " + data.getMain().getPressure() + "ppi");
                    windSpeedTextView.setText("Wind Speed: " + data.getWind().getSpeed() + " MPH");
                    String icon = data.getWeather().get(0).getIcon();
                    String iconUrl = "http://openweathermap.org/img/w/" + icon + ".png";
                    //Picasso.get().load(iconUrl).into(weatherIcon);
                }

                @Override
                public void onFailure(Call<WeatherOutputData> call, Throwable t) {
                    Log.d("null", t.getMessage());
                }
            });
        }


    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    /**
     * This interface must be implemented by activities that contain this
     * fragment to allow an interaction in this fragment to be communicated
     * to the activity and potentially other fragments contained in that
     * activity.
     * <p>
     * See the Android Training lesson <a href=
     * "http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        // TODO: Update argument type and name
        void onFragmentInteraction(Uri uri);
    }
}
public class MainActivity extends AppCompatActivity implements Frag1.OnHeadlineSelectedListener {
    private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
    private static final String COURSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION;
    private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
    private Boolean mLocationPermissionsGranted = false;
    private FusedLocationProviderClient mFusedLocationProviderClient;
    public static double lat, lon;

    public FragmentRefreshListener getFragmentRefreshListener() {
        return fragmentRefreshListener;
    }

    public void setFragmentRefreshListener(FragmentRefreshListener fragmentRefreshListener) {
        this.fragmentRefreshListener = fragmentRefreshListener;
    }

    private FragmentRefreshListener fragmentRefreshListener;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        getLocationPermission();
        getDeviceLocation();

        SectionsPagerAdapter sectionsPagerAdapter = new SectionsPagerAdapter(this, getSupportFragmentManager());
        ViewPager viewPager = findViewById(R.id.view_pager);
        viewPager.setAdapter(sectionsPagerAdapter);
        TabLayout tabs = findViewById(R.id.tabs);
        tabs.setupWithViewPager(viewPager);
        FloatingActionButton fab = findViewById(R.id.fab);



    }
    public void onAttachFragment(Fragment fragment) {
        if (fragment instanceof Frag1) {
            Frag1 headlinesFragment = (Frag1) fragment;
            headlinesFragment.setOnHeadlineSelectedListener(this);
        }
    }
    public interface FragmentRefreshListener{
        void onRefresh();
    }

    public void getDeviceLocation(){
        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
        try{
            if(mLocationPermissionsGranted){
                final Task location = mFusedLocationProviderClient.getLastLocation();
                location.addOnCompleteListener(new OnCompleteListener() {
                    @Override
                    public void onComplete(@NonNull Task task) {
                        if(task.isSuccessful()){
                                Log.d("YAY", "GOT LOCATION");
                                Location currentLocation = (Location) task.getResult();
                                lat = currentLocation.getLatitude();
                                lon = currentLocation.getLongitude();

                        }else{
                            Log.d("null", "onComplete: current location is null");
                        }
                    }
                });
            }
        }catch (SecurityException e){
            Log.e("tag", "getDeviceLocation: SecurityException: " + e.getMessage() );
        }
    }

    public void getLocationPermission(){
        Log.d("tag", "getLocationPermission: getting location permissions");
        String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.ACCESS_COARSE_LOCATION};

        if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
                FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
            if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
                    COURSE_LOCATION) == PackageManager.PERMISSION_GRANTED){
                mLocationPermissionsGranted = true;

            }else{
                ActivityCompat.requestPermissions(this,
                        permissions,
                        LOCATION_PERMISSION_REQUEST_CODE);
            }
        }else{
            ActivityCompat.requestPermissions(this,
                    permissions,
                    LOCATION_PERMISSION_REQUEST_CODE);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        Log.d("tag", "onRequestPermissionsResult: called.");
        boolean mLocationPermissionsGranted = false;

        switch(requestCode){
            case LOCATION_PERMISSION_REQUEST_CODE:{
                if(grantResults.length > 0){
                    for(int i = 0; i < grantResults.length; i++){
                        if(grantResults[i] != PackageManager.PERMISSION_GRANTED){
                            mLocationPermissionsGranted = false;
                            Log.d("tag", "onRequestPermissionsResult: permission failed");
                            return;
                        }
                    }
                    Log.d("tag", "onRequestPermissionsResult: permission granted");
                    mLocationPermissionsGranted = true;
                }
            }
        }
    }
}

Upvotes: 0

Views: 208

Answers (1)

Bruce Wayne
Bruce Wayne

Reputation: 485

Looks like a job for RXJava, then you can proceed on success or show some error on failure.

Upvotes: 0

Related Questions