Guest User

Untitled

a guest
Jun 22nd, 2018
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.11 KB | None | 0 0
  1. package de.ebuero.android.feedback.appfeedback;
  2.  
  3. import android.Manifest;
  4. import android.app.Activity;
  5. import android.content.Context;
  6. import android.content.DialogInterface;
  7. import android.content.Intent;
  8. import android.content.pm.PackageManager;
  9. import android.database.Cursor;
  10. import android.graphics.Bitmap;
  11. import android.graphics.BitmapFactory;
  12. import android.graphics.Color;
  13. import android.graphics.Matrix;
  14. import android.media.ExifInterface;
  15. import android.net.Uri;
  16. import android.os.Build;
  17. import android.os.Bundle;
  18. import android.provider.MediaStore;
  19. import android.support.annotation.NonNull;
  20. import android.support.v4.app.ActivityCompat;
  21. import android.support.v4.content.PermissionChecker;
  22. import android.support.v7.app.AlertDialog;
  23. import android.util.Log;
  24. import android.view.View;
  25. import android.view.inputmethod.InputMethodManager;
  26. import android.widget.CheckBox;
  27. import android.widget.EditText;
  28. import android.widget.ImageView;
  29. import android.widget.ListAdapter;
  30. import android.widget.RelativeLayout;
  31. import android.widget.TextView;
  32. import android.widget.Toast;
  33.  
  34. import com.afollestad.materialdialogs.MaterialDialog;
  35. import com.afollestad.materialdialogs.simplelist.MaterialSimpleListAdapter;
  36. import com.afollestad.materialdialogs.simplelist.MaterialSimpleListItem;
  37. import com.google.firebase.perf.FirebasePerformance;
  38. import com.google.firebase.perf.metrics.Trace;
  39. import com.google.firebase.storage.FirebaseStorage;
  40. import com.google.firebase.storage.StorageMetadata;
  41. import com.google.firebase.storage.StorageReference;
  42. import com.google.firebase.storage.StorageTask;
  43. import com.google.firebase.storage.UploadTask;
  44. import com.google.firebase.storage.UploadTask.TaskSnapshot;
  45. import de.ebuero.android.R;
  46. import de.ebuero.android.application.model.ApplicationState;
  47. import de.ebuero.android.common.Contextor;
  48. import de.ebuero.android.common.interfaces.RefreshableFragment;
  49. import de.ebuero.android.common.interfaces.UpdatableFragment;
  50. import de.ebuero.android.common.permission.PermissionUtil;
  51. import de.ebuero.android.common.permission.PreferencesUtil;
  52. import de.ebuero.android.common.tracking.TrackableEvent;
  53. import de.ebuero.android.common.ui.ArrayAdapterWithIcon;
  54. import de.ebuero.android.common.ui.TabMenuFragment;
  55. import de.ebuero.android.common.ui.Toaster;
  56. import de.ebuero.android.common.ui.dialogs.ProgressDialog;
  57. import de.ebuero.android.dayplanner.ui.PlanDayFragment_;
  58. import de.ebuero.android.dayplanner.ui.PlanDaySettingFragment_;
  59. import de.ebuero.android.feedback.appfeedback.AppFeedbackContract.Presenter;
  60. import de.ebuero.android.login.db.UserAccountDAO;
  61. import de.ebuero.android.login.model.UserAccount;
  62. import de.ebuero.android.settings.utils.LocaleHelper;
  63. import pl.aprilapps.easyphotopicker.DefaultCallback;
  64. import pl.aprilapps.easyphotopicker.EasyImage;
  65.  
  66. import java.io.ByteArrayOutputStream;
  67. import java.io.File;
  68. import java.io.IOException;
  69. import java.io.InputStream;
  70. import java.util.ArrayList;
  71.  
  72. import org.androidannotations.annotations.AfterViews;
  73. import org.androidannotations.annotations.Background;
  74. import org.androidannotations.annotations.Bean;
  75. import org.androidannotations.annotations.Click;
  76. import org.androidannotations.annotations.EFragment;
  77. import org.androidannotations.annotations.InstanceState;
  78. import org.androidannotations.annotations.SystemService;
  79. import org.androidannotations.annotations.UiThread;
  80. import org.androidannotations.annotations.ViewById;
  81. import org.joda.time.DateTime;
  82.  
  83. import static android.Manifest.permission.CAMERA;
  84. import static android.Manifest.permission.READ_CONTACTS;
  85. import static android.Manifest.permission.READ_EXTERNAL_STORAGE;
  86.  
  87. import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
  88. import static de.ebuero.android.common.tracking.TrackableActions.ATTACH_SCREEN_SHOT;
  89. import static de.ebuero.android.common.tracking.TrackableActions.LOAD_CALL_FORWARDING;
  90.  
  91.  
  92. /**
  93. * Created by Aemgtz on 3/30/2017 AD.
  94. */
  95. @EFragment(R.layout.fragment_app_feedback)
  96. public class AppFeedbackFragment extends TabMenuFragment implements UpdatableFragment,RefreshableFragment,AppFeedbackContract.View {
  97.  
  98. @ViewById(R.id.message)
  99. protected EditText messageEditText;
  100.  
  101. @ViewById(R.id.loading_layout) protected RelativeLayout loadingLayout;
  102.  
  103. @ViewById(R.id.checkbox_idea) protected CheckBox ideaCheckbox;
  104. @ViewById(R.id.checkbox_problem) protected CheckBox problemCheckbox;
  105. @ViewById(R.id.checkbox_question) protected CheckBox questionCheckbox;
  106. @ViewById(R.id.checkbox_praise) protected CheckBox praiseCheckbox;
  107.  
  108. @ViewById(R.id.screen_shot_1) protected RelativeLayout screenshot1;
  109. @ViewById(R.id.screen_shot_2) protected RelativeLayout screenshot2;
  110.  
  111. @ViewById(R.id.screenshot_image_1) protected ImageView screenshotImage1;
  112. @ViewById(R.id.screenshot_image_2) protected ImageView screenshotImage2;
  113.  
  114. @ViewById(R.id.add_screenshot) protected RelativeLayout addScreenshot;
  115. @ViewById(R.id.submit_textview) protected TextView submitTextView;
  116.  
  117.  
  118. @Bean
  119. protected Toaster mToaster;
  120. @Bean
  121. AppFeedbackPresenter mPresenter;
  122.  
  123. @Bean
  124. UserAccountDAO mUserAccountDAO;
  125.  
  126. @Bean
  127. ApplicationState applicationState;
  128.  
  129. Trace myTrace;
  130.  
  131. @SystemService
  132. protected InputMethodManager inputMethodManager;
  133.  
  134. @InstanceState
  135. ArrayList<String> imageURLs = new ArrayList<>();
  136. @InstanceState
  137. ArrayList<Bitmap> images = new ArrayList<>();
  138.  
  139. //@InstanceState
  140. UploadTask uploadTask;
  141.  
  142. private static String kFirebaseStorageBucket = "gs://ebuero-android.appspot.com/";
  143. private String uri = "content://com.google.android";
  144. private int reqSize = 512;
  145. private ProgressDialog progressDialog;
  146. private StorageReference mStorageRef;
  147. private boolean isDestroy = false;
  148.  
  149. @InstanceState
  150. Bundle mSavedInstanceState;
  151.  
  152. @Override
  153. public void onAttach(Context context) {
  154. super.onAttach(context);
  155. setRetainInstance(true);
  156. }
  157.  
  158. @Override
  159. public void setPresenter(Presenter presenter) {
  160.  
  161. }
  162.  
  163. @Override
  164. public void onCreate(Bundle savedInstanceState) {
  165. super.onCreate(savedInstanceState);
  166.  
  167. mPresenter.setUp(this);
  168. FirebaseStorage.getInstance().setMaxUploadRetryTimeMillis(10*1000);
  169. mStorageRef = FirebaseStorage.getInstance().getReferenceFromUrl(kFirebaseStorageBucket);
  170. }
  171.  
  172. @AfterViews
  173. public void initialize() {
  174. progressDialog = new ProgressDialog(getFragmentManager());
  175.  
  176. if (images.size() > 0) {
  177. screenshotImage1.setImageBitmap(images.get(0));
  178. screenshot1.setVisibility(View.VISIBLE);
  179. screenshot2.setVisibility(View.GONE);
  180. addScreenshot.setVisibility(View.VISIBLE);
  181. if (images.size() > 1){
  182. screenshotImage2.setImageBitmap(images.get(1));
  183. screenshot2.setVisibility(View.VISIBLE);
  184. addScreenshot.setVisibility(View.GONE);
  185. }
  186. } else {
  187. resetFeedbackInput();
  188. }
  189. }
  190.  
  191. @UiThread
  192. @Override
  193. public void setLoadingIndicator(boolean active) {
  194. if (active){
  195. loadingLayout.setVisibility(View.VISIBLE);
  196. submitTextView.setEnabled(false);
  197.  
  198. }else{
  199. loadingLayout.setVisibility(View.INVISIBLE);
  200. submitTextView.setEnabled(true);
  201. }
  202. }
  203.  
  204. @UiThread
  205. @Override
  206. public void showErrorMessage(int message) {
  207. showToast(message);
  208. }
  209.  
  210. @UiThread
  211. @Override
  212. public void showSuccessfullyMessage(int message) {
  213. AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme);
  214. builder.setTitle(R.string.send_feedback_sucess_title);
  215. builder.setMessage(R.string.feedback_success_text);
  216. builder.setPositiveButton(R.string.ok, (dialog, id) -> {
  217. });
  218. resetFeedbackInput();
  219. builder.show();
  220. }
  221.  
  222. private void resetFeedbackInput(){
  223.  
  224. ideaCheckbox.setChecked(false);
  225. problemCheckbox.setChecked(false);
  226. questionCheckbox.setChecked(false);
  227. praiseCheckbox.setChecked(false);
  228. imageURLs.clear();
  229. images.clear();
  230. messageEditText.setText("");
  231. progressDialog.dismiss();
  232.  
  233. screenshot1.setVisibility(View.GONE);
  234. screenshot2.setVisibility(View.GONE);
  235. addScreenshot.setVisibility(View.VISIBLE);
  236. }
  237.  
  238.  
  239. @Click(R.id.submit_textview)
  240. protected void submitFeedback() {
  241.  
  242. if (messageEditText.getText().toString().equals("")) {
  243. mToaster.showLongToast(R.string.information_not_complete);
  244. return;
  245. }
  246.  
  247. StringBuilder text = new StringBuilder();
  248. text.append("Message: " + messageEditText.getText().toString());
  249.  
  250. if (ideaCheckbox.isChecked() || problemCheckbox.isChecked() || questionCheckbox.isChecked() || praiseCheckbox.isChecked()) {
  251.  
  252. text.append("\n\nTag: ");
  253.  
  254. if (ideaCheckbox.isChecked()) {
  255. text.append("Idea, ");
  256. }
  257.  
  258. if (problemCheckbox.isChecked()) {
  259. text.append("Problem, ");
  260. }
  261.  
  262. if (questionCheckbox.isChecked()) {
  263. text.append("Question, ");
  264. }
  265.  
  266. if (praiseCheckbox.isChecked()) {
  267. text.append("Praise, ");
  268. }
  269.  
  270. text.delete(text.length() - 2, text.length());
  271. }
  272.  
  273. for (String url : imageURLs) {
  274. if (url != null) {
  275. text.append("\n\nAttached file: " + url);
  276. }
  277. }
  278.  
  279.  
  280. Bundle bundle = new Bundle();
  281. bundle.putString("message",text.toString());
  282. trackEvent(TrackableEvent.FEEDBACK_SEND,bundle );
  283.  
  284. inputMethodManager.hideSoftInputFromWindow(getActivity().getCurrentFocus().getWindowToken(), 0);
  285. mPresenter.sendAppFeedback(text.toString());
  286. }
  287.  
  288.  
  289. @Click(R.id.add_screenshot)
  290. protected void addScreenshot(){
  291. trackEvent(TrackableEvent.FEEDBACK_ADD_SCREEN_SHOT, null);
  292.  
  293. showSelectingSourceDialog();
  294. }
  295.  
  296. private void showSelectingSourceDialog() {
  297. final MaterialSimpleListAdapter adapter =
  298. new MaterialSimpleListAdapter(
  299. (dialog, index1, item) -> selectSourceClicked(dialog ,index1));
  300. adapter.add(
  301. new MaterialSimpleListItem.Builder(getContext())
  302. .content(getResources().getString(R.string.source_camera))
  303. .icon(R.drawable.ic_camera)
  304. .backgroundColor(Color.WHITE)
  305. .build());
  306. adapter.add(
  307. new MaterialSimpleListItem.Builder(getContext())
  308. .content(getResources().getString(R.string.source_gallery))
  309. .icon(R.drawable.ic_gallery)
  310. .backgroundColor(Color.WHITE)
  311. .build());
  312. new MaterialDialog.Builder(getContext()).adapter(adapter, null).show();
  313. }
  314.  
  315. private void selectSourceClicked(MaterialDialog dialog, int which) {
  316. dialog.dismiss();
  317. if (which == 0) {
  318. checkCameraPermission();
  319. } else if (which == 1) {
  320. checkReadExternalPermission();
  321. }
  322. }
  323.  
  324. private void checkReadExternalPermission() {
  325. PermissionUtil.checkPermission(getActivity(), READ_EXTERNAL_STORAGE, new PermissionUtil.PermissionAskListener() {
  326. @Override
  327. public void onNeedPermission() {
  328. requestPermissions(new String[]{READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE}, 0);
  329. }
  330.  
  331. @Override
  332. public void onPermissionPreviouslyDenied() {
  333. requestPermissions(new String[]{READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE}, 0);
  334. }
  335.  
  336. @Override
  337. public void onPermissionDisabled() {
  338. showPermissionDeniedMessage(R.string.no_permission);
  339. }
  340.  
  341. @Override
  342. public void onPermissionGranted() {
  343. EasyImage.openGallery(AppFeedbackFragment.this, 0);
  344. }
  345. });
  346. }
  347.  
  348. private void checkCameraPermission() {
  349. PermissionUtil.checkPermission(getActivity(), CAMERA, new PermissionUtil.PermissionAskListener() {
  350. @Override
  351. public void onNeedPermission() {
  352. requestPermissions(new String[]{CAMERA}, 0);
  353. }
  354.  
  355. @Override
  356. public void onPermissionPreviouslyDenied() {
  357. requestPermissions(new String[]{CAMERA}, 0);
  358. }
  359.  
  360. @Override
  361. public void onPermissionDisabled() {
  362. showPermissionDeniedMessage(R.string.no_permission);
  363. }
  364.  
  365. @Override
  366. public void onPermissionGranted() {
  367. EasyImage.openCamera(AppFeedbackFragment.this, 0);
  368. }
  369. });
  370. }
  371.  
  372. @Override
  373. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  374. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  375.  
  376. if (permissions != null){
  377. if (grantResults[0] == PackageManager.PERMISSION_GRANTED){
  378. if (permissions[0].equals(CAMERA)){
  379. EasyImage.openCamera(AppFeedbackFragment.this, 0);
  380. } else if (permissions[0].equals(READ_EXTERNAL_STORAGE)){
  381. EasyImage.openGallery(AppFeedbackFragment.this, 0);
  382. }
  383. }
  384. }
  385. }
  386.  
  387. @Override
  388. public void updateFragment(Object data) {
  389.  
  390. }
  391.  
  392. @Override
  393. public void restartFragment() {
  394.  
  395. }
  396.  
  397. @Override
  398. public void onActivityResult(int requestCode, int resultCode, Intent data) {
  399. super.onActivityResult(requestCode, resultCode, data);
  400. if ((resultCode != Activity.RESULT_OK)) {
  401. return;
  402. }
  403.  
  404.  
  405. EasyImage.handleActivityResult(requestCode, resultCode, data, getActivity(), new DefaultCallback() {
  406. @Override
  407. public void onImagePickerError(Exception e, EasyImage.ImageSource source, int type) {
  408. //Some error handling
  409. progressDialog.dismiss();
  410. Toast.makeText(getContext(),"Pick image fail",Toast.LENGTH_SHORT).show();
  411. return;
  412. }
  413.  
  414. @Override
  415. public void onImagePicked(File imageFile, EasyImage.ImageSource source, int type) {
  416.  
  417. Bitmap bitmap = null;
  418. try {
  419. myTrace = FirebasePerformance.getInstance().newTrace(ATTACH_SCREEN_SHOT);
  420. myTrace.start();
  421. progressDialog.show();
  422. bitmap = handleSamplingAndRotationBitmap(getContext(), Uri.fromFile(imageFile));
  423. uploadBitmap(bitmap);
  424. LocaleHelper.onAttach(Contextor.getInstance().getContext());
  425. } catch (IOException e) {
  426. Toast.makeText(getContext(),"Pick image fail",Toast.LENGTH_SHORT).show();
  427. progressDialog.dismiss();
  428. e.printStackTrace();
  429. }
  430.  
  431.  
  432.  
  433. }
  434.  
  435. @Override
  436. public void onCanceled(EasyImage.ImageSource source, int type) {
  437. super.onCanceled(source, type);
  438. progressDialog.dismiss();
  439. }
  440. });
  441.  
  442.  
  443. }
  444.  
  445.  
  446.  
  447. @Background
  448. protected void uploadBitmap(final Bitmap bitmap) {
  449.  
  450. UserAccount userAccount = mUserAccountDAO.findById(applicationState.currentUserId);
  451.  
  452. StorageReference feedbackImageRef = mStorageRef.child("feedback-images/");
  453.  
  454. DateTime today = DateTime.now();
  455. String imageName = "feedback_" + userAccount.getUsername() + "_" + today.toString() + "jpg";
  456.  
  457. StorageReference imageRef = feedbackImageRef.child(imageName);
  458. StorageMetadata metadata = new StorageMetadata.Builder()
  459. .setContentType("image/jpg")
  460. .build();
  461.  
  462. ByteArrayOutputStream stream = new ByteArrayOutputStream();
  463. bitmap.compress(Bitmap.CompressFormat.JPEG, 50, stream);
  464. byte[] data = stream.toByteArray();
  465. imageRef.putBytes(data,metadata);
  466. uploadTask = imageRef.putBytes(data,metadata);
  467. StorageTask<TaskSnapshot> taskSnapshotStorageTask = uploadTask
  468. .addOnFailureListener(exception -> {
  469. // Handle unsuccessful uploads
  470. showToast(getResources().getString(R.string.no_network));
  471. progressDialog.dismiss();
  472.  
  473. }).addOnSuccessListener(taskSnapshot -> {
  474. progressDialog.dismiss();
  475.  
  476. imageRef.getDownloadUrl().addOnSuccessListener(uri -> {
  477. if (!isDestroy) setBitmap(bitmap,uri.toString());
  478. Log.d("AppFeedback",uri.toString());
  479. });
  480.  
  481. });
  482. myTrace = FirebasePerformance.getInstance().newTrace(ATTACH_SCREEN_SHOT);
  483. myTrace.stop();
  484.  
  485. }
  486.  
  487.  
  488. @UiThread
  489. protected void setBitmap(Bitmap bitmap, String url) {
  490. progressDialog.dismiss();
  491. images.add(bitmap);
  492. imageURLs.add(url);
  493. int index = images.size();
  494. switch (index) {
  495. case 1:
  496. screenshotImage1.setImageBitmap(bitmap);
  497. screenshot1.setVisibility(View.VISIBLE);
  498. addScreenshot.setVisibility(View.VISIBLE);
  499. break;
  500.  
  501. case 2:
  502. screenshotImage2.setImageBitmap(bitmap);
  503. screenshot2.setVisibility(View.VISIBLE);
  504. addScreenshot.setVisibility(View.GONE);
  505. break;
  506. }
  507. }
  508. @Override
  509. public void refreshContent() {
  510. }
  511.  
  512.  
  513. @Click(R.id.screen_shot_1)
  514. protected void screenshot1Clicked(){
  515.  
  516. AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme);
  517. builder.setMessage(R.string.remove_screenshot);
  518. builder.setPositiveButton(R.string.delete, (dialog, id) -> {
  519.  
  520. trackEvent(TrackableEvent.FEEDBACK_REMOVE_SCREEN_SHOT, null);
  521.  
  522.  
  523. if (images.size() > 1){
  524.  
  525. images.remove(0);
  526. imageURLs.remove(0);
  527.  
  528. setScreenshots();
  529.  
  530. }else{
  531.  
  532. images.remove(0);
  533. imageURLs.remove(0);
  534.  
  535. setScreenshots();
  536. }
  537.  
  538. });
  539. builder.setNegativeButton(R.string.cancel, (dialog, id) -> {
  540. // User cancelled the dialog
  541. });
  542. builder.show();
  543.  
  544. }
  545.  
  546. @Click(R.id.screen_shot_2)
  547. protected void screenshot2Clicked(){
  548.  
  549. AlertDialog.Builder builder = new AlertDialog.Builder(getActivity(), R.style.AlertDialogTheme);
  550. builder.setMessage(R.string.remove_screenshot);
  551. builder.setPositiveButton(R.string.remove, (dialog, id) -> {
  552.  
  553. trackEvent(TrackableEvent.FEEDBACK_REMOVE_SCREEN_SHOT, null);
  554.  
  555. if (images.size() > 1){
  556. images.remove(1);
  557. imageURLs.remove(1);
  558.  
  559. setScreenshots();
  560. }
  561.  
  562. });
  563. builder.setNegativeButton(R.string.cancel, (dialog, id) -> {
  564.  
  565. });
  566. builder.show();
  567. }
  568.  
  569. private void setScreenshots(){
  570.  
  571. screenshot1.setVisibility(View.GONE);
  572. screenshot2.setVisibility(View.GONE);
  573. addScreenshot.setVisibility(View.VISIBLE);
  574.  
  575. for(int i = 0; i < images.size(); i++){
  576.  
  577. if (i == 0){
  578.  
  579. screenshot1.setVisibility(View.VISIBLE);
  580. Bitmap bitmap = images.get(i);
  581. screenshotImage1.setImageBitmap(bitmap);
  582.  
  583. }
  584. if (i == 1){
  585.  
  586. screenshot2.setVisibility(View.VISIBLE);
  587. Bitmap bitmap = images.get(i);
  588. screenshotImage2.setImageBitmap(bitmap);
  589. addScreenshot.setVisibility(View.GONE);
  590. }
  591. }
  592. }
  593.  
  594. /**
  595. * This method is responsible for solving the rotation issue if exist. Also scale the images to
  596. * 1024x1024 resolution
  597. *
  598. * @param context The current context
  599. * @param selectedImage The Image URI
  600. * @return Bitmap image results
  601. * @throws IOException
  602. */
  603. public static Bitmap handleSamplingAndRotationBitmap(Context context, Uri selectedImage)
  604. throws IOException {
  605. int MAX_HEIGHT = 1024;
  606. int MAX_WIDTH = 1024;
  607.  
  608. // First decode with inJustDecodeBounds=true to check dimensions
  609. final BitmapFactory.Options options = new BitmapFactory.Options();
  610. options.inJustDecodeBounds = true;
  611. InputStream imageStream = context.getContentResolver().openInputStream(selectedImage);
  612. BitmapFactory.decodeStream(imageStream, null, options);
  613. imageStream.close();
  614.  
  615. // Calculate inSampleSize
  616. options.inSampleSize = calculateInSampleSize(options, MAX_WIDTH, MAX_HEIGHT);
  617.  
  618. // Decode bitmap with inSampleSize set
  619. options.inJustDecodeBounds = false;
  620. imageStream = context.getContentResolver().openInputStream(selectedImage);
  621. Bitmap img = BitmapFactory.decodeStream(imageStream, null, options);
  622.  
  623. img = rotateImageIfRequired(img, selectedImage, context);
  624. return img;
  625. }
  626.  
  627. /**
  628. * Calculate an inSampleSize for use in a {@link BitmapFactory.Options} object when decoding
  629. * bitmaps using the decode* methods from {@link BitmapFactory}. This implementation calculates
  630. * the closest inSampleSize that will result in the final decoded bitmap having a width and
  631. * height equal to or larger than the requested width and height. This implementation does not
  632. * ensure a power of 2 is returned for inSampleSize which can be faster when decoding but
  633. * results in a larger bitmap which isn't as useful for caching purposes.
  634. *
  635. * @param options An options object with out* params already populated (run through a decode*
  636. * method with inJustDecodeBounds==true
  637. * @param reqWidth The requested width of the resulting bitmap
  638. * @param reqHeight The requested height of the resulting bitmap
  639. * @return The value to be used for inSampleSize
  640. */
  641. private static int calculateInSampleSize(BitmapFactory.Options options,
  642. int reqWidth, int reqHeight) {
  643. // Raw height and width of image
  644. final int height = options.outHeight;
  645. final int width = options.outWidth;
  646. int inSampleSize = 1;
  647.  
  648. if (height > reqHeight || width > reqWidth) {
  649.  
  650. // Calculate ratios of height and width to requested height and width
  651. final int heightRatio = Math.round((float) height / (float) reqHeight);
  652. final int widthRatio = Math.round((float) width / (float) reqWidth);
  653.  
  654. // Choose the smallest ratio as inSampleSize value, this will guarantee a final image
  655. // with both dimensions larger than or equal to the requested height and width.
  656. inSampleSize = heightRatio < widthRatio ? heightRatio : widthRatio;
  657.  
  658. // This offers some additional logic in case the image has a strange
  659. // aspect ratio. For example, a panorama may have a much larger
  660. // width than height. In these cases the total pixels might still
  661. // end up being too large to fit comfortably in memory, so we should
  662. // be more aggressive with sample down the image (=larger inSampleSize).
  663.  
  664. final float totalPixels = width * height;
  665.  
  666. // Anything more than 2x the requested pixels we'll sample down further
  667. final float totalReqPixelsCap = reqWidth * reqHeight * 2;
  668.  
  669. while (totalPixels / (inSampleSize * inSampleSize) > totalReqPixelsCap) {
  670. inSampleSize++;
  671. }
  672. }
  673. return inSampleSize;
  674. }
  675.  
  676. /**
  677. * Rotate an image if required.
  678. *
  679. * @param img The image bitmap
  680. * @param selectedImage Image URI
  681. * @return The resulted Bitmap after manipulation
  682. */
  683. private static Bitmap rotateImageIfRequired(Bitmap img, Uri selectedImage, Context _mContext) throws IOException {
  684.  
  685. InputStream input = _mContext.getContentResolver().openInputStream(selectedImage);
  686. ExifInterface ei;
  687. if (Build.VERSION.SDK_INT > 23)
  688. ei = new ExifInterface(input);
  689. else
  690. ei = new ExifInterface(selectedImage.getPath());
  691.  
  692. int orientation = ei.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
  693.  
  694. switch (orientation) {
  695. case ExifInterface.ORIENTATION_ROTATE_90:
  696. return rotateImage(img, 90);
  697. case ExifInterface.ORIENTATION_ROTATE_180:
  698. return rotateImage(img, 180);
  699. case ExifInterface.ORIENTATION_ROTATE_270:
  700. return rotateImage(img, 270);
  701. default:
  702. return img;
  703. }
  704. }
  705.  
  706. private static Bitmap rotateImage(Bitmap img, int degree) {
  707. Matrix matrix = new Matrix();
  708. matrix.postRotate(degree);
  709. Bitmap rotatedImg = Bitmap.createBitmap(img, 0, 0, img.getWidth(), img.getHeight(), matrix, true);
  710. img.recycle();
  711. return rotatedImg;
  712. }
  713.  
  714. @Override
  715. public void onDestroy() {
  716. isDestroy = true;
  717. super.onDestroy();
  718. }
  719.  
  720. @Override
  721. public void onResume() {
  722. super.onResume();
  723. if (progressDialog!=null){
  724. progressDialog.onResume();
  725. }
  726. }
  727.  
  728. @Override
  729. public void onStop() {
  730. super.onStop();
  731. if (progressDialog!=null){
  732. progressDialog.onStop();
  733. }
  734. }
  735. }
Add Comment
Please, Sign In to add comment