-1

My app needs below permissions. Which has been incorporated in AndroidManifest.xml

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.autofocus"/>

After upgrading to API 26

(targetSdkVersion 26)

Some functionality is not working. As I need to incorporate runtime permission. I am using RxPermission . The problem is my most of the implementations are placed in helper class(not inside main activity). when I am trying to use helper library getting error - .Can not resolve constructor I have tried with the following options too -

RxPermissions rxPermissions = new RxPermissions((FragmentActivity) mContext);

As RxPermission require Fragment as target.Can we ask user all the permission in the main activity? A sample code will help me. Project code for reference

[Fixed] Now I am calling from the activity. ReferenceCode changed -

RxPermissions rxPermissions=new RxPermissions(this);
rxPermissions.request(Manifest.permission.CAMERA)
        .subscribe(granted -> {
            if (granted) {

                //LogUtil.e(LOG_TAG, "Granted external permission");
                setContentView(R.layout.activity_local_album);
                ViewGroup backGround = (ViewGroup) findViewById(R.id.background);
                MyUtil.setBackgroundBlur(backGround, this);

                initAdapter();
                assignViews();

            } else {
                // Oups permission denied
            }
        });

[New error] I am getting android.os.FileUriExposedException: error. Code:

public void onClick(View v) {
    switch (v.getId()) {
        // 返回
        case R.id.action_back:
            myFinish();
            break;
        // 拍照
        case R.id.action_capture:
            PackageManager pm = getPackageManager();
            // FEATURE_CAMERA - 后置相机
            // FEATURE_CAMERA_FRONT - 前置相机
            if (pm.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)) {
                // 访问相机类型
                int requestType;
                // 截取主题壁纸
                if (mRequestType != 2) {
                    requestType = REQUEST_IMAGE_CAPTURE_THEME;
                } else { // 截取二维码logo
                    requestType = REQUEST_IMAGE_CAPTURE_QRCODE_LOGO;
                }

                Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                mImageUri = Uri.fromFile(MyUtil.getFileDirectory(this, "/Android/data/" +
                        getPackageName() + "/capture/temporary.jpg"));
                intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);
                startActivityForResult(intent, requestType);
                overridePendingTransition(0, R.anim.zoomin);
            }

Error

 Process: com.bisw.weac, PID: 20997
android.os.FileUriExposedException: file:///storage/emulated/0/Android/data/com.bisw.weac/capture/temporary.jpg exposed beyond app through ClipData.Item.getUri()
    at android.os.StrictMode.onFileUriExposed(StrictMode.java:1958)
    at android.net.Uri.checkFileUriExposed(Uri.java:2356)
    at android.content.ClipData.prepareToLeaveProcess(ClipData.java:944)
    at android.content.Intent.prepareToLeaveProcess(Intent.java:10480)
    at android.content.Intent.prepareToLeaveProcess(Intent.java:10465)
    at android.app.Instrumentation.execStartActivity(Instrumentation.java:1616)
    at android.app.Activity.startActivityForResult(Activity.java:4564)
    at android.support.v4.app.BaseFragmentActivityApi16.startActivityForResult(BaseFragmentActivityApi16.java:54)
    at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:68)
    at android.app.Activity.startActivityForResult(Activity.java:4522)
    at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:751)
    at com.bisw.weac.activities.LocalAlbumActivity.onClick(LocalAlbumActivity.java:222)
    at android.view.View.performClick(View.java:6877)
    at android.widget.TextView.performClick(TextView.java:12651)
    at android.view.View$PerformClick.run(View.java:26069)
    at android.os.Handler.handleCallback(Handler.java:789)
    at android.os.Handler.dispatchMessage(Handler.java:98)
    at android.os.Looper.loop(Looper.java:164)
    at android.app.ActivityThread.main(ActivityThread.java:6938)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
Biswajit Das
  • 644
  • 7
  • 26
  • I'm assuming the library requires a `FragmentActivity` instance, which you are not supplying - your `mContext` is the `Application` looking at your naming of the parameter. Consider passing the correct `Context` on the method calls inside your helper, not the constructor, as they should have a short lived scope you won't want to hold a reference to. – Mark Nov 10 '18 at 11:37
  • Thanks @mark-keen. I am calling the helper class like this LocalAlbumImagePickerHelper.getInstance(LocalAlbumActivity.this). Do you want me to change here? – Biswajit Das Nov 10 '18 at 11:47

2 Answers2

1

My app needs below permissions

Note that your app cannot hold MOUNT_UNMOUNT_FILESYTEMS unless it is signed by the firmware signing key or is installed on the privileged app partition (mostly for rooted devices).

Can we ask user all the permission in the main activity?

You do not have a choice, according to the documentation. According to those instructions, RxPermissions only works if you request the permissions from onCreate() of your Activity (or possibly onCreate() of your Fragment, though that part is unclear).

A sample code will help me

In addition to documentation, the RxPermissions GitHub repository has a sample app. Here is the v0.9.3 edition of that sample app.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • @CommnsWare thanks for clarification. Last point as I said I can do easily from the activity. But I need to refer fragment. from helper class where I don't have fragment. – Biswajit Das Nov 10 '18 at 12:05
  • @BiswajitDas: By the time you call `getThumbnail()` from anywhere, you need to ensure that you have your runtime permission. Then, you do not need an `RxPermissions` instance in `getThumbnail()`. Your "helper" class appears to be a singleton; a singleton cannot and should not be attempting to request runtime permissions. – CommonsWare Nov 10 '18 at 12:06
  • @CommnsWare friend inside main activity I am still getting the same error - Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/images/thumbnails from pid=25888, uid=10229 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission() – Biswajit Das Nov 10 '18 at 16:24
  • @BiswajitDas: Perhaps you are not waiting until you get permission before calling `getThumbnail()`. – CommonsWare Nov 10 '18 at 16:34
  • @CommnsWare Please see the updated code above **Edit 1** – Biswajit Das Nov 10 '18 at 16:55
  • @BiswajitDas: You do not appear to be using RxPermissions correctly. `ensure()` is meant to be used as part of an overall `Observable` chain, where you do not attempt to use the permission until your subscriber is invoked. In particular, `ensure()` is not a blocking call; you will not have permission when it returns. If you are unfamiliar with RxJava and `Observable`, you might wish to use something other than RxPermissions. For example, [the official documentation](https://developer.android.com/training/permissions/requesting) does not use a third-party library. – CommonsWare Nov 10 '18 at 16:59
  • finally I am able to fix. it – Biswajit Das Nov 11 '18 at 16:04
  • @CommnsWare I am getting **FileUriExposedException** error. Updated desc **newError** – Biswajit Das Nov 11 '18 at 16:26
  • @BiswajitDas: You can find [this SO question and answers](https://stackoverflow.com/questions/38200282/android-os-fileuriexposedexception-file-storage-emulated-0-test-txt-exposed) by searching on major search engines for `FileUriExposedException`. If you have additional concerns, please ask a new question. – CommonsWare Nov 11 '18 at 16:30
  • saw the suggestion so need to replace file with content? – Biswajit Das Nov 11 '18 at 16:51
  • @CommnsWare post the new question. Could you please help me.https://stackoverflow.com/questions/53255297/java-lang-securityexception-permission-denial-writing-android-support-v4-conte/53257038#53257038 – Biswajit Das Nov 12 '18 at 20:57
0

Finally I am able to fix it calling from main class.

 RxPermissions rxPermissions=new RxPermissions(this);
    rxPermissions.request(Manifest.permission.READ_EXTERNAL_STORAGE)
            .subscribe(granted -> {
                if (granted) {
                    customDefineBtn.setOnClickListener(this);
                    LogUtil.e(LOG_TAG, "Granted external permission");

                } else {
                    // Oups permission denied
                }
            });
Biswajit Das
  • 644
  • 7
  • 26