- * http://www.kayenko.com ported april 5th, 2012
- *
- * This is A compromise between Gaussian Blur and Box blur It creates much better looking blurs
- * than Box Blur, but is 7x faster than my Gaussian Blur implementation.
- *
- *
I called it Stack Blur because this describes best how this filter works internally: it
- * creates A kind of moving stack of colors whilst scanning through the image. Thereby it just has
- * to add one new block of color to the right side of the stack and removeFromParent the leftmost
- * color. The remaining colors on the topmost layer of the stack are either added on or reduced by
- * one, depending on if they are on the right or on the x side of the stack.
- *
- *
If you are using this algorithm in your code please add the following line: Stack Blur
- * Algorithm by Mario Klingemann
- */
- public static Bitmap FastBlurSupportAlpha(Bitmap sentBitmap, float scale, int radius) {
-
- int width = Math.round(sentBitmap.getWidth() * scale);
- int height = Math.round(sentBitmap.getHeight() * scale);
- sentBitmap = Bitmap.createScaledBitmap(sentBitmap, width, height, false);
-
- Bitmap bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
-
- if (radius < 1) {
- return (null);
- }
-
- int w = bitmap.getWidth();
- int h = bitmap.getHeight();
-
- int[] pix = new int[w * h];
- // Log.e("pix", w + " " + h + " " + pix.length);
- bitmap.getPixels(pix, 0, w, 0, 0, w, h);
-
- int wm = w - 1;
- int hm = h - 1;
- int wh = w * h;
- int div = radius + radius + 1;
-
- int[] r = new int[wh];
- int[] g = new int[wh];
- int[] b = new int[wh];
- int[] a = new int[wh];
- int rsum, gsum, bsum, asum, x, y, i, p, yp, yi, yw;
- int[] vmin = new int[Math.max(w, h)];
-
- int divsum = (div + 1) >> 1;
- divsum *= divsum;
- int[] dv = new int[256 * divsum];
- for (i = 0; i < 256 * divsum; i++) {
- dv[i] = (i / divsum);
- }
-
- yw = yi = 0;
-
- int[][] stack = new int[div][4];
- int stackpointer;
- int stackstart;
- int[] sir;
- int rbs;
- int r1 = radius + 1;
- int routsum, goutsum, boutsum, aoutsum;
- int rinsum, ginsum, binsum, ainsum;
-
- for (y = 0; y < h; y++) {
- rinsum =
- ginsum =
- binsum =
- ainsum = routsum = goutsum = boutsum = aoutsum = rsum = gsum = bsum = asum = 0;
- for (i = -radius; i <= radius; i++) {
- p = pix[yi + Math.min(wm, Math.max(i, 0))];
- sir = stack[i + radius];
- sir[0] = (p & 0xff0000) >> 16;
- sir[1] = (p & 0x00ff00) >> 8;
- sir[2] = (p & 0x0000ff);
- sir[3] = 0xff & (p >> 24);
-
- rbs = r1 - Math.abs(i);
- rsum += sir[0] * rbs;
- gsum += sir[1] * rbs;
- bsum += sir[2] * rbs;
- asum += sir[3] * rbs;
- if (i > 0) {
- rinsum += sir[0];
- ginsum += sir[1];
- binsum += sir[2];
- ainsum += sir[3];
- } else {
- routsum += sir[0];
- goutsum += sir[1];
- boutsum += sir[2];
- aoutsum += sir[3];
- }
- }
- stackpointer = radius;
-
- for (x = 0; x < w; x++) {
-
- r[yi] = dv[rsum];
- g[yi] = dv[gsum];
- b[yi] = dv[bsum];
- a[yi] = dv[asum];
-
- rsum -= routsum;
- gsum -= goutsum;
- bsum -= boutsum;
- asum -= aoutsum;
-
- stackstart = stackpointer - radius + div;
- sir = stack[stackstart % div];
-
- routsum -= sir[0];
- goutsum -= sir[1];
- boutsum -= sir[2];
- aoutsum -= sir[3];
-
- if (y == 0) {
- vmin[x] = Math.min(x + radius + 1, wm);
- }
- p = pix[yw + vmin[x]];
-
- sir[0] = (p & 0xff0000) >> 16;
- sir[1] = (p & 0x00ff00) >> 8;
- sir[2] = (p & 0x0000ff);
- sir[3] = 0xff & (p >> 24);
-
- rinsum += sir[0];
- ginsum += sir[1];
- binsum += sir[2];
- ainsum += sir[3];
-
- rsum += rinsum;
- gsum += ginsum;
- bsum += binsum;
- asum += ainsum;
-
- stackpointer = (stackpointer + 1) % div;
- sir = stack[(stackpointer) % div];
-
- routsum += sir[0];
- goutsum += sir[1];
- boutsum += sir[2];
- aoutsum += sir[3];
-
- rinsum -= sir[0];
- ginsum -= sir[1];
- binsum -= sir[2];
- ainsum -= sir[3];
-
- yi++;
- }
- yw += w;
- }
- for (x = 0; x < w; x++) {
- rinsum =
- ginsum =
- binsum =
- ainsum = routsum = goutsum = boutsum = aoutsum = rsum = gsum = bsum = asum = 0;
- yp = -radius * w;
- for (i = -radius; i <= radius; i++) {
- yi = Math.max(0, yp) + x;
-
- sir = stack[i + radius];
-
- sir[0] = r[yi];
- sir[1] = g[yi];
- sir[2] = b[yi];
- sir[3] = a[yi];
-
- rbs = r1 - Math.abs(i);
-
- rsum += r[yi] * rbs;
- gsum += g[yi] * rbs;
- bsum += b[yi] * rbs;
- asum += a[yi] * rbs;
-
- if (i > 0) {
- rinsum += sir[0];
- ginsum += sir[1];
- binsum += sir[2];
- ainsum += sir[3];
- } else {
- routsum += sir[0];
- goutsum += sir[1];
- boutsum += sir[2];
- aoutsum += sir[3];
- }
-
- if (i < hm) {
- yp += w;
- }
- }
- yi = x;
- stackpointer = radius;
- for (y = 0; y < h; y++) {
- pix[yi] = (dv[asum] << 24) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];
-
- rsum -= routsum;
- gsum -= goutsum;
- bsum -= boutsum;
- asum -= aoutsum;
-
- stackstart = stackpointer - radius + div;
- sir = stack[stackstart % div];
-
- routsum -= sir[0];
- goutsum -= sir[1];
- boutsum -= sir[2];
- aoutsum -= sir[3];
-
- if (x == 0) {
- vmin[y] = Math.min(y + r1, hm) * w;
- }
- p = x + vmin[y];
-
- sir[0] = r[p];
- sir[1] = g[p];
- sir[2] = b[p];
- sir[3] = a[p];
-
- rinsum += sir[0];
- ginsum += sir[1];
- binsum += sir[2];
- ainsum += sir[3];
-
- rsum += rinsum;
- gsum += ginsum;
- bsum += binsum;
- asum += ainsum;
-
- stackpointer = (stackpointer + 1) % div;
- sir = stack[stackpointer];
-
- routsum += sir[0];
- goutsum += sir[1];
- boutsum += sir[2];
- aoutsum += sir[3];
-
- rinsum -= sir[0];
- ginsum -= sir[1];
- binsum -= sir[2];
- ainsum -= sir[3];
-
- yi += w;
- }
- }
-
- // Log.e("pix", w + " " + h + " " + pix.length);
- bitmap.setPixels(pix, 0, w, 0, 0, w, h);
-
- return (bitmap);
- }
-
- public static boolean PerceivedBrightness(int will_White, int[] c) {
- double TBT = Math.sqrt(c[0] * c[0] * .241 + c[1] * c[1] * .691 + c[2] * c[2] * .068);
- // Log.d("themee",TBT+"");
- return !(TBT > will_White);
- }
-
- public static int[] getAverageColorRGB(Bitmap bitmap) {
- final int width = bitmap.getWidth();
- final int height = bitmap.getHeight();
- int size = width * height;
- int pixelColor;
- int r, g, b;
- r = g = b = 0;
- for (int x = 0; x < width; ++x) {
- for (int y = 0; y < height; ++y) {
- pixelColor = bitmap.getPixel(x, y);
- if (pixelColor == 0) {
- size--;
- continue;
- }
- r += Color.red(pixelColor);
- g += Color.green(pixelColor);
- b += Color.blue(pixelColor);
- }
- }
- r /= size;
- g /= size;
- b /= size;
- return new int[] {r, g, b};
- }
-
- public static Bitmap updateSat(Bitmap src, float settingSat) {
-
- int w = src.getWidth();
- int h = src.getHeight();
-
- Bitmap bitmapResult = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
- Canvas canvasResult = new Canvas(bitmapResult);
- Paint paint = new Paint();
- ColorMatrix colorMatrix = new ColorMatrix();
- colorMatrix.setSaturation(settingSat);
- ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
- paint.setColorFilter(filter);
- canvasResult.drawBitmap(src, 0, 0, paint);
- canvasResult.setBitmap(null);
- canvasResult = null;
- return bitmapResult;
- }
-
- /**
- * Stack Blur v1.0 from http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html Java
- * Author: Mario Klingemann http://incubator.quasimondo.com
- *
- * created Feburary 29, 2004 Android port : Yahel Bouaziz
- * http://www.kayenko.com ported april 5th, 2012
- *
- * This is A compromise between Gaussian Blur and Box blur It creates much better looking blurs
- * than Box Blur, but is 7x faster than my Gaussian Blur implementation.
- *
- *
I called it Stack Blur because this describes best how this filter works internally: it
- * creates A kind of moving stack of colors whilst scanning through the image. Thereby it just has
- * to add one new block of color to the right side of the stack and removeFromParent the leftmost
- * color. The remaining colors on the topmost layer of the stack are either added on or reduced by
- * one, depending on if they are on the right or on the x side of the stack.
- *
- *
If you are using this algorithm in your code please add the following line: Stack Blur
- * Algorithm by Mario Klingemann
- */
- public static Bitmap fastblur(Bitmap sentBitmap, float scale, int radius) {
-
- Bitmap afterscaleSentBitmap;
- Bitmap bitmap;
- if (scale != 1) {
- int width = Math.round(sentBitmap.getWidth() * scale); // lấy chiều rộng làm tròn
- int height = Math.round(sentBitmap.getHeight() * scale); // lấy chiều cao làm tròn
- afterscaleSentBitmap =
- Bitmap.createScaledBitmap(sentBitmap, width, height, false); // tạo bitmap scaled
- bitmap = afterscaleSentBitmap.copy(afterscaleSentBitmap.getConfig(), true);
- afterscaleSentBitmap.recycle();
- } else {
- bitmap = sentBitmap.copy(sentBitmap.getConfig(), true); // đơn giản chỉ copy
- }
-
- if (radius < 1) {
- return (sentBitmap.copy(sentBitmap.getConfig(), true));
- }
-
- int w = bitmap.getWidth(); // w is the width of sample bitmap
- int h = bitmap.getHeight(); // h is the height of sample bitmap
-
- int[] pix = new int[w * h]; // pix is the arrary of all bitmap pixel
-
- bitmap.getPixels(pix, 0, w, 0, 0, w, h);
-
- int wm = w - 1;
- int hm = h - 1;
- int wh = w * h;
- int div = radius + radius + 1;
-
- int[] r = new int[wh];
- int[] g = new int[wh];
- int[] b = new int[wh];
- int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
- int[] vmin = new int[Math.max(w, h)];
-
- int divsum = (div + 1) >> 1;
- divsum *= divsum;
- int[] dv = new int[256 * divsum];
- for (i = 0; i < 256 * divsum; i++) {
- dv[i] = (i / divsum);
- }
-
- yw = yi = 0;
-
- int[][] stack = new int[div][3];
- int stackpointer;
- int stackstart;
- int[] sir;
- int rbs;
- int r1 = radius + 1;
- int routsum, goutsum, boutsum;
- int rinsum, ginsum, binsum;
-
- for (y = 0; y < h; y++) {
- rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
- for (i = -radius; i <= radius; i++) {
- p = pix[yi + Math.min(wm, Math.max(i, 0))];
- sir = stack[i + radius];
- sir[0] = (p & 0xff0000) >> 16;
- sir[1] = (p & 0x00ff00) >> 8;
- sir[2] = (p & 0x0000ff);
- rbs = r1 - Math.abs(i);
- rsum += sir[0] * rbs;
- gsum += sir[1] * rbs;
- bsum += sir[2] * rbs;
- if (i > 0) {
- rinsum += sir[0];
- ginsum += sir[1];
- binsum += sir[2];
- } else {
- routsum += sir[0];
- goutsum += sir[1];
- boutsum += sir[2];
- }
- }
- stackpointer = radius;
-
- for (x = 0; x < w; x++) {
-
- r[yi] = dv[rsum];
- g[yi] = dv[gsum];
- b[yi] = dv[bsum];
-
- rsum -= routsum;
- gsum -= goutsum;
- bsum -= boutsum;
-
- stackstart = stackpointer - radius + div;
- sir = stack[stackstart % div];
-
- routsum -= sir[0];
- goutsum -= sir[1];
- boutsum -= sir[2];
-
- if (y == 0) {
- vmin[x] = Math.min(x + radius + 1, wm);
- }
- p = pix[yw + vmin[x]];
-
- sir[0] = (p & 0xff0000) >> 16;
- sir[1] = (p & 0x00ff00) >> 8;
- sir[2] = (p & 0x0000ff);
-
- rinsum += sir[0];
- ginsum += sir[1];
- binsum += sir[2];
-
- rsum += rinsum;
- gsum += ginsum;
- bsum += binsum;
-
- stackpointer = (stackpointer + 1) % div;
- sir = stack[(stackpointer) % div];
-
- routsum += sir[0];
- goutsum += sir[1];
- boutsum += sir[2];
-
- rinsum -= sir[0];
- ginsum -= sir[1];
- binsum -= sir[2];
-
- yi++;
- }
- yw += w;
- }
- for (x = 0; x < w; x++) {
- rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
- yp = -radius * w;
- for (i = -radius; i <= radius; i++) {
- yi = Math.max(0, yp) + x;
-
- sir = stack[i + radius];
-
- sir[0] = r[yi];
- sir[1] = g[yi];
- sir[2] = b[yi];
-
- rbs = r1 - Math.abs(i);
-
- rsum += r[yi] * rbs;
- gsum += g[yi] * rbs;
- bsum += b[yi] * rbs;
-
- if (i > 0) {
- rinsum += sir[0];
- ginsum += sir[1];
- binsum += sir[2];
- } else {
- routsum += sir[0];
- goutsum += sir[1];
- boutsum += sir[2];
- }
-
- if (i < hm) {
- yp += w;
- }
- }
- yi = x;
- stackpointer = radius;
- for (y = 0; y < h; y++) {
- // Preserve alpha channel: ( 0xff000000 & pix[yi] )
- pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];
-
- rsum -= routsum;
- gsum -= goutsum;
- bsum -= boutsum;
-
- stackstart = stackpointer - radius + div;
- sir = stack[stackstart % div];
-
- routsum -= sir[0];
- goutsum -= sir[1];
- boutsum -= sir[2];
-
- if (x == 0) {
- vmin[y] = Math.min(y + r1, hm) * w;
- }
- p = x + vmin[y];
-
- sir[0] = r[p];
- sir[1] = g[p];
- sir[2] = b[p];
-
- rinsum += sir[0];
- ginsum += sir[1];
- binsum += sir[2];
-
- rsum += rinsum;
- gsum += ginsum;
- bsum += binsum;
-
- stackpointer = (stackpointer + 1) % div;
- sir = stack[stackpointer];
-
- routsum += sir[0];
- goutsum += sir[1];
- boutsum += sir[2];
-
- rinsum -= sir[0];
- ginsum -= sir[1];
- binsum -= sir[2];
-
- yi += w;
- }
- }
-
- bitmap.setPixels(pix, 0, w, 0, 0, w, h);
-
- return (bitmap);
- }
-
- public static Bitmap getRoundedCornerBitmap(Bitmap bitmap, int pixels) {
- Bitmap output =
- Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(output);
-
- final int color = 0xff424242;
- final Paint paint = new Paint();
- final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
- // final ScreenSize rectF = new ScreenSize(rect);
- final float roundPx = pixels;
-
- paint.setAntiAlias(true);
- canvas.drawARGB(0, 0, 0, 0);
- paint.setColor(color);
- // canvas.drawRoundRect(rectF, roundPx, roundPx, paint);
- canvas.drawPath(
- BitmapEditor.RoundedRect(
- 0, 0, bitmap.getWidth(), bitmap.getHeight(), roundPx, roundPx, false),
- paint);
- paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
- canvas.drawBitmap(bitmap, rect, rect, paint);
-
- return output;
- }
-
- /**
- * getResizedBitmap method is used to Resized the Image according to custom width and height
- *
- * @param image image to be resized
- * @param newHeight (new desired height)
- * @param newWidth (new desired Width)
- * @return image (new resized image)
- */
- public static Bitmap getResizedBitmap(Bitmap image, int newHeight, int newWidth) {
- int width = image.getWidth();
- int height = image.getHeight();
- float scaleWidth = ((float) newWidth) / width;
- float scaleHeight = ((float) newHeight) / height;
- // create A matrix for the manipulation
- Matrix matrix = new Matrix();
- // onTap the bit map
- matrix.postScale(scaleWidth, scaleHeight);
- // recreate the new Bitmap
- return Bitmap.createBitmap(image, 0, 0, width, height, matrix, false);
- }
-
- public static boolean TrueIfBitmapBigger(Bitmap bitmap, int size) {
- int sizeBitmap =
- Math.max(bitmap.getHeight(), bitmap.getWidth());
- return sizeBitmap > size;
- }
-
- public static Bitmap getRoundedBitmapWithBlurShadow(
- Bitmap original, int paddingTop, int paddingBottom, int paddingLeft, int paddingRight) {
- int original_width = original.getWidth();
- int original_height = original.getHeight();
- int bitmap_width = original_width + paddingLeft + paddingRight;
- int bitmap_height = original_height + paddingTop + paddingBottom;
- Bitmap bitmap = Bitmap.createBitmap(bitmap_width, bitmap_height, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- Paint paint = new Paint();
- paint.setStyle(Paint.Style.FILL);
- // paint.setAlpha(60);
- // canvas.drawRect(0,0,bitmap_width,bitmap_height,paint);
- paint.setAntiAlias(true);
- canvas.drawBitmap(original, paddingLeft, paddingTop, paint);
- Bitmap blurred_bitmap = getBlurredWithGoodPerformance(bitmap, 1, 6, 4);
- canvas.setBitmap(null);
- bitmap.recycle();
- return blurred_bitmap;
- }
-
- // Activity.
- // |
- // Original bitmap.
- // |
- // | To make the blur background, the original must to padding.
- // |
- // | | | |
- // |
- // V
- // V V V V
- // V
- public static Bitmap GetRoundedBitmapWithBlurShadow(
- Context context,
- Bitmap original,
- int paddingTop,
- int paddingBottom,
- int paddingLeft,
- int paddingRight,
- int TopBack // this value makes the overview bitmap is higher or belower the background.
- ,
- int alphaBlurBackground // this is the alpha of the background Bitmap, you need A number
- // between 0 -> 255, the value recommend is 180.
- ,
- int valueBlurBackground // this is the value used to blur the background Bitmap, the
- // recommended one is 12.
- ,
- int valueSaturationBlurBackground // this is the value used to background Bitmap more
- // colorful, if valueBlur is 12, the valudeSaturation should
- // be 2.
- ) {
- int original_width = original.getWidth();
- int orginal_height = original.getHeight();
- int bitmap_width = original_width + paddingLeft + paddingRight;
- int bitmap_height = orginal_height + paddingTop + paddingBottom;
- Bitmap bitmap = Bitmap.createBitmap(bitmap_width, bitmap_height, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- Paint paint = new Paint();
- paint.setStyle(Paint.Style.FILL);
- paint.setAntiAlias(true);
- canvas.drawBitmap(original, paddingLeft, paddingTop, paint);
- Bitmap blurred_bitmap =
- getBlurredWithGoodPerformance(
- context, bitmap, 1, valueBlurBackground, valueSaturationBlurBackground);
- // Bitmap blurred_bitmap= getBlurredWithGoodPerformance(context, bitmap,1,15,3);
- Bitmap end_bitmap = Bitmap.createBitmap(bitmap_width, bitmap_height, Bitmap.Config.ARGB_8888);
- canvas.setBitmap(end_bitmap);
- paint.setAlpha(alphaBlurBackground);
-
- canvas.drawBitmap(
- blurred_bitmap,
- new Rect(0, 0, blurred_bitmap.getWidth(), blurred_bitmap.getHeight()),
- new Rect(0, 0, bitmap_width, bitmap_height),
- paint);
- paint.setAlpha(255);
-
- canvas.drawBitmap(bitmap, 0, TopBack, paint); // drawVisualWave cái lớn
- canvas.setBitmap(null);
- blurred_bitmap.recycle();
- bitmap.recycle();
- return end_bitmap;
- }
-
- public static void setBitmapforImageView(ImageView imv, Bitmap apply) {
- Bitmap old = ((BitmapDrawable) imv.getDrawable()).getBitmap();
- imv.setImageBitmap(apply);
- if (old != null) old.recycle();
- }
-
- public static Bitmap getBlurredWithGoodPerformance(
- Bitmap bitmap, int scale, int radius, int saturation) {
- BitmapFactory.Options options = new BitmapFactory.Options();
- Bitmap bitmap1 = getResizedBitmap(bitmap, 50, 50);
- Bitmap updateSatBitmap = updateSat(bitmap1, saturation);
- Bitmap blurredBitmap = FastBlurSupportAlpha(updateSatBitmap, scale, radius);
-
- updateSatBitmap.recycle();
- bitmap1.recycle();
- return blurredBitmap;
- }
-
- public static Path RoundedRect(
- float left,
- float top,
- float right,
- float bottom,
- float rx,
- float ry,
- boolean conformToOriginalPost) {
- Path path = new Path();
- if (rx < 0) rx = 0;
- if (ry < 0) ry = 0;
- float width = right - left;
- float height = bottom - top;
- if (rx > width / 2) rx = width / 2;
- if (ry > height / 2) ry = height / 2;
- float widthMinusCorners = (width - (2 * rx)); // do dai phan "thang" cua chieu rong
- float heightMinusCorners = (height - (2 * ry)); // do dai phan "thang" cua chieu dai
-
- path.moveTo(right, top + ry); // bat dau tu day
- path.rQuadTo(0, -ry, -rx, -ry); // y-right corner
- path.rLineTo(-widthMinusCorners, 0);
- path.rQuadTo(-rx, 0, -rx, ry); // y-x corner
- path.rLineTo(0, heightMinusCorners);
-
- if (conformToOriginalPost) {
- path.rLineTo(0, ry);
- path.rLineTo(width, 0);
- path.rLineTo(0, -ry);
- } else {
-
- path.rQuadTo(0, ry, rx, ry); // bottom-x corner
- path.rLineTo(widthMinusCorners, 0);
- path.rQuadTo(rx, 0, rx, -ry); // bottom-right corner
- }
-
- path.rLineTo(0, -heightMinusCorners);
-
- path.close(); // Given close, last lineto can be removed.
-
- return path;
- }
-
- public static int mixTwoColors(int color1, int color2, float amount) {
- final byte ALPHA_CHANNEL = 24;
- final byte RED_CHANNEL = 16;
- final byte GREEN_CHANNEL = 8;
- final byte BLUE_CHANNEL = 0;
-
- final float inverseAmount = 1.0f - amount;
-
- int a =
- ((int)
- (((float) (color1 >> ALPHA_CHANNEL & 0xff) * amount)
- + ((float) (color2 >> ALPHA_CHANNEL & 0xff) * inverseAmount)))
- & 0xff;
- int r =
- ((int)
- (((float) (color1 >> RED_CHANNEL & 0xff) * amount)
- + ((float) (color2 >> RED_CHANNEL & 0xff) * inverseAmount)))
- & 0xff;
- int g =
- ((int)
- (((float) (color1 >> GREEN_CHANNEL & 0xff) * amount)
- + ((float) (color2 >> GREEN_CHANNEL & 0xff) * inverseAmount)))
- & 0xff;
- int b =
- ((int) (((float) (color1 & 0xff) * amount) + ((float) (color2 & 0xff) * inverseAmount)))
- & 0xff;
-
- return a << ALPHA_CHANNEL | r << RED_CHANNEL | g << GREEN_CHANNEL | b << BLUE_CHANNEL;
- }
-
- public static Bitmap getBlurredWithGoodPerformance(
- Context context, Bitmap bitmap, int scale, int radius, float saturation) {
- Bitmap bitmap1 = getResizedBitmap(bitmap, 150, 150);
- Bitmap updateSatBimap = updateSat(bitmap1, saturation);
- Bitmap blurredBitmap = BlurBitmapWithRenderScript(context, updateSatBimap, radius);
- updateSatBimap.recycle();
- bitmap1.recycle();
- return blurredBitmap;
- }
-
- public static Bitmap getBlurredBimapWithRenderScript(
- Context context, Bitmap bitmapOriginal, float radius) {
- // define this only once if blurring multiple times
- RenderScript rs = RenderScript.create(context);
-
- // this will blur the bitmapOriginal with A radius of 8 and save it in bitmapOriginal
- final Allocation input =
- Allocation.createFromBitmap(
- rs, bitmapOriginal); // use this constructor for best performance, because it uses
- // USAGE_SHARED mode which reuses memory
- final Allocation output = Allocation.createTyped(rs, input.getType());
- final ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
- script.setRadius(radius);
- script.setInput(input);
- script.forEach(output);
- output.copyTo(bitmapOriginal);
- return bitmapOriginal;
- }
-
- public static Bitmap BlurBitmapWithRenderScript(Context context, Bitmap bitmap, float radius) {
- // Let's create an empty bitmap with the same size of the bitmap we want to blur
- Bitmap outBitmap =
- Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
-
- // Instantiate A new Renderscript
- RenderScript rs = RenderScript.create(context);
-
- // Create an Intrinsic Blur Script using the Renderscript
- ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
-
- // Create the Allocations (in/out) with the Renderscript and the in/out bitmaps
- Allocation allIn = Allocation.createFromBitmap(rs, bitmap);
- Allocation allOut = Allocation.createFromBitmap(rs, outBitmap);
- // Set the radius of the blur
- blurScript.setRadius(radius);
-
- // Perform the Renderscript
- blurScript.setInput(allIn);
- blurScript.forEach(allOut);
-
- // Copy the final bitmap created by the out Allocation to the outBitmap
- allOut.copyTo(outBitmap);
-
- // recycle the original bitmap
-
- // After finishing everything, we destroy the Renderscript.
- rs.destroy();
-
- return outBitmap;
- }
-
- public static Drawable covertBitmapToDrawable(Context context, Bitmap bitmap) {
- Drawable d = new BitmapDrawable(context.getResources(), bitmap);
- return d;
- }
-
- public static Bitmap convertDrawableToBitmap(Drawable drawable) {
- if (drawable instanceof BitmapDrawable) {
- return ((BitmapDrawable) drawable).getBitmap();
- }
- Bitmap bitmap =
- Bitmap.createBitmap(
- drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
- drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
- drawable.draw(canvas);
- return bitmap;
- }
-
- public static Bitmap changeBitmapColor(Bitmap sourceBitmap, int color) {
- Bitmap resultBitmap = sourceBitmap.copy(sourceBitmap.getConfig(), true);
- Paint paint = new Paint();
- ColorFilter filter = new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_IN);
- paint.setColorFilter(filter);
- Canvas canvas = new Canvas(resultBitmap);
- canvas.drawBitmap(resultBitmap, 0, 0, paint);
- return resultBitmap;
- }
-
- /**
- * @param mode
- * @return 0 : CLEAR
- * 1 : SRC
- * 2 : DST
- * 3 : SRC_OVER
- * 4 : DST_OVER
- * 5 : SRC_IN
- * 6 : DST_IN
- * 7 : SRC_OUT
- * 8 : DST_OUT
- * 9 : SRC_ATOP
- * 10 : DST_ATOP
- * 11 : XOR
- * 12 : ADD
- * 13 : MULTIPLY
- * 14 : SCREEN
- * 15 : OVERLAY
- * 16 : DARKEN
- * 17 : LIGHTEN
- */
- public static PorterDuff.Mode getPorterMode(int mode) {
- switch (mode) {
- default:
- case 0:
- return PorterDuff.Mode.CLEAR;
- case 1:
- return PorterDuff.Mode.SRC;
- case 2:
- return PorterDuff.Mode.DST;
- case 3:
- return PorterDuff.Mode.SRC_OVER;
- case 4:
- return PorterDuff.Mode.DST_OVER;
- case 5:
- return PorterDuff.Mode.SRC_IN;
- case 6:
- return PorterDuff.Mode.DST_IN;
- case 7:
- return PorterDuff.Mode.SRC_OUT;
- case 8:
- return PorterDuff.Mode.DST_OUT;
- case 9:
- return PorterDuff.Mode.SRC_ATOP;
- case 10:
- return PorterDuff.Mode.DST_ATOP;
- case 11:
- return PorterDuff.Mode.XOR;
- case 16:
- return PorterDuff.Mode.DARKEN;
- case 17:
- return PorterDuff.Mode.LIGHTEN;
- case 13:
- return PorterDuff.Mode.MULTIPLY;
- case 14:
- return PorterDuff.Mode.SCREEN;
- case 12:
- return PorterDuff.Mode.ADD;
- case 15:
- return PorterDuff.Mode.OVERLAY;
- }
- }
-
- public static void applyNewColor4Bitmap(
- Context context, int[] idBitmaps, ImageView[] imageViews, int color, float alpha) {
- android.content.res.Resources resource = context.getResources();
- int size = idBitmaps.length;
- Bitmap usingBitmap, resultBitmap;
- for (int i = 0; i < size; i++) {
- usingBitmap = BitmapFactory.decodeResource(resource, idBitmaps[i]);
- resultBitmap = changeBitmapColor(usingBitmap, color);
- imageViews[i].setImageBitmap(resultBitmap);
- imageViews[i].setAlpha(alpha);
- }
- }
-
- public static void applyNewColor4Bitmap(
- Context context, int idBitmap, ImageView applyView, int color, float alpha) {
-
- android.content.res.Resources resource = context.getResources();
- Bitmap usingBitmap = BitmapFactory.decodeResource(resource, idBitmap);
- Bitmap resultBitmap = changeBitmapColor(usingBitmap, color);
- applyView.setImageBitmap(resultBitmap);
- applyView.setAlpha(alpha);
- }
-
- public static Bitmap getBitmapFromView(View view) {
- Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(bitmap);
- view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
- view.draw(c);
- return bitmap;
- }
-
- public static Bitmap getBitmapFromView(View view, int left, int top, int right, int bottom) {
- Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(bitmap);
- view.layout(left, top, right, bottom);
- view.draw(c);
- return bitmap;
- }
-
- public static Bitmap getBackgroundBitmapAViewWithParent(View childView, View parentView) {
- int[] pos_child = new int[2];
- childView.getLocationOnScreen(pos_child);
- return getBitmapFromView(
- parentView, pos_child[0], pos_child[1], parentView.getRight(), parentView.getBottom());
- }
-
- public static Bitmap getBackgroundBlurAViewWithParent(
- Activity activity, View childView, View parentView) {
- Bitmap b1 = getBackgroundBitmapAViewWithParent(childView, parentView);
- Bitmap b2 = getBlurredWithGoodPerformance(activity, b1, 1, 8, 2);
- b1.recycle();
- return b2;
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/CalendarUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/CalendarUtil.java
deleted file mode 100644
index 28a75cc14..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/util/CalendarUtil.java
+++ /dev/null
@@ -1,140 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package code.name.monkey.retromusic.util;
-
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-
-/** @author Eugene Cheung (arkon) */
-public class CalendarUtil {
- private static final long MS_PER_MINUTE = 60 * 1000;
- private static final long MS_PER_DAY = 24 * 60 * MS_PER_MINUTE;
-
- private final Calendar calendar;
-
- public CalendarUtil() {
- this.calendar = Calendar.getInstance();
- }
-
- /**
- * Returns the time elapsed so far today in milliseconds.
- *
- * @return Time elapsed today in milliseconds.
- */
- public long getElapsedToday() {
- // Time elapsed so far today
- return (calendar.get(Calendar.HOUR_OF_DAY) * 60 + calendar.get(Calendar.MINUTE)) * MS_PER_MINUTE
- + calendar.get(Calendar.SECOND) * 1000
- + calendar.get(Calendar.MILLISECOND);
- }
-
- /**
- * Returns the time elapsed so far this week in milliseconds.
- *
- * @return Time elapsed this week in milliseconds.
- */
- public long getElapsedWeek() {
- // Today + days passed this week
- long elapsed = getElapsedToday();
-
- final int passedWeekdays =
- calendar.get(Calendar.DAY_OF_WEEK) - 1 - calendar.getFirstDayOfWeek();
- if (passedWeekdays > 0) {
- elapsed += passedWeekdays * MS_PER_DAY;
- }
-
- return elapsed;
- }
-
- /**
- * Returns the time elapsed so far this month in milliseconds.
- *
- * @return Time elapsed this month in milliseconds.
- */
- public long getElapsedMonth() {
- // Today + rest of this month
- return getElapsedToday() + ((calendar.get(Calendar.DAY_OF_MONTH) - 1) * MS_PER_DAY);
- }
-
- /**
- * Returns the time elapsed so far this month and the last numMonths months in milliseconds.
- *
- * @param numMonths Additional number of months prior to the current month to calculate.
- * @return Time elapsed this month and the last numMonths months in milliseconds.
- */
- public long getElapsedMonths(int numMonths) {
- // Today + rest of this month
- long elapsed = getElapsedMonth();
-
- // Previous numMonths months
- int month = calendar.get(Calendar.MONTH);
- int year = calendar.get(Calendar.YEAR);
- for (int i = 0; i < numMonths; i++) {
- month--;
-
- if (month < Calendar.JANUARY) {
- month = Calendar.DECEMBER;
- year--;
- }
-
- elapsed += getDaysInMonth(month) * MS_PER_DAY;
- }
-
- return elapsed;
- }
-
- /**
- * Returns the time elapsed so far this year in milliseconds.
- *
- * @return Time elapsed this year in milliseconds.
- */
- public long getElapsedYear() {
- // Today + rest of this month + previous months until January
- long elapsed = getElapsedMonth();
-
- int month = calendar.get(Calendar.MONTH) - 1;
- int year = calendar.get(Calendar.YEAR);
- while (month > Calendar.JANUARY) {
- elapsed += getDaysInMonth(month) * MS_PER_DAY;
-
- month--;
- }
-
- return elapsed;
- }
-
- /**
- * Gets the number of days for the given month in the given year.
- *
- * @param month The month (1 - 12).
- * @return The days in that month/year.
- */
- private int getDaysInMonth(int month) {
- final Calendar monthCal = new GregorianCalendar(calendar.get(Calendar.YEAR), month, 1);
- return monthCal.getActualMaximum(Calendar.DAY_OF_MONTH);
- }
-
- /**
- * Returns the time elapsed so far last N days in milliseconds.
- *
- * @return Time elapsed since N days in milliseconds.
- */
- public long getElapsedDays(int numDays) {
- long elapsed = getElapsedToday();
- elapsed += numDays * MS_PER_DAY;
-
- return elapsed;
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/CalendarUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/CalendarUtil.kt
new file mode 100644
index 000000000..777b63842
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/util/CalendarUtil.kt
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2019 Hemanth Savarala.
+ *
+ * Licensed under the GNU General Public License v3
+ *
+ * This is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by
+ * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ */
+package code.name.monkey.retromusic.util
+
+import java.util.*
+
+/** @author Eugene Cheung (arkon)
+ */
+class CalendarUtil {
+ private val calendar = Calendar.getInstance()// Time elapsed so far today
+
+ /**
+ * Returns the time elapsed so far today in milliseconds.
+ *
+ * @return Time elapsed today in milliseconds.
+ */
+ val elapsedToday: Long
+ get() =// Time elapsed so far today
+ (calendar[Calendar.HOUR_OF_DAY] * 60 + calendar[Calendar.MINUTE]) * MS_PER_MINUTE + calendar[Calendar.SECOND] * 1000 + calendar[Calendar.MILLISECOND]// Today + days passed this week
+
+ /**
+ * Returns the time elapsed so far this week in milliseconds.
+ *
+ * @return Time elapsed this week in milliseconds.
+ */
+ val elapsedWeek: Long
+ get() {
+ // Today + days passed this week
+ var elapsed = elapsedToday
+ val passedWeekdays = calendar[Calendar.DAY_OF_WEEK] - 1 - calendar.firstDayOfWeek
+ if (passedWeekdays > 0) {
+ elapsed += passedWeekdays * MS_PER_DAY
+ }
+ return elapsed
+ }// Today + rest of this month
+
+ /**
+ * Returns the time elapsed so far this month in milliseconds.
+ *
+ * @return Time elapsed this month in milliseconds.
+ */
+ val elapsedMonth: Long
+ get() =// Today + rest of this month
+ elapsedToday + (calendar[Calendar.DAY_OF_MONTH] - 1) * MS_PER_DAY
+
+ /**
+ * Returns the time elapsed so far this month and the last numMonths months in milliseconds.
+ *
+ * @param numMonths Additional number of months prior to the current month to calculate.
+ * @return Time elapsed this month and the last numMonths months in milliseconds.
+ */
+ fun getElapsedMonths(numMonths: Int): Long {
+ // Today + rest of this month
+ var elapsed = elapsedMonth
+
+ // Previous numMonths months
+ var month = calendar[Calendar.MONTH]
+ var year = calendar[Calendar.YEAR]
+ for (i in 0 until numMonths) {
+ month--
+ if (month < Calendar.JANUARY) {
+ month = Calendar.DECEMBER
+ year--
+ }
+ elapsed += getDaysInMonth(month) * MS_PER_DAY
+ }
+ return elapsed
+ }// Today + rest of this month + previous months until January
+
+ /**
+ * Returns the time elapsed so far this year in milliseconds.
+ *
+ * @return Time elapsed this year in milliseconds.
+ */
+ val elapsedYear: Long
+ get() {
+ // Today + rest of this month + previous months until January
+ var elapsed = elapsedMonth
+ var month = calendar[Calendar.MONTH] - 1
+ while (month > Calendar.JANUARY) {
+ elapsed += getDaysInMonth(month) * MS_PER_DAY
+ month--
+ }
+ return elapsed
+ }
+
+ /**
+ * Gets the number of days for the given month in the given year.
+ *
+ * @param month The month (1 - 12).
+ * @return The days in that month/year.
+ */
+ private fun getDaysInMonth(month: Int): Int {
+ val monthCal: Calendar = GregorianCalendar(calendar[Calendar.YEAR], month, 1)
+ return monthCal.getActualMaximum(Calendar.DAY_OF_MONTH)
+ }
+
+ /**
+ * Returns the time elapsed so far last N days in milliseconds.
+ *
+ * @return Time elapsed since N days in milliseconds.
+ */
+ fun getElapsedDays(numDays: Int): Long {
+ var elapsed = elapsedToday
+ elapsed += numDays * MS_PER_DAY
+ return elapsed
+ }
+
+ companion object {
+ private const val MS_PER_MINUTE = (60 * 1000).toLong()
+ private const val MS_PER_DAY = 24 * 60 * MS_PER_MINUTE
+ }
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/ColorAnimUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/ColorAnimUtil.kt
deleted file mode 100644
index 81cb66de6..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/util/ColorAnimUtil.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package code.name.monkey.retromusic.util
-
-import android.animation.ArgbEvaluator
-import android.animation.ValueAnimator
-
-class ColorAnimUtil {
- companion object {
- fun createColorAnimator(
- fromColor: Int,
- toColor: Int,
- mDuration: Long = 300
- ): ValueAnimator {
- return ValueAnimator.ofInt(fromColor, toColor).apply {
- setEvaluator(ArgbEvaluator())
- duration = mDuration
- }
- }
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/Compressor.java b/app/src/main/java/code/name/monkey/retromusic/util/Compressor.java
deleted file mode 100644
index 6259a52bf..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/util/Compressor.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package code.name.monkey.retromusic.util;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-
-import java.io.File;
-import java.io.IOException;
-
-/**
- * Created on : June 18, 2016 Author : zetbaitsu Name : Zetra GitHub : https://github.com/zetbaitsu
- */
-public class Compressor {
- // max width and height values of the compressed image is taken as 612x816
- private int maxWidth = 612;
- private int maxHeight = 816;
- private Bitmap.CompressFormat compressFormat = Bitmap.CompressFormat.JPEG;
- private int quality = 80;
- private String destinationDirectoryPath;
-
- public Compressor(Context context) {
- destinationDirectoryPath = context.getCacheDir().getPath() + File.separator + "images";
- }
-
- public Compressor setMaxWidth(int maxWidth) {
- this.maxWidth = maxWidth;
- return this;
- }
-
- public Compressor setMaxHeight(int maxHeight) {
- this.maxHeight = maxHeight;
- return this;
- }
-
- public Compressor setCompressFormat(Bitmap.CompressFormat compressFormat) {
- this.compressFormat = compressFormat;
- return this;
- }
-
- public Compressor setQuality(int quality) {
- this.quality = quality;
- return this;
- }
-
- public Compressor setDestinationDirectoryPath(String destinationDirectoryPath) {
- this.destinationDirectoryPath = destinationDirectoryPath;
- return this;
- }
-
- public File compressToFile(File imageFile) throws IOException {
- return compressToFile(imageFile, imageFile.getName());
- }
-
- public File compressToFile(File imageFile, String compressedFileName) throws IOException {
- return ImageUtil.compressImage(
- imageFile,
- maxWidth,
- maxHeight,
- compressFormat,
- quality,
- destinationDirectoryPath + File.separator + compressedFileName);
- }
-
- public Bitmap compressToBitmap(File imageFile) throws IOException {
- return ImageUtil.decodeSampledBitmapFromFile(imageFile, maxWidth, maxHeight);
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.kt
index 4836032a1..39994818f 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/util/CustomArtistImageUtil.kt
@@ -14,25 +14,21 @@
package code.name.monkey.retromusic.util
-import android.annotation.SuppressLint
import android.content.Context
import android.content.SharedPreferences
import android.graphics.Bitmap
-import android.graphics.drawable.Drawable
import android.net.Uri
-import android.os.AsyncTask
import android.provider.MediaStore
import android.widget.Toast
import androidx.core.content.edit
import code.name.monkey.retromusic.App
+import code.name.monkey.retromusic.extensions.showToast
+import code.name.monkey.retromusic.glide.GlideApp
import code.name.monkey.retromusic.model.Artist
-import com.bumptech.glide.Glide
import com.bumptech.glide.load.engine.DiskCacheStrategy
-import com.bumptech.glide.request.target.SimpleTarget
-import com.bumptech.glide.request.transition.Transition
-import java.io.BufferedOutputStream
+import kotlinx.coroutines.Dispatchers.IO
+import kotlinx.coroutines.withContext
import java.io.File
-import java.io.FileOutputStream
import java.io.IOException
import java.util.*
@@ -44,78 +40,71 @@ class CustomArtistImageUtil private constructor(context: Context) {
Context.MODE_PRIVATE
)
- fun setCustomArtistImage(artist: Artist, uri: Uri) {
- Glide.with(App.getContext())
- .asBitmap()
- .load(uri)
- .diskCacheStrategy(DiskCacheStrategy.NONE)
- .skipMemoryCache(true)
- .into(object : SimpleTarget() {
- override fun onLoadFailed(errorDrawable: Drawable?) {
- super.onLoadFailed(errorDrawable)
- Toast.makeText(App.getContext(), "Load Failed", Toast.LENGTH_LONG).show()
+ suspend fun setCustomArtistImage(artist: Artist, uri: Uri) {
+ val context = App.getContext()
+ withContext(IO) {
+ runCatching {
+ GlideApp.with(context)
+ .asBitmap()
+ .load(uri)
+ .diskCacheStrategy(DiskCacheStrategy.NONE)
+ .skipMemoryCache(true)
+ .submit()
+ .get()
+ }
+ .onSuccess {
+ saveImage(context, artist, it)
}
-
- @SuppressLint("StaticFieldLeak")
- override fun onResourceReady(resource: Bitmap, transition: Transition?) {
- object : AsyncTask() {
- override fun doInBackground(vararg params: Void): Void? {
- val dir = File(App.getContext().filesDir, FOLDER_NAME)
- if (!dir.exists()) {
- if (!dir.mkdirs()) { // create the folder
- return null
- }
- }
- val file = File(dir, getFileName(artist))
-
- var succesful = false
- try {
- val os = BufferedOutputStream(FileOutputStream(file))
- succesful = ImageUtil.resizeBitmap(resource, 2048)
- .compress(Bitmap.CompressFormat.JPEG, 100, os)
- os.close()
- } catch (e: IOException) {
- Toast.makeText(App.getContext(), e.toString(), Toast.LENGTH_LONG)
- .show()
- }
-
- if (succesful) {
- mPreferences.edit { putBoolean(getFileName(artist), true) }
- ArtistSignatureUtil.getInstance(App.getContext())
- .updateArtistSignature(artist.name)
- App.getContext().contentResolver.notifyChange(
- MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
- null
- ) // trigger media store changed to force artist image reload
- }
- return null
- }
- }.execute()
+ .onFailure {
+ context.showToast("Load Failed")
}
- })
+ }
}
- @SuppressLint("StaticFieldLeak")
- fun resetCustomArtistImage(artist: Artist) {
- object : AsyncTask() {
- @SuppressLint("ApplySharedPref")
- override fun doInBackground(vararg params: Void): Void? {
- mPreferences.edit(commit = true) { putBoolean(getFileName(artist), false) }
- ArtistSignatureUtil.getInstance(App.getContext()).updateArtistSignature(artist.name)
- App.getContext().contentResolver.notifyChange(
- MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
- null
- ) // trigger media store changed to force artist image reload
-
- val file = getFile(artist)
- if (!file.exists()) {
- return null
- } else {
- file.delete()
- }
- return null
+ private fun saveImage(context: Context, artist: Artist, bitmap: Bitmap) {
+ val dir = File(context.filesDir, FOLDER_NAME)
+ if (!dir.exists()) {
+ if (!dir.mkdirs()) { // create the folder
+ return
}
- }.execute()
+ }
+ val file = File(dir, getFileName(artist))
+
+ var successful = false
+ try {
+ file.outputStream().buffered().use { bos ->
+ successful = ImageUtil.resizeBitmap(bitmap, 2048)
+ .compress(Bitmap.CompressFormat.JPEG, 100, bos)
+ }
+ } catch (e: IOException) {
+ context.showToast(e.toString(), Toast.LENGTH_LONG)
+ }
+
+ if (successful) {
+ mPreferences.edit { putBoolean(getFileName(artist), true) }
+ ArtistSignatureUtil.getInstance(context)
+ .updateArtistSignature(artist.name)
+ context.contentResolver.notifyChange(
+ MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
+ null
+ ) // trigger media store changed to force artist image reload
+ }
+ }
+
+ suspend fun resetCustomArtistImage(artist: Artist) {
+ withContext(IO) {
+ mPreferences.edit { putBoolean(getFileName(artist), false) }
+ ArtistSignatureUtil.getInstance(App.getContext()).updateArtistSignature(artist.name)
+ App.getContext().contentResolver.notifyChange(
+ MediaStore.Audio.Artists.EXTERNAL_CONTENT_URI,
+ null
+ ) // trigger media store changed to force artist image reload
+
+ val file = getFile(artist)
+ if (file.exists()) {
+ file.delete()
+ }
+ }
}
// shared prefs saves us many IO operations
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/FilePathUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/FilePathUtil.kt
index da30e71c9..b0abc8af5 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/FilePathUtil.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/util/FilePathUtil.kt
@@ -1,14 +1,13 @@
package code.name.monkey.retromusic.util
import android.os.Environment
-import java.io.File
object FilePathUtil {
fun blacklistFilePaths(): List {
- return listOf(
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_ALARMS),
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_RINGTONES),
- Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_NOTIFICATIONS)
+ return listOf(
+ getExternalStoragePublicDirectory(Environment.DIRECTORY_ALARMS),
+ getExternalStoragePublicDirectory(Environment.DIRECTORY_RINGTONES),
+ getExternalStoragePublicDirectory(Environment.DIRECTORY_NOTIFICATIONS)
).map {
FileUtil.safeGetCanonicalPath(it)
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/FileUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/FileUtil.java
index 09957a93c..903df0aab 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/FileUtil.java
+++ b/app/src/main/java/code/name/monkey/retromusic/util/FileUtil.java
@@ -14,10 +14,11 @@
package code.name.monkey.retromusic.util;
+import static code.name.monkey.retromusic.util.FileUtilsKt.getExternalStorageDirectory;
+
import android.content.Context;
import android.database.Cursor;
import android.os.Environment;
-import android.provider.MediaStore;
import android.webkit.MimeTypeMap;
import androidx.annotation.NonNull;
@@ -40,6 +41,7 @@ import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
+import code.name.monkey.retromusic.Constants;
import code.name.monkey.retromusic.adapter.Storage;
import code.name.monkey.retromusic.model.Song;
import code.name.monkey.retromusic.repository.RealSongRepository;
@@ -87,7 +89,7 @@ public final class FileUtil {
if (files.size() > 0
&& files.size() < 999) { // 999 is the max amount Androids SQL implementation can handle.
selection =
- MediaStore.Audio.AudioColumns.DATA + " IN (" + makePlaceholders(files.size()) + ")";
+ Constants.DATA + " IN (" + makePlaceholders(files.size()) + ")";
}
}
@@ -96,7 +98,7 @@ public final class FileUtil {
return songCursor == null
? null
- : new SortedCursor(songCursor, paths, MediaStore.Audio.AudioColumns.DATA);
+ : new SortedCursor(songCursor, paths, Constants.DATA);
}
private static String makePlaceholders(int len) {
@@ -113,12 +115,6 @@ public final class FileUtil {
if (files != null) {
String[] paths = new String[files.size()];
for (int i = 0; i < files.size(); i++) {
- /*try {
- paths[i] = files.get(i).getCanonicalPath(); // canonical path is important here because we want to compare the path with the media store entry later
- } catch (IOException e) {
- e.printStackTrace();
- paths[i] = files.get(i).getPath();
- }*/
paths[i] = safeGetCanonicalPath(files.get(i));
}
return paths;
@@ -268,7 +264,7 @@ public final class FileUtil {
public static ArrayList listRoots() {
ArrayList storageItems = new ArrayList<>();
HashSet paths = new HashSet<>();
- String defaultPath = Environment.getExternalStorageDirectory().getPath();
+ String defaultPath = getExternalStorageDirectory().getPath();
String defaultPathState = Environment.getExternalStorageState();
if (defaultPathState.equals(Environment.MEDIA_MOUNTED) || defaultPathState.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
Storage ext = new Storage();
@@ -277,7 +273,7 @@ public final class FileUtil {
} else {
ext.title = "Internal Storage";
}
- ext.file = Environment.getExternalStorageDirectory();
+ ext.file = getExternalStorageDirectory();
storageItems.add(ext);
paths.add(defaultPath);
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/FileUtils.kt b/app/src/main/java/code/name/monkey/retromusic/util/FileUtils.kt
index e38e006ee..8a06bf62b 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/FileUtils.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/util/FileUtils.kt
@@ -2,6 +2,7 @@ package code.name.monkey.retromusic.util
import android.content.Context
import android.net.Uri
+import android.os.Environment
import android.util.Log
import java.io.File
import java.io.IOException
@@ -23,7 +24,13 @@ object FileUtils {
* @return the file
* @throws IOException
*/
- fun createFile(context: Context, directoryName: String, fileName: String, body: String, fileType: String): File {
+ fun createFile(
+ context: Context,
+ directoryName: String,
+ fileName: String,
+ body: String,
+ fileType: String
+ ): File {
val root = createDirectory(context, directoryName)
val filePath = "$root/$fileName$fileType"
val file = File(filePath)
@@ -57,4 +64,13 @@ object FileUtils {
}
return file
}
+}
+@Suppress("Deprecation")
+fun getExternalStorageDirectory(): File {
+ return Environment.getExternalStorageDirectory()
+}
+
+@Suppress("Deprecation")
+fun getExternalStoragePublicDirectory(type: String): File {
+ return Environment.getExternalStoragePublicDirectory(type)
}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/ImageUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/ImageUtil.java
index d10a4232f..b87eceab9 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/ImageUtil.java
+++ b/app/src/main/java/code/name/monkey/retromusic/util/ImageUtil.java
@@ -14,128 +14,17 @@
package code.name.monkey.retromusic.util;
-import android.content.Context;
-import android.content.res.Resources;
import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Canvas;
-import android.graphics.Matrix;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.PorterDuffColorFilter;
-import android.graphics.drawable.Drawable;
-import android.media.ExifInterface;
-import androidx.annotation.ColorInt;
-import androidx.annotation.DrawableRes;
import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.content.res.ResourcesCompat;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-
-import code.name.monkey.appthemehelper.util.TintHelper;
/**
* Created on : June 18, 2016 Author : zetbaitsu Name : Zetra GitHub : https://github.com/zetbaitsu
*/
public class ImageUtil {
- private static final int TOLERANCE = 20;
- // Alpha amount for which values below are considered transparent.
- private static final int ALPHA_TOLERANCE = 50;
- private static int[] mTempBuffer;
-
private ImageUtil() {}
- public static boolean isGrayscale(Bitmap bitmap) {
- final int height = bitmap.getHeight();
- final int width = bitmap.getWidth();
- int size = height * width;
- ensureBufferSize(size);
- bitmap.getPixels(mTempBuffer, 0, width, 0, 0, width, height);
- for (int i = 0; i < size; i++) {
- if (!isGrayscale(mTempBuffer[i])) {
- return false;
- }
- }
- return true;
- }
-
- public static Bitmap createBitmap(Drawable drawable) {
- return createBitmap(drawable, 1f);
- }
-
- public static Bitmap createBitmap(Drawable drawable, float sizeMultiplier) {
- Bitmap bitmap =
- Bitmap.createBitmap(
- (int) (drawable.getIntrinsicWidth() * sizeMultiplier),
- (int) (drawable.getIntrinsicHeight() * sizeMultiplier),
- Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(bitmap);
- drawable.setBounds(0, 0, c.getWidth(), c.getHeight());
- drawable.draw(c);
- return bitmap;
- }
-
- public static Drawable getTintedVectorDrawable(
- @NonNull Resources res,
- @DrawableRes int resId,
- @Nullable Resources.Theme theme,
- @ColorInt int color) {
- return TintHelper.createTintedDrawable(getVectorDrawable(res, resId, theme), color);
- }
-
- public static Drawable getTintedVectorDrawable(
- @NonNull Context context, @DrawableRes int id, @ColorInt int color) {
- return TintHelper.createTintedDrawable(
- getVectorDrawable(context.getResources(), id, context.getTheme()), color);
- }
-
- public static Drawable getVectorDrawable(@NonNull Context context, @DrawableRes int id) {
- return getVectorDrawable(context.getResources(), id, context.getTheme());
- }
-
- public static Drawable getVectorDrawable(
- @NonNull Resources res, @DrawableRes int resId, @Nullable Resources.Theme theme) {
- return ResourcesCompat.getDrawable(res,resId, theme);
- }
-
- /** Makes sure that {@code mTempBuffer} has at least length {@code size}. */
- private static void ensureBufferSize(int size) {
- if (mTempBuffer == null || mTempBuffer.length < size) {
- mTempBuffer = new int[size];
- }
- }
-
- public static Bitmap setBitmapColor(Bitmap bitmap, int color) {
- Bitmap result =
- Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth() - 1, bitmap.getHeight() - 1);
- Paint paint = new Paint();
- paint.setColorFilter(new PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP));
-
- Canvas canvas = new Canvas(result);
- canvas.drawBitmap(result, 0, 0, paint);
-
- return result;
- }
-
- public static boolean isGrayscale(int color) {
- int alpha = 0xFF & (color >> 24);
- if (alpha < ALPHA_TOLERANCE) {
- return true;
- }
- int r = 0xFF & (color >> 16);
- int g = 0xFF & (color >> 8);
- int b = 0xFF & color;
- return Math.abs(r - g) < TOLERANCE
- && Math.abs(r - b) < TOLERANCE
- && Math.abs(g - b) < TOLERANCE;
- } // Amount (max is 255) that two channels can differ before the color is no longer "gray".
-
public static Bitmap resizeBitmap(@NonNull Bitmap src, int maxForSmallerSize) {
int width = src.getWidth();
int height = src.getHeight();
@@ -185,108 +74,4 @@ public class ImageUtil {
return inSampleSize;
}
-
- static File compressImage(
- File imageFile,
- int reqWidth,
- int reqHeight,
- Bitmap.CompressFormat compressFormat,
- int quality,
- String destinationPath)
- throws IOException {
- FileOutputStream fileOutputStream = null;
- File file = new File(destinationPath).getParentFile();
- if (!file.exists()) {
- file.mkdirs();
- }
- try {
- fileOutputStream = new FileOutputStream(destinationPath);
- // write the compressed bitmap at the destination specified by destinationPath.
- decodeSampledBitmapFromFile(imageFile, reqWidth, reqHeight)
- .compress(compressFormat, quality, fileOutputStream);
- } finally {
- if (fileOutputStream != null) {
- fileOutputStream.flush();
- fileOutputStream.close();
- }
- }
-
- return new File(destinationPath);
- }
-
- static Bitmap decodeSampledBitmapFromFile(File imageFile, int reqWidth, int reqHeight)
- throws IOException {
- // First decode with inJustDecodeBounds=true to check dimensions
- BitmapFactory.Options options = new BitmapFactory.Options();
- options.inJustDecodeBounds = true;
- BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);
-
- // Calculate inSampleSize
- options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
-
- // Decode bitmap with inSampleSize set
- options.inJustDecodeBounds = false;
-
- Bitmap scaledBitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath(), options);
-
- // check the rotation of the image and display it properly
- ExifInterface exif;
- exif = new ExifInterface(imageFile.getAbsolutePath());
- int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0);
- Matrix matrix = new Matrix();
- if (orientation == 6) {
- matrix.postRotate(90);
- } else if (orientation == 3) {
- matrix.postRotate(180);
- } else if (orientation == 8) {
- matrix.postRotate(270);
- }
- scaledBitmap =
- Bitmap.createBitmap(
- scaledBitmap, 0, 0, scaledBitmap.getWidth(), scaledBitmap.getHeight(), matrix, true);
- return scaledBitmap;
- }
-
- 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;
- }
-
- @NonNull
- public static Bitmap getResizedBitmap(@NonNull Bitmap image, int maxSize) {
- int width = image.getWidth();
- int height = image.getHeight();
-
- float bitmapRatio = (float) width / (float) height;
- if (bitmapRatio > 1) {
- width = maxSize;
- height = (int) (width / bitmapRatio);
- } else {
- height = maxSize;
- width = (int) (height * bitmapRatio);
- }
- return Bitmap.createScaledBitmap(image, width, height, true);
- }
-
- public static Bitmap resize(InputStream stream, int scaledWidth, int scaledHeight) {
- final Bitmap bitmap = BitmapFactory.decodeStream(stream);
- return Bitmap.createScaledBitmap(bitmap, scaledWidth, scaledHeight, true);
- }
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/LyricUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/LyricUtil.kt
index 66e46929a..6db2a55c1 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/LyricUtil.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/util/LyricUtil.kt
@@ -13,7 +13,6 @@
*/
package code.name.monkey.retromusic.util
-import android.os.Environment
import android.util.Log
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.model.lyrics.AbsSynchronizedLyrics
@@ -26,7 +25,7 @@ import java.io.*
*/
object LyricUtil {
private val lrcRootPath =
- Environment.getExternalStorageDirectory().toString() + "/RetroMusic/lyrics/"
+ getExternalStorageDirectory().toString() + "/RetroMusic/lyrics/"
private const val TAG = "LyricUtil"
fun writeLrcToLoc(
title: String, artist: String, lrcContext: String
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/MusicUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/MusicUtil.kt
index 62b364e8d..3262157ff 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/MusicUtil.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/util/MusicUtil.kt
@@ -5,27 +5,25 @@ import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.net.Uri
-import android.os.Environment
import android.provider.BaseColumns
import android.provider.MediaStore
import android.util.Log
-import android.widget.Toast
import androidx.core.content.FileProvider
import androidx.core.content.contentValuesOf
import androidx.core.net.toUri
import androidx.fragment.app.FragmentActivity
import code.name.monkey.appthemehelper.util.VersionUtils
+import code.name.monkey.retromusic.Constants
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.db.PlaylistEntity
import code.name.monkey.retromusic.db.SongEntity
import code.name.monkey.retromusic.db.toSongEntity
import code.name.monkey.retromusic.extensions.getLong
+import code.name.monkey.retromusic.extensions.showToast
import code.name.monkey.retromusic.helper.MusicPlayerRemote.removeFromQueue
import code.name.monkey.retromusic.model.Artist
-import code.name.monkey.retromusic.model.Playlist
import code.name.monkey.retromusic.model.Song
import code.name.monkey.retromusic.model.lyrics.AbsSynchronizedLyrics
-import code.name.monkey.retromusic.repository.RealPlaylistRepository
import code.name.monkey.retromusic.repository.Repository
import code.name.monkey.retromusic.repository.SongRepository
import code.name.monkey.retromusic.service.MusicService
@@ -56,14 +54,10 @@ object MusicUtil : KoinComponent {
)
).addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION).setType("audio/*")
} catch (e: IllegalArgumentException) {
- // TODO the path is most likely not like /storage/emulated/0/... but something like /storage/28C7-75B0/...
- e.printStackTrace()
- Toast.makeText(
- context,
- "Could not share this file, I'm aware of the issue.",
- Toast.LENGTH_SHORT
- ).show()
- Intent()
+ Intent().setAction(Intent.ACTION_SEND).putExtra(
+ Intent.EXTRA_STREAM,
+ getSongFileUri(song.id)
+ ).addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION).setType("audio/*")
}
}
@@ -83,7 +77,7 @@ object MusicUtil : KoinComponent {
private fun createAlbumArtDir(context: Context): File {
val albumArtDir = File(
- if (VersionUtils.hasR()) context.cacheDir else Environment.getExternalStorageDirectory(),
+ if (VersionUtils.hasR()) context.cacheDir else getExternalStorageDirectory(),
"/albumthumbs/"
)
if (!albumArtDir.exists()) {
@@ -268,15 +262,14 @@ object MusicUtil : KoinComponent {
)
}
- fun getSongFilePath(context: Context, uri: Uri): String? {
- val projection = arrayOf(MediaStore.MediaColumns.DATA)
- return context.contentResolver.query(uri, projection, null, null, null)?.use {
+ fun getSongFilePath(context: Context, uri: Uri): String {
+ val projection = arrayOf(Constants.DATA)
+ context.contentResolver.query(uri, projection, null, null, null)?.use {
if (it.moveToFirst()) {
- it.getString(0)
- } else {
- ""
+ return it.getString(0)
}
}
+ return ""
}
fun getTotalDuration(songs: List): Long {
@@ -340,48 +333,21 @@ object MusicUtil : KoinComponent {
return false
}
- fun isFavorite(context: Context, song: Song): Boolean {
- return PlaylistsUtil
- .doPlaylistContains(context, getFavoritesPlaylist(context).id, song.id)
- }
-
- fun isFavoritePlaylist(
- context: Context,
- playlist: Playlist
- ): Boolean {
- return playlist.name == context.getString(R.string.favorites)
- }
-
val repository = get()
fun toggleFavorite(context: Context, song: Song) {
GlobalScope.launch {
val playlist: PlaylistEntity = repository.favoritePlaylist()
- if (playlist != null) {
- val songEntity = song.toSongEntity(playlist.playListId)
- val isFavorite = repository.isFavoriteSong(songEntity).isNotEmpty()
- if (isFavorite) {
- repository.removeSongFromPlaylist(songEntity)
- } else {
- repository.insertSongs(listOf(song.toSongEntity(playlist.playListId)))
- }
+ val songEntity = song.toSongEntity(playlist.playListId)
+ val isFavorite = repository.isFavoriteSong(songEntity).isNotEmpty()
+ if (isFavorite) {
+ repository.removeSongFromPlaylist(songEntity)
+ } else {
+ repository.insertSongs(listOf(song.toSongEntity(playlist.playListId)))
}
context.sendBroadcast(Intent(MusicService.FAVORITE_STATE_CHANGED))
}
}
- private fun getFavoritesPlaylist(context: Context): Playlist {
- return RealPlaylistRepository(context.contentResolver).playlist(context.getString(R.string.favorites))
- }
-
- private fun getOrCreateFavoritesPlaylist(context: Context): Playlist {
- return RealPlaylistRepository(context.contentResolver).playlist(
- PlaylistsUtil.createPlaylist(
- context,
- context.getString(R.string.favorites)
- )
- )
- }
-
fun deleteTracks(
activity: FragmentActivity,
songs: List,
@@ -390,7 +356,7 @@ object MusicUtil : KoinComponent {
) {
val songRepository: SongRepository = get()
val projection = arrayOf(
- BaseColumns._ID, MediaStore.MediaColumns.DATA
+ BaseColumns._ID, Constants.DATA
)
// Split the query into multiple batches, and merge the resulting cursors
var batchStart: Int
@@ -457,20 +423,14 @@ object MusicUtil : KoinComponent {
}
activity.contentResolver.notifyChange("content://media".toUri(), null)
activity.runOnUiThread {
- Toast.makeText(
- activity,
- activity.getString(R.string.deleted_x_songs, songCount),
- Toast.LENGTH_SHORT
- )
- .show()
+ activity.showToast(activity.getString(R.string.deleted_x_songs, songCount))
callback?.run()
}
-
}
}
suspend fun deleteTracks(context: Context, songs: List) {
- val projection = arrayOf(BaseColumns._ID, MediaStore.MediaColumns.DATA)
+ val projection = arrayOf(BaseColumns._ID, Constants.DATA)
val selection = StringBuilder()
selection.append(BaseColumns._ID + " IN (")
for (i in songs.indices) {
@@ -520,11 +480,7 @@ object MusicUtil : KoinComponent {
cursor.close()
}
withContext(Dispatchers.Main) {
- Toast.makeText(
- context,
- context.getString(R.string.deleted_x_songs, deletedCount),
- Toast.LENGTH_SHORT
- ).show()
+ context.showToast(context.getString(R.string.deleted_x_songs, deletedCount))
}
} catch (ignored: SecurityException) {
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.kt
index 37e26254f..2d960af00 100755
--- a/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/util/NavigationUtil.kt
@@ -19,9 +19,11 @@ import android.content.Context
import android.content.Intent
import android.media.audiofx.AudioEffect
import android.widget.Toast
+import androidx.fragment.app.FragmentActivity
import code.name.monkey.retromusic.R
import code.name.monkey.retromusic.activities.*
import code.name.monkey.retromusic.activities.bugreport.BugReportActivity
+import code.name.monkey.retromusic.extensions.showToast
import code.name.monkey.retromusic.helper.MusicPlayerRemote.audioSessionId
object NavigationUtil {
@@ -55,10 +57,9 @@ object NavigationUtil {
)
}
- fun gotoWhatNews(activity: Activity) {
- activity.startActivity(
- Intent(activity, WhatsNewActivity::class.java), null
- )
+ fun gotoWhatNews(activity: FragmentActivity) {
+ val changelogBottomSheet = WhatsNewFragment()
+ changelogBottomSheet.show(activity.supportFragmentManager, WhatsNewFragment.TAG)
}
fun openEqualizer(activity: Activity) {
@@ -68,10 +69,7 @@ object NavigationUtil {
private fun stockEqualizer(activity: Activity) {
val sessionId = audioSessionId
if (sessionId == AudioEffect.ERROR_BAD_VALUE) {
- Toast.makeText(
- activity, activity.resources.getString(R.string.no_audio_ID), Toast.LENGTH_LONG
- )
- .show()
+ activity.showToast(R.string.no_audio_ID, Toast.LENGTH_LONG)
} else {
try {
val effects = Intent(AudioEffect.ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL)
@@ -79,12 +77,7 @@ object NavigationUtil {
effects.putExtra(AudioEffect.EXTRA_CONTENT_TYPE, AudioEffect.CONTENT_TYPE_MUSIC)
activity.startActivityForResult(effects, 0)
} catch (notFound: ActivityNotFoundException) {
- Toast.makeText(
- activity,
- activity.resources.getString(R.string.no_equalizer),
- Toast.LENGTH_SHORT
- )
- .show()
+ activity.showToast(R.string.no_equalizer)
}
}
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PackageValidator.kt b/app/src/main/java/code/name/monkey/retromusic/util/PackageValidator.kt
index 15b9722ee..cc4124a90 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/PackageValidator.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/util/PackageValidator.kt
@@ -71,7 +71,7 @@ class PackageValidator(
/**
* Checks whether the caller attempting to connect to a [MediaBrowserServiceCompat] is known.
- * See [MusicService.onGetRoot] for where this is utilized.
+ * See [MediaBrowserServiceCompat.onGetRoot] for where this is utilized.
*
* @param callingPackage The package name of the caller.
* @param callingUid The user id of the caller.
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.java
deleted file mode 100644
index 028625509..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.java
+++ /dev/null
@@ -1,333 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package code.name.monkey.retromusic.util;
-
-import static android.provider.MediaStore.Audio.Playlists.EXTERNAL_CONTENT_URI;
-
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Environment;
-import android.provider.BaseColumns;
-import android.provider.MediaStore;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import code.name.monkey.retromusic.R;
-import code.name.monkey.retromusic.db.PlaylistWithSongs;
-import code.name.monkey.retromusic.helper.M3UWriter;
-import code.name.monkey.retromusic.model.Playlist;
-import code.name.monkey.retromusic.model.PlaylistSong;
-import code.name.monkey.retromusic.model.Song;
-
-public class PlaylistsUtil {
-
- public static long createPlaylist(@NonNull final Context context, @Nullable final String name) {
- int id = -1;
- if (name != null && name.length() > 0) {
- try {
- Cursor cursor =
- context
- .getContentResolver()
- .query(
- EXTERNAL_CONTENT_URI,
- new String[] {MediaStore.Audio.Playlists._ID},
- MediaStore.Audio.PlaylistsColumns.NAME + "=?",
- new String[] {name},
- null);
- if (cursor == null || cursor.getCount() < 1) {
- final ContentValues values = new ContentValues(1);
- values.put(MediaStore.Audio.PlaylistsColumns.NAME, name);
- final Uri uri = context.getContentResolver().insert(EXTERNAL_CONTENT_URI, values);
- if (uri != null) {
- // Necessary because somehow the MediaStoreObserver is not notified when adding a
- // playlist
- context.getContentResolver().notifyChange(Uri.parse("content://media"), null);
- Toast.makeText(
- context,
- context.getResources().getString(R.string.created_playlist_x, name),
- Toast.LENGTH_SHORT)
- .show();
- id = Integer.parseInt(uri.getLastPathSegment());
- }
- } else {
- // Playlist exists
- if (cursor.moveToFirst()) {
- id = cursor.getInt(cursor.getColumnIndex(MediaStore.Audio.Playlists._ID));
- }
- }
- if (cursor != null) {
- cursor.close();
- }
- } catch (SecurityException e) {
- e.printStackTrace();
- }
- }
- if (id == -1) {
- Toast.makeText(
- context,
- context.getResources().getString(R.string.could_not_create_playlist),
- Toast.LENGTH_SHORT)
- .show();
- }
- return id;
- }
-
- public static void deletePlaylists(
- @NonNull final Context context, @NonNull final List playlists) {
- final StringBuilder selection = new StringBuilder();
- selection.append(MediaStore.Audio.Playlists._ID + " IN (");
- for (int i = 0; i < playlists.size(); i++) {
- selection.append(playlists.get(i).getId());
- if (i < playlists.size() - 1) {
- selection.append(",");
- }
- }
- selection.append(")");
- try {
- context.getContentResolver().delete(EXTERNAL_CONTENT_URI, selection.toString(), null);
- context.getContentResolver().notifyChange(Uri.parse("content://media"), null);
- } catch (SecurityException ignored) {
- }
- }
-
- public static void addToPlaylist(
- @NonNull final Context context,
- final Song song,
- final long playlistId,
- final boolean showToastOnFinish) {
- List helperList = new ArrayList<>();
- helperList.add(song);
- addToPlaylist(context, helperList, playlistId, showToastOnFinish);
- }
-
- public static void addToPlaylist(
- @NonNull final Context context,
- @NonNull final List songs,
- final long playlistId,
- final boolean showToastOnFinish) {
- final int size = songs.size();
- final ContentResolver resolver = context.getContentResolver();
- final String[] projection =
- new String[] {
- "max(" + MediaStore.Audio.Playlists.Members.PLAY_ORDER + ")",
- };
- final Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId);
- Cursor cursor = null;
- int base = 0;
-
- try {
- try {
- cursor = resolver.query(uri, projection, null, null, null);
-
- if (cursor != null && cursor.moveToFirst()) {
- base = cursor.getInt(0) + 1;
- }
- } finally {
- if (cursor != null) {
- cursor.close();
- }
- }
-
- int numInserted = 0;
- for (int offSet = 0; offSet < size; offSet += 1000)
- numInserted += resolver.bulkInsert(uri, makeInsertItems(songs, offSet, 1000, base));
-
- if (showToastOnFinish) {
- Toast.makeText(
- context,
- context
- .getResources()
- .getString(
- R.string.inserted_x_songs_into_playlist_x,
- numInserted,
- getNameForPlaylist(context, playlistId)),
- Toast.LENGTH_SHORT)
- .show();
- }
- } catch (SecurityException exception) {
- exception.printStackTrace();
- }
- }
-
- @NonNull
- public static ContentValues[] makeInsertItems(
- @NonNull final List songs, final int offset, int len, final int base) {
- if (offset + len > songs.size()) {
- len = songs.size() - offset;
- }
-
- ContentValues[] contentValues = new ContentValues[len];
-
- for (int i = 0; i < len; i++) {
- contentValues[i] = new ContentValues();
- contentValues[i].put(MediaStore.Audio.Playlists.Members.PLAY_ORDER, base + offset + i);
- contentValues[i].put(
- MediaStore.Audio.Playlists.Members.AUDIO_ID, songs.get(offset + i).getId());
- }
- return contentValues;
- }
-
- public static String getNameForPlaylist(@NonNull final Context context, final long id) {
- try {
- Cursor cursor =
- context
- .getContentResolver()
- .query(
- EXTERNAL_CONTENT_URI,
- new String[] {MediaStore.Audio.PlaylistsColumns.NAME},
- BaseColumns._ID + "=?",
- new String[] {String.valueOf(id)},
- null);
- if (cursor != null) {
- try {
- if (cursor.moveToFirst()) {
- return cursor.getString(0);
- }
- } finally {
- cursor.close();
- }
- }
- } catch (SecurityException ignored) {
- }
- return "";
- }
-
- public static void removeFromPlaylist(
- @NonNull final Context context, @NonNull final Song song, long playlistId) {
- Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId);
- String selection = MediaStore.Audio.Playlists.Members.AUDIO_ID + " =?";
- String[] selectionArgs = new String[] {String.valueOf(song.getId())};
-
- try {
- context.getContentResolver().delete(uri, selection, selectionArgs);
- } catch (SecurityException ignored) {
- }
- }
-
- public static void removeFromPlaylist(
- @NonNull final Context context, @NonNull final List songs) {
- final long playlistId = songs.get(0).getPlaylistId();
- Uri uri = MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId);
- String[] selectionArgs = new String[songs.size()];
- for (int i = 0; i < selectionArgs.length; i++) {
- selectionArgs[i] = String.valueOf(songs.get(i).getIdInPlayList());
- }
- StringBuilder selection = new StringBuilder(MediaStore.Audio.Playlists.Members._ID + " in (");
-
- for (String selectionArg : selectionArgs) selection.append("?, ");
- selection = new StringBuilder(selection.substring(0, selection.length() - 2) + ")");
-
- try {
- context.getContentResolver().delete(uri, selection.toString(), selectionArgs);
- } catch (SecurityException ignored) {
- }
- }
-
- public static boolean doPlaylistContains(
- @NonNull final Context context, final long playlistId, final long songId) {
- if (playlistId != -1) {
- try {
- Cursor c =
- context
- .getContentResolver()
- .query(
- MediaStore.Audio.Playlists.Members.getContentUri("external", playlistId),
- new String[] {MediaStore.Audio.Playlists.Members.AUDIO_ID},
- MediaStore.Audio.Playlists.Members.AUDIO_ID + "=?",
- new String[] {String.valueOf(songId)},
- null);
- int count = 0;
- if (c != null) {
- count = c.getCount();
- c.close();
- }
- return count > 0;
- } catch (SecurityException ignored) {
- }
- }
- return false;
- }
-
- public static boolean moveItem(
- @NonNull final Context context, long playlistId, int from, int to) {
- return MediaStore.Audio.Playlists.Members.moveItem(
- context.getContentResolver(), playlistId, from, to);
- }
-
- public static void renamePlaylist(
- @NonNull final Context context, final long id, final String newName) {
- ContentValues contentValues = new ContentValues();
- contentValues.put(MediaStore.Audio.PlaylistsColumns.NAME, newName);
- try {
- context
- .getContentResolver()
- .update(
- EXTERNAL_CONTENT_URI,
- contentValues,
- MediaStore.Audio.Playlists._ID + "=?",
- new String[] {String.valueOf(id)});
- context.getContentResolver().notifyChange(Uri.parse("content://media"), null);
- } catch (SecurityException ignored) {
- }
- }
-
- public static File savePlaylist(Context context, Playlist playlist) throws IOException {
- return M3UWriter.write(
- new File(Environment.getExternalStorageDirectory(), "Playlists"), playlist);
- }
-
- public static File savePlaylistWithSongs(PlaylistWithSongs playlist) throws IOException {
- return M3UWriter.writeIO(
- new File(Environment.getExternalStorageDirectory(), "Playlists"), playlist);
- }
-
- public static boolean doesPlaylistExist(@NonNull final Context context, final int playlistId) {
- return playlistId != -1
- && doesPlaylistExist(
- context,
- MediaStore.Audio.Playlists._ID + "=?",
- new String[] {String.valueOf(playlistId)});
- }
-
- public static boolean doesPlaylistExist(@NonNull final Context context, final String name) {
- return doesPlaylistExist(
- context, MediaStore.Audio.PlaylistsColumns.NAME + "=?", new String[] {name});
- }
-
- private static boolean doesPlaylistExist(
- @NonNull Context context, @NonNull final String selection, @NonNull final String[] values) {
- Cursor cursor =
- context
- .getContentResolver()
- .query(EXTERNAL_CONTENT_URI, new String[]{}, selection, values, null);
-
- boolean exists = false;
- if (cursor != null) {
- exists = cursor.getCount() != 0;
- cursor.close();
- }
- return exists;
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.kt
new file mode 100644
index 000000000..d8e3003ab
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/util/PlaylistsUtil.kt
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2019 Hemanth Savarala.
+ *
+ * Licensed under the GNU General Public License v3
+ *
+ * This is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by
+ * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ */
+package code.name.monkey.retromusic.util
+
+import code.name.monkey.retromusic.db.PlaylistWithSongs
+import code.name.monkey.retromusic.helper.M3UWriter.writeIO
+import java.io.File
+import java.io.IOException
+
+object PlaylistsUtil {
+ @Throws(IOException::class)
+ fun savePlaylistWithSongs(playlist: PlaylistWithSongs?): File {
+ return writeIO(
+ File(getExternalStorageDirectory(), "Playlists"), playlist!!
+ )
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt
index 3f819e68d..c46a169fb 100644
--- a/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt
+++ b/app/src/main/java/code/name/monkey/retromusic/util/PreferenceUtil.kt
@@ -1,10 +1,12 @@
package code.name.monkey.retromusic.util
+import android.content.Context
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
import android.net.ConnectivityManager
-import android.net.NetworkInfo
import androidx.core.content.edit
import androidx.core.content.getSystemService
+import androidx.core.content.res.use
+import androidx.fragment.app.Fragment
import androidx.preference.PreferenceManager
import androidx.viewpager.widget.ViewPager
import code.name.monkey.appthemehelper.util.VersionUtils
@@ -97,10 +99,10 @@ object PreferenceUtil {
val languageCode: String get() = sharedPreferences.getString(LANGUAGE_NAME, "auto") ?: "auto"
- var userName
+ var Fragment.userName
get() = sharedPreferences.getString(
USER_NAME,
- App.getContext().getString(R.string.user_name)
+ getString(R.string.user_name)
)
set(value) = sharedPreferences.edit {
putString(USER_NAME, value)
@@ -333,15 +335,12 @@ object PreferenceUtil {
val isLockScreen get() = sharedPreferences.getBoolean(LOCK_SCREEN, false)
- fun isAllowedToDownloadMetadata(): Boolean {
+ fun isAllowedToDownloadMetadata(context: Context): Boolean {
return when (autoDownloadImagesPolicy) {
"always" -> true
"only_wifi" -> {
- val connectivityManager = App.getContext().getSystemService()
- var netInfo: NetworkInfo? = null
- if (connectivityManager != null) {
- netInfo = connectivityManager.activeNetworkInfo
- }
+ val connectivityManager = context.getSystemService()
+ val netInfo = connectivityManager?.activeNetworkInfo
netInfo != null && netInfo.type == ConnectivityManager.TYPE_WIFI && netInfo.isConnectedOrConnecting
}
"never" -> false
@@ -395,9 +394,15 @@ object PreferenceUtil {
val filterLength get() = sharedPreferences.getInt(FILTER_SONG, 20)
var lastVersion
- get() = sharedPreferences.getInt(LAST_CHANGELOG_VERSION, 0)
+ // This was stored as an integer before now it's a long, so avoid a ClassCastException
+ get() = try {
+ sharedPreferences.getLong(LAST_CHANGELOG_VERSION, 0)
+ } catch (e: ClassCastException) {
+ sharedPreferences.edit { remove(LAST_CHANGELOG_VERSION) }
+ 0
+ }
set(value) = sharedPreferences.edit {
- putInt(LAST_CHANGELOG_VERSION, value)
+ putLong(LAST_CHANGELOG_VERSION, value)
}
var lastSleepTimerValue
@@ -432,10 +437,11 @@ object PreferenceUtil {
val position = sharedPreferences.getStringOrDefault(
HOME_ARTIST_GRID_STYLE, "0"
).toInt()
- val typedArray = App.getContext()
- .resources.obtainTypedArray(R.array.pref_home_grid_style_layout)
- val layoutRes = typedArray.getResourceId(position, 0)
- typedArray.recycle()
+ val layoutRes =
+ App.getContext().resources.obtainTypedArray(R.array.pref_home_grid_style_layout)
+ .use {
+ it.getResourceId(position, 0)
+ }
return if (layoutRes == 0) {
R.layout.item_artist
} else layoutRes
@@ -446,10 +452,10 @@ object PreferenceUtil {
val position = sharedPreferences.getStringOrDefault(
HOME_ALBUM_GRID_STYLE, "4"
).toInt()
- val typedArray = App.getContext()
- .resources.obtainTypedArray(R.array.pref_home_grid_style_layout)
- val layoutRes = typedArray.getResourceId(position, 0)
- typedArray.recycle()
+ val layoutRes = App.getContext()
+ .resources.obtainTypedArray(R.array.pref_home_grid_style_layout).use {
+ it.getResourceId(position, 0)
+ }
return if (layoutRes == 0) {
R.layout.item_image
} else layoutRes
@@ -590,7 +596,7 @@ object PreferenceUtil {
4 -> VerticalFlipTransformation()
5 -> HingeTransformation()
6 -> VerticalStackTransformer()
- else -> NormalPageTransformer()
+ else -> ViewPager.PageTransformer { _, _ -> }
}
}
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/RetroUtil.java b/app/src/main/java/code/name/monkey/retromusic/util/RetroUtil.java
deleted file mode 100644
index 8005ab2b4..000000000
--- a/app/src/main/java/code/name/monkey/retromusic/util/RetroUtil.java
+++ /dev/null
@@ -1,262 +0,0 @@
-/*
- * Copyright (c) 2019 Hemanth Savarala.
- *
- * Licensed under the GNU General Public License v3
- *
- * This is free software: you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by
- * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * See the GNU General Public License for more details.
- */
-
-package code.name.monkey.retromusic.util;
-
-import android.annotation.TargetApi;
-import android.app.Activity;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Color;
-import android.graphics.Point;
-import android.graphics.drawable.Drawable;
-import android.net.ConnectivityManager;
-import android.net.NetworkInfo;
-import android.net.Uri;
-import android.os.Build;
-import android.util.DisplayMetrics;
-import android.view.Display;
-import android.view.View;
-import android.view.Window;
-import android.view.WindowManager;
-import android.view.inputmethod.InputMethodManager;
-
-import androidx.annotation.ColorInt;
-import androidx.annotation.DrawableRes;
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.content.res.ResourcesCompat;
-
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.text.DecimalFormat;
-import java.util.Collections;
-import java.util.List;
-
-import code.name.monkey.appthemehelper.util.TintHelper;
-import code.name.monkey.retromusic.App;
-
-public class RetroUtil {
-
- private static final int[] TEMP_ARRAY = new int[1];
-
- private static final String SHOW_NAV_BAR_RES_NAME = "config_showNavigationBar";
-
- public static int calculateNoOfColumns(@NonNull Context context) {
- DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
- float dpWidth = displayMetrics.widthPixels / displayMetrics.density;
- return (int) (dpWidth / 180);
- }
-
- @NonNull
- public static Bitmap createBitmap(@NonNull Drawable drawable, float sizeMultiplier) {
- Bitmap bitmap =
- Bitmap.createBitmap(
- (int) (drawable.getIntrinsicWidth() * sizeMultiplier),
- (int) (drawable.getIntrinsicHeight() * sizeMultiplier),
- Bitmap.Config.ARGB_8888);
- Canvas c = new Canvas(bitmap);
- drawable.setBounds(0, 0, c.getWidth(), c.getHeight());
- drawable.draw(c);
- return bitmap;
- }
-
- public static String formatValue(float value) {
- String[] arr = {"", "K", "M", "B", "T", "P", "E"};
- int index = 0;
- while ((value / 1000) >= 1) {
- value = value / 1000;
- index++;
- }
- DecimalFormat decimalFormat = new DecimalFormat("#.##");
- return String.format("%s %s", decimalFormat.format(value), arr[index]);
- }
-
- public static float frequencyCount(int frequency) {
- return (float) (frequency / 1000.0);
- }
-
- public static Point getScreenSize(@NonNull Context c) {
- Display display = null;
- if (c.getSystemService(Context.WINDOW_SERVICE) != null) {
- display = ((WindowManager) c.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
- }
- Point size = new Point();
- if (display != null) {
- display.getSize(size);
- }
- return size;
- }
-
- public static int getStatusBarHeight() {
- int result = 0;
- int resourceId =
- App.Companion.getContext()
- .getResources()
- .getIdentifier("status_bar_height", "dimen", "android");
- if (resourceId > 0) {
- result = App.Companion.getContext().getResources().getDimensionPixelSize(resourceId);
- }
- return result;
- }
-
- public static int getNavigationBarHeight() {
- int result = 0;
- int resourceId =
- App.Companion.getContext()
- .getResources()
- .getIdentifier("navigation_bar_height", "dimen", "android");
- if (resourceId > 0) {
- result = App.Companion.getContext().getResources().getDimensionPixelSize(resourceId);
- }
- return result;
- }
-
- @NonNull
- public static Drawable getTintedVectorDrawable(
- @NonNull Context context, @DrawableRes int id, @ColorInt int color) {
- return TintHelper.createTintedDrawable(
- getVectorDrawable(context.getResources(), id, context.getTheme()), color);
- }
-
- @NonNull
- public static Drawable getTintedVectorDrawable(
- @NonNull Resources res,
- @DrawableRes int resId,
- @Nullable Resources.Theme theme,
- @ColorInt int color) {
- return TintHelper.createTintedDrawable(getVectorDrawable(res, resId, theme), color);
- }
-
- @Nullable
- public static Drawable getVectorDrawable(
- @NonNull Resources res, @DrawableRes int resId, @Nullable Resources.Theme theme) {
- return ResourcesCompat.getDrawable(res, resId, theme);
- }
-
- public static void hideSoftKeyboard(@Nullable Activity activity) {
- if (activity != null) {
- View currentFocus = activity.getCurrentFocus();
- if (currentFocus != null) {
- InputMethodManager inputMethodManager =
- (InputMethodManager) activity.getSystemService(Activity.INPUT_METHOD_SERVICE);
- if (inputMethodManager != null) {
- inputMethodManager.hideSoftInputFromWindow(currentFocus.getWindowToken(), 0);
- }
- }
- }
- }
-
- public static boolean isAllowedToDownloadMetadata(final @NonNull Context context) {
- switch (PreferenceUtil.INSTANCE.getAutoDownloadImagesPolicy()) {
- case "always":
- return true;
- case "only_wifi":
- final ConnectivityManager connectivityManager =
- (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
- NetworkInfo netInfo = connectivityManager.getActiveNetworkInfo();
- return netInfo != null
- && netInfo.getType() == ConnectivityManager.TYPE_WIFI
- && netInfo.isConnectedOrConnecting();
- case "never":
- default:
- return false;
- }
- }
-
- public static boolean isLandscape() {
- return App.Companion.getContext().getResources().getConfiguration().orientation
- == Configuration.ORIENTATION_LANDSCAPE;
- }
-
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
- public static boolean isRTL(@NonNull Context context) {
- Configuration config = context.getResources().getConfiguration();
- return config.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
- }
-
- public static boolean isTablet() {
- return App.Companion.getContext().getResources().getConfiguration().smallestScreenWidthDp
- >= 600;
- }
-
- public static void openUrl(@NonNull Activity context, @NonNull String str) {
- Intent intent = new Intent("android.intent.action.VIEW");
- intent.setData(Uri.parse(str));
- intent.setFlags(268435456);
- context.startActivity(intent);
- }
-
- public static void setAllowDrawUnderNavigationBar(Window window) {
- window.setNavigationBarColor(Color.TRANSPARENT);
- window
- .getDecorView()
- .setSystemUiVisibility(
- Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
- ? View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
- : View.SYSTEM_UI_FLAG_LAYOUT_STABLE
- | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
- | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
- }
-
- public static void setAllowDrawUnderStatusBar(@NonNull Window window) {
- window
- .getDecorView()
- .setSystemUiVisibility(
- View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
- window.setStatusBarColor(Color.TRANSPARENT);
- }
-
- public static String getIpAddress(boolean useIPv4) {
- try {
- List interfaces =
- Collections.list(NetworkInterface.getNetworkInterfaces());
- for (NetworkInterface intf : interfaces) {
- List addrs = Collections.list(intf.getInetAddresses());
- for (InetAddress addr : addrs) {
- if (!addr.isLoopbackAddress()) {
- String sAddr = addr.getHostAddress();
- //boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr);
- boolean isIPv4 = sAddr.indexOf(':') < 0;
- if (useIPv4) {
- if (isIPv4) return sAddr;
- } else {
- if (!isIPv4) {
- int delim = sAddr.indexOf('%'); // drop ip6 zone suffix
- if (delim < 0) {
- return sAddr.toUpperCase();
- } else {
- return sAddr.substring(
- 0,
- delim
- ).toUpperCase();
- }
- }
- }
- }
- }
-
- }
- } catch (Exception ignored) {
- }
- return "";
- }
-}
diff --git a/app/src/main/java/code/name/monkey/retromusic/util/RetroUtil.kt b/app/src/main/java/code/name/monkey/retromusic/util/RetroUtil.kt
new file mode 100644
index 000000000..60f4f5823
--- /dev/null
+++ b/app/src/main/java/code/name/monkey/retromusic/util/RetroUtil.kt
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2019 Hemanth Savarala.
+ *
+ * Licensed under the GNU General Public License v3
+ *
+ * This is free software: you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License as published by
+ * the Free Software Foundation either version 3 of the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ */
+package code.name.monkey.retromusic.util
+
+import android.content.Context
+import android.content.res.Configuration
+import android.graphics.Point
+import code.name.monkey.retromusic.App.Companion.getContext
+import java.net.InetAddress
+import java.net.NetworkInterface
+import java.text.DecimalFormat
+import java.util.*
+
+object RetroUtil {
+ fun formatValue(numValue: Float): String {
+ var value = numValue
+ val arr = arrayOf("", "K", "M", "B", "T", "P", "E")
+ var index = 0
+ while (value / 1000 >= 1) {
+ value /= 1000
+ index++
+ }
+ val decimalFormat = DecimalFormat("#.##")
+ return String.format("%s %s", decimalFormat.format(value.toDouble()), arr[index])
+ }
+
+ fun frequencyCount(frequency: Int): Float {
+ return (frequency / 1000.0).toFloat()
+ }
+
+ fun getScreenSize(context: Context): Point {
+ val x: Int = context.resources.displayMetrics.widthPixels
+ val y: Int = context.resources.displayMetrics.heightPixels
+ return Point(x, y)
+ }
+
+ val statusBarHeight: Int
+ get() {
+ var result = 0
+ val resourceId = getContext()
+ .resources
+ .getIdentifier("status_bar_height", "dimen", "android")
+ if (resourceId > 0) {
+ result = getContext().resources.getDimensionPixelSize(resourceId)
+ }
+ return result
+ }
+
+ val navigationBarHeight: Int
+ get() {
+ var result = 0
+ val resourceId = getContext()
+ .resources
+ .getIdentifier("navigation_bar_height", "dimen", "android")
+ if (resourceId > 0) {
+ result = getContext().resources.getDimensionPixelSize(resourceId)
+ }
+ return result
+ }
+
+ val isLandscape: Boolean
+ get() = (getContext().resources.configuration.orientation
+ == Configuration.ORIENTATION_LANDSCAPE)
+ val isTablet: Boolean
+ get() = (getContext().resources.configuration.smallestScreenWidthDp
+ >= 600)
+
+ fun getIpAddress(useIPv4: Boolean): String? {
+ try {
+ val interfaces: List =
+ Collections.list(NetworkInterface.getNetworkInterfaces())
+ for (intf in interfaces) {
+ val addrs: List