BitmapFactory:无法解码流:React Native的java.io.FileNotFoundException

时间:2018-07-21 11:40:32

标签: java android android-studio react-native android-permissions

当我从图像选择器中选择图像时,出现此错误。在开始在应用程序中使用权限之前,我从来没有得到过它。这是我的SDK版本:

    compileSdkVersion 27
    buildToolsVersion "27.0.3"

    configurations {
        all*.exclude group: 'com.android.support', module: 'support-v4'
        all*.exclude group: 'com.android.support', module: 'support-annotations'
        compile.exclude group: "org.apache.httpcomponents", module: "httpclient"
    }


    defaultConfig {
        applicationId "com.myapp"
        minSdkVersion 16
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        multiDexEnabled true

        ndk {
            abiFilters "armeabi-v7a", "x86"
        }


    dexOptions {
    javaMaxHeapSize "4g"
    preDexLibraries = false
    incremental true
}

compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation "com.github.hotchemi:permissionsdispatcher:4.0.0-alpha1"
    annotationProcessor "com.github.hotchemi:permissionsdispatcher-processor:4.0.0-alpha1"

    implementation 'com.android.support:support-v13:27+'
    implementation 'com.android.support:appcompat-v7:27+'
    implementation "com.facebook.react:react-native:+"  // From node_modules

}

我阅读了其他问题来帮助解决此问题,并找到了以下Java代码以获得权限:

    private static final int PICK_FROM_GALLERY = 1;

ChoosePhoto.setOnClickListener(new View.OnClickListener()
{
    @Override
    public void onClick (View v){
    try {
        if (ActivityCompat.checkSelfPermission(EditProfileActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(EditProfileActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, PICK_FROM_GALLERY);
        } else {
            Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
            startActivityForResult(galleryIntent, PICK_FROM_GALLERY);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
  }
});


@Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults)
    {
       switch (requestCode) {
            case PICK_FROM_GALLERY:
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                  Intent galleryIntent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
                  startActivityForResult(galleryIntent, PICK_FROM_GALLERY);
                } else {
                    //do something like displaying a message that he didn`t allow the app to access gallery and you wont be able to let him select from gallery
                }
                break;
        }
    }

我将其放在mainactivity.java文件的类中,并收到以下错误:error: <identifier> expected ChoosePhoto.setOnClickListener(new View.OnClickListener()。我不确定这是否可以解决权限错误。

Stacktrace:

    07-22 17:59:03.978  8497  8497 D ViewRootImpl@39eadf9[UCropActivity]: MSG_WINDOW_FOCUS_CHANGED 0
07-22 17:59:03.992  8497  8497 E BitmapFactory: Unable to decode stream: java.io.FileNotFoundException: /storage/emulated/0/DCIM/IMMQY/IMG_20180722175858_942.jpg (No such file or directory)
07-22 17:59:03.996  8497  8497 W System.err: java.lang.Exception: Invalid image selected

本地代码:

    componentDidMount(){
async function requestCameraPermission() {
  try {
    const granted = await PermissionsAndroid.request(
      PermissionsAndroid.PERMISSIONS.CAMERA,
      {
        'title': 'Cool Photo App Camera Permission',
        'message': 'Cool Photo App needs access to your camera ' +
                   'so you can take awesome pictures.'
      }
    )
    if (granted === PermissionsAndroid.RESULTS.GRANTED) {
      console.log("You can use the camera")
    } else {
      console.log("Camera permission denied")
    }
  } catch (err) {
    console.warn(err)
  }
}
}

2 个答案:

答案 0 :(得分:1)

有两件事:1.您需要在清单中添加外部读取存储的权限,然后才能使用它;如果您使用的是高于23的api,则必须使用“简单”权限。

要写:

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

阅读:

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

23岁以上

 private String[] galleryPermissions = {Manifest.permission.READ_EXTERNAL_STORAGE, 
 Manifest.permission.WRITE_EXTERNAL_STORAGE};

 if (EasyPermissions.hasPermissions(this, galleryPermissions)) {
        pickImageFromGallery();
    } else {
        EasyPermissions.requestPermissions(this, "Access for storage",
                101, galleryPermissions);
    }
  1. 在Android 4.4及更高版本中,将其删除。而且您获得的uri已经没有路径。

您仍然可以通过InputStream(ContentResolver#openInputStream(Uri uri))或通过文件描述符访问文件内容。

这在较旧的android版本上也适用

 @Override
 public void onActivityResult(int requestCode, int resultCode, Intent data) {
 if (resultCode == RESULT_OK && requestCode == 1 && null != data) {
    decodeUri(data.getData());
 }
  }

   public void decodeUri(Uri uri) {
   ParcelFileDescriptor parcelFD = null;
    try {
    parcelFD = getContentResolver().openFileDescriptor(uri, "r");
    FileDescriptor imageSource = parcelFD.getFileDescriptor();

    // Decode image size
    BitmapFactory.Options o = new BitmapFactory.Options();
    o.inJustDecodeBounds = true;
    BitmapFactory.decodeFileDescriptor(imageSource, null, o);

    // the new size we want to scale to
    final int REQUIRED_SIZE = 1024;

    // Find the correct scale value. It should be the power of 2.
    int width_tmp = o.outWidth, height_tmp = o.outHeight;
    int scale = 1;
    while (true) {
        if (width_tmp < REQUIRED_SIZE && height_tmp < REQUIRED_SIZE) {
            break;
        }
        width_tmp /= 2;
        height_tmp /= 2;
        scale *= 2;
    }

    // decode with inSampleSize
    BitmapFactory.Options o2 = new BitmapFactory.Options();
    o2.inSampleSize = scale;
    Bitmap bitmap = BitmapFactory.decodeFileDescriptor(imageSource, null, o2);

    imageview.setImageBitmap(bitmap);

   } catch (FileNotFoundException e) {
    // handle errors
   } catch (IOException e) {
    // handle errors
    } finally {
    if (parcelFD != null)
        try {
            parcelFD.close();
        } catch (IOException e) {
            // ignored
        }
     }
           }

希望这对您有帮助

答案 1 :(得分:0)

访问此网站: https://developer.android.com/training/permissions/requesting 您的AndroidManifest.xml文件中可能没有摄像头权限。

另请参阅: https://facebook.github.io/react-native/docs/permissionsandroid 问题可能是您没有React Native的摄像头许可。