【问题标题】:Android GPS App (get user's location) - Permissions, not workingAndroid GPS App(获取用户的位置) - 权限,不起作用
【发布时间】:2016-04-03 13:21:53
【问题描述】:

我正在尝试制作一个简单的 Android GPS 应用来读取用户的当前位置。

在执行此操作时,我需要请求权限。我已经按照 Google 自己的 Android 页面上的教程进行操作。

我的应用程序启动良好,它达到了我需要开始请求权限的地步,然后它就不再工作了。

我在将文本打印到 textViews 的应用程序中放置了几个“调试消息”。 它只会在 onConnected() 方法中达到“1”。

任何线索我做错了什么?非常感谢!

这是我的 Activity Java 代码

    public class StartActivity extends AppCompatActivity implements ConnectionCallbacks, OnConnectionFailedListener {

    private Location mLastLocation;
    private boolean locationPermissionGoodToGo = false;

    private final int MY_PERMISSION_ACCESS_FINE_LOCATION = 1;

    // Google client to interact with Google API
    private GoogleApiClient mGoogleApiClient;

    // UI elements
    private TextView mLatitudeText,mLongitudeText, mTextTest, mTextPerRes;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Create an instance of GoogleAPIClient.
        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
        }
        mLatitudeText = (TextView) findViewById(R.id.mLatitudeText);
        mLongitudeText = (TextView) findViewById(R.id.mLongitudeText);
        mTextTest = (TextView) findViewById(R.id.textTest);
        mTextPerRes = (TextView) findViewById(R.id.textPerRes);

        LocationRequest mLocationRequest = createLocationRequest();

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(mLocationRequest);

        PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, //mGoogleClient
                        builder.build());

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @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_start, 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_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    protected void onStart() {
        mGoogleApiClient.connect();
        super.onStart();
    }

    protected void onStop() {
        mGoogleApiClient.disconnect();
        super.onStop();
    }

    public boolean refreshLocation(){
        return false;
    }

    @Override
    public void onConnected(Bundle bundle) {
        mTextPerRes.setText("Permission getting ready");//DEBUG!!!
        mTextTest.setText("1");//DEBUG!!!
        if ( ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
            mTextTest.setText("1.5");//DEBUG!!!
            ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_ACCESS_FINE_LOCATION);
        }
        if(locationPermissionGoodToGo == true) {
            //TODO: Kommer inte in här. Något fel med permissions! :(
            mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            mTextTest.setText("2");//DEBUG!!!
            if (mLastLocation != null) {
                mTextTest.setText("3");//DEBUG!!!
                mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
                mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
            }
        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    protected LocationRequest createLocationRequest() {
        LocationRequest mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10000);
        mLocationRequest.setFastestInterval(5000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        return mLocationRequest;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        mTextPerRes.setText("Permission wanted");//DEBUG!!!
        switch (requestCode) {
            case MY_PERMISSION_ACCESS_FINE_LOCATION: {
                mTextPerRes.setText("Permission case right");//DEBUG!!!
                // 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.
                    mTextPerRes.setText("Permission granted");//DEBUG!!!
                    locationPermissionGoodToGo = true;
                } 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
        }
    }
}

这是我的清单:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="se.adrianhansson.gpsapp"
    android:versionCode="1"
    android:versionName="1.0">

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

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        <activity
            android:name=".StartActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

我编辑的代码仍然无法正常工作。结果相同。

public class StartActivity extends AppCompatActivity implements ConnectionCallbacks, OnConnectionFailedListener {

    private Location mLastLocation;
    private boolean locationPermissionGoodToGo = false;

    private final int MY_PERMISSION_ACCESS_FINE_LOCATION = 1;

    // Google client to interact with Google API
    private GoogleApiClient mGoogleApiClient;

    // UI elements
    private TextView mLatitudeText,mLongitudeText, mTextTest, mTextPerRes;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_start);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        // Create an instance of GoogleAPIClient.
        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
        }
        mLatitudeText = (TextView) findViewById(R.id.mLatitudeText);
        mLongitudeText = (TextView) findViewById(R.id.mLongitudeText);
        mTextTest = (TextView) findViewById(R.id.textTest);
        mTextPerRes = (TextView) findViewById(R.id.textPerRes);

        LocationRequest mLocationRequest = createLocationRequest();

        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
                .addLocationRequest(mLocationRequest);

        PendingResult<LocationSettingsResult> result =
                LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, //mGoogleClient
                        builder.build());

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });
    }

    @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_start, 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_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }

    protected void onStart() {
        mGoogleApiClient.connect();
        super.onStart();
    }

    protected void onStop() {
        mGoogleApiClient.disconnect();
        super.onStop();
    }

    public boolean refreshLocation(){
        return false;
    }

    @Override
    public void onConnected(Bundle bundle) {
        mTextPerRes.setText("Permission getting ready");//DEBUG!!!
        mTextTest.setText("1");//DEBUG!!!
        if ( ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED ) {
            mTextTest.setText("1.5");//DEBUG!!!
            ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSION_ACCESS_FINE_LOCATION);
        }
        setCoordinates();
//      original location of setCoordinates() code
    }

    public void setCoordinates(){
        if(locationPermissionGoodToGo == true) {
            //TODO: Kommer inte in här. Något fel med permissions! :(
            mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            mTextTest.setText("2");//DEBUG!!!
            if (mLastLocation != null) {
                mTextTest.setText("3");//DEBUG!!!
                mLatitudeText.setText(String.valueOf(mLastLocation.getLatitude()));
                mLongitudeText.setText(String.valueOf(mLastLocation.getLongitude()));
            }
        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    protected LocationRequest createLocationRequest() {
        LocationRequest mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(10000);
        mLocationRequest.setFastestInterval(5000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        return mLocationRequest;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        mTextPerRes.setText("Permission wanted");//DEBUG!!!
        switch (requestCode) {
            case MY_PERMISSION_ACCESS_FINE_LOCATION: {
                mTextPerRes.setText("Permission case right");//DEBUG!!!
                // 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.
                    mTextPerRes.setText("Permission granted");//DEBUG!!!
                    locationPermissionGoodToGo = true;
                    setCoordinates();
                } else {
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    locationPermissionGoodToGo = false;
                }
                return;
            }
            // other 'case' lines to check for other
            // permissions this app might request
        }
    }
}

【问题讨论】:

    标签: android permissions gps


    【解决方案1】:

    requestPermissions() 是异步的。您在调用locationPermissionGoodToGo 后立即检查它,这太多太早了。

    if(locationPermissionGoodToGo == true) 块中的代码移动到单独的方法中。如果checkSelfPermission() 说您有权限,请立即调用该单独的方法。否则,在onRequestPermissionResult() 中调用它,您将在其中将locationPermissionGoodToGo 设置为true

    【讨论】:

    • 感谢您的回复!!我试图这样做,但结果是一样的,而且似乎不起作用。现在我可能误解了你让我做的事情。我在上面的主要帖子的底部附加了我新的、编辑过的 Java 代码。
    • @AdrianHansson:让我引用我自己的话,特别强调一下:“如果 checkSelfPermission() 表明您拥有权限,请立即调用该单独的方法。”您总是在调用它,而不仅仅是在您已经获得许可的情况下。使用else 块来包装setCoordinates() 调用,因此只有在您已经拥有权限时才会执行它(因此不需要调用requestPermissions())。
    • @AdrianHansson:This sample app 演示了在使用 Play Services 的融合位置提供程序的上下文中请求运行时权限。
    猜你喜欢
    • 2019-08-14
    • 2020-12-17
    • 1970-01-01
    • 1970-01-01
    • 2016-10-17
    • 2013-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多