我的自定义相机应用程序基本上拍摄视频和照片。这些照片或视频将上传到我的服务器。当我尝试从图库上传照片/视频时,我可以毫无问题地上传文件。当我尝试从相机拍摄后立即上传照片或视频时,我没有收到任何错误(服务器响应代码为200),但文件没有上传。即我无法在服务器上找到该文件,例如我上传后,我的照片/视频来自图库。录制视频后不久我的视频缩略图预览也是空白的(不包含任何内容)。这是我的代码片段,我想我会犯错误。
MyCamera.class
//imports done
public class MyCamera extends Activity implements OnClickListener,
OnTouchListener {
private CameraSurface view;
static ImageView gallery;
String upload_type_TAG = "";
final static int PIC_CHOOSE = 100;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
view = new CameraSurface(this, null);
setContentView(R.layout.camera_view);
......
}
public void startVideoRecorder() {
if (isRecording == true) {
if (view.prepareVideoRecorder()) {
System.out.println("Prepared");
view.mMediaRecorder.start();
}
}
System.out.println("Video Recording");
}
public void captureImage() {
CameraSurface.takePic();
System.out.println("Image Capture");
}
@Override
public void onClick(View v) {
//calls intent to choose pic or video from gallery
...made necessary calls
}
@Override
public boolean onTouch(View v, MotionEvent event) {
//based on different touch durations I call
//functions to take pic or shoot video
...made necessary calls
}
//called whenever a pic is shot or video is recorded
static void callDirectUploadActivity(File pictureFile, Context ctx) {
System.out.println("Upload activity called");
Uri filePath = Uri.fromFile(pictureFile);
String value= pictureFile.getAbsolutePath();
Intent i = new Intent(ctx, DirectUpload.class);
i.putExtra("file_path", filePath.toString());
i.putExtra("uploadFilePath", value);
System.out.println("Dialog stopped showing");
dialog.dismiss();
ctx.startActivity(i);
}
//called when image / video has to be choosen from gallery
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case PIC_CHOOSE:
if (resultCode == RESULT_OK) {
Uri path=data.getData();
String filePath=getRealPathFromURI(MyCamera.this, path);
File f=new File(filePath);
//Uri selectedImg = data.getData();
//String selectedImage=getRealPathFromURI(MyCamera.this, selectedImg);
Uri selectedImage=Uri.fromFile(f);
Intent i = new Intent(MyCamera.this, DirectUpload.class);
i.putExtra("file_path", selectedImage.toString());
i.putExtra("uploadFilePath", filePath);
System.out.println("Dialog stopped showing");
dialog.dismiss();
startActivity(i);
}
break;
}
}
//for taking videos (view is CameraSurface.class)
public void startVideoRecorder() {
if (isRecording == true) {
if (view.prepareVideoRecorder()) {
System.out.println("Prepared");
view.mMediaRecorder.start();
}
}
System.out.println("Video Recording");
}
//for taking photos
public void captureImage() {
CameraSurface.takePic();
System.out.println("Image Capture");
}
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null,
null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
}
CameraSurface.class
public class CameraSurface extends SurfaceView implements OnTouchListener {
static Context ctx;
public CameraSurface(Context context, AttributeSet attrs) {
super(context, attrs);
ctx = context;
if (surface_holder == null) {
surface_holder = this.getHolder();
}
sh_callback = my_callback();
surface_holder.addCallback(sh_callback);
setOnTouchListener(this);
}
public static void takePic() {
System.out.println("Take pic called");
final PictureCallback mPicture = new PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
System.out.println("Photo taken");
File pictureFile = getOutputMediaFile(MEDIA_TYPE_IMAGE);
if (pictureFile == null) {
return;
}
try {
FileOutputStream fos = new FileOutputStream(pictureFile);
fos.write(data);
fos.close();
mCamera.stopPreview();
mCamera.startPreview();
String u = MediaStore.Images.Media.insertImage(
ctx.getContentResolver(),
pictureFile.getAbsolutePath(),
pictureFile.getName(), pictureFile.getName());
System.out.println("URL:" + u);
processImage(pictureFile.toString());
MyCamera.callDirectUploadActivity(pictureFile, ctx);
} catch (Exception e) {
e.printStackTrace();
}
}
};
mCamera.takePicture(null, null, null, mPicture);
}
private static void processImage(String u) throws IOException {
System.out.println("Decode Starts Here");
Bitmap temp,image;
Matrix mat = new Matrix();
mat.setRotate(90);
String path = u;
image = BitmapFactory.decodeFile(path);
int x = image.getWidth();
int y = image.getHeight();
temp = Bitmap.createBitmap(image, 0, 0, x, y, mat, true);
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
temp.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File f1 = new File(path.toString());
try {
f1.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(f1);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
fos.write(bytes.toByteArray());
} catch (IOException e) {
e.printStackTrace();
}
fos.close();
}
public static void processVideo(){
System.out.println("Video taken");
File pictureFile = getOutputMediaFile(MEDIA_TYPE_VIDEO);
if (pictureFile == null) {
return;
}
try {
MyCamera.callDirectUploadActivity(pictureFile, ctx);
} catch (Exception e) {
e.printStackTrace();
}
}
public static String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null,
null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
boolean prepareVideoRecorder() {
int videoWidth = mCamera.getParameters().getPreviewSize().width;
int videoHeight = mCamera.getParameters().getPreviewSize().height;
mMediaRecorder = new MediaRecorder();
mCamera.unlock();
mMediaRecorder.setCamera(mCamera);
mMediaRecorder.setOrientationHint(90);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setProfile(CamcorderProfile
.get(CamcorderProfile.QUALITY_LOW));
mMediaRecorder.setOutputFile(getOutputMediaFile(MEDIA_TYPE_VIDEO)
.toString());
mMediaRecorder.setPreviewDisplay(this.getHolder().getSurface());
try {
mMediaRecorder.prepare();
} catch (IllegalStateException e) {
Log.d(TAG,
"IllegalStateException preparing MediaRecorder: "
+ e.getMessage());
releaseMediaRecorder();
return false;
} catch (IOException e) {
Log.d(TAG, "IOException preparing MediaRecorder: " + e.getMessage());
releaseMediaRecorder();
return false;
}
return true;
}
void releaseMediaRecorder() {
if (mMediaRecorder != null) {
mMediaRecorder.reset();
mMediaRecorder.release();
mMediaRecorder = null;
processVideo();
}
}
private static File getOutputMediaFile(int type) {
System.out.println("Function CALLED");
File mediaStorageDir = new File(
Environment.getExternalStorageDirectory(), "");
if (!mediaStorageDir.exists()) {
if (!mediaStorageDir.mkdirs()) {
System.out.println("No directory!!");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
.format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE) {
System.out.println("image mode");
mediaFile = new File(Environment.getExternalStorageDirectory()
+ "/directory/" + "IMG_" + timeStamp + ".jpg");
System.out.println(Environment.getExternalStorageDirectory()
+ "/directory/" + "IMG_" + timeStamp + ".jpg");
} else if (type == MEDIA_TYPE_VIDEO) {
System.out.println("video mode");
mediaFile = new File(Environment.getExternalStorageDirectory()
+ "/directory/" + "VID_" + timeStamp + ".mp4");
ContentValues cv=new ContentValues(3);
cv.put(MediaStore.Video.Media.TITLE,"VID_" + timeStamp + ".mp4");
cv.put(MediaStore.Video.Media.DATA,Environment.getExternalStorageDirectory()
+ "/iCop/Videos/" + "VID_" + timeStamp + ".mp4");
cv.put(MediaStore.Video.Media.MIME_TYPE,"video/mp4");
ThumbnailUtils.createVideoThumbnail(Environment.getExternalStorageDirectory()
+ "/directupload/" + "VID_" + timeStamp + ".mp4", MediaStore.Video.Thumbnails.MICRO_KIND);
ctx.getContentResolver().insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, cv);
System.out.println(Environment.getExternalStorageDirectory()
+ "/directory/" + "VID_" + timeStamp + ".mp4");
} else {
System.out.println("null returned");
return null;
}
return mediaFile;
}
SurfaceHolder.Callback my_callback() {
SurfaceHolder.Callback ob1 = new SurfaceHolder.Callback() {
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
mCamera = null;
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
mCamera = Camera.open();
mCamera.setDisplayOrientation(90);
try {
mCamera.setPreviewDisplay(holder);
} catch (IOException exception) {
mCamera.release();
mCamera = null;
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
mCamera.startPreview();
}
};
return ob1;
}
@Override
public boolean onTouch(View v, MotionEvent event) {
//just some cool stuff, nothing related to taking pics/videos
System.out.println("Touched");
}
}
DirectUpload.class
public class DirectUpload extends Activity implements OnClickListener {
String uploadFilePath;
String uploadServerUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
uploadServerUri ="" ;//server url given correctly
getIntentData();
bUpload.setOnClickListener(this);
bCancel.setOnClickListener(this);
}
public void getIntentData() {
try {
Bundle b = getIntent().getExtras();
uploadFilePath=b.getString("uploadfilepath");
String path = b.getString("file_path");
Uri u = Uri.parse(b.getString("file_path"));
Uri parsUri=Uri.parse(path);
//Photo preview working correctly for both pics taken
//from camera and pics chosen from gallery
if (path.endsWith(".jpg") || path.endsWith(".jpeg") || path.endsWith(".png") || path.endsWith(".gif") || path.contains("images")) {
ivPreview.setVisibility(View.VISIBLE);
Bitmap d = MediaStore.Images.Media.getBitmap(
this.getContentResolver(), u);
int nh = (int) (d.getHeight() * (512.0 / d.getWidth()));
Bitmap scaled = Bitmap.createScaledBitmap(d, 512, nh, true);
ivPreview.setImageBitmap(scaled);
System.out.println("Image uploading");
} else {
//Video preview working correctly for gallery videos
//but not working for videos shot with came
File f=new File(u.toString());
ivPreview.setVisibility(View.VISIBLE);
String projection[]={
MediaStore.Video.Media._ID,MediaStore.Video.Media.DATA
};
Cursor videoCursor=this.getContentResolver().query(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, projection, MediaStore.Video.Media.DATA+" like ? ",
new String[]{"%/"+testFile.getName()}, null);
Log.i("Cursor count", videoCursor.getCount()+"");
videoCursor.moveToFirst();
int idIndex=videoCursor.getColumnIndex(MediaStore.Video.Media._ID);
int id=videoCursor.getInt(idIndex);
Bitmap curThumb = MediaStore.Video.Thumbnails.getThumbnail(getContentResolver(),id, MediaStore.Video.Thumbnails.MICRO_KIND, null);
videoCursor.close();
ivPreview.setImageBitmap(curThumb);
System.out.println("Video uploading");
}
File f=new File(path);
filepath_name = u.toString();
} catch (Exception e) {
e.printStackTrace();
}
}
public String getRealPathFromURI(Context context, Uri contentUri) {
Cursor cursor = null;
try {
String[] proj = { MediaStore.Images.Media.DATA };
cursor = context.getContentResolver().query(contentUri, proj, null,
null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
} finally {
if (cursor != null) {
cursor.close();
}
}
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.bUpload) {
description = etDescription.getText();
dialog = ProgressDialog.show(DirectUpload.this, "",
"Uploading file", true);
new Thread(new Runnable() {
public void run() {
uploadFile(uploadFilePath);
}
}).start();
} else if (v.getId() == R.id.bCancel) {
finish();
}
}
//upload code 200 OK but photos/videos taken from camera not found in server
//photos/videos from gallery uploaded successfully
public void uploadFile(String sourceFileUri) {
String fileName = sourceFileUri;
HttpURLConnection conn = null;
DataOutputStream dos = null;
String lineEnd = "\r\n";
String twoHyphens = "--";
String boundary = "*****";
int bytesRead, bytesAvailable, bufferSize;
byte[] buffer;
int maxBufferSize = 1 * 1024 * 1024;
File sourceFile = new File(sourceFileUri);
if (!sourceFile.isFile()) {
dialog.dismiss();
Log.e("uploadFile", "Source File not exist :"+filepath_name);
return ;
}
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("uploaded_file", 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)
int serverResponseCode = conn.getResponseCode();
String serverResponseMessage = conn.getResponseMessage();
Log.i("uploadFile", "HTTP Response is : "
+ serverResponseMessage + ": " + serverResponseCode);
//close the streams //
fileInputStream.close();
dos.flush();
dos.close();
} catch (MalformedURLException ex) {
dialog.dismiss();
ex.printStackTrace();
Log.e("Upload file to server", "error: " + ex.getMessage(), ex);
} catch (Exception e) {
dialog.dismiss();
e.printStackTrace();
Log.e("Upload file to server Exception", "Exception : " + e.getMessage(), e);
}
dialog.dismiss();
} // End else block
}
}
我无法弄清楚我可能出错的地方。请帮我解决这个问题,我是Android新手。
答案 0 :(得分:1)
弄错了。我已经两次调用方法 getOutputMediaFile(MEDIA_TYPE_VIDEO)。第一次调用 prepareVideoRecorder()(实际写入录制的视频)。我第二次从 processVideo()方法调用它(我在其中创建一个没有任何数据的新文件)。删除第二个函数调用(到 getOutputMediaFile()),问题解决了。