上传图像在某些设备上有效,但返回 Stream FixedLengthSource .inputStream()
Posted
技术标签:
【中文标题】上传图像在某些设备上有效,但返回 Stream FixedLengthSource .inputStream()【英文标题】:Uploading a Image Works on some devices but returns Stream FixedLengthSource .inputStream() 【发布时间】:2020-12-22 14:58:32 【问题描述】:我正在开发一个使用 php 和 okhttp 将图像上传到指定目录的 android 应用程序。嗯,前端和后端在我的个人设备上运行良好,但在非三星设备上崩溃。
当我挖掘问题时,我发现服务器返回:
com.android.okhttp.internal.http.Http1xStream$FixedLengthSource@17768aa).inputStream() 在非三星设备上。
文件上传的Java代码如下:
public class UploadGalleryStoryPost
private Context context;
private String fileName = "", User_Id = "",Type="";
private ProgressDialog progressDialog;
private int serverResponseCode = 0;
private String count = "";
private String fileCount = "";
public UploadGalleryStoryPost(String fileName, Context context, String User_Id, String Type, String count, String fileCount)
this.fileName = fileName;
this.context = context;
this.User_Id = User_Id;
this.Type = Type;
this.count = count;
this.fileCount = fileCount;
new UploadingGalleryPost().execute();
private class UploadingGalleryPost extends AsyncTask<Void, Void, Void>
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_profile = new File(fileName);
private String upLoadServerUri = APP_SERVER_URL+"AddAStory.php";
@Override
protected void onPreExecute()
super.onPreExecute();
progressDialog=new ProgressDialog(context);
progressDialog.setMessage("Uploading...");
progressDialog.setCancelable(false);
progressDialog.show();
@Override
protected void onPostExecute(Void result)
try
if(serverResponseCode == 200)
int count1 = Integer.parseInt(count);
int fileCount1 = Integer.parseInt(fileCount);
Log.e("value", " "+ String.valueOf(count1-1)+" "+fileCount1);
if((fileCount1-1) == count1)
AlertDialog.Builder builder1 = new AlertDialog.Builder(context, R.style.myDialog);
builder1.setCancelable(false);
builder1.setTitle("Alert!");
builder1.setMessage("Uploaded successfully.");
builder1.setPositiveButton("OK", new DialogInterface.OnClickListener()
@Override
public void onClick(DialogInterface dialog, int which)
dialog.dismiss();
Intent i = new Intent(context, DashBoard.class);
context.startActivity(i);
);
AlertDialog dialog1 = builder1.create();
dialog1.show();
else
progressDialog.dismiss();
Toast.makeText(context, fileName+" has been uploaded successfully", Toast.LENGTH_SHORT).show();
catch (Exception e)
e.printStackTrace();
Toast.makeText(context, "Got Exception : see logcat ", Toast.LENGTH_SHORT).show();
Log.e("UploadtoserverException", "Exception : "
+ e.getMessage(), e);
super.onPostExecute(result);
@Override
protected Void doInBackground(Void... voids)
try
// open a URL connection to the Servlet
FileInputStream fileInputStream_profile = new FileInputStream(sourceFile_profile);
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.setChunkedStreamingMode(1024);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.setRequestProperty("ENCTYPE", "multipart/form-data");
conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
conn.setRequestProperty("Attachment", fileName);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"Attachment\";filename=\""+fileName+"\"" + lineEnd);
dos.writeBytes(lineEnd);
// create a buffer of maximum size
bytesAvailable = fileInputStream_profile.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
// read file and write it into form...
bytesRead = fileInputStream_profile.read(buffer, 0, bufferSize);
while (bytesRead > 0)
dos.write(buffer, 0, bufferSize);
bytesAvailable = fileInputStream_profile.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
bytesRead = fileInputStream_profile.read(buffer, 0, bufferSize);
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"User_Id\"" + lineEnd);
dos.writeBytes(lineEnd);
dos.writeBytes(User_Id);
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"Type\"" + lineEnd);
dos.writeBytes(lineEnd);
dos.writeBytes(Type);
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + twoHyphens + lineEnd);
// Responses from the server (code and message)
serverResponseCode = conn.getResponseCode();
String serverResponseMessage = conn.getResponseMessage();
conn.getErrorStream();
Log.e("uploadFile", "HTTP Response is : "
+ serverResponseMessage + ": " + serverResponseCode+" "+ conn.getErrorStream());
//close the streams //
fileInputStream_profile.close();
dos.flush();
dos.close();
catch (MalformedURLException ex)
ex.printStackTrace();
Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
catch (Exception e)
e.printStackTrace();
Log.e("UploadtoserverException", "Exception : "
+ e.getMessage(), e);
return null;
php代码是:
<?php
date_default_timezone_set('Asia/Kolkata');
$date = date('Y-m-d H:i:s');
$new_time = date("Y-m-d H:i:s", strtotime('+24 hours'));
$day = date("l");
$response = array();
include 'db_connect.php';
if ($_SERVER['REQUEST_METHOD'] == 'POST')
$User_Id = $_POST['User_Id'];
$Story_Content = $_POST['Story_Content'];
$B_Id = $_POST['B_Id'];
$Type = $_POST['Type'];
if($Type == 'BGTXT')
$sql = "INSERT INTO Story_Common(User_Id,Timestamp_Start,Status, Timestamp_End)
VALUES('$User_Id','$date','Open','$new_time')";
$result = sqlsrv_query($conn, $sql);
if($result)
$sql1 = "SELECT TOP 1 * FROM Story_Common ORDER BY Story_Id DESC";
$res1 = sqlsrv_query($conn, $sql1);
if (sqlsrv_has_rows($res1) == true)
while ($row_sql1 = sqlsrv_fetch_array($res1, SQLSRV_FETCH_BOTH))
$Story_Id = $row_sql1["Story_Id"];
$sql2 = "INSERT INTO Story(Story_Id,Story_Content,B_Id)
VALUES('$Story_Id',N'$Story_Content','$B_Id')";
$result2 = sqlsrv_query($conn, $sql2);
if($result2)
$response['success'] = 200;
$response['message'] = "Insert in db success.";
else
$response['success'] = 0;
$response['message'] = "Failed to insert db.";
else
$response['success'] = 0;
$response['message'] = "Failed to insert db.";
else if($Type == 'Photo/Video')
$sql = "INSERT INTO Story_Common(User_Id,Timestamp_Start,Status,Timestamp_End)
VALUES('$User_Id','$date','Open','$new_time')";
$result = sqlsrv_query($conn, $sql);
if($result)
if (empty($_FILES["Attachment"]["name"]))
$path = "NA";
else
$Attachment=$_FILES["Attachment"]["name"];
$temp=$_FILES["Attachment"]["tmp_name"];
$tst= time();
$url = "Post_Media/" . $tst . $Attachment;
$path="http://kidsfb.kidsfb.com/ver1PHP/".$url;
move_uploaded_file($temp,$url);
$sql1 = "SELECT TOP 1 * FROM Story_Common ORDER BY Story_Id DESC";
$res1 = sqlsrv_query($conn, $sql1);
if (sqlsrv_has_rows($res1) == true)
while ($row_sql1 = sqlsrv_fetch_array($res1, SQLSRV_FETCH_BOTH))
$Story_Id = $row_sql1["Story_Id"];
$sql2 = "INSERT INTO Story_Media(Story_Id,Media_Att)
VALUES('$Story_Id','$path')";
$result2 = sqlsrv_query($conn, $sql2);
if($result2)
$response['success'] = 200;
$response['message'] = "Insert in db success.";
else
$response['success'] = 0;
$response['message'] = "Failed to insert db.";
else
$response['success'] = 0;
$response['message'] = "Failed to insert db.";
echo json_encode($response);
?>
尝试将缓冲区大小从 1024 增加到 2048 仍然无法在其他设备上运行。
【问题讨论】:
【参考方案1】:这对我来说很好,所以请试试这个
//php文件imageUpload.php
$encodedImage = $_POST['image'];
$encodedImage_Name = $_POST['img_name'];
$imageLocation = "Images/IMG_$encodedImage_Name.jpg";
$imagpath="Images/IMG_$encodedImage_Name.jpg";
$uploade_url= 'http://192.168.1.18/'.$imagpath;
echo "[\n";
if(file_put_contents($imageLocation, base64_decode($encodedImage)))
$myObj=new \stdClass();
$myObj->success = 'true';
$myJSON = json_encode($myObj);
echo $myJSON;
else
$myObj=new \stdClass();
$myObj->success = 'false';
$myJSON = json_encode($myObj);
echo $myJSON;
echo "]\n";
//java文件
static final int PICK_FROM_GALLERY=123;
Bitmap imageBitmap;
boolean isSelected;
//从图库中打开图片
profile.setOnClickListener( new View.OnClickListener()
@Override
public void onClick(View v)
try
if (ActivityCompat.checkSelfPermission(getContext(),
Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
ActivityCompat.requestPermissions(getActivity(), 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();
);
//打开图片设置为Bitmap
@Override
public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data)
super.onActivityResult(requestCode, resultCode, data);
if(requestCode==PICK_FROM_GALLERY)
if (resultCode == RESULT_OK)
Uri path = data.getData();
try
imageBitmap= MediaStore.Images.Media.getBitmap(getActivity().getContentResolver(),path);
profile.setImageBitmap(imageBitmap);
Log.e("Image path",imageBitmap+"");
isSelected=true;
catch (IOException e)
e.printStackTrace();
public void UploadImage()
if (isSelected == true)
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
imageBitmap.compress(Bitmap.CompressFormat.JPEG,75, byteArrayOutputStream);
byte[] imageInByte = byteArrayOutputStream.toByteArray();
//picked image covert to base64
String encodedImage = Base64.encodeToString(imageInByte,Base64.DEFAULT);
OkHttpClient client = new OkHttpClient();
RequestBody reqestBody = new MultipartBody.Builder()
.setType( MultipartBody.FORM )
.addFormDataPart( "image",encodedImage )
.addFormDataPart( "img_name","abc" )
.build();
Request request = new Request.Builder()
.url("Upload Url in Server (exsample : http://192.168.1.18/imageUpload.php) " )
.post( reqestBody )
.build();
client.newCall( request ).enqueue( new Callback()
@Override
public void onFailure(Call call, IOException e)
e.printStackTrace();
@Override
public void onResponse(Call call, Response response) throws IOException
if (response.isSuccessful())
final String myResponse = response.body().string();
getActivity().runOnUiThread( new Runnable()
@Override
public void run()
try
String JSON_STRING = myResponse;
JSONArray mJsonArray = new JSONArray( JSON_STRING );
JSONObject mJsonObject = mJsonArray.getJSONObject( 0 );
String success = mJsonObject.getString( "success" );
Log.d( "Image Uploade", success );
if (success.equals( "true" ))
Toast.makeText( getActivity(), " Success! ", Toast.LENGTH_LONG ).show();
else
pd.dismiss();
Toast.makeText( getActivity(), " failed! Please try again later", Toast.LENGTH_LONG ).show();
catch (JSONException e)
Log.e( "Image Uploade", e.toString() );
Toast.makeText( getActivity(), e.toString(), Toast.LENGTH_LONG ).show();
);
else
Log.d( "Image Uploade", "Error" );
);
else
Toast.makeText( getActivity(), " Please select a PostImage before submitting", Toast.LENGTH_LONG ).show();
【讨论】:
感谢您的回复,但从相机拍摄的图像上似乎仍然存在问题。从相机拍摄的图像转换为位图,也转换为 base64 字符串。但是在上传时仍然会由于某种未知原因引发错误。 我认为您正在使用 AsyncTask 。但是当涉及到 android 10 时他们有一些问题 .. 但是您可以按照我的步骤进行操作,并且效果很好。如果您认为我的回答对您的问题有帮助吗?您可以对我的个人资料提供反馈吗以上是关于上传图像在某些设备上有效,但返回 Stream FixedLengthSource .inputStream()的主要内容,如果未能解决你的问题,请参考以下文章
使用“com.android.camera.action.CROP”意图裁剪图像,在某些设备上返回小尺寸位图
如何在 C# 中正确使用 WCF REST API 上的 Stream 将文件(图像/视频/等)上传到服务器?
在某些 Gingerbread 设备上,使用 ACTION_IMAGE_CAPTURE 拍摄的图像对于 ExifInterface.TAG_ORIENTATION 始终返回 1