Uploading an image to a server: stuck at FileInputStream

橙三吉。 提交于 2019-12-02 06:03:36

This happens because you haven't requested EXTERNAL_STORAGE permission.

Starting from android API level 23 (marshmallow), android permission framework (I don't know whether that's the right term for it or not), have changed.

Before marshmallow you just had to declare permissions in the manifest file. But on and above marshmallow, android permissions have been categorized into Normal permissions and Dangerous permissions. If you are using a normal permission, things are the same on all android versions. But if you are using a dangerous permission, you have to request the user to grant that permission at runtime.

In your case, you are uploading an image, which require READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions. Those are categorized as dangerous permissions. So you have to request those permissions before you do any actions that require those permissions.

But you don't have to request both the permissions separately, since those permissions fall under one permission group.

From official docs,

If an app requests a dangerous permission listed in its manifest, and the app already has another dangerous permission in the same permission group, the system immediately grants the permission without any interaction with the user..

ie, if you have declared a couple of permissions that are on a single permission group, you have to request for only one of those permissions. If the user grants permission for that permission group, all those permissions you declared, which are in the same permission group will be granted by the system.

Here is the code to request storage permission

private static final int STORAGE_REQ_ID=3465;

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

                if (ActivityCompat.shouldShowRequestPermissionRationale(CreateSetcardStep1Activity.this,
                        Manifest.permission.READ_EXTERNAL_STORAGE)) {

                    //THIS CONDITION WORKS WHEN WE ARE REQUSETING PERMISSION AGAIN SINCE USER DENIED PERMISSION ON PREVIOUS REQUEST(S)

                    ActivityCompat.requestPermissions(CreateSetcardStep1Activity.this,
                                new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                                STORAGE_REQ_ID);

                } else {

                    //REQUESTING PERMISSION FOR FIRST TIME, EXPLAIN WHY THE APPLICATION NEED PERMISSION

                    AlertDialog.Builder builder = new AlertDialog.Builder(CreateSetcardStep1Activity.this);
                    builder.setTitle("Permission Request");
                    builder.setMessage("To upload image, Application need External storage permission");
                    builder.setPositiveButton("Grant", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                            ActivityCompat.requestPermissions(CreateSetcardStep1Activity.this,
                                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                                    STORAGE_REQ_ID);
                        }
                    });
                    builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                        public void onClick(DialogInterface dialog, int id) {
                        }
                    });
                    AlertDialog dialog = builder.create();
                    dialog.show();
                    ActivityCompat.requestPermissions(CreateSetcardStep1Activity.this,
                            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                           STORAGE_REQ_ID);
                }
            }
            else startImageCapture();
        }

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

//HERE YOU HANDLE PERMISSION REQUEST RESULTS
    switch (requestCode) {
        case STORAGE_REQ_ID: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                //PERMISSION GRANTED!!
                startImageCapture();

            } else {

                //USER DENIED PERMISSION, NOTIFY THE USER THAT PERMISSION IS DENIED, MAY BE A TOAST?

            }
            return;
        }

    }
}


private void startImageCapture(){
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(destination));
    startActivityForResult(intent, REQUEST_IMAGE);
}

Everything else is pretty much the same. (And sorry for my poor English)

More on permission request here

Hi please check first Permission like(Read External,Write External and Camera if used) into Manifest file after that put Runtime permission code for Greater then Marshmallow devices.And Use File Provider to get Image Uri from SD Card.

And put below code into onActivityResult().

                 if (mPhotouri != null) {
                    try {
                        mBitmap = MediaStore.Images.Media.getBitmap(
                                getContentResolver(), mPhotouri);
                        Uri tempUri = getImageUri(this, mBitmap);
                        finalFile = new File(getRealPathFromURI(tempUri, this));
                        mSelectedImagePath = finalFile.getAbsolutePath();

                        if (mSelectedImagePath != null)
                            mFileSelectedImage = new File(mSelectedImagePath);

                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

public static Uri getImageUri(Activity inContext, Bitmap inImage) {

        ByteArrayOutputStream bytes = new ByteArrayOutputStream();
        inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
        String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
        return Uri.parse(path);
    }

public static String getRealPathFromURI(Uri uri, Activity signupActivity) {
    Cursor cursor = signupActivity.getContentResolver().query(uri, null, null, null, null);
    cursor.moveToFirst();
    int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
    return cursor.getString(idx);
}

hope it helps.

add this to your AndroidManifest.xml:

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

and for api 23+ , read this tutorial:

Runtime Permissions

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!