错误:客户端必须具有ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION [英] Error: Client must have ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION

查看:1095
本文介绍了错误:客户端必须具有ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在另一个应用程序中使用了一个模块.在实现该模块之前,请像主项目一样在API级别23(编译和目标)上进行设置 除此错误外,此方法工作正常.问题是,自marshmellow以来,Google已更改了权限管理.最后,现在,我不知道如何以及在何处设置权限.

I use a module in a another app. Before I implement the module, I set it on API Level 23 (compile and target) like my Main Project This works fine, except this Error. The Pproblem is, that Google has changed the permissions management since marshmellow. Finaly now, i dont know how and where I should set the permissions.

启动应用程序时出现此错误:

This error I get when starting the application:

java.lang.SecurityException:客户端必须具有ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION权限才能执行任何操作位置.

java.lang.SecurityException: Client must have ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission to perform any operations location.

请您帮助我并简要说明一下(我需要哪种代码以及在何处插入),以避免出现此错误?

Could you please help me and explain briefly (what kind of code i need and where to insert) to avoid this error?

来自模块的清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.cs.android.weminder">

<!--

android:versionCode="3"
android:versionName="1.2.0" >


<uses-sdk
    android:minSdkVersion="9"
    android:targetSdkVersion="19" />

    -->

<!-- Grant the network access permission -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"           />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- Grant the location access permission -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Allows using PowerManager WakeLocks to keep processor from sleeping or screen from dimming -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- Permission required to use Alarm Manager -->
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
<uses-permission android:name="android.permission.GET_TASKS" />

<application
    android:allowBackup="true"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">

    <!--    android:name="com.cs.android.weminder.MyApplication"
            android:label="@string/app_name">-->

    <!-- This meta-data tag is required to use Google Play Services. -->
    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
    <!-- Required for creating dialog of the ACRA report -->
    <activity
        android:name="org.acra.CrashReportDialog"
        android:excludeFromRecents="true"
        android:finishOnTaskLaunch="true"
        android:launchMode="singleInstance"
        android:theme="@style/AcraDialog" />
    <activity
        android:name="com.cs.android.weminder.MainActivity"
        android:launchMode="singleTop"
        android:screenOrientation="portrait" >

        <action android:name="android.intent.action.MAIN" />

        <category android:name="android.intent.category.LAUNCHER" />

    </activity>
    <activity android:name="com.cs.android.weminder.BaseScreen" />
    <activity android:name="com.cs.android.weminder.LocationBaseScreen" />
    <activity android:name="com.cs.android.weminder.SettingsActivity" />
    <activity android:name="com.cs.android.weminder.WeminderApplication" />


    <!-- Required by the AdMob Ads SDK -->



    <activity
        android:name="com.google.ads.AdActivity"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize" />
    <!-- Include the AdActivity configChanges and theme. -->
    <activity
        android:name="com.google.android.gms.ads.AdActivity"
        android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"
        android:theme="@android:style/Theme.Translucent" />


    <receiver
        android:name="com.cs.android.weminder.AlarmReceiver"
        android:process=":remote" >
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
        </intent-filter>
    </receiver>

    <service android:name="com.cs.android.weminder.AlarmService" >
    </service>
</application>

Modul的主要活动:

Main Activity from the Modul:

public class MainActivity extends SettingsActivity implements ActionTypes,
    ResultType {




private TextView tvLocation, tvHTemp, tvLTemp, tvCurrentTemp, tvTimestamp,
        tvDate, tvWindSpeed, tvPressure;
private ImageView ivCurrentWeather, ivRefresh, ivUnit, ivSearch, ivRemind,
        ivMyLocation;
private HorizontalViewGallery forecastGallery;
// Search field
private MyCustomEditText etSearch;

// holding different weather icons presenting weather condition
// alternatively.
private IconFinder mIconFinder;

private ApiCallQueue requestsQueue = new ApiCallQueue();

// Ads View
private AdView adView;





private void setupUI(View view) {
    // Set up touch listener for non-text box views to hide keyboard.
    if (!(view instanceof EditText)) {
        view.setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                // Hide the search field if the user is touching anywhere
                // except the search field
                if (etSearch.isShown()) {
                    etSearch.startDeflation();
                    return true;
                }
                return false;
            }
        });
    }

    // If a layout container, iterate over children and seed recursion.
    if (view instanceof ViewGroup) {
        for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) {
            View innerView = ((ViewGroup) view).getChildAt(i);
            setupUI(innerView);
        }
    }
}

/**
 * Initial the UI of current screen Initial variables;
 */
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private void initialActivity() {
    setupUI(findViewById(R.id.parent));
    // display the name of location
    tvLocation = (TextView) findViewById(R.id.tvLocation);
    // Set the location icon
    tvLocation.setCompoundDrawablesWithIntrinsicBounds(getResources()
            .getDrawable(R.drawable.icon_marker), null, null, null);
    // display today highest temperature
    tvHTemp = (TextView) findViewById(R.id.tvHTemp);
    // Set the highest temperature icon
    tvHTemp.setCompoundDrawablesWithIntrinsicBounds(getResources()
            .getDrawable(R.drawable.icon_highest), null, null, null);
    // display today lowest temperature
    tvLTemp = (TextView) findViewById(R.id.tvLTemp);
    // Set the lowest temperature icon
    tvLTemp.setCompoundDrawablesWithIntrinsicBounds(getResources()
            .getDrawable(R.drawable.icon_lowest), null, null, null);
    // display the current temperature
    tvCurrentTemp = (TextView) findViewById(R.id.tvCurrentTemp);
    // display the update time stamp
    tvTimestamp = (TextView) findViewById(R.id.tvTimestamp);
    // display the date of today
    tvDate = (TextView) findViewById(R.id.tvDate);
    // display the wind speed
    tvWindSpeed = (TextView) findViewById(R.id.tvWindSpeed);
    // Set wind speed icon
    tvWindSpeed.setCompoundDrawablesWithIntrinsicBounds(getResources()
            .getDrawable(R.drawable.icon_wind), null, null, null);
    // display the pressure
    tvPressure = (TextView) findViewById(R.id.tvPressure);
    // Set wind speed icon
    tvPressure.setCompoundDrawablesWithIntrinsicBounds(getResources()
            .getDrawable(R.drawable.icon_pressure), null, null, null);
    // visualize the current weather condition
    ivCurrentWeather = (ImageView) findViewById(R.id.ivCurrentWeather);
    // Scrollable forecast
    forecastGallery = (HorizontalViewGallery) findViewById(R.id.gForcast);
    // Search city button
    ivSearch = (ImageView) findViewById(R.id.ivSearch);
    // Setting button
    ivRemind = (ImageView) findViewById(R.id.ivRemind);
    // My location button
    ivMyLocation = (ImageView) findViewById(R.id.ivMyLocation);
    // Temp unit setting Button
    ivUnit = (ImageView) findViewById(R.id.ivUnit);
    if (getTempUnit().equals(PARAM_TEMP_UNIT_C))
        ivUnit.setImageDrawable(getResources().getDrawable(
                R.drawable.button_unit_f));
    else if (getTempUnit().equals(PARAM_TEMP_UNIT_F))
        ivUnit.setImageDrawable(getResources().getDrawable(
                R.drawable.button_unit_c));
    // Refresh button
    ivRefresh = (ImageView) findViewById(R.id.ivRefresh);
    // Search field
    etSearch = (MyCustomEditText) findViewById(R.id.etSearch);
    // set the animation of search field
    // Animation Duration in milliseconds;
    int duration = 500;
    // Inflate animation
    final AnimationSet inflate = new AnimationSet(true);
    ScaleAnimation scaleIn = new ScaleAnimation(0f, 1.0f, 1.0f, 1.0f,
            Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF,
            0.5f);
    scaleIn.setDuration(duration);
    inflate.addAnimation(scaleIn);
    inflate.setAnimationListener(new AnimationListener() {

        @Override
        public void onAnimationEnd(Animation animation) {
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
        }

        @Override
        public void onAnimationStart(Animation animation) {
            etSearch.setVisibility(View.VISIBLE);
            etSearch.requestFocus();
            showSoftKeyboard(etSearch);
        }
    });
    // Deflate animation
    final AnimationSet deflate = new AnimationSet(true);
    ScaleAnimation scaleDe = new ScaleAnimation(1.0f, 0f, 1.0f, 1.0f,
            Animation.RELATIVE_TO_SELF, 1.0f, Animation.RELATIVE_TO_SELF,
            0.5f);
    scaleDe.setDuration(duration);
    deflate.addAnimation(scaleDe);
    deflate.setAnimationListener(new AnimationListener() {

        @Override
        public void onAnimationEnd(Animation animation) {
            etSearch.setVisibility(View.INVISIBLE);
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
        }

        @Override
        public void onAnimationStart(Animation animation) {
            hideSoftKeyboard(etSearch);
        }
    });

    etSearch.setInflation(inflate);
    etSearch.setDeflation(deflate);

    // Running the change of digital clock on separate UI thread
    // to avoid any delay of other action on UI.
    runOnUiThread(new Runnable() {
        @Override
        public void run() {
            if (!Utils.androidMinimum(API_JELLY_BEAN_MR1)) {
                // Using the widget class {@code DigitalClock} if the
                // android api is less than 17
                DigitalClock dcClock = (DigitalClock) findViewById(R.id.dcClock);
                dcClock.addTextChangedListener(new TextWatcher() {

                    @Override
                    public void onTextChanged(CharSequence s, int start,
                            int before, int count) {
                    }

                    @Override
                    public void beforeTextChanged(CharSequence s,
                            int start, int count, int after) {
                    }

                    @Override
                    public void afterTextChanged(Editable s) {
                        // Removed seconds
                        if (s.length() >= 5) {
                            if (s.charAt(4) == ':') {
                                s.delete(4, s.length());
                            } else if (s.length() >= 6
                                    && s.charAt(5) == ':') {
                                s.delete(5, s.length());
                            }
                        }
                    }
                });
            } else {
                // Using the widget class {@code TextClock} if the android
                // api is greater than or equal to 17
                TextClock dcClock = (TextClock) findViewById(R.id.dcClock);
                dcClock.addTextChangedListener(new TextWatcher() {

                    @Override
                    public void onTextChanged(CharSequence s, int start,
                            int before, int count) {
                    }

                    @Override
                    public void beforeTextChanged(CharSequence s,
                            int start, int count, int after) {
                    }

                    @Override
                    public void afterTextChanged(Editable s) {
                        // Removed seconds
                        if (s.length() >= 5) {
                            if (s.charAt(4) == ':') {
                                s.delete(4, s.length());
                            } else if (s.length() >= 6
                                    && s.charAt(5) == ':') {
                                s.delete(5, s.length());
                            }
                        }
                    }
                });
            }
        }
    });

    mIconFinder = new IconFinder(this);
}

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




    /*
     * Create a new location client, using the enclosing class to handle
     * callbacks.
     */
    mLocationClient = new LocationClient(this, this, this);

    // Create the LocationRequest object
    mLocationRequest = LocationRequest.create();
    // Use high accuracy
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    // Set the update interval to 5 seconds
    mLocationRequest.setInterval(UPDATE_INTERVAL);
    // Set the fastest update interval to 1 second
    mLocationRequest.setFastestInterval(FASTEST_INTERVAL);

    setContentView(R.layout.activity_main);
    .
    .
    .

请您解释一下,管理新的权限系统的最佳方法是什么.请以简单的方式向我解释

Could you please explain, what is the best way to manage the new Permission-System. Please explain to me in a simple way

推荐答案

粗略位置和精细位置被认为是危险权限.必须在Android 6及更高版本上明确要求这些权限.这是解决问题的一种方法:

The coarse and fine location are considered dangerous permissions. These permissions have to be explicitly requested on Android 6 and up. Here's one way to go about it:

public void checkPermission(){
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ||
                       ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    ){//Can add more as per requirement

                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION},
                        123);
    }
}

并致电:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
    checkPermission();
}

您可以在任何地方实现它.您可以在首次启动时或在需要它们时请求它.

You can implement it anywhere. You can request it on the first launch, or whenever they're needed.

尽管如此,总是记住要在使用前检查您是否具有许可权.也可以在运行时撤消该权限,这将绕过启动时进行的所有检查.

Nonetheless, always remember to check whether you have the permission before using it. The permission can be revoked at runtime as well, which would bypass any checks you have on startup.

这是一种方法:

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

    /*
    This is called before initializing the map because the map needs permissions(the cause of the crash)
    */
    if (Build.VERSION.SDK_INT == Build.VERSION_CODES.M ) {
        checkPermission();
    }
    // Re-check before enabling. You can add an else statement to warn the user about the lack of functionality if it's disabled. 
    // "or" is used instead of "and" as per the error. If it requires both, flip it over to &&. (I'm not sure, I haven't used GPS stuff before)
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED ||
                   ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED){
        /*
         * Create a new location client, using the enclosing class to handle
         * callbacks.
         */
        mLocationClient = new LocationClient(this, this, this);

        // Create the LocationRequest object
        mLocationRequest = LocationRequest.create();
        // Use high accuracy
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        // Set the update interval to 5 seconds
        mLocationRequest.setInterval(UPDATE_INTERVAL);
        // Set the fastest update interval to 1 second
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
    }
    setContentView(R.layout.activity_main);
    .
    .
    .

这是我建议这样做的方式.还有其他处理权限的方法,但是无论选择哪种方法,都必须确保在访问依赖于危险权限的API之前检查是否具有权限.可以在运行时撤消权限,而不会触发销毁生命周期事件,因此可以绕过启动时进行的所有检查以确保您具有该权限.因此,在使用API​​之前进行检查非常重要.

This is the way I recommend doing it. There are other ways to deal with permissions, but no matter what you pick, do make sure you check whether you have the permission before accessing an API dependent on dangerous permissions. The permissions can be withdrawn at runtime without triggering the destroy lifecycle events, and therefore bypass any checks you have on startup to make sure you have the permissions. Because of that, checking before you use APIs is extremely important.

还有其他方法可以实现权限请求.如果您正在寻找这种超级基本启动检查的替代方法,请参考以下建议:

There's also other ways to implement permission requesting. If you're looking for alternatives to this super basic startup check, here's some ideas:

  • 如果您有设置活动,请向其添加请求权限.
  • 在启动时不请求权限,而是在需要权限时
  • 如果权限检查在启动时失败,请向您的启动流程添加一个权限请求活动

还有很多解决方法,比我所知道的要多.我已经有两年没有接触过Android了,而且我还不熟悉请求权限的所有方式.另请参阅文档,以获取最新的建议.

There's also more ways to go about this than I know if. I haven't touched Android in a couple years, and I'm far from familiar with all the ways to request permissions. See also the documentation for potentially more up to date advice.

这篇关于错误:客户端必须具有ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆