title: How Can We Determine If We Can Request Location Permission Upgrade in Android 12?
body: <p>In Android 12, if an app requests fine location permission via <code>ACCESS_FINE_LOCATION</code>, the user might elect to only grant coarse location permission. Unfortunately, not all APIs work with coarse location permission — in particular, AFAICT, to look up the SSID of the connected WiFi network, we need fine location permission, not coarse location permission.</p>
  <p>If you re-request fine location permission, the user will be asked to upgrade your access, but the user might decline. As a result, we need a way to gracefully determine that the user granted us coarse location permission and that we are still eligible to request the upgrade.</p>
  <p><a href="https://gitlab.com/commonsguy/thisisfine" rel="noreferrer">This sample project</a> just has a button to trigger a <code>requestPermissions()</code> for <code>ACCESS_FINE_LOCATION</code>, along with four labels to report:</p>
  <ul>
  <li>Were we granted fine location permission? (<code>checkSelfPermission()</code> for <code>ACCESS_FINE_LOCATION</code>)</li>
  <li>Were we granted coarse location permission? (<code>checkSelfPermission()</code> for <code>ACCESS_COARSE_LOCATION</code>)</li>
  <li>Should we prompt the user with rationale for our request, for fine permission? (<code>shouldShowRequestPermissionRationale()</code> for <code>ACCESS_FINE_LOCATION</code>)</li>
  <li>Should we prompt the user with rationale for our request, for coarse permission? (<code>shouldShowRequestPermissionRationale()</code> for <code>ACCESS_COARSE_LOCATION</code>)</li>
  </ul>
  <p>Running this after a fresh install on an Pixel 3a XL running the final beta of Android 12, I get the following results after the listed sequence of actions:</p>
  <div class="s-table-container">
  <table class="s-table">
  <thead>
  <tr>
  <th style="text-align: center;">Action</th>
  <th style="text-align: center;">Has Fine Permission?</th>
  <th style="text-align: center;">Has Coarse Permission?</th>
  <th style="text-align: center;">Prompt for Fine?</th>
  <th style="text-align: center;">Prompt for Coarse?</th>
  </tr>
  </thead>
  <tbody>
  <tr>
  <td style="text-align: center;">launch the app</td>
  <td style="text-align: center;">no</td>
  <td style="text-align: center;">no</td>
  <td style="text-align: center;">no</td>
  <td style="text-align: center;">no</td>
  </tr>
  <tr>
  <td style="text-align: center;">click button and grant approximate location while using the app</td>
  <td style="text-align: center;">no</td>
  <td style="text-align: center;">yes</td>
  <td style="text-align: center;">no</td>
  <td style="text-align: center;">no</td>
  </tr>
  <tr>
  <td style="text-align: center;">click button again and choose &quot;Keep approximate location&quot;</td>
  <td style="text-align: center;">no</td>
  <td style="text-align: center;">yes</td>
  <td style="text-align: center;">yes</td>
  <td style="text-align: center;">no</td>
  </tr>
  <tr>
  <td style="text-align: center;">click button a 3rd time and choose &quot;Keep approximate location&quot;</td>
  <td style="text-align: center;">no</td>
  <td style="text-align: center;">yes</td>
  <td style="text-align: center;">no</td>
  <td style="text-align: center;">no</td>
  </tr>
  </tbody>
  </table>
  </div>
  <p>While these all make some sense individually, the problem is that the second and fourth results are the same:</p>
  <ul>
  <li>I have coarse location access</li>
  <li>I am not told that I need to show rationale</li>
  </ul>
  <p>The problem is that if the user tries clicking the button a 4th time, we're into the &quot;don't ask again&quot; state, and no permission dialog appears. All the previous times, a permission dialog appears, either to initially grant the permission or to grant the upgrade. I would like to be able to detect the 4th or later attempt, so I can show my own dialog that says &quot;sorry, you need to go to Settings and grant the permission manually now&quot;. However, other than by tracking the count of requests myself, I do not know how to identify this case distinctly.</p>
  <p>So, my question is: is there a way, using some existing permission or location APIs, to determine that I am no longer allowed to re-request <code>ACCESS_FINE_LOCATION</code>, and that further requests will result in immediate failures? In particular, the answer needs to be able to distinguish between the second and fourth rows in that table, so between &quot;the user only granted coarse access&quot; and &quot;the user only granted coarse access, and you tried the upgrade twice, which the user rejected each time&quot;.</p>