简体   繁体   English

位置服务无法分段运行

[英]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. 收到的位置是0.0,因为在获取位置之前加载了View。 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. 您只需要更新LocationReceiver.onReceive方法即可在那里更新视图。 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 ;) 抱歉,现在只了解您的代码;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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