无法在棉花糖中获得用户的经纬度

时间:2017-01-12 12:05:12

标签: android google-maps currentlocation

我正在努力访问用户当前位置,并完成了本教程Current location和本教程Current Location。一切似乎都很好,但是TextView字段中没有出现纬度和经度。

这是我的代码

@Keep
public class edit_information extends Fragment implements AdapterView.OnItemSelectedListener, GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener, LocationListener, ResultCallback<LocationSettingsResult> {
    protected final static String TAG = "EditInformation";
    private static final int MY_PERMISSIONS_ACCESS_LOCATION = 1;
    private RadioGroup radioGroup;
    private RadioGroup musicRadioGroup;
    private RadioGroup decorRadioGroup;
    protected static final int REQUEST_CHECK_SETTINGS = 0x1;
    //The desired interval for location updates
    public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
    //The fastest rate for active location updates
    public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 2;
    //Keys for storing activity state in bundle
    protected static final String KEY_REQUESTING_LOCATION_UPDATES = "requesting-location-updates";
    protected static final String KEY_LOCATION = "location";
    protected static final String KEY_LAST_UPDATED_TIME_STRING = "last-updated-time-string";
    /*
    Provides entry point to Google play service
     */
    protected GoogleApiClient mGoogleApiClient;
    //Store parametrers for request to the FusedLocationProviderApi
    protected LocationRequest mLocationRequest;
    //location setting request
    protected LocationSettingsRequest mLocationSettingsRequest;
    protected Location mCurrentLocation;
    //UI
    protected TextView mLatitudeText;
    protected TextView mLongitudeText;
    protected Boolean mRequestingLocationUpdates;
    protected String mLastUpdateTime;

    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.edit_information, container, false);
        Spinner spinner = (Spinner) view.findViewById(R.id.spinner1);
        Spinner spinner2 = (Spinner) view.findViewById(R.id.spinner2);

        //Creating an array adapter using the string array and a default spinner layout
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(getContext(), R.array.hall_type, simple_spinner_item);
        ArrayAdapter<CharSequence> adapter1 = ArrayAdapter.createFromResource(getContext(), R.array.hall_size, simple_spinner_item);

        //Layout to choose the dropdown list
        adapter.setDropDownViewResource(simple_spinner_dropdown_item);
        adapter1.setDropDownViewResource(simple_spinner_dropdown_item);
        spinner.setAdapter(adapter);
        spinner2.setAdapter(adapter1);
        spinner.setOnItemSelectedListener(this);
        spinner2.setOnItemSelectedListener(this);
        radioGroup = (RadioGroup) view.findViewById(R.id.food_facility);
        musicRadioGroup = (RadioGroup) view.findViewById(R.id.music_facility);
        decorRadioGroup = (RadioGroup) view.findViewById(R.id.decor_facility);
        mLatitudeText = (TextView) view.findViewById(R.id.myLatitude);
        mLongitudeText = (TextView) view.findViewById(R.id.myLongitude);
        mRequestingLocationUpdates = false;
        mLastUpdateTime = "";
        updateValuesFromBundle(savedInstanceState);
        //Start the process of building GoogleApiClient, LocationRequest and LocationSettingRequest
        buildGoogleApiClient();
        createLocationRequest();
        buildLocationSettingsRequest();
        radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int checkedId) {
                switch (checkedId) {
                    case R.id.yes:
                        Toast.makeText(getContext(), "Yes", Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.may:
                        Toast.makeText(getContext(), "May be", Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.no:
                        Toast.makeText(getContext(), "No", Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        });
        musicRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {
                switch (i) {
                    case R.id.yesMusic:
                        Toast.makeText(getContext(), "Yes", Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.mayMusic:
                        Toast.makeText(getContext(), "May be", Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.noMusic:
                        Toast.makeText(getContext(), "No", Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        });
        decorRadioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(RadioGroup radioGroup, int i) {

                switch (i) {
                    case R.id.yesDecor:
                        Toast.makeText(getContext(), "Yes", Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.mayDecor:
                        Toast.makeText(getContext(), "May be", Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.noDecor:
                        Toast.makeText(getContext(), "No", Toast.LENGTH_SHORT).show();
                        break;
                }
            }
        });
        return view;
    }

    @Override
    public void onItemSelected(AdapterView<?> adapterView, View view, int i, long l) {
        Toast.makeText(adapterView.getContext(), "" + adapterView.getItemAtPosition(i).toString(), Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onNothingSelected(AdapterView<?> adapterView) {

    }

    private void updateValuesFromBundle(Bundle savedInstanceState) {
        if (savedInstanceState != null) {
            // Update the value of mRequestingLocationUpdates from the Bundle, and make sure that
            // the Start Updates and Stop Updates buttons are correctly enabled or disabled.
            if (savedInstanceState.keySet().contains(KEY_REQUESTING_LOCATION_UPDATES)) {
                mRequestingLocationUpdates = savedInstanceState.getBoolean(
                        KEY_REQUESTING_LOCATION_UPDATES);
            }

            // Update the value of mCurrentLocation from the Bundle and update the UI to show the
            // correct latitude and longitude.
            if (savedInstanceState.keySet().contains(KEY_LOCATION)) {
                // Since KEY_LOCATION was found in the Bundle, we can be sure that mCurrentLocation
                // is not null.
                mCurrentLocation = savedInstanceState.getParcelable(KEY_LOCATION);
            }

            // Update the value of mLastUpdateTime from the Bundle and update the UI.
            if (savedInstanceState.keySet().contains(KEY_LAST_UPDATED_TIME_STRING)) {
                mLastUpdateTime = savedInstanceState.getString(KEY_LAST_UPDATED_TIME_STRING);
            }
            updateUI();
        }
    }

    protected synchronized void buildGoogleApiClient() {
        Log.i(TAG, "Building GoogleApiClient");
        mGoogleApiClient = new GoogleApiClient.Builder(getContext())
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    protected void buildLocationSettingsRequest() {
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);
        mLocationSettingsRequest = builder.build();
    }

    protected void checkLocationSettings() {
        PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(
                        mGoogleApiClient,
                        mLocationSettingsRequest
                );
        result.setResultCallback(this);
    }

    @Override
    public void onResult(LocationSettingsResult locationSettingsResult) {
        final Status status = locationSettingsResult.getStatus();
        switch (status.getStatusCode()) {
            case LocationSettingsStatusCodes.SUCCESS:
                Log.i(TAG, "All location settings are satisfied.");
                startLocationUpdates();
                break;
            case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to" +
                        "upgrade location settings ");

                try {
                    // Show the dialog by calling startResolutionForResult(), and check the result
                    // in onActivityResult().
                    status.startResolutionForResult(getActivity(), REQUEST_CHECK_SETTINGS);
                } catch (IntentSender.SendIntentException e) {
                    Log.i(TAG, "PendingIntent unable to execute request.");
                }
                break;
            case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog " +
                        "not created.");
                break;
        }
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
            // Check for the integer request code originally supplied to startResolutionForResult().
            case REQUEST_CHECK_SETTINGS:
                switch (resultCode) {
                    case Activity.RESULT_OK:
                        Log.i(TAG, "User agreed to make required location settings changes.");
                        startLocationUpdates();
                        break;
                    case Activity.RESULT_CANCELED:
                        Log.i(TAG, "User chose not to make required location settings changes.");
                        break;
                }
                break;
        }
    }

    public void startUpdatesButtonHandler(View view) {
        checkLocationSettings();
    }
    public void stopUpdatesButtonHandler(View view) {
        // It is a good practice to remove location requests when the activity is in a paused or
        // stopped state. Doing so helps battery performance and is especially
        // recommended in applications that request frequent location updates.
        stopLocationUpdates();
    }

    protected void startLocationUpdates() {
        if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_FINE_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;
        }
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient,
                mLocationRequest,
                this
        ).setResultCallback(new ResultCallback<Status>() {
            @Override
            public void onResult(Status status) {
                mRequestingLocationUpdates = true;
            }
        });
    }

    private void updateUI() {
        updateLocationUI();
    }

    private void updateLocationUI() {
        if (mCurrentLocation != null) {
            mLatitudeText.setText(String.valueOf(mCurrentLocation.getLatitude()));
            mLongitudeText.setText(String.valueOf(mCurrentLocation.getLongitude()));
        }
    }

    @Override
    public void onStart() {
        super.onStart();
        mGoogleApiClient.connect();
    }

    @Override
    public void onResume() {
        super.onResume();
        // Within {@code onPause()}, we pause location updates, but leave the
        // connection to GoogleApiClient intact.  Here, we resume receiving
        // location updates if the user has requested them.
        if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
            startLocationUpdates();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        // Stop location updates to save battery, but don't disconnect the GoogleApiClient object.
        if (mGoogleApiClient.isConnected()) {
            stopLocationUpdates();
        }
    }

    protected void stopLocationUpdates() {
        // It is a good practice to remove location requests when the activity is in a paused or
        // stopped state. Doing so helps battery performance and is especially
        // recommended in applications that request frequent location updates.
        LocationServices.FusedLocationApi.removeLocationUpdates(
                mGoogleApiClient,
                this
        ).setResultCallback(new ResultCallback<Status>() {
            @Override
            public void onResult(Status status) {
                mRequestingLocationUpdates = false;
            }
        });
    }

    @Override
    public void onStop() {
        super.onStop();
        mGoogleApiClient.disconnect();
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onConnected(@Nullable Bundle bundle) {
        Log.i(TAG, "Connected to GoogleApiClient");

        // If the initial location was never previously requested, we use
        // FusedLocationApi.getLastLocation() to get it. If it was previously requested, we store
        // its value in the Bundle and check for it in onCreate(). We
        // do not request it again unless the user specifically requests location updates by pressing
        // the Start Updates button.
        //
        // Because we cache the value of the initial location in the Bundle, it means that if the
        // user launches the activity,
        // moves to a new location, and then changes the device orientation, the original location
        // is displayed as the activity is re-created.
        if (mCurrentLocation == null) {
            if (ActivityCompat.checkSelfPermission(getContext(), android.Manifest.permission.ACCESS_FINE_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;
            }
            mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
            updateLocationUI();
        }
    }
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_ACCESS_LOCATION: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    updateLocationUI();

                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.

                } else {

                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        Log.i(TAG, "Connection suspended");
    }

    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
        Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
    }

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onLocationChanged(Location location) {
        mCurrentLocation = location;
        mLastUpdateTime = DateFormat.getTimeInstance().format(new Date());
        updateLocationUI();
    }
    /**
     * Stores activity data in the Bundle.
     */
    public void onSaveInstanceState(Bundle savedInstanceState) {
        savedInstanceState.putBoolean(KEY_REQUESTING_LOCATION_UPDATES, mRequestingLocationUpdates);
        savedInstanceState.putParcelable(KEY_LOCATION, mCurrentLocation);
        savedInstanceState.putString(KEY_LAST_UPDATED_TIME_STRING, mLastUpdateTime);
        super.onSaveInstanceState(savedInstanceState);
    }
}

这些是我在清单文件中添加的权限

<uses-permission android:name = "android.permission.INTERNET" />
<uses-permission android:name = "android.permission.ACCESS_FINE_LOCATION" />


这是纬度和经度的xml代码

<TextView
        android:id="@+id/myLatitude"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="15sp"
        android:textColor="@color/cordinates_color"
        />
    <TextView
        android:id="@+id/myLongitude"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:textSize="15sp"
        android:textColor="@color/cordinates_color"
        />

我已在build.gradle应用级别添加此行并同步项目compile 'com.google.android.gms:play-services:10.0.1'

我已经能够连接到GoogleApiClient,但坐标不会出现。这是logcat的一瞥

01-29 14:49:31.395 10560-10560/com.example.luke.xyz I/EditInformation: Building GoogleApiClient
01-29 14:49:31.675 10560-10560/com.example.luke.xyz D/ViewRootImpl: #1 mView = android.widget.LinearLayout{2782c80 V.E...... ......I. 0,0-0,0}
01-29 14:49:31.715 10560-10616/com.example.luke.xyz D/mali_winsys: new_window_surface returns 0x3000,  [468x91]-format:1
01-29 14:49:31.755 10560-10560/com.example.luke.xyz I/EditInformation: Connected to GoogleApiClient
01-29 14:49:31.805 10560-10616/com.example.luke.xyz V/RenderScript: 0xdc179000 Launching thread(s), CPUs 8

我在Android Marshmallow上测试它。仍无法弄明白。
你能救我吗? 谢谢

5 个答案:

答案 0 :(得分:1)

询问这样的运行时权限:

// Here, thisActivity is the current activity
if (ContextCompat.checkSelfPermission(thisActivity,
                Manifest.permission.ACCESS_COURSE_L‌​OCATION)
        != PackageManager.PERMISSION_GRANTED) {

    // Should we show an explanation?
    if (ActivityCompat.shouldShowRequestPermissionRationale(thisActivity,
            Manifest.permission.ACCESS_COURSE_L‌​OCATION)) {

        // Show an explanation to the user *asynchronously* -- don't block
        // this thread waiting for the user's response! After the user
        // sees the explanation, try again to request the permission.

    } else {

        // No explanation needed, we can request the permission.

        ActivityCompat.requestPermissions(thisActivity,
                new String[]{Manifest.permission.ACCESS_COURSE_L‌​OCATION},
                MY_PERMISSIONS_REQUEST_LOCATION);

        // MY_PERMISSIONS_REQUEST_LOCATION is an
        // app-defined int constant. The callback method gets the
        // result of the request.
    }
}

然后:

@Override
public void onRequestPermissionsResult(int requestCode,
        String permissions[], int[] grantResults) {
    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_LOCATION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                // permission was granted, yay! Do the
                // contacts-related task you need to do.

            } else {

                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            return;
        }

        // other 'case' lines to check for other
        // permissions this app might request
    }
}

您可以在此处找到更多详细信息:https://developer.android.com/training/permissions/requesting.html

答案 1 :(得分:0)

转到设置&gt;应用&gt; Your_app ,在权限标签中,启用位置即可立即获取Marshmallow的输出。

答案 2 :(得分:0)

使用位置Permission - ACCESS_COARSE_LOCATION , ACCESS_FINE_LOCATION,同时使用Double LatLng

@Override
public void onConnected(@Nullable Bundle connectionHint) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

        if (ActivityCompat.checkSelfPermission
                (getContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                &&
                ActivityCompat.checkSelfPermission
                        (getContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
        {
            requestPermissions(new String[]{
                    Manifest.permission.ACCESS_COARSE_LOCATION,
                    Manifest.permission.ACCESS_FINE_LOCATION
            }, 1);
            return;

        }
    }
    else{
        Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if(mLastLocation!=null){
        mLatitudeText.setText(Double.parseDouble(mLastLocation.getLatitude()));
        mLongitudeText.setText(Double.parseDouble(mLastLocation.getLongitude()));
        }else {
              Toast.makeText(getContext(),"LOcation is null",Toast.LENGTH_SHORT).show();
              }

    }

}

处理请求Permission

  @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    switch (requestCode) {

        case 1:
            if (grantResults[0] != PackageManager.PERMISSION_GRANTED){
                Toast.makeText(getContext(),"PERMISSION_GRANTED",Toast.LENGTH_SHORT).show();
              }
              else {
                    Toast.makeText(getContext(),"PERMISSION_GRANTED",Toast.LENGTH_SHORT).show();
              }
           break;
       }
  }

答案 3 :(得分:0)

您的编码很好,您只需要为清单文件添加更多权限

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.LOCATION_HARDWARE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>


确保您的gps已启用。如果这可以解决您的问题,请告诉我。

答案 4 :(得分:0)

您目前只询问onConnected中的最后一个已知位置。如果没有缓存位置,则不执行任何操作。

一旦您的Google API客户端连接,您应该覆盖onLocationChanged以接收当前位置。 https://developer.android.com/training/location/receive-location-updates.html#callback

GoogleApiClient.connect方法是异步的。在上面链接的文档中,位置更新请求是在GoogleApiClient连接后进行的。您是在onResume内提出此请求,但不保证GoogleApiClientonConnected之前已连接。在onConnected中发出请求,如文档中的示例所示。