Java tutorial
package com.segma.trim; import android.Manifest; import android.app.Activity; import android.app.ActivityManager; import android.app.DialogFragment; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.ActivityInfo; import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Color; import android.graphics.Point; import android.graphics.drawable.BitmapDrawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.provider.MediaStore; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; import android.support.v4.content.FileProvider; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.text.TextUtils; import android.util.Log; import android.util.TypedValue; import android.view.Display; import android.view.Gravity; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.WindowManager; import android.view.animation.AlphaAnimation; import android.view.animation.Animation; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.PopupWindow; import android.widget.RelativeLayout; import android.widget.SeekBar; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.ads.AdListener; import com.google.android.gms.ads.AdRequest; import com.google.android.gms.ads.AdView; import com.google.android.gms.ads.InterstitialAd; import com.google.android.gms.ads.MobileAds; import com.segma.dirchooser.DirectoryChooserConfig; import com.segma.dirchooser.DirectoryChooserFragment; import com.segma.trim.InAppBillingUtilities.InAppBillingBroadcastReceiver; import com.segma.trim.InAppBillingUtilities.InAppBillingHelper; import com.segma.trim.InAppBillingUtilities.InAppBillingResult; import com.segma.trim.InAppBillingUtilities.Inventory; import com.segma.trim.InAppBillingUtilities.Purchase; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.Date; public class MainActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback, InAppBillingHelper.OnInAppBillingPurchaseFinishedListener, InAppBillingBroadcastReceiver.InAppBillingBroadcastListener, DirectoryChooserFragment.OnFragmentInteractionListener, ImageProcessingView.SaveTriangulatedBitmapCallback, SeekBar.OnSeekBarChangeListener, ColorPickerDialog.OnColorChangedListener, InAppBillingHelper.QueryInventoryFinishedListener { /** * Debug */ private static final String TAG = "trim"; private static boolean MODE_DEBUG = false; /** * License */ private static final String PUBLIC_KEY = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApxkR5S3wRAWRZY+LDMy0H9y7YfExOdPYovUbEg6h+/hbiIcqh+FfOuLF1YgQy8zOdle58VAv8ATyh6L2+TL+Dtcw7ShXAKpin4lEtjEeSaNGjpYf7EGyQ/TtQzC9IiZ2za21h91/c4iYBVRjv8rzHTl4LDmTydjnoOObB2cvVCvPas1KHfCo31hQA3/a4k7DXfR9yo+FDGf0RWL0Jd9mw7ocfSQAzLXQzJNZA2GMVQvOecEXa4bRpFUdpCziNw6qtFkr7gQFl+T+L/TcoHLvVYJqEcUa9BYOljZo0vQ4r9y7BDEczf7LA19IplRQUuiv1v4aAIfQDGgo3jsGRL6UtwIDAQAB"; private static final String PURCHASE_KEY = PUBLIC_KEY; private static boolean isLicenseLoaded = false; private static final boolean LICENSE_PREMIUM = true; private static final boolean LICENSE_TRIAL = false; private static final String LICENSE_PREMIUM_ID = "product_triango_license_premium_2016_7_16"; private static boolean LICENSE = LICENSE_TRIAL; private static InAppBillingHelper purchaseHelper; private static InAppBillingBroadcastReceiver broadcastReceiver; private static final int REQUEST_CODE_PURCHASE = 8080; /** * Admob */ private static final String ADMOB_KEY = "ca-app-pub-3882895524336494~4932860163"; /** * Screen size */ int screenWidth = 0; int screenHeight = 0; /** * Message & State Constants */ private static final String WARNING_NO_APPROPRIATE_INTENT = "No share application found."; private static final String MESSAGE_IMAGE_SAVED = "Image is saved."; private static final String ERROR_GOOGLE_PLAY_NOT_AVAILABLE = "Google Play is temporarily not available."; private static final String WARNING_CAMERA_IMPORT_ERROR = "Error in importing camera image."; private static final String WARNING_NO_SDCARD = "No SD card available."; private static final String MESSAGE_PURCHASE = "Congratulations! You are premium now. Enjoy!"; private static final String WARNING_NO_IMAGE_IMPORTED = "No image is imported."; private static final String WARNING_PREMIUM_FEATURE_SAVE_IMAGE = "Go premium to save image."; private static final String WARNING_PREMIUM_FEATURE_SHARE_IMAGE = "Go premium to share image."; private static final String WARNING_COMPUTING = "Already running..."; private static final String WARNING_SAVE_IMAGE_FAILED = "Failed to save image.\nPlease choose another SD Card."; private static final String MESSAGE_STARTUP = "Press me to load a random sample\nor take image from camera or gallery."; private static final int STATE_NO_IMAGE_IMPORTED = 1; private static final int STATE_PROCESSING_IMAGE = 2; private int STATE = STATE_NO_IMAGE_IMPORTED; private static final int REQUEST_CODE_SHARE = 9090; /** * TextView */ public final static int LONG_PRESS_TIME_ON_TEXTVIEW = 500; private final Handler handlerOnTextView = new Handler(); private TextView textView; /** * ColorPickerDialog */ private ColorPickerDialog colorPickerDialog; /** * PopupWindow */ PopupWindow popupWindowAbout; /** * Toolbar **/ private static boolean isMenuLoaded = false; private Menu menu; private MenuItem menuItem_TakeAPhoto; private MenuItem menuItem_ImportFromGallery; private ActionBar actionBar; private boolean isMenuLocked = false; /** * ImageView */ private ImageProcessingView ipv; private int ImageProcessingViewHeight = 0; private int ImageProcessingViewWidth = 0; /** * External Storage & Share Controls */ private DirectoryChooserFragment dirChooser; private static boolean isExternalStorageAllowed = true; private static int REQUEST_CODE_EXTERNAL_STORAGE_PERMISSION = 7070; private static final int ACTION_SHARE = 3; private static final int ACTION_SAVE = 4; private static int ACTION = ACTION_SAVE; private static Uri shareCacheUri = null; private OutputStream out; String cacheFileName = "9p845y1034895y9q348hf34hf.jpg"; /** * Algorithm values */ private Bitmap rawBitmap; private int rawBitmapWidth; private int rawBitmapHeight; private boolean IMAGE_ROTATED_TO_PROCESS = false; /** * Memory */ private static int MEMORY_SIZE = 0; private static int MAX_BITMAP_PIXELS = 0; /** * User Preference */ private static SharedPreferences preferences; private static SharedPreferences.Editor preferenceEditor; private static final String USER_PREFERENCE = "0"; // save location private static final String PREF_SAVE_LOCATION = "1"; private static String PREF_SAVE_LOCATION_NULL; private static String PREF_SAVE_LOCATION_VALUE; // mesh private static final String PREF_MESH = "4"; private static boolean PREF_MESH_NULL = false; private static boolean PREF_MESH_VALUE; // color private static final String PREF_COLOR = "2"; private static int PREF_COLOR_NULL = Color.parseColor("#99FF00"); private static int PREF_COLOR_VALUE; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); MobileAds.initialize(getApplicationContext(), ADMOB_KEY); setContentView(R.layout.activity_main); loadAds(); MEMORY_SIZE = ((ActivityManager) getSystemService(ACTIVITY_SERVICE)).getMemoryClass(); MAX_BITMAP_PIXELS = calculateMaxBitmapPixels(); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); ipv = (ImageProcessingView) findViewById(R.id.ipv); loadLicense(); loadUserSetting(); final Runnable runnableOnTextView = new Runnable() { @Override public void run() { ipv.setVisibility(View.VISIBLE); // TODO: update pending: the image enlarges due to larger space rawBitmap = getSampleImage(); rawBitmapWidth = rawBitmap.getWidth(); rawBitmapHeight = rawBitmap.getHeight(); STATE = STATE_PROCESSING_IMAGE; textView.setVisibility(View.GONE); ipv.process(rawBitmap); } }; Display display = getWindowManager().getDefaultDisplay(); Point size = new Point(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB_MR2) { display.getSize(size); screenWidth = size.x; screenHeight = size.y; } else { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); screenWidth = display.getWidth(); screenHeight = display.getHeight(); } initControls(); textView = (TextView) findViewById(R.id.tv_message); textView.setEnabled(false); ViewTreeObserver viewTreeObserver = ipv.getViewTreeObserver(); if (viewTreeObserver.isAlive()) { viewTreeObserver.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { @Override public void onGlobalLayout() { ImageProcessingViewWidth = ipv.getWidth(); ImageProcessingViewHeight = ipv.getHeight(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { ipv.getViewTreeObserver().removeOnGlobalLayoutListener(this); } else { ipv.getViewTreeObserver().removeGlobalOnLayoutListener(this); } if (ImageProcessingViewHeight != 0) textView.setEnabled(true); } }); } textView.setText(MESSAGE_STARTUP); textView.setOnTouchListener(new View.OnTouchListener() { float original_text_size; @Override public boolean onTouch(View v, final MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: original_text_size = textView.getTextSize(); //textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, Math.round(original_text_size * 1.15)); handlerOnTextView.postDelayed(runnableOnTextView, LONG_PRESS_TIME_ON_TEXTVIEW); textView.setEnabled(false); break; case MotionEvent.ACTION_MOVE: handlerOnTextView.removeCallbacks(runnableOnTextView); break; case MotionEvent.ACTION_UP: //textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, original_text_size); handlerOnTextView.removeCallbacks(runnableOnTextView); v.setEnabled(true); break; } return false; } }); setSupportActionBar((Toolbar) findViewById(R.id.toolbar)); actionBar = getSupportActionBar(); //actionBar.setDisplayHomeAsUpEnabled(true); ipv.setVisibility(View.INVISIBLE); if (MODE_DEBUG) { LICENSE = LICENSE_PREMIUM; getPackageManager().clearPackagePreferredActivities(getApplicationContext().getPackageName()); } } private void loadLicense() { purchaseHelper = new InAppBillingHelper(this, PUBLIC_KEY); purchaseHelper.enableDebugLogging(true); purchaseHelper.startSetup(new InAppBillingHelper.OnInAppBillingSetupFinishedListener() { @Override public void onInAppBillingSetupFinished(InAppBillingResult result) { if (!result.isSuccess()) { Log.d(TAG, "InAppBillingHelper setting up failed: " + result); return; } if (purchaseHelper == null) return; broadcastReceiver = new InAppBillingBroadcastReceiver(MainActivity.this); registerReceiver(broadcastReceiver, new IntentFilter(InAppBillingBroadcastReceiver.ACTION)); Log.d(TAG, "Helper setup successful. Querying inventory."); try { purchaseHelper.queryInventoryAsync(MainActivity.this); } catch (InAppBillingHelper.InAppBillingAsyncInProgressException e) { Log.d(TAG, "Error querying inventory. Another async request is not finished."); } } }); } private void initControls() { int MIN_TAG_WIDTH = 20; int MIN_VALUE_WIDTH = 10; int MIN_GO_WIDTH = 15; int TAG_WIDTH = Math.round((float) 0.2 * screenWidth); int VALUE_WIDTH = Math.round((float) 0.1 * screenWidth); int GO_WIDTH = Math.round((float) 0.15 * screenWidth); if (TAG_WIDTH < MIN_TAG_WIDTH) TAG_WIDTH = MIN_TAG_WIDTH; if (VALUE_WIDTH < MIN_VALUE_WIDTH) VALUE_WIDTH = MIN_VALUE_WIDTH; if (GO_WIDTH < MIN_GO_WIDTH) GO_WIDTH = MIN_GO_WIDTH; ((TextView) findViewById(R.id.tv_density_tag)).setWidth(TAG_WIDTH); ((TextView) findViewById(R.id.tv_density_value)).setWidth(VALUE_WIDTH); ((TextView) findViewById(R.id.tv_density_value)).setText(String.valueOf(density_min)); ((TextView) findViewById(R.id.tv_complexity_tag)).setWidth(TAG_WIDTH); ((TextView) findViewById(R.id.tv_complexity_value)).setWidth(VALUE_WIDTH); ((TextView) findViewById(R.id.tv_complexity_value)).setText(String.valueOf(complexity_min)); ((Button) findViewById(R.id.bt_go)).setWidth(GO_WIDTH); int step = 100 / 8; ((SeekBar) findViewById(R.id.sb_complexity)).incrementProgressBy(step); ((SeekBar) findViewById(R.id.sb_complexity)).setOnSeekBarChangeListener(this); ((SeekBar) findViewById(R.id.sb_complexity)).setProgress(2 * step); step = Math.round(100 / 7); ((SeekBar) findViewById(R.id.sb_density)).setKeyProgressIncrement(step); ((SeekBar) findViewById(R.id.sb_density)).setOnSeekBarChangeListener(this); ((SeekBar) findViewById(R.id.sb_density)).setProgress(5 * step); findViewById(R.id.bt_go).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (ipv.getDrawable() == null) { showWarning(WARNING_NO_IMAGE_IMPORTED); return; } if (ImageProcessingView.STATUS == ImageProcessingView.STATUS_COMPUTING) { Toast.makeText(getApplicationContext(), WARNING_COMPUTING, Toast.LENGTH_SHORT).show(); return; } ipv.process(); } }); findViewById(R.id.bt_go).setOnTouchListener(new View.OnTouchListener() { float original_size_in_sp = 0; boolean o_o = true; @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: if (o_o) original_size_in_sp = pixelsToSp(((Button) v).getTextSize()); ((Button) v).setTextSize(TypedValue.COMPLEX_UNIT_SP, Math.round(original_size_in_sp * 0.9)); if (o_o) o_o = false; break; case MotionEvent.ACTION_UP: ((Button) v).setTextSize(TypedValue.COMPLEX_UNIT_SP, Math.round(original_size_in_sp)); ; break; } return false; } }); } public float pixelsToSp(float px) { float scaledDensity = getResources().getDisplayMetrics().scaledDensity; return px / scaledDensity; } private void loadUserSetting() { preferences = getSharedPreferences(USER_PREFERENCE, MODE_PRIVATE); preferenceEditor = preferences.edit(); if (isSDCARDAvailable()) { // check phone version > 5.1 if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) { isExternalStorageAllowed = checkPermission_6_0(this); } PREF_SAVE_LOCATION_NULL = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) .getAbsolutePath(); PREF_SAVE_LOCATION_VALUE = preferences.getString(PREF_SAVE_LOCATION, PREF_SAVE_LOCATION_NULL); Log.d(TAG, "isExternalStorageAllowed: " + String.valueOf(isExternalStorageAllowed)); } else { //Toast.makeText(getApplicationContext(), WARNING_NO_SDCARD, Toast.LENGTH_LONG).show(); PREF_SAVE_LOCATION_NULL = getFilesDir().getAbsolutePath(); PREF_SAVE_LOCATION_VALUE = preferences.getString(PREF_SAVE_LOCATION, PREF_SAVE_LOCATION_NULL); } PREF_COLOR_VALUE = preferences.getInt(PREF_COLOR, PREF_COLOR_NULL); ipv.setInkColor(PREF_COLOR_VALUE); } @Override protected void onResume() { //TODO: 11-4-2016 FIX: Hiding Navigation Bar seems not permanently, scheme disposed //hideNavigationBar(); super.onResume(); } private void hideNavigationBar() { //TODO: 11-4-2016 FIX: Hide Navigation Bar final int flags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_FULLSCREEN //| View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY | View.SYSTEM_UI_FLAG_IMMERSIVE | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; final View decorView = getWindow().getDecorView(); decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() { @Override public void onSystemUiVisibilityChange(int visibility) { // Note that system bars will only be "visible" if none of the // LOW_PROFILE, HIDE_NAVIGATION, or FULLSCREEN flags are set. if ((visibility & View.SYSTEM_UI_FLAG_FULLSCREEN) == 0) { // TODO: The system bars are visible. Make any desired // adjustments to your UI, such as showing the action bar or // other navigational controls. //decorView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); //decorView.setSystemUiVisibility(decorView.getSystemUiVisibility()); //getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); decorView.setSystemUiVisibility(flags); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); } else { // TODO: The system bars are NOT visible. Make any desired // adjustments to your UI, such as hiding the action bar or // other navigational controls. } } }); decorView.setSystemUiVisibility(flags); } private int calculateMaxBitmapPixels() { float percentageEachBitmapInUse = 0.15f; float eachPixelMemory = (float) 8; return (int) (percentageEachBitmapInUse * MEMORY_SIZE * 1024 * 1024 / eachPixelMemory); } private Bitmap getSampleImage() { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; options.inScaled = false; int sample = getRandomSample(); BitmapFactory.decodeResource(getResources(), sample, options); int imageHeight = options.outHeight; int imageWidth = options.outWidth; options.inJustDecodeBounds = false; if (true || imageHeight >= ImageProcessingViewHeight || imageWidth >= ImageProcessingViewWidth) { options.inSampleSize = calculateInSampleSize(options, ImageProcessingViewHeight * imageWidth / imageHeight, ImageProcessingViewHeight); return Bitmap.createScaledBitmap( decodeSampledBitmapFromResource(getResources(), sample, ImageProcessingViewHeight * imageWidth / imageHeight, ImageProcessingViewHeight), ImageProcessingViewHeight * imageWidth / imageHeight, ImageProcessingViewHeight, true); } return BitmapFactory.decodeResource(getResources(), sample, options); //decodeSampledBitmapFromResource(getResources(), R.drawable.sample, ImageProcessingViewHeight * imageWidth / imageHeight, ImageProcessingViewHeight); } private int getRandomSample() { int out_ = getResources().getIdentifier("sample_" + String.valueOf(RandomGenerator.getIntFromRange(1, 4)), "drawable", getPackageName()); return out_; } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.action_buttons, menu); this.menu = menu; //menuItem_TakeAPhoto = toolbar.getMenu().findItem(R.id.take_a_photo); //menuItem_ImportFromGallery = toolbar.getMenu().findItem(R.id.import_from_gallery); //toolbar.getMenu().findItem(R.id.about).setVisible(false); menu.findItem(R.id.about).setVisible(false); menuItem_ImportFromGallery = menu.findItem(R.id.import_from_gallery); menuItem_TakeAPhoto = menu.findItem(R.id.take_a_photo); isMenuLoaded = true; if (isLicenseLoaded && LICENSE) menu.findItem(R.id.premium).setVisible(false); // load show mesh preference PREF_MESH_VALUE = preferences.getBoolean(PREF_MESH, PREF_MESH_NULL); if (PREF_MESH_VALUE) { menu.findItem(R.id.show_mesh).setTitle(R.string.hide_mesh); return super.onCreateOptionsMenu(menu); } menu.findItem(R.id.show_mesh).setTitle(R.string.show_mesh); return super.onCreateOptionsMenu(menu); } private void updateUI() { ipv.hideProgressDialog(); if (!LICENSE) { getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE, WindowManager.LayoutParams.FLAG_SECURE); return; } if (LICENSE && isMenuLoaded) menu.findItem(R.id.premium).setVisible(false); } private void showWarning(final String string) { //(findViewById(R.id.bt_go)).setEnabled(false); //(findViewById(R.id.save_file)).setEnabled(false); //textView.setEnabled(false); lockScreen(); final Animation in = new AlphaAnimation(0f, 1f) { { setDuration(250); } }; final Animation out = new AlphaAnimation(1f, 0f) { { setDuration(250); } }; out.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { textView.setText(string); textView.startAnimation(in); } @Override public void onAnimationRepeat(Animation animation) { } }); in.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { if (!textView.getText().toString().equals(WARNING_NO_IMAGE_IMPORTED)) { //textView.setEnabled(true); //(findViewById(R.id.bt_go)).setEnabled(true); //(findViewById(R.id.save_file)).setEnabled(true); unlockScreen(); } } @Override public void onAnimationRepeat(Animation animation) { } }); textView.startAnimation(out); new Handler().postDelayed(new Runnable() { @Override public void run() { out.setAnimationListener(new Animation.AnimationListener() { @Override public void onAnimationStart(Animation animation) { } @Override public void onAnimationEnd(Animation animation) { textView.setText(MESSAGE_STARTUP); textView.startAnimation(in); } @Override public void onAnimationRepeat(Animation animation) { } }); textView.startAnimation(out); } }, 1500); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (isMenuLocked) return super.onOptionsItemSelected(item); ipv.setClickable(false); switch (STATE) { case STATE_NO_IMAGE_IMPORTED: switch (item.getItemId()) { case R.id.online_gallery: goOnlineGallery(); return super.onOptionsItemSelected(item); case R.id.premium: goPremium(); return super.onOptionsItemSelected(item); case R.id.take_a_photo: photoFromCamera(); return super.onOptionsItemSelected(item); case R.id.import_from_gallery: importFromGallery(); return super.onOptionsItemSelected(item); case R.id.save_file: showWarning(WARNING_NO_IMAGE_IMPORTED); return super.onOptionsItemSelected(item); case R.id.show_mesh: showWarning(WARNING_NO_IMAGE_IMPORTED); return super.onOptionsItemSelected(item); case R.id.save_location: if (LICENSE == LICENSE_TRIAL) { Toast.makeText(getApplicationContext(), WARNING_PREMIUM_FEATURE_SAVE_IMAGE, Toast.LENGTH_SHORT) .show(); return super.onOptionsItemSelected(item); } showSaveLocation(); return super.onOptionsItemSelected(item); case R.id.meshColor: showWarning(WARNING_NO_IMAGE_IMPORTED); return super.onOptionsItemSelected(item); case R.id.share: showWarning(WARNING_NO_IMAGE_IMPORTED); return super.onOptionsItemSelected(item); case R.id.about: showAbout(); return super.onOptionsItemSelected(item); //TODO: 11-4-2016 FIX: Hiding Navigation Bar scheme dispose, exit button not required /* case R.id.exit: exit(); return super.onOptionsItemSelected(item); */ default: return super.onOptionsItemSelected(item); } case STATE_PROCESSING_IMAGE: switch (item.getItemId()) { case R.id.online_gallery: goOnlineGallery(); return super.onOptionsItemSelected(item); case R.id.premium: goPremium(); return super.onOptionsItemSelected(item); case R.id.take_a_photo: photoFromCamera(); return super.onOptionsItemSelected(item); case R.id.import_from_gallery: importFromGallery(); return super.onOptionsItemSelected(item); case R.id.save_file: if (LICENSE == LICENSE_TRIAL) { Toast.makeText(getApplicationContext(), WARNING_PREMIUM_FEATURE_SAVE_IMAGE, Toast.LENGTH_SHORT) .show(); return super.onOptionsItemSelected(item); } requestProcessedPhoto(); return super.onOptionsItemSelected(item); case R.id.show_mesh: if (!ipv.SHOW_MESH) { item.setTitle(R.string.hide_mesh); ipv.showMesh(true); PREF_MESH_VALUE = true; preferenceEditor.putBoolean(PREF_MESH, PREF_MESH_VALUE); preferenceEditor.commit(); } else { item.setTitle(R.string.show_mesh); ipv.showMesh(false); PREF_MESH_VALUE = false; preferenceEditor.putBoolean(PREF_MESH, PREF_MESH_VALUE); preferenceEditor.commit(); } return super.onOptionsItemSelected(item); case R.id.meshColor: showColorPickerDialog(); return super.onOptionsItemSelected(item); case R.id.save_location: if (LICENSE == LICENSE_TRIAL) { Toast.makeText(getApplicationContext(), WARNING_PREMIUM_FEATURE_SAVE_IMAGE, Toast.LENGTH_SHORT) .show(); return super.onOptionsItemSelected(item); } showSaveLocation(); return super.onOptionsItemSelected(item); case R.id.share: /* if (LICENSE == LICENSE_TRIAL) { Toast.makeText(getApplicationContext(), WARNING_PREMIUM_FEATURE_SHARE_IMAGE, Toast.LENGTH_SHORT).show(); return super.onOptionsItemSelected(item); } */ share(); return super.onOptionsItemSelected(item); case R.id.about: showAbout(); return super.onOptionsItemSelected(item); //TODO: 11-4-2016 FIX: Hiding Navigation Bar scheme dispose, exit button not required /* case R.id.exit: exit(); return super.onOptionsItemSelected(item); */ default: return super.onOptionsItemSelected(item); } } ipv.setClickable(true); return super.onOptionsItemSelected(item); } private void goOnlineGallery() { Toast.makeText(getApplicationContext(), "Online gallery will be avaliable soon.", Toast.LENGTH_LONG).show(); } private void share() { Log.d(TAG, "Sharing photo."); if (isMenuLoaded) { ACTION = ACTION_SHARE; requestProcessedPhoto(); } } private void goPremium() { try { ipv.showProgressDialog(); if (purchaseHelper == null || !isLicenseLoaded) { Toast.makeText(getApplicationContext(), ERROR_GOOGLE_PLAY_NOT_AVAILABLE, Toast.LENGTH_LONG).show(); ipv.hideProgressDialog(); return; } purchaseHelper.launchPurchaseFlow(this, LICENSE_PREMIUM_ID, REQUEST_CODE_PURCHASE, MainActivity.this, PURCHASE_KEY); } catch (InAppBillingHelper.InAppBillingAsyncInProgressException e) { ipv.hideProgressDialog(); Log.d(TAG, "Error launching purchase flow. Another async operation in progress."); e.printStackTrace(); } } private void showColorPickerDialog() { if (colorPickerDialog == null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { colorPickerDialog = new ColorPickerDialog(this, this, PREF_COLOR_VALUE, (int) (ImageProcessingViewHeight * 0.15), (int) (ImageProcessingViewHeight * 0.1), actionBar.getHeight() / 2, R.style.ColorPickerTheme_v21); } else { colorPickerDialog = new ColorPickerDialog(this, this, PREF_COLOR_VALUE, (int) (ImageProcessingViewHeight * 0.15), (int) (ImageProcessingViewHeight * 0.1), actionBar.getHeight() / 2, R.style.ColorPickerTheme); } } ipv.setInkColor(PREF_COLOR_VALUE); //Log.d("debugging", String.valueOf(actionBar.getHeight())); colorPickerDialog.show(); } private void exit() { //System.exit(0); Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_HOME); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(intent); } private static final int REQUEST_CODE_GALLERY = 1; private static final int REQUEST_CODE_CAMERA = 2; private void importFromGallery() { startActivityForResult( new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI), REQUEST_CODE_GALLERY); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { ipv.hideProgressDialog(); switch (requestCode) { case REQUEST_CODE_SHARE: // delete cache deleteCache(); unlockMenu(); unlockScreen(); ipv.hideProgressDialog(); try { out.close(); } catch (IOException e) { e.printStackTrace(); } break; case REQUEST_CODE_CAMERA: if (resultCode != RESULT_OK) { Toast.makeText(getApplicationContext(), WARNING_NO_IMAGE_IMPORTED, Toast.LENGTH_LONG).show(); return; } ipv.setVisibility(View.VISIBLE); textView.setVisibility(View.INVISIBLE); rawBitmap = getBitmapFromPath(); rawBitmapWidth = rawBitmap.getWidth(); rawBitmapHeight = rawBitmap.getHeight(); /* if ((float) rawBitmapWidth / rawBitmapHeight < (float) ImageProcessingViewWidth / ImageProcessingViewHeight) { IMAGE_ROTATED_TO_PROCESS = true; Matrix matrix = new Matrix(); matrix.postRotate(90); rawBitmap = Bitmap.createBitmap(rawBitmap, 0, 0, rawBitmapWidth, rawBitmapHeight, matrix, true); Toast.makeText(getApplicationContext(), "Processed image will be rotated back when save.", Toast.LENGTH_LONG).show(); } */ if (rawBitmap == null) { Toast.makeText(getApplicationContext(), WARNING_NO_IMAGE_IMPORTED, Toast.LENGTH_LONG).show(); break; } else { ipv.setVisibility(View.VISIBLE); textView.setVisibility(View.INVISIBLE); } ipv.process(compressImgSize2FitIPV(rawBitmap)); STATE = STATE_PROCESSING_IMAGE; break; case REQUEST_CODE_GALLERY: if (resultCode != RESULT_OK) { Toast.makeText(getApplicationContext(), WARNING_NO_IMAGE_IMPORTED, Toast.LENGTH_LONG).show(); return; } InputStream stream; try { stream = getContentResolver().openInputStream(data.getData()); ipv.setVisibility(View.VISIBLE); textView.setVisibility(View.INVISIBLE); // FIXME: first calculate suitable size and then ensure import .png format rawBitmap = BitmapFactory.decodeStream(stream); rawBitmapWidth = rawBitmap.getWidth(); rawBitmapHeight = rawBitmap.getHeight(); ipv.process(compressImgSize2FitIPV(rawBitmap)); STATE = STATE_PROCESSING_IMAGE; stream.close(); } catch (FileNotFoundException e) { Toast.makeText(getApplicationContext(), WARNING_NO_IMAGE_IMPORTED, Toast.LENGTH_LONG).show(); e.printStackTrace(); break; } catch (IOException e) { e.printStackTrace(); } break; case REQUEST_CODE_PURCHASE: if (purchaseHelper == null) return; if (!purchaseHelper.handleActivityResult(REQUEST_CODE_PURCHASE, resultCode, data)) { super.onActivityResult(requestCode, resultCode, data); } Log.d(TAG, "Request result is processing"); break; } } private void photoFromCamera() { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // Ensure that there's a camera activity to handle the intent if (takePictureIntent.resolveActivity(getPackageManager()) != null) { // Create the File where the photo should go File photoFile = null; try { photoFile = createImageFile(); } catch (IOException ex) { // Error occurred while creating the File Toast.makeText(getApplicationContext(), WARNING_CAMERA_IMPORT_ERROR, Toast.LENGTH_LONG).show(); } // Continue only if the File was successfully created if (photoFile != null) { takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile)); startActivityForResult(takePictureIntent, REQUEST_CODE_CAMERA); } } } private final static int SAVE_BITMAP_MAX_PIXEL_SIZE = 2400 * 1600; private Bitmap getBitmapFromPath() { //BitmapFactory.Options bmOptions = new BitmapFactory.Options(); //bmOptions.inJustDecodeBounds = false; // TODO: UPDATE: Decode bitmap to suitable size to avoid memory issue BitmapFactory.Options option = new BitmapFactory.Options(); option.inJustDecodeBounds = true; BitmapFactory.decodeFile(mCurrentPhotoPath, option); double resizeRatio = Math.sqrt((double) SAVE_BITMAP_MAX_PIXEL_SIZE / (option.outWidth * option.outHeight)); int autoHeight = (int) (resizeRatio * option.outHeight); int autoWidth = (int) (resizeRatio * option.outWidth); // Calculate inSampleSize option.inSampleSize = calculateInSampleSize(option, autoWidth, autoHeight); // Decode bitmap with inSampleSize set option.inJustDecodeBounds = false; return Bitmap.createScaledBitmap(BitmapFactory.decodeFile(mCurrentPhotoPath, option), (int) (resizeRatio * option.outWidth), (int) (resizeRatio * option.outHeight), false); } private String mCurrentPhotoPath; private File createImageFile() throws IOException { // Create an image file name String imageFileName = "TEMP"; File storageDir = getExternalFilesDir(null); File image = new File(storageDir, imageFileName + ".jpg"); // Save a file: path for use with ACTION_VIEW intents mCurrentPhotoPath = image.getAbsolutePath(); return image; } private Bitmap compressImgSize2FitIPV(Bitmap bitmap) { int imageHeight = bitmap.getHeight(); int imageWidth = bitmap.getWidth(); // TODO: prevent height or width == 0 even after getting bitmap while (ImageProcessingViewHeight == 0) ; return Bitmap.createScaledBitmap(bitmap, ImageProcessingViewHeight * imageWidth / imageHeight, ImageProcessingViewHeight, true); } private void showSaveLocation() { if (true || dirChooser == null) { dirChooser = DirectoryChooserFragment .newInstance( DirectoryChooserConfig.builder().initialDirectory(PREF_SAVE_LOCATION_VALUE) .allowReadOnlyDirectory(false).allowNewDirectoryNameModification(true) .newDirectoryName(getApplicationContext() .getString(getApplicationContext().getApplicationInfo().labelRes)) .build()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { dirChooser.setStyle(DialogFragment.STYLE_NO_TITLE, R.style.AppTheme_DialogTheme_API21); } else { dirChooser.setStyle(DialogFragment.STYLE_NO_TITLE, R.style.AppTheme_DialogTheme); } //dirChooser.setStyle(DialogFragment.STYLE_NO_TITLE, R.style.AppTheme_DialogTheme); } dirChooser.show(getFragmentManager(), null); } private void showAbout() { final View view = ((LayoutInflater) getBaseContext().getSystemService(LAYOUT_INFLATER_SERVICE)) .inflate(R.layout.popup_about, null); if (popupWindowAbout == null) { float height = ((ImageView) view.findViewById(R.id.imv)).getDrawable().getIntrinsicHeight(); float width = ((ImageView) view.findViewById(R.id.imv)).getDrawable().getIntrinsicWidth(); float ratio = height / (2 * width); width = Math.round(screenWidth * 0.9f); height = width * ratio; popupWindowAbout = new PopupWindow(view, Math.round(width), Math.round(height), true); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.CUPCAKE) { popupWindowAbout.setOutsideTouchable(true); } else { popupWindowAbout.setTouchInterceptor(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { popupWindowAbout.dismiss(); return false; } }); } popupWindowAbout.setBackgroundDrawable(new BitmapDrawable()); popupWindowAbout.setAnimationStyle(R.style.AnimationFade); //((TextView) view.findViewById(R.id.about_values)).setLinksClickable(true); //((TextView) view.findViewById(R.id.about_values)).setTextIsSelectable(false); view.setFocusable(true); view.setSelected(false); //((TextView) view.findViewById(R.id.about_values)).setText(Html.fromHtml("      Developer: Edward Yung <p>       Github: <a href='https://github.com/Edward-Yung'>github.com/Edward-Yung</a>")); //((TextView) view.findViewById(R.id.about_values)).setMovementMethod(LinkMovementMethod.getInstance()); } popupWindowAbout.showAtLocation(view, Gravity.CENTER, 0, -findViewById(R.id.tv_density_tag).getHeight()); } @Override public void onSelectDirectory(String location) { // debug Log.d(TAG, "isRemovableSDCARDAvaliable: " + String.valueOf(isRemovableSDCARDAvaliable())); Log.d(TAG, location); Log.d(TAG, "getRemovableStorage().getPath(): " + getRemovableStorage() == null ? getRemovableStorage().getPath() : ""); Log.d(TAG, "isOnRemovableSDCARDPath(location): " + String.valueOf(isOnRemovableSDCARDPath(location))); PREF_SAVE_LOCATION_VALUE = location; preferenceEditor.putString(PREF_SAVE_LOCATION, PREF_SAVE_LOCATION_VALUE); preferenceEditor.commit(); dirChooser.dismiss(); } @Override public void onCancelChooser() { dirChooser.dismiss(); } private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight) { // Raw height and width of image final int height = options.outHeight; final int width = options.outWidth; int inSampleSize = 1; if (height > reqHeight || width > reqWidth) { final int halfHeight = height / 2; final int halfWidth = width / 2; // Calculate the largest inSampleSize value that is a power of 2 and keeps both // height and width larger than the requested height and width. while ((halfHeight / inSampleSize) > reqHeight && (halfWidth / inSampleSize) > reqWidth) { inSampleSize *= 2; } } return inSampleSize; } private static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, int reqWidth, int reqHeight) { // First decode with inJustDecodeBounds=true to check dimensions final BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeResource(res, resId, options); // Calculate inSampleSize options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); // Decode bitmap with inSampleSize set options.inJustDecodeBounds = false; return BitmapFactory.decodeResource(res, resId, options); } @Override public void onProcessedResult(Bitmap bitmap) { switch (ACTION) { case ACTION_SHARE: try { File cacheDirectory = new File(getApplicationContext().getCacheDir().getPath() + "/images/"); cacheDirectory.mkdirs(); shareCacheUri = Uri .parse(getApplicationContext().getCacheDir().getPath() + "/images/" + cacheFileName); // save to cache out = new FileOutputStream(shareCacheUri.getPath()); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, out); File file = new File(shareCacheUri.getPath()); shareCacheUri = FileProvider.getUriForFile(getApplicationContext(), "com.segma.trim.fileprovider", file); // share CacheUri Intent send = ImageAPIParser.parse(this, getPackageManager(), shareCacheUri); if (send == null) { Toast.makeText(getApplicationContext(), WARNING_NO_APPROPRIATE_INTENT, Toast.LENGTH_LONG) .show(); break; } startActivityForResult(send, REQUEST_CODE_SHARE); } catch (Exception e) { Log.d(TAG, "Exception: " + e.toString()); unlockMenu(); unlockScreen(); ipv.hideProgressDialog(); e.printStackTrace(); } ACTION = ACTION_SAVE; break; case ACTION_SAVE: //FIXME: UPDATE PENDING: custom saving location try { if (isOnRemovableSDCARDPath(PREF_SAVE_LOCATION_VALUE)) { MediaFile mediaFile = new MediaFile(getContentResolver(), new File(PREF_SAVE_LOCATION_VALUE + "/result_" + new SimpleDateFormat("yyyyMMddHHmm").format(new Date()) + ".png")); out = mediaFile.write(); bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); Toast.makeText(getApplicationContext(), MESSAGE_IMAGE_SAVED, Toast.LENGTH_LONG).show(); new Handler().postDelayed(new Runnable() { @Override public void run() { unlockMenu(); unlockScreen(); ipv.hideProgressDialog(); } }, 2000); out.close(); break; } out = new FileOutputStream(PREF_SAVE_LOCATION_VALUE + "/result_" + new SimpleDateFormat("yyyyMMddHHmm").format(new Date()) + ".png"); bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); Toast.makeText(getApplicationContext(), MESSAGE_IMAGE_SAVED, Toast.LENGTH_LONG).show(); new Handler().postDelayed(new Runnable() { @Override public void run() { unlockMenu(); unlockScreen(); ipv.hideProgressDialog(); } }, 2000); out.close(); } catch (Exception e) { unlockMenu(); unlockScreen(); ipv.hideProgressDialog(); Toast.makeText(getApplicationContext(), WARNING_SAVE_IMAGE_FAILED, Toast.LENGTH_LONG).show(); new Handler().postDelayed(new Runnable() { @Override public void run() { showSaveLocation(); } }, 1000); e.printStackTrace(); } break; } } private void lockScreen() { getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); } private void unlockScreen() { getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE); } private void lockMenu() { isMenuLocked = true; } private void unlockMenu() { isMenuLocked = false; } private void requestProcessedPhoto() { Log.d(TAG, "requesting processing results"); switch (ACTION) { case ACTION_SAVE: if (isExternalStorageAllowed) { lockScreen(); lockMenu(); //if (Environment.getExternalStorageState() == Environment.) { //Toast.makeText(getApplicationContext(), "Saving image.", Toast.LENGTH_SHORT).show(); ipv.showProgressDialog(); ipv.saveTriangulatedImage(this, rawBitmapWidth, rawBitmapHeight); } else { unlockMenu(); unlockScreen(); isExternalStorageAllowed = checkPermission_6_0(this); if (!isExternalStorageAllowed) { Toast.makeText(getApplicationContext(), WARNING_SAVE_IMAGE_FAILED, Toast.LENGTH_SHORT).show(); return; } requestProcessedPhoto(); } break; case ACTION_SHARE: lockScreen(); lockMenu(); ipv.showProgressDialog(); ipv.saveTriangulatedImage(this, rawBitmapWidth, rawBitmapHeight); break; } } /** * SeekBar's controls */ int complexity_min = 2; int complexity_max = 10; int complexity = complexity_min; float density_min = 0.05f; float density_max = 0.95f; float density = density_min; DecimalFormat df = new DecimalFormat("#.#"); @Override public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { switch (seekBar.getId()) { case R.id.sb_complexity: int richness = (complexity_max - complexity_min) * progress / 100 + complexity_min; if (richness == this.complexity) break; this.complexity = richness; ((TextView) findViewById(R.id.tv_complexity_value)).setText(String.valueOf(richness)); break; case R.id.sb_density: float density = (density_max - density_min) * progress / 100 + density_min; if (density == this.density) break; this.density = density; ((TextView) findViewById(R.id.tv_density_value)).setText(String.valueOf(df.format(density))); break; } } @Override public void onStartTrackingTouch(SeekBar seekBar) { switch (seekBar.getId()) { case R.id.sb_complexity: //((TextView)findViewById(R.id.tv_richness_value)).setTextColor(getResources().getColor(R.color.BurlyWood)); //((TextView) findViewById(R.id.tv_richness_value)).setTextSize(18); break; case R.id.sb_density: //((TextView)findViewById(R.id.tv_density_value)).setTextColor(getResources().getColor(R.color.Gray)); //((TextView) findViewById(R.id.tv_density_value)).setTextSize(18); break; } } @Override public void onStopTrackingTouch(SeekBar seekBar) { switch (seekBar.getId()) { case R.id.sb_complexity: ((TextView) findViewById(R.id.tv_complexity_value)) .setTextColor(getResources().getColor(R.color.WhiteSmoke)); //((TextView) findViewById(R.id.tv_richness_value)).setTextSize(12); Log.d(TAG, "java complexity: " + String.valueOf(complexity)); ImageProcessingView.params.richness = complexity; break; case R.id.sb_density: ((TextView) findViewById(R.id.tv_density_value)) .setTextColor(getResources().getColor(R.color.WhiteSmoke)); //((TextView) findViewById(R.id.tv_density_value)).setTextSize(12); Log.d(TAG, "java density: " + String.valueOf(density)); ImageProcessingView.params.density = density; break; } } /** * ColorPicker's controls */ @Override public void colorChanged(int color) { ipv.setInkColor(color); PREF_COLOR_VALUE = color; preferenceEditor.putInt(PREF_COLOR, PREF_COLOR_VALUE); preferenceEditor.commit(); colorPickerDialog.dismiss(); } /** * License */ @Override public void receivedBroadcast() { try { purchaseHelper.queryInventoryAsync(MainActivity.this); } catch (InAppBillingHelper.InAppBillingAsyncInProgressException e) { Log.d(TAG, "Error querying inventory. Another async request is not finished."); e.printStackTrace(); } } @Override public void onQueryInventoryFinished(InAppBillingResult result, Inventory inventory) { Log.d(TAG, "Query inventory finished."); if (purchaseHelper == null) return; if (result.isFailure()) { Log.d(TAG, "Failed to query inventory: " + result); return; } Log.d(TAG, "Query inventory was successful."); // check license updates Purchase purchase = inventory.getPurchase(LICENSE_PREMIUM_ID); LICENSE = (purchase != null && isPurchaseLegal(purchase)); if (MODE_DEBUG) { LICENSE = LICENSE_PREMIUM; getPackageManager().clearPackagePreferredActivities(getApplicationContext().getPackageName()); } isLicenseLoaded = true; updateUI(); } @Override public void onInAppBillingPurchaseFinished(InAppBillingResult result, Purchase purchase) { Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase); if (purchaseHelper == null) return; if (result.isFailure()) { Log.d(TAG, "Error purchasing: " + result); ipv.hideProgressDialog(); return; } if (!isPurchaseLegal(purchase)) { Log.d(TAG, "Error purchasing. Authenticity verification failed."); ipv.hideProgressDialog(); return; } if (purchase.getStockKeepingUnit().equals(LICENSE_PREMIUM_ID)) { Log.d(TAG, "Purchase successful."); LICENSE = LICENSE_PREMIUM; Toast.makeText(getApplicationContext(), MESSAGE_PURCHASE, Toast.LENGTH_LONG).show(); updateUI(); } else { Log.d(TAG, "Unknown purchase."); } } boolean isPurchaseLegal(Purchase purchase) { String purchaseKey = purchase.getDeveloperPayload(); if (purchaseKey == PURCHASE_KEY) return true; return false; } /** * Activity Cycles */ @Override protected void onDestroy() { super.onDestroy(); if (broadcastReceiver != null) { unregisterReceiver(broadcastReceiver); } if (purchaseHelper != null) { purchaseHelper.disposeWhenFinished(); purchaseHelper = null; } Log.d(TAG, "Activity is destroyed"); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); } @Override protected void onSaveInstanceState(Bundle outState) { Log.d(TAG, "activity is request to save states"); super.onSaveInstanceState(outState); } /** * External Storage functions */ @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CODE_EXTERNAL_STORAGE_PERMISSION) isExternalStorageAllowed = (grantResults[0] == PackageManager.PERMISSION_GRANTED); } private static boolean isSDCARDAvailable() { return Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED); } private static boolean isRemovableSDCARDAvaliable() { final String value = System.getenv("SECONDARY_STORAGE"); if (!TextUtils.isEmpty(value)) return true; return false; } public static File getRemovableStorage() { final String value = System.getenv("SECONDARY_STORAGE"); if (!TextUtils.isEmpty(value)) { final String[] paths = value.split(":"); for (String path : paths) { File file = new File(path); if (file.isDirectory()) { return file; } } } return null; } private static boolean isOnRemovableSDCARDPath(String location) { final File microSD = getRemovableStorage(); if (microSD != null) { if (("/storage" + location).startsWith(microSD.getAbsolutePath())) { return true; } } return false; } private static boolean checkPermission_6_0(Activity activity) { if (ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) return true; ActivityCompat.requestPermissions(activity, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, REQUEST_CODE_EXTERNAL_STORAGE_PERMISSION); return false; } public void deleteCache() { try { File dir = getCacheDir(); deleteDir(dir); } catch (Exception e) { } } public static boolean deleteDir(File dir) { if (dir != null && dir.isDirectory()) { String[] children = dir.list(); for (int i = 0; i < children.length; i++) { boolean success = deleteDir(new File(dir, children[i])); if (!success) { return false; } } return dir.delete(); } else if (dir != null && dir.isFile()) { return dir.delete(); } else { return false; } } /** * Admob */ private static AdView mAdView; private static InterstitialAd fullScreenAdView; private static int adViewHeight; private void loadAds() { RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) findViewById(R.id.adView_wrapper) .getLayoutParams(); adViewHeight = params.height; params.height = 0; findViewById(R.id.adView_wrapper).setLayoutParams(params); new Runnable() { final Handler handler = new Handler(); @Override public void run() { if (!isLicenseLoaded) { handler.postDelayed(this, 1000); return; } if (LICENSE) { mAdView = (AdView) findViewById(R.id.adView); mAdView.setVisibility(View.GONE); return; } RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) findViewById(R.id.adView_wrapper) .getLayoutParams(); params.height = adViewHeight; findViewById(R.id.adView_wrapper).setLayoutParams(params); //findViewById(R.id.adView_wrapper).setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,RelativeLayout.LayoutParams.WRAP_CONTENT)); mAdView = (AdView) findViewById(R.id.adView); AdRequest adRequest_0 = new AdRequest.Builder().build(); if (mAdView != null) mAdView.loadAd(adRequest_0); fullScreenAdView = new InterstitialAd(MainActivity.this); fullScreenAdView.setAdUnitId(getString(R.string.ads_segma_triango_1)); AdRequest adRequest_1 = new AdRequest.Builder().build(); if (fullScreenAdView != null) fullScreenAdView.loadAd(adRequest_1); fullScreenAdView.setAdListener(new AdListener() { @Override public void onAdClosed() { super.onAdClosed(); } @Override public void onAdLoaded() { //showFullScreenAd(); } }); } }.run(); } public static void showFullScreenAd() { if (!isLicenseLoaded || LICENSE) return; if (fullScreenAdView.isLoaded()) { fullScreenAdView.show(); } } }