1

So watch faces are Android Wear apps that don't have any activities but only a service. It's visible and interactive, but a service. And if the app wants to access anything like location or settings, it needs to request the corresponding permissions in code. Adding it to the manifest file is not effective, despite all tutorials saying so. Maybe they're outdated faster than things change on Android.

There is the ContextCompat.checkSelfPermission function to check whether the app has a certain permission. This can be called before I do anything. But if it says I don't have that permission, it must be requested.

There is the ActivityCompat.requestPermissions function to request a permission from the user through a dialog view. Unfortunately this requires an activity which a watch face doesn't have.

I've seen another question about this issue but it has no useful answers. The answers include external libraries (I've tried the two and none of them works), a code sample in Java that also fails because it extends from AppCompatActivity that doesn't exist in my version of Android Studio, and otherwise no code.

The web doesn't offer any solutions for this and I couldn't find any other web forums where I could ask such questions that would be still active today.

My application is written in Kotlin, a supposedly superior and more comfortable language than Java. I'm new to all this and cannot easily convert Java samples to Kotlin. Besides that I can't find any suitable code samples at all.

My understanding is that I need to open an activity which can then request the permission. Unfortunately, the Android developer documentation isn't what I'm used to from Microsoft and doesn't cover creating an activity for a Wear app. And it generally doesn't provide any examples that would show how this method must be called. These are the most helpful parts of a documentation and Android doesn't have that. So I'm quite stuck now. Android wants me do something that I'm unable to figure out how that's possible.

So how is it possible? What Kotlin code do I need to solve this elementary platform issue and request permissions from a watch face service?

ygoe
  • 18,655
  • 23
  • 113
  • 210
  • As it says here https://developer.android.com/training/articles/wear-permissions.html "If the user interacts with your app via a service, such as a watch face, the service must open an activity before requesting the permission." – Ken Wolf Mar 22 '18 at 11:37
  • @KenWolf Yes, that's was I was saying. But it doesn't show me how that works. I haven't done this kind of thing before and I can't make enough sense of the available documentation and nobody has a working solution to this published, so I have to seek help elsewhere. – ygoe Mar 22 '18 at 11:45
  • You're asking for quite a lot of code that would better be handled as different questions. Step 1) Check if permissions are granted in your service. If they are not, 2) Launch a new activity and 3) In that activity request the permissions – Ken Wolf Mar 22 '18 at 11:49
  • @KenWolf The activity part is the one I have no idea of. Checking is just a single line, requesting also looks like a single line, both with the function calls mentioned in the question. And a bit of if-blocks around them. – ygoe Mar 22 '18 at 12:19
  • Thankfully starting another activity is very well documented: https://developer.android.com/training/basics/firstapp/starting-activity.html. It's the same for a service except you have to add a flag FLAG_ACTIVITY_NEW_TASK – Ken Wolf Mar 22 '18 at 12:22
  • so are you interested to open an activity and request permission and go back? Or you dont want any activity at all? I have a sample watch face whcih uses gps and record audio permission – Amir Mar 27 '18 at 09:35
  • also have you tried complication data? – Amir Mar 27 '18 at 09:37

1 Answers1

2

Here is how I manage to do this on my watch faces (example to clean depending on your usage):

public static class PermissionRequestActivity extends Activity {
private static int PERMISSIONS_CODE = 0;
String[] mPermissions;
int mRequestCode;

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    if (requestCode == mRequestCode) {
            for (int i = 0; i < permissions.length; i++) {
                String permission = permissions[i];
                int grantResult = grantResults[i];
                Log.d("PermissionRequestActivity", "" + permission + " " + (grantResult==PackageManager.PERMISSION_GRANTED?"granted":"revoked"));
            }
    }
    finish();
}

@Override
protected void onStart() {
    super.onStart();
    mPermissions = new String[1];
    mPermissions[0] = this.getIntent().getStringExtra("KEY_PERMISSIONS");
    mRequestCode = this.getIntent().getIntExtra("KEY_REQUEST_CODE", PERMISSIONS_CODE);

    ActivityCompat.requestPermissions(this, mPermissions, mRequestCode);
}}

And then from your service, start it like this:

Intent myIntent = new Intent(getBaseContext(), PermissionRequestActivity.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
myIntent.putExtra("KEY_PERMISSIONS", Manifest.permission.BODY_SENSORS);
startActivity(myIntent);
Thomas Thomas
  • 824
  • 1
  • 9
  • 21