在应用程序中,想法是让用户能够将照片发送给彼此。使用选择器意图选择照片,它预览就好了,用户确认发送。 uri被发送到后台服务,后者使用URL连接获取真实路径后将照片上传到服务器。整个过程效果很好......但仅限于某些文件夹或图像类型。这是我的问题。我在这里失踪了什么变量?是否缺少权限,文件类型不兼容,文件命名问题??
<uses-permission android:name="android.permission.MANAGE_DOCUMENTS" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
public void transfer(String id, String handle) {
photoToHandle = handle;
photoToId = id;
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
startActivityForResult(Intent.createChooser(intent, "Complete action using"), 1999);
}
//onActivity Result passes data to dialog fragment here
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1999 && resultCode == -1) {
if (data == null) return;
Bundle pBundle = new Bundle();
pBundle.putString("handle", photoToHandle);
pBundle.putString("id", photoToId);
pBundle.putString("uri", String.valueOf(data.getData()));
send_photo_dialog sfd = new send_photo_dialog();
sfd.setArguments(pBundle);
sfd.setStyle(DialogFragment.STYLE_NO_TITLE, R.style.mydialog);
sfd.setCancelable(false);
sfd.show(getFragmentManager(), "sfd");
}
}
//dialog confirms visually to user the image is correct and they want to send it here
public class send_photo_dialog extends DialogFragment implements View.OnClickListener {
private Context context;
private ImageView image;
private String fileString;
private String[] data;
private Activity activity;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.send_photo_dilaog_layout, container, false);
fileString = getArguments().getString("uri");
data = new String[3];
data[0] = getArguments().getString("id");
data[1] = fileString;
SharedPreferences user = context.getSharedPreferences("user", Context.MODE_PRIVATE);
data[2] = user.getString("handle"," ");
TextView handle = (TextView) v.findViewById(R.id.town);
handle.setText(getArguments().getString("handle"));
TextView ok = (TextView) v.findViewById(R.id.send);
TextView cancel = (TextView) v.findViewById(R.id.cancel);
image = (ImageView) v.findViewById(R.id.image);
ok.setOnClickListener(this);
cancel.setOnClickListener(this);
return v;
}
@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
Bitmap bitmap = null;
try {
InputStream stream = context.getContentResolver().openInputStream(Uri.parse(fileString));
bitmap = BitmapFactory.decodeStream(stream);
if (stream != null) stream.close();
} catch (IOException e) {
e.printStackTrace();
}
if (bitmap != null) {
Display display = activity.getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int screenWidth = size.x;
int screenHeight = size.y;
int bitmapHeight = bitmap.getHeight();
int bitmapWidth = bitmap.getWidth();
while (bitmapHeight > (screenHeight - 200) || bitmapWidth > (screenWidth - 100)) {
bitmapHeight = (int) (bitmapHeight * .7);
bitmapWidth = (int) (bitmapWidth * .7);
}
BitmapDrawable resizedBitmap = new BitmapDrawable(context.getResources(), Bitmap.createScaledBitmap(bitmap, bitmapWidth, bitmapHeight, false));
image.setImageDrawable(resizedBitmap);
}
}
@Override
public void onClick(View v) {
context.sendBroadcast(new Intent("nineteenVibrate"));
context.sendBroadcast(new Intent("nineteenClickSound"));
if (v.getId() == R.id.send) {
Intent send = new Intent("nineteenSendPhoto");
send.putExtra("data", data);
context.sendBroadcast(send);
}
dismiss();
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
context = activity.getApplicationContext();
this.activity = activity;
}
}
//Service Broadcast Receiver picks up the intent here and passes it to uploadPhoto method.
case "nineteenSendPhoto":
uploadPhoto(intent.getStringArrayExtra("data"));
break;
private void uploadPhoto(final String[] data) {
if (!networkIsActive()) {
Toaster.toastlow(this, "Try Again Later");
return;
}
final String imagePath = getRealPathFromURI(Uri.parse(data[1]));
if (imagePath == null) {
LOG.l("imagePath is null");
return;
}
final File sourceFile = new File(imagePath);
if (!sourceFile.isFile()) return;
new AsyncTask<Void, Void, Integer>() {
@Override
protected Integer doInBackground(Void... params) {
int code = 0;
String upLoadServerUri = SITE_URL + "posting_photoz.php";
HttpURLConnection conn;
DataOutputStream dos;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1024 * 1024;
try {
FileInputStream fileInputStream = new FileInputStream(sourceFile);
URL url = new URL(upLoadServerUri);
conn = (HttpURLConnection) url.openConnection();
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setConnectTimeout(8000);
conn.setReadTimeout(8000);
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("uploaded_file", imagePath);
dos = new DataOutputStream(conn.getOutputStream());
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"uploaded_file\";filename=\"" + imagePath + "\"" + lineEnd);
dos.writeBytes(lineEnd);
bytesAvailable = fileInputStream.available();
bufferSize = Math.min(bytesAvailable, maxBufferSize);
buffer = new byte[bufferSize];
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);
if (isCancelled()) {
fileInputStream.close();
code = 0;
return null;
}
}
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"userId\"" + lineEnd);
dos.writeBytes(lineEnd);
dos.writeBytes(String.valueOf(data[0]));
dos.writeBytes(lineEnd);
dos.writeBytes(twoHyphens + boundary + lineEnd);
dos.writeBytes("Content-Disposition: form-data; name=\"handle\"" + lineEnd);
dos.writeBytes(lineEnd);
dos.writeBytes(String.valueOf(data[2]));
dos.writeBytes(lineEnd);
code = conn.getResponseCode();
fileInputStream.close();
dos.flush();
dos.close();
} catch (Exception e) {
LOG.l(String.valueOf(e));
}
return code;
}
@Override
protected void onPostExecute(Integer code) {
super.onPostExecute(code);
if (code == 200) Toast("Photo Sent!");
else Toast("Try Again Later");
}
}.execute(null, null, null);
}
//Here is the php on the server side that puts the file in the correct folder and (hidden but working properly) notifies the intended receiver via gcm to download said photo.
<?php
$userId=$_POST['userId'];
$handle=$_POST['handle'];
$name=$_POST['name'];
try {
if (
!isset($_FILES['upfile']['error']) ||
is_array($_FILES['upfile']['error'])
) {
throw new RuntimeException('Invalid parameters.');
}
switch ($_FILES['uploaded_file']['error']) {
case UPLOAD_ERR_OK:
break;
case UPLOAD_ERR_NO_FILE:
throw new RuntimeException('No file sent.');
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
throw new RuntimeException('Exceeded filesize limit.');
default:
throw new RuntimeException('Unknown errors.');
}
if ($_FILES['uploaded_file']['size'] > 1000000) {
throw new RuntimeException('Exceeded filesize limit.');
}
$finfo = new finfo(FILEINFO_MIME_TYPE);
if (false === $ext = array_search(
$finfo->file($_FILES['uploaded_file']['tmp_name']),
array(
'jpg' => 'image/jpeg',
'png' => 'image/png',
'gif' => 'image/gif',
),
true
)) {
throw new RuntimeException('Invalid file format.');
}
if (!move_uploaded_file($_FILES['uploaded_file']['tmp_name'], "photos/".$name)){
throw new RuntimeException('Failed to move uploaded file.');
}
echo 'File is uploaded successfully.';
} catch (RuntimeException $e) {
echo $e->getMessage();
}
?>