简体   繁体   中英

Location Service doesn't work in fragment

I'm trying to get a location to show the three closest restaurants in a fragment.

The location should be get before load the View because the position of the resturants depends on the location.

/////////////////Fragment///////////////////

    private double latitude;
    private double longitude;
    private LocationReceiver locationReceiver;


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

        final View myFragmentView = inflater.inflate(R.layout.fragment_resturants, container, false);

        DataSource dataSource = new DataSource(getContext());
        final List<Restaurant> lista = dataSource.getThreeNearRestaurants(latitude, longitude);

        TextView nombre1 = (TextView) myFragmentView.findViewById(R.id.input_nombre1);
        TextView direccion1 = (TextView) myFragmentView.findViewById(R.id.input_direccion1);
        TextView ciudad1 = (TextView) myFragmentView.findViewById(R.id.input_ciudad1);
        TextView pais1 = (TextView) myFragmentView.findViewById(R.id.input_pais1);
        nombre1.setText(lista.get(0).getName());
        direccion1.setText(lista.get(0).getAddress());
        ciudad1.setText(lista.get(0).getCity());
        switch(lista.get(0).getCountry()){
            case "France":
                pais1.setText(R.string.france);
                break;
            case "Spain":
                pais1.setText(R.string.spain);
                break;
            case "Poland":
                pais1.setText(R.string.poland);
                break;
            case "Portugal":
                pais1.setText(R.string.portugal);
        }

        TextView nombre2 = (TextView) myFragmentView.findViewById(R.id.input_nombre2);
        TextView direccion2 = (TextView) myFragmentView.findViewById(R.id.input_direccion2);
        TextView ciudad2 = (TextView) myFragmentView.findViewById(R.id.input_ciudad2);
        TextView pais2 = (TextView) myFragmentView.findViewById(R.id.input_pais2);
        nombre2.setText(lista.get(1).getName());
        direccion2.setText(lista.get(1).getAddress());
        ciudad2.setText(lista.get(1).getCity());
        switch(lista.get(1).getCountry()){
            case "France":
                pais2.setText(R.string.france);
                break;
            case "Spain":
                pais2.setText(R.string.spain);
                break;
            case "Poland":
                pais2.setText(R.string.poland);
                break;
            case "Portugal":
                pais2.setText(R.string.portugal);
        }

        TextView nombre3 = (TextView) myFragmentView.findViewById(R.id.input_nombre3);
        TextView direccion3 = (TextView) myFragmentView.findViewById(R.id.input_direccion3);
        TextView ciudad3 = (TextView) myFragmentView.findViewById(R.id.input_ciudad3);
        TextView pais3 = (TextView) myFragmentView.findViewById(R.id.input_pais3);
        nombre3.setText(lista.get(2).getName());
        direccion3.setText(lista.get(2).getAddress());
        ciudad3.setText(lista.get(2).getCity());
        switch(lista.get(2).getCountry()) {
            case "France":
                pais3.setText(R.string.france);
                break;
            case "Spain":
                pais3.setText(R.string.spain);
                break;
            case "Poland":
                pais3.setText(R.string.poland);
                break;
            case "Portugal":
                pais3.setText(R.string.portugal);
        }

        CardView cardView1 = (CardView) myFragmentView.findViewById(R.id.card_view1);

        cardView1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                localizar(lista.get(0));
            }
        });

        CardView cardView2 = (CardView) myFragmentView.findViewById(R.id.card_view2);

        cardView2.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                localizar(lista.get(1));
            }
        });

        CardView cardView3 = (CardView) myFragmentView.findViewById(R.id.card_view3);

        cardView3.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                localizar(lista.get(2));
            }
        });

        return myFragmentView;
    }

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

        locationReceiver = new LocationReceiver();
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(LocationService.MY_ACTION);
        getActivity().registerReceiver(locationReceiver, intentFilter);

        Intent intent = new Intent(getContext(), LocationService.class);
        getActivity().startService(intent);


    }

    private void localizar(Restaurant restaurant) {
        Uri gmmIntentUri = Uri.parse("google.navigation:q=" + restaurant.getLatitude() + "," + restaurant.getLongitude());
        Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
        mapIntent.setPackage("com.google.android.apps.maps");
        startActivity(mapIntent);
    }

    private class LocationReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context arg0, Intent intent) {
            Bundle b = intent.getExtras();
            latitude = b.getDouble("latitude");
            longitude = b.getDouble("longitude");
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        getActivity().unregisterReceiver(locationReceiver);
    }

/////////////////LocationService///////////////////

public class LocationService extends Service {
    final static String MY_ACTION = "MY_ACTION";
    private LocationManager mLocationManager = null;
    private static final int LOCATION_INTERVAL = 1000;
    private static final float LOCATION_DISTANCE = 10f;
    private Location mLastLocation;

    private class LocationListener implements android.location.LocationListener {

        public LocationListener(String provider) {
            Log.e(TAG, "LocationListener " + provider);
            mLastLocation = new Location(provider);
        }

        @Override
        public void onLocationChanged(Location location) {
            Log.e(TAG, "onLocationChanged: " + location);

            mLastLocation.set(location);
        }

        @Override
        public void onProviderDisabled(String provider) {
            Log.e(TAG, "onProviderDisabled: " + provider);
        }

        @Override
        public void onProviderEnabled(String provider) {
            Log.e(TAG, "onProviderEnabled: " + provider);
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            Log.e(TAG, "onStatusChanged: " + provider);
        }
    }

    LocationListener[] mLocationListeners = new LocationListener[]{
            new LocationListener(LocationManager.GPS_PROVIDER),
            new LocationListener(LocationManager.NETWORK_PROVIDER)
    };

    @Override
    public IBinder onBind(Intent arg0) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.e(TAG, "onStartCommand");
        MyThread myThread = new MyThread();
        myThread.start();
        return  super.onStartCommand(intent, flags, startId);
//        return START_STICKY;
    }

    public class MyThread extends Thread {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            for (int i = 0; i < 10; i++) {
                try {
                    Thread.sleep(5000);
                    Intent intent = new Intent();
                    intent.setAction(MY_ACTION);

                    intent.putExtra("latitude", mLastLocation.getLatitude());
                    intent.putExtra("longitude", mLastLocation.getLongitude());

                    sendBroadcast(intent);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            stopSelf();
        }

    }

    @Override
    public void onCreate() {
        Log.e(TAG, "onCreate");
        initializeLocationManager();
        try {
            mLocationManager.requestLocationUpdates(
                    LocationManager.NETWORK_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                    mLocationListeners[1]);
        } catch (SecurityException ex) {
            Log.i(TAG, "fail to request location update, ignore", ex);
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "network provider does not exist, " + ex.getMessage());
        }
        try {
            mLocationManager.requestLocationUpdates(
                    LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
                    mLocationListeners[0]);
        } catch (SecurityException ex) {
            Log.i(TAG, "fail to request location update, ignore", ex);
        } catch (IllegalArgumentException ex) {
            Log.d(TAG, "gps provider does not exist " + ex.getMessage());
        }
    }

    @Override
    public void onDestroy() {
        Log.e(TAG, "onDestroy");
        super.onDestroy();
        if (mLocationManager != null) {
            for (LocationListener mLocationListener : mLocationListeners) {
                try {
                    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        // TODO: Consider calling
                        //    ActivityCompat#requestPermissions
                        // here to request the missing permissions, and then overriding
                        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                        //                                          int[] grantResults)
                        // to handle the case where the user grants the permission. See the documentation
                        // for ActivityCompat#requestPermissions for more details.
                        return;
                    }
                    mLocationManager.removeUpdates(mLocationListener);
                } catch (Exception ex) {
                    Log.i(TAG, "fail to remove location listners, ignore", ex);
                }
            }
        }
    }

    private void initializeLocationManager() {
        Log.e(TAG, "initializeLocationManager");
        if (mLocationManager == null) {
            mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        }
    }

The location received is 0.0 because the View load before getting the location. How can I solve it?

Thanks in advance

You're using the broadcasts, this would work as well. you just need to update the LocationReceiver.onReceive method to update the Views there. basically your saying "hey LocationService, get my restaurants. The LocationService Broadcasts it to you saying, hey you these are the restaurants. " And you're only storing the coordinates, but not refreshing the Views. you need to take into consideration that this process takes time, and your views will be already drawn. Just refresh all the views after receiving the broadcast. It will do it. Sorry, only understood your code now ;)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM