0

I have an activity that extends AppCompatActivity. For this activity to run I need to grant the app with ACCESS_COARSE_LOCATION and WRITE_EXTERNAL_STORAGE permissions. Everything was working well until I updated to Android Studio 3.0.

Now, the prompt for requesting WRITE_EXTERNAL_STORAGE permissions is not showing, and the function

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

is returning -1 at grantResults without even asking.

This behavior is not happening if I request the permission ACCESS_COARSE_LOCATION, which works as it should. Below, the code invoking both checks:

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

            if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("This app needs location access");
                builder.setMessage("Please grant location access so this app can detect beacons.");
                builder.setPositiveButton(android.R.string.ok, null);
                builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                    public void onDismiss(DialogInterface dialog) {
                        requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION);
                    }
                });

                builder.show();
            }
        }

And the other:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            final int PERMISSION_REQUEST_COARSE_LOCATION = 1;

            if (this.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
                final AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("This app needs sd access");
                builder.setMessage("Please grant sd access so this app can save files.");
                builder.setPositiveButton(android.R.string.ok, null);
                builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                    public void onDismiss(DialogInterface dialog) {
                        requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);
                    }
                });

                builder.show();
            }
        }

The corresponding section in my manifest looks like this:

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

I've read many things, but this is pretty strange, when some type of permissions are showing up the request dialog, while others aren't. By the way, there is no SD card in the device (always used internal storage), but that was never a problem.

Both my targetSdkVersion and compileSdkVersion are 26.

EDIT

Other relevant permissions, such as READ_EXTERNAL_STORAGE, are also working correctly. It's just an issue with the write permission. Tested on two android devices and emulator

Complete onCreate Method:

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

    setContentView(R.layout.activity_device_discovery);

    context = this;
    wm = (WifiManager) context.getApplicationContext().getSystemService(WIFI_SERVICE);
    intent = getIntent();

    if(intent.getBooleanExtra("LOCAL_NETWORK", true) == true){
        ipAddress = Formatter.formatIpAddress(wm.getConnectionInfo().getIpAddress());
        port = DEFAULT_LIGHT_PORT;
    }
    else{
         ipAddress = intent.getStringExtra("TRACK_IP");
         port = intent.getIntExtra("TRACK_PORT", DEFAULT_GATEWAY_PORT);
    }

    font = Typeface.createFromAsset(MainActivity.mainActivity.getAssets(), "RepRg.ttf");
    mHandler = new Handler();

    deviceArrayList = new ArrayList<>();
    devicesBufferList = new ArrayList<>();

    lightListAdapter = new LightListAdapter(this, deviceArrayList, intent);

    discoveredListView = (ListView) findViewById(R.id.paired_devices);
    discoveredListView.setAdapter(lightListAdapter);

    listAllCheckBox = (CheckBox) findViewById(R.id.listAllCheckBox);
    refreshButton = (ImageButton) findViewById(R.id.refreshButton);

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

        if (this.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            final AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("This app needs sd access");
            builder.setMessage("Please grant sd access so this app can save files.");
            builder.setPositiveButton(android.R.string.ok, null);
            builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
                public void onDismiss(DialogInterface dialog) {
                    requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);
                }
            });

            builder.show();
        }
    }


    listAllCheckBox.setTypeface(font);
    listAllCheckBox.setTextSize(18);
    listAllCheckBox.setTextColor(Color.parseColor("#202020"));
    listAllCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            lightListAdapter.clear();
            processDeviceListing();
        }
    });

    refreshButton.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {

            switch (event.getAction()) {
                case MotionEvent.ACTION_DOWN:
                    refreshButton.setImageResource(R.drawable.refresh_down);
                    break;
                case MotionEvent.ACTION_UP:
                    refreshButton.setImageResource(R.drawable.refresh_up);
                    refreshDevicesList();
                    break;
                case MotionEvent.ACTION_CANCEL:
                    refreshButton.setImageResource(R.drawable.refresh_up);
                    break;
            }
            return false;
        }
    });

}

Thanks in advance.

gotramaval
  • 59
  • 9

2 Answers2

4

Turns out that the issue is due to the new version of HockeyApp. HockeySDK is integrated in my application. Now, since version 5.0.0, the docs say:

To be ready for Android O, HockeySDK-Android now limits the WRITE_EXTERNAL_STORAGE permission with the maxSdkVersion filter. In some use cases, e.g. where an app contains a dependency that requires this permission, maxSdkVersion makes it impossible for those dependencies to grant or request the permission. The solution for those cases is to declare the tools:node="replace" manifest merging strategy later in the dependency tree

Thus, after adding tools:node="replace" to the WRITE permission in the manifest, the problem is solved.

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/>

Source here

I hope this is useful for somebody else

gotramaval
  • 59
  • 9
0

Try this:

if (ContextCompat.checkSelfPermission(this,
                Manifest.permission.ACCESS_COARSE_LOCATION)
        != PackageManager.PERMISSION_GRANTED) {

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

I suggest you check the documentation: https://developer.android.com/training/permissions/requesting.html

Update

Why are you using the same request code for both permissions?

 requestPermissions(new String[]{Manifest.permission. ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION); <-- PERMISSION_REQUEST_COARSE_LOCATION

and

 requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_COARSE_LOCATION);  <-- PERMISSION_REQUEST_COARSE_LOCATION

Change the request code value for each one.

diegoveloper
  • 93,875
  • 20
  • 236
  • 194
  • You haven't got my point. The issue is that the prompt for permission request is showing up when asking for ACCESS_COARSE_LOCATION, but not when asking for WRITE_EXTERNAL_STORAGE. Thats happening both with your and with my code. I'd read the documentation before posting ;) – gotramaval Nov 15 '17 at 23:20
  • That was a copy-paste issue, sorry. I changed that, but it's still not solving the problem – gotramaval Nov 15 '17 at 23:30
  • did you try uninstalling and installing again? maybe you revoked the permissions – diegoveloper Nov 16 '17 at 16:17
  • Yes, and no luck. Also doing so in the emulator should be like doing a fresh install. Still nothing. Found similar posts: [link] (https://stackoverflow.com/questions/38245226/requestpermissions-not-showing-permission-dialog-on-device-works-well-on-androi) – gotramaval Nov 16 '17 at 21:37