package com.tistory.link2me.imageupload;
import android.Manifest; import android.app.Activity; import android.app.ActivityManager; import android.app.AlertDialog; import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; import android.database.Cursor; import android.graphics.Bitmap; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.provider.Settings; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.text.TextUtils; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.Toast;
import com.squareup.picasso.Picasso; import com.tistory.link2me.common.BackPressHandler; import com.tistory.link2me.common.JSONParser; import com.tistory.link2me.common.NetworkHelper;
import org.json.JSONException; import org.json.JSONObject;
import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.List;
public class PhotoActivity extends Activity { Context mContext;
private static final int PICK_FROM_CAMERA = 0; //카메라 촬영으로 사진 가져오기 private static final int PICK_FROM_ALBUM = 1; //앨범에서 사진 가져오기 private static final int CROP_FROM_CAMERA = 2; // 가져온 사진을 자르기 위한 변수 private static final int PICK_FROM_File = 3; //앨범에서 사진 가져오기(원본 올리기)
private static Uri mImageCaptureUri; // Stactic 으로 설정해야 에러 발생하지 않음. private String imagePath; private ImageView imageView; private Bitmap photoBitmap; String saveFolderName = "cameraTemp"; File mediaFile = null; String saveFileName = "myphoto.jpg";
ProgressDialog mProgressDialog; private BackPressHandler backPressHandler;
private String[] permissions = { Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO }; private static final int MULTIPLE_PERMISSIONS = 101;
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_photo); mContext = this.getBaseContext(); backPressHandler = new BackPressHandler(this); // 뒤로 가기 버튼 이벤트
System.out.println("프로세스당 메모리 용량 : " + ((ActivityManager)getSystemService(Context.ACTIVITY_SERVICE)).getMemoryClass()); System.out.println("largeHeap 크기 : " + ((ActivityManager)getSystemService(Context.ACTIVITY_SERVICE)).getLargeMemoryClass()); System.out.println("패키지 설치 경로 : " + getApplicationContext().getFilesDir().getAbsolutePath().replace("files", ""));
checkPermissions(); initView(); }
private void initView() { imageView = (ImageView) findViewById(R.id.croppedImageView); imageView.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { AlertDialog.Builder builder = new AlertDialog.Builder(PhotoActivity.this); builder.setMessage("업로드할 이미지 선택"); DialogInterface.OnClickListener cameraListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { doTakePhotoAction(); } };
DialogInterface.OnClickListener albumListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { getGallery(); // 갤러리(앨범)에서 이미지 가져오기 } };
DialogInterface.OnClickListener cancelListener = new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); }
}; builder.setTitle("업로드할 이미지 선택"); builder.setPositiveButton("사진촬영", cameraListener); builder.setNeutralButton("앨범선택", albumListener); builder.setNegativeButton("취소", cancelListener); builder.show();
} });
Button btn_UploadPhoto = (Button) findViewById(R.id.btn_Upload); btn_UploadPhoto.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { if (TextUtils.isEmpty(imagePath)) { Toast.makeText(getApplicationContext(), "업로드할 사진을 선택해주세요", Toast.LENGTH_SHORT).show(); } else { if (NetworkHelper.checkConnection(mContext)) { // 인터넷 연결 체크 Log.d("Photo", "Photo Upload Task Start"); String ImageUploadURL = Value.IPADDRESS + "/upload.php"; ImageUploadTask imageUploadTask = new ImageUploadTask(); imageUploadTask.execute(ImageUploadURL, imagePath); } else { Toast.makeText(mContext, "인터넷 연결을 확인하세요", Toast.LENGTH_LONG).show(); } } } });
}
private Boolean isAirModeOn() { Boolean isAirplaneMode; if(Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1){ isAirplaneMode = Settings.System.getInt(getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) == 1; }else{ isAirplaneMode = Settings.Global.getInt(getContentResolver(), Settings.Global.AIRPLANE_MODE_ON, 0) == 1; } return isAirplaneMode; }
/** * 카메라에서 사진 촬영 */ private void doTakePhotoAction() { // 카메라 앱을 이용하여 사진 찍기 // Intent를 사용하여 안드로이드에서 기본적으로 제공해주는 카메라를 이용하는 방법 이용 Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 이미지가 저장될 파일은 카메라 앱이 구동되기 전에 세팅해서 넘겨준다. cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, getImageUri(saveFileName)); // null cameraIntent.putExtra("return-data", true); startActivityForResult(cameraIntent, PICK_FROM_CAMERA); // 7.0 에서는 에러가 발생함. (API26 으로 컴파일 한 경우) }
// 사진 선택을 위해 갤러리를 호출 private void getGallery() { // File System. final Intent galleryIntent = new Intent(); galleryIntent.setType("image/*"); // 이미지 파일 호출 galleryIntent.setAction(Intent.ACTION_PICK);
// Chooser of file system options. final Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Image"); galleryIntent.setType(MediaStore.Images.Media.CONTENT_TYPE); //startActivityForResult(chooserIntent, PICK_FROM_File); startActivityForResult(chooserIntent, PICK_FROM_ALBUM); }
private Uri getImageUri(String saveFile) { // 임시로 사용할 파일의 경로를 생성 File mediaStorageDir = new File(Environment.getExternalStorageDirectory() + "/DCIM", saveFolderName); if (! mediaStorageDir.exists()){ if (! mediaStorageDir.mkdirs()){ Log.d("MyCameraApp", "failed to create directory"); return null; } }
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); if(saveFile != null){ mediaFile = new File(mediaStorageDir.getPath() + File.separator + saveFile); } else { mediaFile = new File(mediaStorageDir.getPath() + File.separator + "pic_"+ timeStamp + ".jpg"); } mImageCaptureUri = Uri.fromFile(mediaFile); imagePath = mImageCaptureUri.getPath(); Log.e("mImageCaptureUri : ", mImageCaptureUri.toString()); Log.e("imagePath : ", imagePath);
return mImageCaptureUri; }
public String getRealPathFromURI(Uri contentUri) { String[] proj = { MediaStore.Images.Media.DATA }; Cursor cursor = getContentResolver().query(contentUri, proj, null, null, null); int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); }
@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(resultCode != Activity.RESULT_OK) return; switch (requestCode){ case PICK_FROM_ALBUM: { mImageCaptureUri = data.getData(); Log.e("앨범이미지 CROP",mImageCaptureUri.getPath().toString()); imagePath = getRealPathFromURI(mImageCaptureUri); // 실제 파일이 존재하는 경로 Log.e("앨범이미지 경로",imagePath); }
case PICK_FROM_CAMERA: {
// 이미지를 가져온 이후의 리사이즈할 이미지 크기를 결정 Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(mImageCaptureUri, "image/*");
// CROP할 이미지를 125*170 크기로 저장 intent.putExtra("outputX", 125); // CROP한 이미지의 x축 크기 intent.putExtra("outputY", 170); // CROP한 이미지의 y축 크기 intent.putExtra("aspectX", 1); // CROP 박스의 X축 비율 intent.putExtra("aspectY", 1); // CROP 박스의 Y축 비율 intent.putExtra("scale", true); intent.putExtra("return-data", true);
startActivityForResult(intent, CROP_FROM_CAMERA); // CROP_FROM_CAMERA case문 이동 break; }
case CROP_FROM_CAMERA: { // CROP 된 이후의 이미지를 넘겨 받음 final Bundle extras = data.getExtras();
// CROP 된 이미지를 저장하기 위한 File 경로 설정 String filePath = getImageUri(saveFileName).getPath(); Log.e("mImageCaptureUri : ", "Croped " + mImageCaptureUri.toString());
imagePath = filePath;
if(extras != null) { //photoBitmap = extras.getParcelable("data"); // CROP된 BITMAP photoBitmap = (Bitmap)data.getExtras().get("data"); // CROP된 BITMAP // 레이아웃의 이미지칸에 CROP된 BITMAP을 보여줌 saveCropImage(photoBitmap,imagePath); // CROP 된 이미지를 외부저장소, 앨범에 저장한다. // sendBroadcast를 통해 Crop된 사진을 앨범에 보이도록 갱신한다. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { sendBroadcast(new Intent( Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(mediaFile)) ); } else { sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://"+ Environment.getExternalStorageDirectory()))); } }
Picasso.with(mContext).load(new File(imagePath)) .into(imageView); // 피카소 라이브러를 이용하여 선택한 이미지를 imageView에 출력
break; } case PICK_FROM_File: { // URI 정보를 이용하여 이미지(사진) 정보를 가져온다. if (data == null) { Toast.makeText(mContext, "Unable to Pickup Image", Toast.LENGTH_SHORT).show(); return; } Uri selectedImageUri = data.getData(); Log.e("IMAGE SEL", "" + selectedImageUri); String[] filePathColumn = {MediaStore.Images.Media.DATA};
Cursor cursor = getContentResolver().query(selectedImageUri, filePathColumn, null, null, null);
if (cursor != null) { cursor.moveToFirst();
imagePath = cursor.getString(cursor.getColumnIndex(filePathColumn[0])); Log.e("IMAGE SEL imagePath : ", imagePath);
Picasso.with(mContext).load(new File(imagePath)) .into(imageView); // 피카소 라이브러를 이용하여 선택한 이미지를 imageView에 출력 cursor.close();
}
break; } }
}
// Bitmap 을 저장하는 메소드 private void saveCropImage(Bitmap bitmap, String filePath) { //read image file File copyFile = new File(filePath); BufferedOutputStream bos = null; try { copyFile.createNewFile(); int quality = 100; bos = new BufferedOutputStream(new FileOutputStream(copyFile)); bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bos); // 이미지가 클 경우 OutOfMemoryException 발생이 예상되어 압축 bos.flush(); bos.close(); } catch (Exception e) { e.printStackTrace(); } }
class ImageUploadTask extends AsyncTask<String, Integer, Boolean> { ProgressDialog progressDialog; // API 26에서 deprecated
@Override protected void onPreExecute() { super.onPreExecute(); progressDialog = new ProgressDialog(PhotoActivity.this); progressDialog.setMessage("이미지 업로드중...."); progressDialog.show(); }
@Override protected Boolean doInBackground(String... params) { try { JSONObject jsonObject = JSONParser.uploadImage(params[0],params[1]); if (jsonObject != null) return jsonObject.getString("result").equals("success");
} catch (JSONException e) { Log.i("TAG", "Error : " + e.getLocalizedMessage()); } return false; }
@Override protected void onPostExecute(Boolean aBoolean) { super.onPostExecute(aBoolean); if (progressDialog != null) progressDialog.dismiss();
if (aBoolean){ Toast.makeText(getApplicationContext(), "파일 업로드 성공", Toast.LENGTH_LONG).show(); } else{ Toast.makeText(getApplicationContext(), "파일 업로드 실패", Toast.LENGTH_LONG).show(); }
// 임시 파일 삭제 (카메라로 사진 촬영한 이미지) if(mImageCaptureUri != null){ File file = new File(mImageCaptureUri.getPath()); if(file.exists()) { file.delete(); } mImageCaptureUri = null; }
if (aBoolean){ imagePath = null; } }
}
@Override public void onBackPressed() { backPressHandler.onBackPressed(); }
public boolean checkPermissions() { int result; List<String> permissionList = new ArrayList<>(); for (String pm : permissions) { result = ContextCompat.checkSelfPermission(this, pm); if (result != PackageManager.PERMISSION_GRANTED) { permissionList.add(pm); } } if (!permissionList.isEmpty()) { ActivityCompat.requestPermissions(this, permissionList.toArray(new String[permissionList.size()]), MULTIPLE_PERMISSIONS); return false; } return true; }
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MULTIPLE_PERMISSIONS: { if (grantResults.length > 0) { for (int i = 0; i < permissions.length; i++) { if (permissions[i].equals(this.permissions[i])) { if (grantResults[i] != PackageManager.PERMISSION_GRANTED) { showToast_PermissionDeny(); } } } } else { showToast_PermissionDeny(); } return; } } }
public void showToast_PermissionDeny() { Toast.makeText(this, "권한 요청에 동의 해주셔야 이용 가능합니다. 설정에서 권한 허용 하시기 바랍니다.", Toast.LENGTH_SHORT).show(); finish(); } }
|