簡體   English   中英

Android “gps 需要 ACCESS_FINE_LOCATION” 錯誤

[英]Android “gps requires ACCESS_FINE_LOCATION” error

我正在使用 SDK-23,每次運行應用程序時,我的SecurityException都會被拋出,調試器的錯誤如下所示:

java.lang.SecurityException:“gps”位置提供程序需要 ACCESS_COARSE_LOCATION 或 ACCESS_FINE_LOCATION 權限。

這似乎是一個簡單的錯誤,但是,我的清單文件是完全正確的。 在這里,這也是我的MapActivity代碼:

package com.buahbatu.salesmonitoring;



public class MainActivity extends AppCompatActivity implements View.OnClickListener {
final static String TAG = "MainActivity";
SwitchCompat switchTracked;
MyService service;
private GoogleMap googleMap;
Context mContext;
private TextView textAddress;


/* Google Fused Location Service */
public static GoogleApiClient mGoogleApiClient;
public static LocationRequest mLocationRequest;
public static GoogleApiClient.ConnectionCallbacks connectionCallbacks;
public static GoogleApiClient.OnConnectionFailedListener onConnectionFailedListener;
public final static int REQUEST_LOCATION = 199;
public final static int REQUEST_CONNECTION = 11;
public final static int NOTIFICATION_ID = 2;

private static final String[] INITIAL_PERMS={
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.READ_CONTACTS
};
private static final String[] LOCATION_PERMS={
        Manifest.permission.ACCESS_FINE_LOCATION
};


boolean checkPermission() {
    String location_fine = "android.permission.ACCESS_FINE_LOCATION";
    String location_coarse = "android.permission.ACCESS_COARSE_LOCATION";
    int permission_fine = mContext.checkCallingOrSelfPermission(location_fine);
    int permission_coarse = mContext.checkCallingOrSelfPermission(location_coarse);
    return permission_fine == PackageManager.PERMISSION_GRANTED && permission_coarse == PackageManager.PERMISSION_GRANTED;
}


public void startTracking(Activity activity) {
    if (checkPermission()) {
        Log.i(TAG, "startTracking");
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, (com.google.android.gms.location.LocationListener) this);
    } else {
        int permissionCheck = ContextCompat.checkSelfPermission(activity,
                Manifest.permission.ACCESS_FINE_LOCATION);
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    try {
        service.setUpdateView(null);
        initilizeMap();
    } catch (Exception e) {
        e.printStackTrace();
    }

}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    checkLoggedStatus();
    setSupportActionBar((Toolbar) findViewById(R.id.top_toolbar));
    ((TextView) findViewById(R.id.username_text)).setText(AppConfig.getUserName(this));
    switchTracked = (SwitchCompat) findViewById(R.id.tracked_switch);
    switchTracked.setOnCheckedChangeListener(onCheckedChangeListener);
    switchTracked.setChecked(AppConfig.getOnTracked(this));
    findViewById(R.id.test_but).setOnClickListener(this);
    textAddress = (TextView) findViewById(R.id.txtAddress);
}

CompoundButton.OnCheckedChangeListener onCheckedChangeListener = new CompoundButton.OnCheckedChangeListener() {
    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        if (!isChecked) {
            switchTracked.setText(R.string.untracked);
            service.stopTracking();
            AppConfig.saveOnTracked(MainActivity.this, false);
        } else {
            switchTracked.setText(R.string.tracked);
            service = AcaciaX.createService(getApplicationContext(), MyService.class);
            service.startTracking(MainActivity.this);
            service.setUpdateView((TextView) findViewById(R.id.location_text));
            AppConfig.saveOnTracked(MainActivity.this, true);
        }
    }
};

void checkLoggedStatus() {
    if (!AppConfig.getLoginStatus(this)) {
        moveToLogin();
    }
}

void moveToLogin() {
    Intent move = new Intent(this, LoginActivity.class);
    startActivity(move);
    finish();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    Log.d(TAG, Integer.toString(resultCode));

    //final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
    switch (requestCode) {
        case ServiceImpl.REQUEST_CONNECTION:
            switch (resultCode) {
                case Activity.RESULT_OK: {

                    switchTracked.setChecked(true);
                    break;
                }
                case Activity.RESULT_CANCELED: {

                    Toast.makeText(this, "Location not enabled, user cancelled.", Toast.LENGTH_LONG).show();
                    break;
                }
                default: {
                    break;
                }
            }
            break;
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_logout) {
        AppConfig.saveLoginStatus(this, false);
        AppConfig.storeAccount(this, "", "");
        switchTracked.setChecked(false);

        moveToLogin();
        return true;
    }

    return super.onOptionsItemSelected(item);
}

@Override
public void onClick(View v) {
    NetHelper.login(MainActivity.this, "Tester", "pasu", new PostWebTask.HttpConnectionEvent() {
        @Override
        public void preEvent() {

        }

        @Override
        public void postEvent(String... result) {

        }
    });

}

private void initilizeMap() {
    if (googleMap == null) {
        googleMap = ((MapFragment) getFragmentManager().findFragmentById(
                R.id.map)).getMap();
        setUpMap();

        // check if map is created successfully or not
        if (googleMap == null) {
            Toast.makeText(getApplicationContext(),
                    "Sorry! unable to create maps", Toast.LENGTH_SHORT)
                    .show();
        }
        if (googleMap != null) {
            //setUpMap();
        }
    }

}

@Override
protected void onResume() {
    super.onResume();
    initilizeMap();
    //googleMap.setMyLocationEnabled(true);
    setUpMap();
}

public void setUpMap() {
    if(checkPermission()) {
        googleMap.setMyLocationEnabled(true);
        LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
        Criteria criteria = new Criteria();
        String provider = locationManager.getBestProvider(criteria, true);
        Location location = locationManager.getLastKnownLocation(provider);

        CameraUpdate center = CameraUpdateFactory.newLatLng(new LatLng(location.getLatitude(), location.getLongitude()));
        CameraUpdate zoom = CameraUpdateFactory.zoomTo(15);

        googleMap.moveCamera(center);
        googleMap.animateCamera(zoom);

        Geocoder geocoder;
        List<Address> addresses;
        geocoder = new Geocoder(this, Locale.getDefault());

        try {
            addresses = geocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);

            if (addresses != null) {
                String address = addresses.get(0).getAddressLine(0);
                String city = addresses.get(0).getLocality();
                String state = addresses.get(0).getAdminArea();
                String country = addresses.get(0).getCountryName();
                String postalCode = addresses.get(0).getPostalCode();
                String knowName = addresses.get(0).getFeatureName();

                String addressfull = address + " " + city + " " + state + " " + country + " " + postalCode + " " + knowName;

                Intent intent = new Intent();
                intent.putExtra("addressfull", addressfull);
                textAddress.setText(addressfull);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }else{
        requestPermissions(INITIAL_PERMS, 2);
    }

}

}

如果您的目標是 Android M,則需要詢問用戶是否允許訪問設備 GPS。這是一個不太干凈的代碼,但可能會對您有所幫助。 更好的方法是創建您自己的權限管理器 class 來處理請求和 alertDialog 活動。

下面發生的是

1)您正在檢查是否授予權限。 2)如果沒有,您正在檢查權限是否之前被拒絕,在這種情況下,您正在展示一個理由,向用戶解釋為什么您需要權限。 3) 您使用 ActivityCompat 顯示請求權限彈出窗口。 4) 如果用戶拒絕,顯示帶有查看按鈕的快餐欄,將用戶帶到應用程序信息屏幕,每當您需要訪問 GPS 但注意未授予權限時。

if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_COARSE_LOCATION)) {
            showRationale();
        } else {
            // do request the permission
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 8);
        }
    }

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

    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ){
                //Start your code
            } else {
                //Show snackbar
            }
    }
}

private void showRationale(){
    String strDeleteMessage = getResources().getString(R.string.rationale_message11) ;

    final View dialogView = LayoutInflater.from(this.getActivity()).inflate(R.layout.dialog_fragment, null);

    final AlertDialog storageRationaleAlert = new AlertDialog.Builder(this.getActivity()).create();
    storageRationaleAlert.setView(dialogView, 0, 0, 0, 0);
    storageRationaleAlert.setCanceledOnTouchOutside(false);
    TextView mDialogTitle = (TextView) dialogView.findViewById(R.id.dialog_title);
    TextView mDialogDetails = (TextView) dialogView.findViewById(R.id.dialog_details);
    mDialogDetails.setVisibility(View.VISIBLE);
    Button mCancelButton = (Button) dialogView.findViewById(R.id.cancel_btn);
    Button mOkButton = (Button) dialogView.findViewById(R.id.ok_btn);
    mOkButton.setText(getString(R.string.dialog_continue));

    mDialogDetails.setText(Html.fromHtml(strDeleteMessage));

    final Activity activity = this.getActivity();
    mOkButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            storageRationaleAlert.dismiss();

            //Ask for GPS permission
        }
    });

    mCancelButton.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            storageRationaleAlert.dismiss();
            //Show permission snackbar
        }
    });

    storageRationaleAlert.show();
}

這是適合我的代碼:

  private void askForGeoPermissions(boolean _askGeo) throws InterruptedException {
    if (_askGeo) {
      for (int i = 0; i < 5; i++)
      {
        if (!String.valueOf(latitude).equals("0.0")) {
          break;
        }
        new SdkTrackingLocationUtils().checkGeolocationPermissions(this.context, getCurrentActivity());
        TimeUnit.SECONDS.sleep(2);
      }
    }
  }
protected void checkGeolocationPermissions(Context context, Activity activity)
  {
    try
    {
      if (ContextCompat.checkSelfPermission(activity, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
        && ContextCompat.checkSelfPermission(activity, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)
      {
        getLocation(context);
      }
      else
      {
        ActivityCompat.requestPermissions(activity, new String[] {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION }, 1);
      }
    }
    catch (Exception e)
    {
      Log.e("SDK_TRACKING_ERROR", e.getMessage());
    }
  }
  @SuppressLint("MissingPermission")
  protected Location getLocation(Context context)
  {
    try
    {
      locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
      isGPSEnabled    = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

      // getting network status
      isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
      if (isGPSEnabled == false && isNetworkEnabled == false)
      {
        Log.e("SDK_TRACKING_ERROR", "No network provider is enabled");
      }
      else
      {
        this.canGetLocation = true;
        if (isNetworkEnabled)
        {
          location = null;
          locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
          Log.d("Network", "Network");
          if (locationManager != null)
          {
            location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            if (location != null)
            {
              latitude  = location.getLatitude();
              longitude = location.getLongitude();
            }
          }
        }
        // if GPS Enabled get lat/long using GPS Services
        if (isGPSEnabled)
        {
          location = null;
          if (location == null)
          {
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
            Log.d("GPS Enabled", "GPS Enabled");
            if (locationManager != null)
            {
              location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
              if (location != null)
              {
                latitude  = location.getLatitude();
                longitude = location.getLongitude();
              }
            }
          }
        }
      }
    }
    catch (Exception e)
    {
      e.printStackTrace();
    }

    return location;
  }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM