AsyncTask 进度对话框未显示且仍在跳帧
AsyncTask progress dialog not showing & still skipping frames
我有两个 AsyncTasks,它们包含将照片和视频保存到文件的代码。我使用了我创建的其他 类 中的工作 AsyncTask 代码,但由于某种原因它们在这里不起作用。这是 2 个问题:
我没有看到进度对话框
我仍然在控制台中看到消息说 "skipped 276 frames! Doing too much work on the main thread."
但是,当我的 doInBackground()
中有储蓄时,那怎么可能呢?我的照片和视频确实保存了,所以我知道 doInBackground()
运行。但是我不知道为什么进度对话框根本不显示。我在 Stack 上寻找答案,但没有解决我的情况。我的上下文正确,onPreExecute()
中没有参数,没有使用 get()
,并且此问题的其他答案不适用。
感谢您的帮助。
更新
感谢@perosperK,我将 ImageView
联系人完全移出 doInBackground()
,这意味着我必须在其他地方调用点击监听器。我还将我的 Toast
结果放入 onPostExecute()
中,这些更改完全奏效了!我现在看到了照片和视频的进度对话框。 :) 下面是工作代码,虽然我只能 post 更改代码的片段,因为我已经达到了 StackO 的字符限制:
工作MakePhotoVideo.java
public void enableClickListener(){
mImageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// saves photo & sets to ImageView
new SavePhotoTask().execute();
}
});
}
private Bitmap setPic() {
/*Taken out code ...*/
/* Set Bitmap to the ImageView, make sure the VideoView is cleared to replace with ImageView */
mImageView.setImageBitmap(mImageBitmap);
// enable the click listener here, so don't save empty files before this
enableClickListener();
// make sure video view is invisible
mVideoUri = null;
return mImageBitmap;
}
private class SavePhotoTask extends AsyncTask<Bitmap, Void, Bitmap>{
@Override
protected void onPreExecute() {
super.onPreExecute();
// instantiate your photo progress dialog
progressPhoto = new ProgressDialog(MakePhotoVideo.this);
progressPhoto.setMessage("Saving cute photo ...");
//set the progress bar to cancelable on back button
progressPhoto.setCancelable(true);
progressPhoto.show();
}
@Override
protected Bitmap doInBackground(Bitmap... params) {
photoSave(mImageBitmap);
return mImageBitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
progressPhoto.dismiss();
if (successPhoto) {
Toast toast = Toast.makeText(getApplicationContext(), "Cute photo saved!",
Toast.LENGTH_LONG);
LinearLayout toastLayout = (LinearLayout) toast.getView();
toastLayout.setBackgroundColor(getResources().getColor(R.color.toast_color));
TextView toastTV = (TextView) toastLayout.getChildAt(0);
toastTV.setTextSize(25);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 80);
toast.show();
} else {
Toast.makeText(getApplicationContext(),
"Error during image saving", Toast.LENGTH_SHORT).show();
}
mImageView.setOnClickListener(null);
}
}
// saves photo to SD card
private Boolean photoSave(final Bitmap bitmapPhoto){
/*Taken out code ...*/
return successPhoto;
}
private class SaveVideoTask extends AsyncTask<Uri, Void, Uri> {
@Override
protected void onPreExecute() {
super.onPreExecute();
// instantiate your video progress dialog
progressVideo = new ProgressDialog(MakePhotoVideo.this);
progressVideo.setMessage("Saving cute video ...");
//set the progress bar to cancelable on back button
progressVideo.setCancelable(true);
progressVideo.show();
}
@Override
protected Uri doInBackground(Uri... params) {
return videoSave(mVideoUri);
}
@Override
protected void onPostExecute(Uri result) {
progressVideo.dismiss();
if (successVideo) {
Toast toast = Toast.makeText(getApplicationContext(), "Cute video saved!",
Toast.LENGTH_SHORT);
LinearLayout toastLayout = (LinearLayout) toast.getView();
toastLayout.setBackgroundColor(getResources().getColor(R.color.toast_color));
TextView toastTV = (TextView) toastLayout.getChildAt(0);
toastTV.setTextSize(30);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 80);
toast.show();
} else {
Toast.makeText(getApplicationContext(),
"Error during video saving", Toast.LENGTH_SHORT).show();
}
}
}
// enables the VideoView listener
protected void enableTouchListener(){
// click the video to save it
mVideoView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP) {
new SaveVideoTask().execute();
}
return true;
}
});
}
private void handleCameraPhoto() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
if (mCurrentPhotoPath != null) {
setPic();
galleryAddPic();
mCurrentPhotoPath = null;
}
}
// Post recorded video into VideoView
private Uri handleCameraVideo(Intent intent) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
mVideoUri = intent.getData();
mVideoView.setVideoURI(mVideoUri);
mImageBitmap = null;
mVideoView.setVisibility(View.VISIBLE);
mImageView.setVisibility(View.INVISIBLE);
mVideoView.start();
enableTouchListener();
return mVideoUri;
}
下面是无效代码
MakePhotoVideo.java
package org.azurespot.makecute;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;
import org.azurespot.R;
import org.azurespot.cutecollection.CuteCollection;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;
public class MakePhotoVideo extends ActionBarActivity {
private static final int ACTION_TAKE_PHOTO = 1;
private static final int ACTION_TAKE_VIDEO = 2;
private static final String BITMAP_STORAGE_KEY = "viewbitmap";
private static final String IMAGEVIEW_VISIBILITY_STORAGE_KEY = "imageviewvisibility";
private ImageView mImageView;
private Bitmap mImageBitmap;
private static final String VIDEO_STORAGE_KEY = "viewvideo";
private static final String VIDEOVIEW_VISIBILITY_STORAGE_KEY = "videoviewvisibility";
private VideoView mVideoView;
private Uri mVideoUri;
private File fileVideo;
private String mCurrentPhotoPath;
String videoPath;
private int position = 0;
int targetH;
int targetW;
private static final String JPEG_FILE_PREFIX = "IMG_";
private static final String JPEG_FILE_SUFFIX = ".jpg";
private PhotoStorageDirFactory mPhotoStorageDirFactory = null;
private ProgressDialog progressPhoto;
private ProgressDialog progressVideo;
/* Photo album for this application */
private String getAlbumName() {
return getString(R.string.album_name);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_make_photo_video);
// instantiate your photo progress dialog
progressPhoto = new ProgressDialog(MakePhotoVideo.this);
// instantiate your video progress dialog
progressVideo = new ProgressDialog(MakePhotoVideo.this);
mImageView = (ImageView) findViewById(R.id.taken_photo);
mVideoView = (VideoView) findViewById(R.id.video_view);
mImageView.setVisibility(View.VISIBLE);
mVideoView.setVisibility(View.INVISIBLE);
mImageView.setSaveEnabled(true);
Button photoBtn = (Button) findViewById(R.id.click);
setBtnListenerOrDisable(photoBtn, mTakePicOnClickListener, MediaStore.ACTION_IMAGE_CAPTURE);
Button videoBtn = (Button) findViewById(R.id.record_video);
setBtnListenerOrDisable(videoBtn, mTakeVidOnClickListener, MediaStore.ACTION_VIDEO_CAPTURE);
mPhotoStorageDirFactory = new BasePhotoDirFactory();
// Shows the up carat near app icon in ActionBar
getSupportActionBar().setDisplayUseLogoEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
public void viewCollection(View v){
// finishes/restarts the activity so the unsaved video does not corrupt
Intent intent = getIntent();
finish();
startActivity(intent);
// goes to Cute Collection activity
Intent i = new Intent(this, CuteCollection.class);
startActivity(i);
}
private File getAlbumDir() {
File storageDir = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
storageDir = mPhotoStorageDirFactory.getAlbumStorageDir(getAlbumName());
if (storageDir != null) {
if (! storageDir.mkdirs()) {
if (! storageDir.exists()){
Log.d("Camera", "failed to create directory");
return null;
}
}
}
} else {
Log.v(getString(R.string.app_name), "External storage is not mounted READ/WRITE.");
}
return storageDir;
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = JPEG_FILE_PREFIX + timeStamp + "_";
File albumF = getAlbumDir();
File imageF = File.createTempFile(imageFileName, JPEG_FILE_SUFFIX, albumF);
return imageF;
}
private File setUpPhotoFile() throws IOException {
File f = createImageFile();
mCurrentPhotoPath = f.getAbsolutePath();
return f;
}
private Bitmap setPic() {
mImageView.setVisibility(View.VISIBLE);
mVideoView.setVisibility(View.INVISIBLE);
/* There isn't enough memory to open up more than a couple camera photos */
/* So pre-scale the target bitmap into which the file is decoded */
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
targetH = 570;
targetW = 960;
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
targetH = 960;
targetW = 570;
}
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
/* Figure out which way needs to be reduced less */
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
/* Set bitmap options to scale the image decode target */
bmOptions.inJustDecodeBounds = false;
bmOptions.inPreferredConfig = Bitmap.Config.RGB_565;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inBitmap = mImageBitmap;
bmOptions.inPurgeable = true;
/* Decode the JPEG file into a Bitmap */
mImageBitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
mImageBitmap = rotateBitmap(mImageBitmap, 90);
}
return mImageBitmap;
}
private class SavePhotoTask extends AsyncTask<Bitmap, Void, Bitmap>{
@Override
protected void onPreExecute() {
super.onPreExecute();
progressPhoto.setMessage("Saving cute photo ...");
//set the progress bar to cancelable on back button
progressPhoto.setCancelable(true);
progressPhoto.show();
}
@Override
protected Bitmap doInBackground(Bitmap... params) {
savePhoto(mImageBitmap);
return mImageBitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
progressPhoto.dismiss();
/* Associate the Bitmap to the ImageView, make sure the VideoView
* is cleared to replace with ImageView */
mImageView.setImageBitmap(mImageBitmap);
mVideoUri = null;
}
}
// save your photo to SD card
private void savePhoto(final Bitmap bitmapPhoto){
// set OnClickListener to save the photo
mImageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
boolean success = false;
File photoDir = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES) + "/Cute Photos");
photoDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String photoName = "Photo" + n + ".jpg";
File filePhoto = new File(photoDir, photoName);
try {
FileOutputStream out = new FileOutputStream(filePhoto);
bitmapPhoto.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
success = true;
} catch (Exception e) {
e.printStackTrace();
}
if (success) {
Toast toast = Toast.makeText(getApplicationContext(), "Cute photo saved!",
Toast.LENGTH_LONG);
LinearLayout toastLayout = (LinearLayout) toast.getView();
toastLayout.setBackgroundColor(getResources().getColor(R.color.toast_color));
TextView toastTV = (TextView) toastLayout.getChildAt(0);
toastTV.setTextSize(25);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 80);
toast.show();
} else {
Toast.makeText(getApplicationContext(),
"Error during image saving", Toast.LENGTH_SHORT).show();
}
}
});
}
private class SaveVideoTask extends AsyncTask<Uri, Void, Uri> {
@Override
protected void onPreExecute() {
super.onPreExecute();
progressVideo.setMessage("Saving cute video ...");
//set the progress bar to cancelable on back button
progressVideo.setCancelable(true);
progressVideo.show();
}
@Override
protected Uri doInBackground(Uri... params) {
return saveVideo(mVideoUri);
}
@Override
protected void onPostExecute(Uri result) {
progressVideo.dismiss();
}
}
// save your video to SD card
protected Uri saveVideo(final Uri uriVideo){
// click the video to save it
mVideoView.setOnTouchListener(new View.OnTouchListener() {
boolean success = false;
boolean savedOnce = false;
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP) {
if (mVideoView.isPlaying()) {
mVideoView.pause();
}
if (!savedOnce) {
try {
// make the directory
File vidDir = new File(android.os.Environment
.getExternalStoragePublicDirectory
(Environment.DIRECTORY_MOVIES) +
File.separator + "Cute Videos");
vidDir.mkdirs();
// create unique identifier
Random generator = new Random();
int n = 100;
n = generator.nextInt(n);
// create file name
String videoName = "Video" + n + ".mp4";
fileVideo = new File(vidDir.getAbsolutePath(), videoName);
videoPath = fileVideo.getAbsolutePath();
fileVideo.setWritable(true, false);
OutputStream out = new FileOutputStream(fileVideo);
InputStream in = getContentResolver().openInputStream(uriVideo);
byte buffer[] = new byte[1024];
int length = 0;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
out.close();
in.close();
success = true;
} catch (Exception e) {
e.printStackTrace();
}
if (success) {
Toast toast = Toast.makeText(getApplicationContext(), "Cute video saved!",
Toast.LENGTH_SHORT);
LinearLayout toastLayout = (LinearLayout) toast.getView();
toastLayout.setBackgroundColor(getResources().getColor(R.color.toast_color));
TextView toastTV = (TextView) toastLayout.getChildAt(0);
toastTV.setTextSize(30);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 80);
toast.show();
} else {
Toast.makeText(getApplicationContext(),
"Error during video saving", Toast.LENGTH_SHORT).show();
}
savedOnce = true;
}
}
return true;
}
});
return uriVideo;
}
public Bitmap rotateBitmap(Bitmap source, int angle)
{
Matrix matrix = new Matrix();
matrix.set(matrix);
matrix.setRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(),
source.getHeight(), matrix, false);
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE");
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
private void dispatchTakePictureIntent(int actionCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
switch(actionCode) {
case ACTION_TAKE_PHOTO:
File f;
try {
f = setUpPhotoFile();
Log.d("TAG", "Value of f in picture intent: " + f);
mCurrentPhotoPath = f.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
} catch (IOException e) {
e.printStackTrace();
f = null;
mCurrentPhotoPath = null;
}
break;
default:
break;
} // switch
startActivityForResult(takePictureIntent, actionCode);
}
// Captures video from Android camera component
protected void dispatchTakeVideoIntent() {
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {
// set the video image quality to high
takeVideoIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
// limit video to 30 seconds
takeVideoIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 30);
startActivityForResult(takeVideoIntent, ACTION_TAKE_VIDEO);
}
}
private void handleCameraPhoto() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
if (mCurrentPhotoPath != null) {
setPic();
// saves photo & sets to ImageView
new SavePhotoTask().execute();
galleryAddPic();
mCurrentPhotoPath = null;
}
}
// Post recorded video into VideoView
private Uri handleCameraVideo(Intent intent) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
mVideoUri = intent.getData();
mVideoView.setVideoURI(mVideoUri);
mImageBitmap = null;
mVideoView.setVisibility(View.VISIBLE);
mImageView.setVisibility(View.INVISIBLE);
mVideoView.start();
new SaveVideoTask().execute();
return mVideoUri;
}
// click listener for the Android Camera button (not my app's button)
Button.OnClickListener mTakePicOnClickListener =
new Button.OnClickListener() {
@Override
public void onClick(View v) {
dispatchTakePictureIntent(ACTION_TAKE_PHOTO);
// releases the orientation lock
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
};
Button.OnClickListener mTakeVidOnClickListener =
new Button.OnClickListener() {
@Override
public void onClick(View v) {
dispatchTakeVideoIntent();
// releases the orientation lock
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
};
// Intent data is how the photo and video transfer into their views
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case ACTION_TAKE_PHOTO: {
if (resultCode == RESULT_OK) {
handleCameraPhoto();
}
break;
}
case ACTION_TAKE_VIDEO: {
if (resultCode == RESULT_OK) {
handleCameraVideo(data);
}
break;
}
}
}
/*Taken out code ...*/
}
进行以下更改以在当前实施中正确使用 AsyncTask
:
1.把mImageView
按钮的onclick方法代码移到doInBackground
里面
2. 通过点击 mImageView
按钮
在 onPostExecute
中添加 if (success) {...}else{...}
块
3. 在 mImageView
上启动 SavePhotoTask
任务 单击按钮在后台线程中执行繁重的任务
我有两个 AsyncTasks,它们包含将照片和视频保存到文件的代码。我使用了我创建的其他 类 中的工作 AsyncTask 代码,但由于某种原因它们在这里不起作用。这是 2 个问题:
我没有看到进度对话框
我仍然在控制台中看到消息说 "skipped 276 frames! Doing too much work on the main thread."
但是,当我的 doInBackground()
中有储蓄时,那怎么可能呢?我的照片和视频确实保存了,所以我知道 doInBackground()
运行。但是我不知道为什么进度对话框根本不显示。我在 Stack 上寻找答案,但没有解决我的情况。我的上下文正确,onPreExecute()
中没有参数,没有使用 get()
,并且此问题的其他答案不适用。
感谢您的帮助。
更新
感谢@perosperK,我将 ImageView
联系人完全移出 doInBackground()
,这意味着我必须在其他地方调用点击监听器。我还将我的 Toast
结果放入 onPostExecute()
中,这些更改完全奏效了!我现在看到了照片和视频的进度对话框。 :) 下面是工作代码,虽然我只能 post 更改代码的片段,因为我已经达到了 StackO 的字符限制:
工作MakePhotoVideo.java
public void enableClickListener(){
mImageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// saves photo & sets to ImageView
new SavePhotoTask().execute();
}
});
}
private Bitmap setPic() {
/*Taken out code ...*/
/* Set Bitmap to the ImageView, make sure the VideoView is cleared to replace with ImageView */
mImageView.setImageBitmap(mImageBitmap);
// enable the click listener here, so don't save empty files before this
enableClickListener();
// make sure video view is invisible
mVideoUri = null;
return mImageBitmap;
}
private class SavePhotoTask extends AsyncTask<Bitmap, Void, Bitmap>{
@Override
protected void onPreExecute() {
super.onPreExecute();
// instantiate your photo progress dialog
progressPhoto = new ProgressDialog(MakePhotoVideo.this);
progressPhoto.setMessage("Saving cute photo ...");
//set the progress bar to cancelable on back button
progressPhoto.setCancelable(true);
progressPhoto.show();
}
@Override
protected Bitmap doInBackground(Bitmap... params) {
photoSave(mImageBitmap);
return mImageBitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
progressPhoto.dismiss();
if (successPhoto) {
Toast toast = Toast.makeText(getApplicationContext(), "Cute photo saved!",
Toast.LENGTH_LONG);
LinearLayout toastLayout = (LinearLayout) toast.getView();
toastLayout.setBackgroundColor(getResources().getColor(R.color.toast_color));
TextView toastTV = (TextView) toastLayout.getChildAt(0);
toastTV.setTextSize(25);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 80);
toast.show();
} else {
Toast.makeText(getApplicationContext(),
"Error during image saving", Toast.LENGTH_SHORT).show();
}
mImageView.setOnClickListener(null);
}
}
// saves photo to SD card
private Boolean photoSave(final Bitmap bitmapPhoto){
/*Taken out code ...*/
return successPhoto;
}
private class SaveVideoTask extends AsyncTask<Uri, Void, Uri> {
@Override
protected void onPreExecute() {
super.onPreExecute();
// instantiate your video progress dialog
progressVideo = new ProgressDialog(MakePhotoVideo.this);
progressVideo.setMessage("Saving cute video ...");
//set the progress bar to cancelable on back button
progressVideo.setCancelable(true);
progressVideo.show();
}
@Override
protected Uri doInBackground(Uri... params) {
return videoSave(mVideoUri);
}
@Override
protected void onPostExecute(Uri result) {
progressVideo.dismiss();
if (successVideo) {
Toast toast = Toast.makeText(getApplicationContext(), "Cute video saved!",
Toast.LENGTH_SHORT);
LinearLayout toastLayout = (LinearLayout) toast.getView();
toastLayout.setBackgroundColor(getResources().getColor(R.color.toast_color));
TextView toastTV = (TextView) toastLayout.getChildAt(0);
toastTV.setTextSize(30);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 80);
toast.show();
} else {
Toast.makeText(getApplicationContext(),
"Error during video saving", Toast.LENGTH_SHORT).show();
}
}
}
// enables the VideoView listener
protected void enableTouchListener(){
// click the video to save it
mVideoView.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP) {
new SaveVideoTask().execute();
}
return true;
}
});
}
private void handleCameraPhoto() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
if (mCurrentPhotoPath != null) {
setPic();
galleryAddPic();
mCurrentPhotoPath = null;
}
}
// Post recorded video into VideoView
private Uri handleCameraVideo(Intent intent) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
mVideoUri = intent.getData();
mVideoView.setVideoURI(mVideoUri);
mImageBitmap = null;
mVideoView.setVisibility(View.VISIBLE);
mImageView.setVisibility(View.INVISIBLE);
mVideoView.start();
enableTouchListener();
return mVideoUri;
}
下面是无效代码
MakePhotoVideo.java
package org.azurespot.makecute;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Gravity;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.VideoView;
import org.azurespot.R;
import org.azurespot.cutecollection.CuteCollection;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;
public class MakePhotoVideo extends ActionBarActivity {
private static final int ACTION_TAKE_PHOTO = 1;
private static final int ACTION_TAKE_VIDEO = 2;
private static final String BITMAP_STORAGE_KEY = "viewbitmap";
private static final String IMAGEVIEW_VISIBILITY_STORAGE_KEY = "imageviewvisibility";
private ImageView mImageView;
private Bitmap mImageBitmap;
private static final String VIDEO_STORAGE_KEY = "viewvideo";
private static final String VIDEOVIEW_VISIBILITY_STORAGE_KEY = "videoviewvisibility";
private VideoView mVideoView;
private Uri mVideoUri;
private File fileVideo;
private String mCurrentPhotoPath;
String videoPath;
private int position = 0;
int targetH;
int targetW;
private static final String JPEG_FILE_PREFIX = "IMG_";
private static final String JPEG_FILE_SUFFIX = ".jpg";
private PhotoStorageDirFactory mPhotoStorageDirFactory = null;
private ProgressDialog progressPhoto;
private ProgressDialog progressVideo;
/* Photo album for this application */
private String getAlbumName() {
return getString(R.string.album_name);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_make_photo_video);
// instantiate your photo progress dialog
progressPhoto = new ProgressDialog(MakePhotoVideo.this);
// instantiate your video progress dialog
progressVideo = new ProgressDialog(MakePhotoVideo.this);
mImageView = (ImageView) findViewById(R.id.taken_photo);
mVideoView = (VideoView) findViewById(R.id.video_view);
mImageView.setVisibility(View.VISIBLE);
mVideoView.setVisibility(View.INVISIBLE);
mImageView.setSaveEnabled(true);
Button photoBtn = (Button) findViewById(R.id.click);
setBtnListenerOrDisable(photoBtn, mTakePicOnClickListener, MediaStore.ACTION_IMAGE_CAPTURE);
Button videoBtn = (Button) findViewById(R.id.record_video);
setBtnListenerOrDisable(videoBtn, mTakeVidOnClickListener, MediaStore.ACTION_VIDEO_CAPTURE);
mPhotoStorageDirFactory = new BasePhotoDirFactory();
// Shows the up carat near app icon in ActionBar
getSupportActionBar().setDisplayUseLogoEnabled(false);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
public void viewCollection(View v){
// finishes/restarts the activity so the unsaved video does not corrupt
Intent intent = getIntent();
finish();
startActivity(intent);
// goes to Cute Collection activity
Intent i = new Intent(this, CuteCollection.class);
startActivity(i);
}
private File getAlbumDir() {
File storageDir = null;
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
storageDir = mPhotoStorageDirFactory.getAlbumStorageDir(getAlbumName());
if (storageDir != null) {
if (! storageDir.mkdirs()) {
if (! storageDir.exists()){
Log.d("Camera", "failed to create directory");
return null;
}
}
}
} else {
Log.v(getString(R.string.app_name), "External storage is not mounted READ/WRITE.");
}
return storageDir;
}
private File createImageFile() throws IOException {
// Create an image file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = JPEG_FILE_PREFIX + timeStamp + "_";
File albumF = getAlbumDir();
File imageF = File.createTempFile(imageFileName, JPEG_FILE_SUFFIX, albumF);
return imageF;
}
private File setUpPhotoFile() throws IOException {
File f = createImageFile();
mCurrentPhotoPath = f.getAbsolutePath();
return f;
}
private Bitmap setPic() {
mImageView.setVisibility(View.VISIBLE);
mVideoView.setVisibility(View.INVISIBLE);
/* There isn't enough memory to open up more than a couple camera photos */
/* So pre-scale the target bitmap into which the file is decoded */
/* Get the size of the image */
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
bmOptions.inJustDecodeBounds = true;
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
targetH = 570;
targetW = 960;
} else if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
targetH = 960;
targetW = 570;
}
BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
int photoW = bmOptions.outWidth;
int photoH = bmOptions.outHeight;
/* Figure out which way needs to be reduced less */
int scaleFactor = Math.min(photoW/targetW, photoH/targetH);
/* Set bitmap options to scale the image decode target */
bmOptions.inJustDecodeBounds = false;
bmOptions.inPreferredConfig = Bitmap.Config.RGB_565;
bmOptions.inSampleSize = scaleFactor;
bmOptions.inBitmap = mImageBitmap;
bmOptions.inPurgeable = true;
/* Decode the JPEG file into a Bitmap */
mImageBitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
mImageBitmap = rotateBitmap(mImageBitmap, 90);
}
return mImageBitmap;
}
private class SavePhotoTask extends AsyncTask<Bitmap, Void, Bitmap>{
@Override
protected void onPreExecute() {
super.onPreExecute();
progressPhoto.setMessage("Saving cute photo ...");
//set the progress bar to cancelable on back button
progressPhoto.setCancelable(true);
progressPhoto.show();
}
@Override
protected Bitmap doInBackground(Bitmap... params) {
savePhoto(mImageBitmap);
return mImageBitmap;
}
@Override
protected void onPostExecute(Bitmap result) {
progressPhoto.dismiss();
/* Associate the Bitmap to the ImageView, make sure the VideoView
* is cleared to replace with ImageView */
mImageView.setImageBitmap(mImageBitmap);
mVideoUri = null;
}
}
// save your photo to SD card
private void savePhoto(final Bitmap bitmapPhoto){
// set OnClickListener to save the photo
mImageView.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
boolean success = false;
File photoDir = new File(Environment.getExternalStoragePublicDirectory
(Environment.DIRECTORY_PICTURES) + "/Cute Photos");
photoDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String photoName = "Photo" + n + ".jpg";
File filePhoto = new File(photoDir, photoName);
try {
FileOutputStream out = new FileOutputStream(filePhoto);
bitmapPhoto.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
success = true;
} catch (Exception e) {
e.printStackTrace();
}
if (success) {
Toast toast = Toast.makeText(getApplicationContext(), "Cute photo saved!",
Toast.LENGTH_LONG);
LinearLayout toastLayout = (LinearLayout) toast.getView();
toastLayout.setBackgroundColor(getResources().getColor(R.color.toast_color));
TextView toastTV = (TextView) toastLayout.getChildAt(0);
toastTV.setTextSize(25);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 80);
toast.show();
} else {
Toast.makeText(getApplicationContext(),
"Error during image saving", Toast.LENGTH_SHORT).show();
}
}
});
}
private class SaveVideoTask extends AsyncTask<Uri, Void, Uri> {
@Override
protected void onPreExecute() {
super.onPreExecute();
progressVideo.setMessage("Saving cute video ...");
//set the progress bar to cancelable on back button
progressVideo.setCancelable(true);
progressVideo.show();
}
@Override
protected Uri doInBackground(Uri... params) {
return saveVideo(mVideoUri);
}
@Override
protected void onPostExecute(Uri result) {
progressVideo.dismiss();
}
}
// save your video to SD card
protected Uri saveVideo(final Uri uriVideo){
// click the video to save it
mVideoView.setOnTouchListener(new View.OnTouchListener() {
boolean success = false;
boolean savedOnce = false;
public boolean onTouch(View v, MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_UP) {
if (mVideoView.isPlaying()) {
mVideoView.pause();
}
if (!savedOnce) {
try {
// make the directory
File vidDir = new File(android.os.Environment
.getExternalStoragePublicDirectory
(Environment.DIRECTORY_MOVIES) +
File.separator + "Cute Videos");
vidDir.mkdirs();
// create unique identifier
Random generator = new Random();
int n = 100;
n = generator.nextInt(n);
// create file name
String videoName = "Video" + n + ".mp4";
fileVideo = new File(vidDir.getAbsolutePath(), videoName);
videoPath = fileVideo.getAbsolutePath();
fileVideo.setWritable(true, false);
OutputStream out = new FileOutputStream(fileVideo);
InputStream in = getContentResolver().openInputStream(uriVideo);
byte buffer[] = new byte[1024];
int length = 0;
while ((length = in.read(buffer)) > 0) {
out.write(buffer, 0, length);
}
out.close();
in.close();
success = true;
} catch (Exception e) {
e.printStackTrace();
}
if (success) {
Toast toast = Toast.makeText(getApplicationContext(), "Cute video saved!",
Toast.LENGTH_SHORT);
LinearLayout toastLayout = (LinearLayout) toast.getView();
toastLayout.setBackgroundColor(getResources().getColor(R.color.toast_color));
TextView toastTV = (TextView) toastLayout.getChildAt(0);
toastTV.setTextSize(30);
toast.setGravity(Gravity.CENTER_VERTICAL, 0, 80);
toast.show();
} else {
Toast.makeText(getApplicationContext(),
"Error during video saving", Toast.LENGTH_SHORT).show();
}
savedOnce = true;
}
}
return true;
}
});
return uriVideo;
}
public Bitmap rotateBitmap(Bitmap source, int angle)
{
Matrix matrix = new Matrix();
matrix.set(matrix);
matrix.setRotate(angle);
return Bitmap.createBitmap(source, 0, 0, source.getWidth(),
source.getHeight(), matrix, false);
}
private void galleryAddPic() {
Intent mediaScanIntent = new Intent("android.intent.action.MEDIA_SCANNER_SCAN_FILE");
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
this.sendBroadcast(mediaScanIntent);
}
private void dispatchTakePictureIntent(int actionCode) {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
switch(actionCode) {
case ACTION_TAKE_PHOTO:
File f;
try {
f = setUpPhotoFile();
Log.d("TAG", "Value of f in picture intent: " + f);
mCurrentPhotoPath = f.getAbsolutePath();
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
} catch (IOException e) {
e.printStackTrace();
f = null;
mCurrentPhotoPath = null;
}
break;
default:
break;
} // switch
startActivityForResult(takePictureIntent, actionCode);
}
// Captures video from Android camera component
protected void dispatchTakeVideoIntent() {
Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
if (takeVideoIntent.resolveActivity(getPackageManager()) != null) {
// set the video image quality to high
takeVideoIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
// limit video to 30 seconds
takeVideoIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 30);
startActivityForResult(takeVideoIntent, ACTION_TAKE_VIDEO);
}
}
private void handleCameraPhoto() {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
if (mCurrentPhotoPath != null) {
setPic();
// saves photo & sets to ImageView
new SavePhotoTask().execute();
galleryAddPic();
mCurrentPhotoPath = null;
}
}
// Post recorded video into VideoView
private Uri handleCameraVideo(Intent intent) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
mVideoUri = intent.getData();
mVideoView.setVideoURI(mVideoUri);
mImageBitmap = null;
mVideoView.setVisibility(View.VISIBLE);
mImageView.setVisibility(View.INVISIBLE);
mVideoView.start();
new SaveVideoTask().execute();
return mVideoUri;
}
// click listener for the Android Camera button (not my app's button)
Button.OnClickListener mTakePicOnClickListener =
new Button.OnClickListener() {
@Override
public void onClick(View v) {
dispatchTakePictureIntent(ACTION_TAKE_PHOTO);
// releases the orientation lock
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
};
Button.OnClickListener mTakeVidOnClickListener =
new Button.OnClickListener() {
@Override
public void onClick(View v) {
dispatchTakeVideoIntent();
// releases the orientation lock
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
}
};
// Intent data is how the photo and video transfer into their views
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case ACTION_TAKE_PHOTO: {
if (resultCode == RESULT_OK) {
handleCameraPhoto();
}
break;
}
case ACTION_TAKE_VIDEO: {
if (resultCode == RESULT_OK) {
handleCameraVideo(data);
}
break;
}
}
}
/*Taken out code ...*/
}
进行以下更改以在当前实施中正确使用 AsyncTask
:
1.把mImageView
按钮的onclick方法代码移到doInBackground
2. 通过点击 mImageView
按钮
onPostExecute
中添加 if (success) {...}else{...}
块
3. 在 mImageView
上启动 SavePhotoTask
任务 单击按钮在后台线程中执行繁重的任务