代码之家  ›  专栏  ›  技术社区  ›  Gabriel

将图像上载到服务器:停留在FileInputStream

  •  1
  • Gabriel  · 技术社区  · 6 年前

    我正在尝试将图像上载到服务器,但不知何故,代码在FileInputStream行停止。不知道为什么,我也不知道如何调试或检查它。这里是我的源代码:

     public class CreateSetcardStep1Activity extends AppCompatActivity {
    
        @Override
        protected void onCreate(final Bundle savedInstanceState) {
    
    
            String filename = appHelper.dateToString(new Date(), "yyyyMMdd-hhmmss");
            destination = new File(Environment.getExternalStorageDirectory(), filename + ".jpg");
    
            buttonTakePhoto.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(destination));
                    startActivityForResult(intent, REQUEST_IMAGE);
                }
            });
    
            buttonSubmitPhoto.setVisibility(View.GONE);
            buttonSubmitPhoto.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    dialog = ProgressDialog.show(CreateSetcardStep1Activity.this, "", "Uploading file...", true);
    
                    new Thread(new Runnable() {
                        public void run() {
                            uploadFile(imagePath);
                        }
                    }).start();
                }
            });
    
    
        }
    
        @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
            if (requestCode == REQUEST_IMAGE && resultCode == Activity.RESULT_OK) {
                try {
                    buttonSubmitPhoto.setVisibility(View.VISIBLE);
                    Log.e(LOG, "breakpoint 1");
                    setcardPic.setVisibility(View.VISIBLE); Log.e(LOG, "breakpoint 2 destination: "+destination);
                    FileInputStream in = new FileInputStream(destination); Log.e(LOG, "breakpoint 3");
                    BitmapFactory.Options options = new BitmapFactory.Options(); Log.e(LOG, "breakpoint 4");
                    options.inSampleSize = 10; Log.e(LOG, "breakpoint 5");
                    imagePath = destination.getAbsolutePath(); Log.e(LOG, "breakpoint 6 imagePath: "+imagePath);
                    Log.e(LOG, "PATH === " + imagePath);
                    //tvPath.setText(imagePath);
                    Bitmap bmp = BitmapFactory.decodeStream(in, null, options);
                    setcardPic.setImageBitmap(bmp);
                    showUploadButton = true;
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                }
    
            } else {
                showUploadButton = false;
                Toast.makeText(getApplicationContext(),
                        R.string.request_cancelled,
                        Toast.LENGTH_LONG).show();
            }
        }
    
        public int uploadFile(String sourceFileUri) {
    
            String fileName = sourceFileUri;
            showUploadButton = false; //revert upload button to hidden
            HttpURLConnection conn = null;
            DataOutputStream dos = null;
            String lineEnd = "\r\n";
            String twoHyphens = "--";
            String boundary = "*****";
            int bytesRead, bytesAvailable, bufferSize;
            byte[] buffer;
            int maxBufferSize = 1024 * 1024;
            File sourceFile = new File(sourceFileUri);
    
            if (!sourceFile.isFile()) {
                dialog.dismiss();
                Log.e(LOG, "Source File not exist :" +imagePath);
                return 0;
            }
            else
            {
                try {
    
                    // open a URL connection to the Servlet
                    FileInputStream fileInputStream = new FileInputStream(sourceFile);
                    URL url = new URL(upLoadServerUri);
    
                    // Open a HTTP  connection to  the URL
                    conn = (HttpURLConnection) url.openConnection();
                    conn.setDoInput(true); // Allow Inputs
                    conn.setDoOutput(true); // Allow Outputs
                    conn.setUseCaches(false); // Don't use a Cached Copy
                    conn.setRequestMethod("POST");
                    conn.setRequestProperty("Connection", "Keep-Alive");
                    conn.setRequestProperty("ENCTYPE", "multipart/form-data");
                    conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
                    conn.setRequestProperty("Filedata", fileName);
    
                    dos = new DataOutputStream(conn.getOutputStream());
    
                    dos.writeBytes(twoHyphens + boundary + lineEnd);
                    dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename="+ fileName + "" + lineEnd);
                    dos.writeBytes(lineEnd);
    
                    // create a buffer of  maximum size
                    bytesAvailable = fileInputStream.available();
    
                    bufferSize = Math.min(bytesAvailable, maxBufferSize);
                    buffer = new byte[bufferSize];
    
                    // read file and write it into form...
                    bytesRead = fileInputStream.read(buffer, 0, bufferSize);
    
                    while (bytesRead > 0) {
    
                        dos.write(buffer, 0, bufferSize);
                        bytesAvailable = fileInputStream.available();
                        bufferSize = Math.min(bytesAvailable, maxBufferSize);
                        bytesRead = fileInputStream.read(buffer, 0, bufferSize);
    
                    }
    
                    // send multipart form data necesssary after file data...
                    dos.writeBytes(lineEnd);
                    dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
    
                    // Responses from the server (code and message)
                    serverResponseCode = conn.getResponseCode();
                    String serverResponseMessage = conn.getResponseMessage();
    
                    Log.i(LOG, "HTTP Response is : "+ serverResponseMessage + ": " + serverResponseCode);
    
                    if(serverResponseCode == 200){
    
                        runOnUiThread(new Runnable() {
                            public void run() {
    
                                Toast.makeText(CreateSetcardStep1Activity.this, "File Upload Complete.",
                                        Toast.LENGTH_SHORT).show();
                            }
                        });
                    }
    
                    //close the streams //
                    fileInputStream.close();
                    dos.flush();
                    dos.close();
    
                } catch (MalformedURLException ex) {
    
                    dialog.dismiss();
                    ex.printStackTrace();
    
                    runOnUiThread(new Runnable() {
                        public void run() {
    
                            Toast.makeText(CreateSetcardStep1Activity.this, "MalformedURLException",
                                    Toast.LENGTH_SHORT).show();
                        }
                    });
    
                    Log.e(LOG, "error: " + ex.getMessage(), ex);
                } catch (Exception e) {
    
                    dialog.dismiss();
                    e.printStackTrace();
    
                    runOnUiThread(new Runnable() {
                        public void run() {
    
                            Toast.makeText(CreateSetcardStep1Activity.this, "Got Exception : see logcat ",
                                    Toast.LENGTH_SHORT).show();
                        }
                    });
                    Log.e(LOG, "Exception : "
                            + e.getMessage(), e);
                }
                dialog.dismiss();
                return serverResponseCode;
    
            }
        }
    }
    

    有没有办法检查问题出在哪里?logcat在断点2处停止:断点2目标:/storage/simulated/0/20171215-051851。jpg公司 如果我检查资源管理器,文件就在那里

    3 回复  |  直到 6 年前
        1
  •  1
  •   Aswin P Ashok    6 年前

    发生这种情况的原因是您没有请求EXTERNAL\u存储权限。

    从android API level 23(marshmallow)开始,android权限框架(我不知道这是否是正确的术语)已经发生了变化。

    在marshmallow之前,您只需在清单文件中声明权限。但在marshmallow上,android权限被分类为 Normal permissions Dangerous permissions . 如果您使用的是普通权限,那么所有android版本上的情况都是一样的。但是 如果您使用的是危险权限,则必须请求用户在运行时授予该权限 .

    在您的情况下,您正在上载一个图像,该图像需要READ\u EXTERNAL\u存储和WRITE\u EXTERNAL\u存储权限。这些被归类为危险权限。因此,在执行任何需要这些权限的操作之前,必须先请求这些权限。

    但是您不必分别请求这两个权限,因为这些权限属于一个权限 permission group .

    根据官方文件,

    如果应用程序请求其清单中列出的危险权限,并且该应用程序在同一权限组中已经有另一个危险权限,则系统会立即授予该权限,而无需与用户进行任何交互。。

    也就是说,如果您在一个权限组上声明了两个权限,那么您只需要请求其中一个权限。如果用户授予该权限组的权限,则系统将授予您声明的位于同一权限组中的所有权限。

    以下是请求存储权限的代码

    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);
    }
    

    其他一切都差不多。(很抱歉我的英语很差)

    有关权限请求的详细信息 here

        2
  •  0
  •   Jyubin Patel    6 年前

    您好,请检查清单文件中的第一个权限,如(读取外部、写入外部和相机,如果使用),然后输入运行时权限代码,以获取比棉花糖更大的设备。并使用文件提供程序从SD卡获取图像Uri。

    并将以下代码放入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);
    }
    

    希望有帮助。

        3
  •  0
  •   Sajad Rahmanipour    6 年前

    将此添加到您的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" />
    

    对于api 23+,请阅读本教程:

    Runtime Permissions