【问题标题】:Call requires permissions that may be rejected by user呼叫需要可能被用户拒绝的权限
【发布时间】:2015-10-25 09:09:46
【问题描述】:

我正在尝试制作一个每五分钟发送一次用户位置更新的应用程序。我想我的代码工作得很好,但我收到有关应用程序正在使用的权限的错误。我很确定我已经在清单文件中添加了权限。有人可以告诉我有什么问题吗?这是我的代码。

MainActivity.java

LocationManager locationManager ;
String provider;

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

    // Getting LocationManager object
    locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

    // Creating an empty criteria object
    Criteria criteria = new Criteria();

    // Getting the name of the provider that meets the criteria
    provider = locationManager.getBestProvider(criteria, false);

    if(provider!=null && !provider.equals("")){

        // Get the location from the given provider
        Location location = locationManager.getLastKnownLocation(provider);
        locationManager.requestLocationUpdates(provider,5*60*1000,0,this);

        if(location!=null)
            onLocationChanged(location);
        else
            Toast.makeText(getBaseContext(), "Location can't be retrieved", Toast.LENGTH_SHORT).show();

    }else{
        Toast.makeText(getBaseContext(), "No Provider Found", Toast.LENGTH_SHORT).show();
    }
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;
}

@Override
public void onLocationChanged(Location location) {
    // Getting reference to TextView tv_longitude
    TextView tvLongitude = (TextView)findViewById(R.id.tv_longitude);

    // Getting reference to TextView tv_latitude
    TextView tvLatitude = (TextView)findViewById(R.id.tv_latitude);

    // Setting Current Longitude
    tvLongitude.setText("Longitude:" + location.getLongitude());

    // Setting Current Latitude
    tvLatitude.setText("Latitude:" + location.getLatitude() );
}

@Override
public void onProviderDisabled(String provider) {
    // TODO Auto-generated method stub
}

@Override
public void onProviderEnabled(String provider) {
    // TODO Auto-generated method stub
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
    // TODO Auto-generated method stub
}

}

我收到一个错误,因为 调用需要权限,这可能会被用户拒绝在这些行中 -

Location location = locationManager.getLastKnownLocation(provider);
        locationManager.requestLocationUpdates(provider,5*60*1000,0,this);

我的AndroidManifest是这样的

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

<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/title_activity_main" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

【问题讨论】:

    标签: android runtime-error locationmanager


    【解决方案1】:

    您使用哪个 SDK? 如果您使用 Marshmallow,则需要检查用户是否已授予每次定位调用的权限。

    看看Here.

    你应该这样做:

      if (ContextCompat.checkSelfPermission( this,android.Manifest.permission.ACCESS_COARSE_LOCATION ) != PackageManager.PERMISSION_GRANTED )
    {
        ActivityCompat.requestPermissions(
            this,
            new String [] { android.Manifest.permission.ACCESS_COARSE_LOCATION },
            LocationService.MY_PERMISSION_ACCESS_COURSE_LOCATION
        );
    }
    

    如果您还没有权限,请请求权限。

    查看上面的链接了解更多信息。

    【讨论】:

    • 我使用的是android 4.2及以上版本。
    • 你一定是用SDK 23编译的,没有其他解释。请检查您应用程序的 gradle 文件
    • 是的,你是对的!它正在使用 SDK 23 进行编译。感谢这解决了问题。
    • 嗯.. 这是什么“MY_PERMISSION_ACCESS_COURSE_LOCATION”?
    • 对不起,它写的是“这解决了问题”,但不是如何?应该修改什么文件以及如何修改?
    【解决方案2】:

    试试我的代码:

    public class MainActivity extends AppCompatActivity {
    
        /* GPS Constant Permission */
        private static final int MY_PERMISSION_ACCESS_COARSE_LOCATION = 11;
        private static final int MY_PERMISSION_ACCESS_FINE_LOCATION = 12;
    
        /* Position */
        private static final int MINIMUM_TIME = 10000;  // 10s
        private static final int MINIMUM_DISTANCE = 50; // 50m
    
        /* GPS */
        private String mProviderName;
        private LocationManager mLocationManager;
        private LocationListener mLocationListener;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            ...
    
            mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    
            // Get the best provider between gps, network and passive
            Criteria criteria = new Criteria();
            mProviderName = mLocationManager.getBestProvider(criteria, true);
    
            // API 23: we have to check if ACCESS_FINE_LOCATION and/or ACCESS_COARSE_LOCATION permission are granted
            if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                    || ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
    
                // No one provider activated: prompt GPS
                if (mProviderName == null || mProviderName.equals("")) {
                    startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                }
    
                // At least one provider activated. Get the coordinates
                switch (mProviderName) {
                    case "passive":
                        mLocationManager.requestLocationUpdates(mProviderName, MINIMUM_TIME, MINIMUM_DISTANCE, this);
                        Location location = mLocationManager.getLastKnownLocation(mProviderName);
                        break;
    
                    case "network":
                        break;
    
                    case "gps":
                        break;
    
                }
    
            // One or both permissions are denied.
            } else {
    
                // The ACCESS_COARSE_LOCATION is denied, then I request it and manage the result in
                // onRequestPermissionsResult() using the constant MY_PERMISSION_ACCESS_FINE_LOCATION
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
                    ActivityCompat.requestPermissions(this,
                            new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                            MY_PERMISSION_ACCESS_COARSE_LOCATION);
                }
                // The ACCESS_FINE_LOCATION is denied, then I request it and manage the result in
                // onRequestPermissionsResult() using the constant MY_PERMISSION_ACCESS_FINE_LOCATION
                if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
                    ActivityCompat.requestPermissions(this,
                            new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
                            MY_PERMISSION_ACCESS_FINE_LOCATION);
                }
    
            }
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
            switch (requestCode) {
                case MY_PERMISSION_ACCESS_COARSE_LOCATION: {
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        // permission was granted
                    } else {
                        // permission denied
                    }
                    break;
    
                case MY_PERMISSION_ACCESS_FINE_LOCATION: {
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        // permission was granted
                    } else {
                        // permission denied
                    }
                    break;
                }
    
            }
        }
    }
    

    来源:LINK

    【讨论】:

    • 你可以调用requestPermission 一次传递数组中的两个权限,
    • @ThiagoPorciúncula 我会尝试 :) 谢谢你的建议
    • 由于Permission groups,它实际上可能没有任何区别。当您获得ACCESS_FINE_LOCATION 的权限时,您将自动获得ACCESS_COARSE_LOCATION 的权限,因为它们属于同一组(LOCATION)。在此处查看更多信息:developer.android.com/intl/pt-br/training/permissions/…
    【解决方案3】:

    这对我有用

    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
       Toast.makeText(YourService.this, "First enable LOCATION ACCESS in settings.", Toast.LENGTH_LONG).show();
       return;
    }
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 100, 1, listener);
    

    【讨论】:

    • 这是对的,无论出于何种原因,如果您在请求位置时没有输入此确切代码,即使您以其他自定义方式管理权限,android studio 也会引发错误。
    【解决方案4】:

    以下是您需要执行的一系列步骤来解决此问题

    主要活动.java

    if (ContextCompat.checkSelfPermission(this,
     android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
     || ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) 
     == PackageManager.PERMISSION_GRANTED) {         
    locationManager.requestLocationUpdates
     (locationManager.requestLocationUpdates(provider,5*60*1000,0,this);
    }//end of if
    

    现在您还需要更新您的 build.gradle

    dependencies{
     ------------- //your pre-generated code
    compile 'com.android.support:support-v4:23.0.1'
    }
    

    this 是 Android.Developers 对它的评价。

    并且不要忘记在应用程序设置中授予权限 如果您使用的是模拟器,因为它可能不会提示此类

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-01-15
      • 1970-01-01
      • 2019-03-26
      • 1970-01-01
      • 2012-06-30
      相关资源
      最近更新 更多