2017-12-15 4 views
1

이미지를 서버에 업로드하려고하는데, 어쨌든 코드가 FileInputStream 행에서 중지되었습니다. 확실하지 왜 그리고 어떻게 디버깅하거나 그것을 확인하지 않습니다. 여기 내 소스 코드 :서버로 이미지 업로드하기 : 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/emulated/0/20171215-051851.jpg 그래서 탐색기를 확인하면 파일이 있습니다.

+0

예외가 있습니까? –

+0

자세한 내용은 다음을 참조하십시오. java.io.FileNotFoundException : /storage/emulated/0/20171215-051851.jpg : open failed : EACCES (Permission denied)하지만 manifest에서 파일을 읽을 수 있습니다. <사용 권한 android : name ="android.permission.READ_EXTERNAL_STORAGE "/>, 아직 사용하지 않음 – Gabriel

+0

대상 SDK 버전? –

답변

1

이 발생합니다.

안드로이드 API 레벨 23 (marshmallow)부터 시작하여 android 권한 프레임 워크 (올바른 용어인지 아닌지)가 변경되었습니다.

marshmallow 이전에는 매니페스트 파일에서 사용 권한을 선언하기 만하면되었습니다. 그러나 마쉬 멜로우 위와 안드로이드 허가는 Normal permissionsDangerous permissions으로 분류되었습니다. 정상적인 권한을 사용하는 경우 모든 Android 버전에서 상황이 동일합니다. 그러나 위험한 권한을 사용하는 경우 런타임에 해당 권한을 부여하도록 사용자에게 요청해야합니다..

귀하의 경우, READ_EXTERNAL_STORAGE 및 WRITE_EXTERNAL_STORAGE 권한이 필요한 이미지를 업로드하고 있습니다. 이들은 위험한 권한으로 분류됩니다. 따라서 이러한 권한이 필요한 작업을 수행하기 전에 해당 권한을 요청해야합니다.

그러나 사용 권한이 모두 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

0

안녕하세요. 먼저 권한 확인 (Read External, Write External 및 Camera를 사용하는 경우) Manifest 파일에 저장 한 후 Runtime 권한 코드를 Greater Marshmallow 장치에 입력합니다. 파일 공급자를 사용하여 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); 
} 

도움이 되길 바랍니다.

0

당신의 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+를위한

는,이 튜토리얼을 읽어 : 당신이 EXTERNAL_STORAGE 권한을 요청하지 않았기 때문에

Runtime Permissions

관련 문제