Created
July 29, 2016 06:37
-
-
Save hvalls/7ae82a392d892c1e03a510e74393ced6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* This is the source code of Telegram for Android v. 3.x.x. | |
* It is licensed under GNU GPL v. 2 or later. | |
* You should have received a copy of the license in this archive (see LICENSE). | |
* | |
* Copyright Nikolai Kudashov, 2013-2016. | |
*/ | |
package org.telegram.messenger; | |
import android.animation.Animator; | |
import android.animation.AnimatorSet; | |
import android.animation.ObjectAnimator; | |
import android.annotation.SuppressLint; | |
import android.app.Activity; | |
import android.app.AlertDialog; | |
import android.content.ContentUris; | |
import android.content.Context; | |
import android.content.DialogInterface; | |
import android.content.Intent; | |
import android.content.pm.ActivityInfo; | |
import android.content.pm.PackageManager; | |
import android.content.res.Configuration; | |
import android.database.Cursor; | |
import android.graphics.Bitmap; | |
import android.graphics.BitmapFactory; | |
import android.graphics.BitmapShader; | |
import android.graphics.Canvas; | |
import android.graphics.Color; | |
import android.graphics.Paint; | |
import android.graphics.Point; | |
import android.graphics.Rect; | |
import android.graphics.RectF; | |
import android.graphics.Shader; | |
import android.graphics.Typeface; | |
import android.graphics.drawable.BitmapDrawable; | |
import android.graphics.drawable.ColorDrawable; | |
import android.graphics.drawable.Drawable; | |
import android.net.Uri; | |
import android.os.Build; | |
import android.os.Environment; | |
import android.provider.DocumentsContract; | |
import android.provider.MediaStore; | |
import android.text.SpannableStringBuilder; | |
import android.text.Spanned; | |
import android.text.style.ForegroundColorSpan; | |
import android.util.DisplayMetrics; | |
import android.util.StateSet; | |
import android.view.Display; | |
import android.view.Surface; | |
import android.view.View; | |
import android.view.WindowManager; | |
import android.view.inputmethod.InputMethodManager; | |
import android.webkit.MimeTypeMap; | |
import android.widget.AbsListView; | |
import android.widget.EdgeEffect; | |
import android.widget.EditText; | |
import android.widget.ListView; | |
import android.widget.ProgressBar; | |
import android.widget.TextView; | |
import net.hockeyapp.android.CrashManager; | |
import net.hockeyapp.android.CrashManagerListener; | |
import net.hockeyapp.android.UpdateManager; | |
import org.telegram.tgnet.ConnectionsManager; | |
import org.telegram.tgnet.TLRPC; | |
import org.telegram.ui.ActionBar.BaseFragment; | |
import org.telegram.ui.Components.ForegroundDetector; | |
import org.telegram.ui.Components.NumberPicker; | |
import org.telegram.ui.Components.TypefaceSpan; | |
import java.io.ByteArrayOutputStream; | |
import java.io.File; | |
import java.io.FileInputStream; | |
import java.io.FileOutputStream; | |
import java.io.IOException; | |
import java.io.InputStream; | |
import java.io.OutputStream; | |
import java.lang.reflect.Field; | |
import java.lang.reflect.Method; | |
import java.text.SimpleDateFormat; | |
import java.util.ArrayList; | |
import java.util.Date; | |
import java.util.Hashtable; | |
import java.util.Locale; | |
import java.util.regex.Pattern; | |
public class AndroidUtilities { | |
private static final Hashtable<String, Typeface> typefaceCache = new Hashtable<>(); | |
private static int prevOrientation = -10; | |
private static boolean waitingForSms = false; | |
private static boolean waitingForCall = false; | |
private static final Object smsLock = new Object(); | |
private static final Object callLock = new Object(); | |
public static int statusBarHeight = 0; | |
public static float density = 1; | |
public static Point displaySize = new Point(); | |
public static Integer photoSize = null; | |
public static DisplayMetrics displayMetrics = new DisplayMetrics(); | |
public static int leftBaseline; | |
public static boolean usingHardwareInput; | |
private static Boolean isTablet = null; | |
private static int adjustOwnerClassGuid = 0; | |
private static Paint roundPaint; | |
private static RectF bitmapRect; | |
public static Pattern WEB_URL = null; | |
static { | |
try { | |
final String GOOD_IRI_CHAR = "a-zA-Z0-9\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF"; | |
final Pattern IP_ADDRESS = Pattern.compile( | |
"((25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\\.(25[0-5]|2[0-4]" | |
+ "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1]" | |
+ "[0-9]{2}|[1-9][0-9]|[1-9]|0)\\.(25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}" | |
+ "|[1-9][0-9]|[0-9]))"); | |
final String IRI = "[" + GOOD_IRI_CHAR + "]([" + GOOD_IRI_CHAR + "\\-]{0,61}[" + GOOD_IRI_CHAR + "]){0,1}"; | |
final String GOOD_GTLD_CHAR = "a-zA-Z\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF"; | |
final String GTLD = "[" + GOOD_GTLD_CHAR + "]{2,63}"; | |
final String HOST_NAME = "(" + IRI + "\\.)+" + GTLD; | |
final Pattern DOMAIN_NAME = Pattern.compile("(" + HOST_NAME + "|" + IP_ADDRESS + ")"); | |
WEB_URL = Pattern.compile( | |
"((?:(http|https|Http|Https):\\/\\/(?:(?:[a-zA-Z0-9\\$\\-\\_\\.\\+\\!\\*\\'\\(\\)" | |
+ "\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,64}(?:\\:(?:[a-zA-Z0-9\\$\\-\\_" | |
+ "\\.\\+\\!\\*\\'\\(\\)\\,\\;\\?\\&\\=]|(?:\\%[a-fA-F0-9]{2})){1,25})?\\@)?)?" | |
+ "(?:" + DOMAIN_NAME + ")" | |
+ "(?:\\:\\d{1,5})?)" // plus option port number | |
+ "(\\/(?:(?:[" + GOOD_IRI_CHAR + "\\;\\/\\?\\:\\@\\&\\=\\#\\~" // plus option query params | |
+ "\\-\\.\\+\\!\\*\\'\\(\\)\\,\\_])|(?:\\%[a-fA-F0-9]{2}))*)?" | |
+ "(?:\\b|$)"); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
static { | |
density = ApplicationLoader.applicationContext.getResources().getDisplayMetrics().density; | |
leftBaseline = isTablet() ? 80 : 72; | |
checkDisplaySize(); | |
} | |
public static int[] calcDrawableColor(Drawable drawable) { | |
int bitmapColor = 0xff000000; | |
int result[] = new int[2]; | |
try { | |
if (drawable instanceof BitmapDrawable) { | |
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); | |
if (bitmap != null) { | |
Bitmap b = Bitmaps.createScaledBitmap(bitmap, 1, 1, true); | |
if (b != null) { | |
bitmapColor = b.getPixel(0, 0); | |
b.recycle(); | |
} | |
} | |
} else if (drawable instanceof ColorDrawable) { | |
bitmapColor = ((ColorDrawable) drawable).getColor(); | |
} | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
double[] hsv = rgbToHsv((bitmapColor >> 16) & 0xff, (bitmapColor >> 8) & 0xff, bitmapColor & 0xff); | |
hsv[1] = Math.min(1.0, hsv[1] + 0.05 + 0.1 * (1.0 - hsv[1])); | |
hsv[2] = Math.max(0, hsv[2] * 0.65); | |
int rgb[] = hsvToRgb(hsv[0], hsv[1], hsv[2]); | |
result[0] = Color.argb(0x66, rgb[0], rgb[1], rgb[2]); | |
result[1] = Color.argb(0x88, rgb[0], rgb[1], rgb[2]); | |
return result; | |
} | |
private static double[] rgbToHsv(int r, int g, int b) { | |
double rf = r / 255.0; | |
double gf = g / 255.0; | |
double bf = b / 255.0; | |
double max = (rf > gf && rf > bf) ? rf : (gf > bf) ? gf : bf; | |
double min = (rf < gf && rf < bf) ? rf : (gf < bf) ? gf : bf; | |
double h, s; | |
double d = max - min; | |
s = max == 0 ? 0 : d / max; | |
if (max == min) { | |
h = 0; | |
} else { | |
if (rf > gf && rf > bf) { | |
h = (gf - bf) / d + (gf < bf ? 6 : 0); | |
} else if (gf > bf) { | |
h = (bf - rf) / d + 2; | |
} else { | |
h = (rf - gf) / d + 4; | |
} | |
h /= 6; | |
} | |
return new double[]{h, s, max}; | |
} | |
private static int[] hsvToRgb(double h, double s, double v) { | |
double r = 0, g = 0, b = 0; | |
double i = (int) Math.floor(h * 6); | |
double f = h * 6 - i; | |
double p = v * (1 - s); | |
double q = v * (1 - f * s); | |
double t = v * (1 - (1 - f) * s); | |
switch ((int) i % 6) { | |
case 0: | |
r = v; | |
g = t; | |
b = p; | |
break; | |
case 1: | |
r = q; | |
g = v; | |
b = p; | |
break; | |
case 2: | |
r = p; | |
g = v; | |
b = t; | |
break; | |
case 3: | |
r = p; | |
g = q; | |
b = v; | |
break; | |
case 4: | |
r = t; | |
g = p; | |
b = v; | |
break; | |
case 5: | |
r = v; | |
g = p; | |
b = q; | |
break; | |
} | |
return new int[]{(int) (r * 255), (int) (g * 255), (int) (b * 255)}; | |
} | |
public static void requestAdjustResize(Activity activity, int classGuid) { | |
if (activity == null || isTablet()) { | |
return; | |
} | |
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); | |
adjustOwnerClassGuid = classGuid; | |
} | |
public static void removeAdjustResize(Activity activity, int classGuid) { | |
if (activity == null || isTablet()) { | |
return; | |
} | |
if (adjustOwnerClassGuid == classGuid) { | |
activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN); | |
} | |
} | |
public static boolean isGoogleMapsInstalled(final BaseFragment fragment) { | |
try { | |
ApplicationLoader.applicationContext.getPackageManager().getApplicationInfo("com.google.android.apps.maps", 0); | |
return true; | |
} catch (PackageManager.NameNotFoundException e) { | |
if (fragment.getParentActivity() == null) { | |
return false; | |
} | |
AlertDialog.Builder builder = new AlertDialog.Builder(fragment.getParentActivity()); | |
builder.setMessage("Install Google Maps?"); | |
builder.setCancelable(true); | |
builder.setPositiveButton(LocaleController.getString("OK", R.string.OK), new DialogInterface.OnClickListener() { | |
@Override | |
public void onClick(DialogInterface dialogInterface, int i) { | |
try { | |
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=com.google.android.apps.maps")); | |
fragment.getParentActivity().startActivityForResult(intent, 500); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
}); | |
builder.setNegativeButton(LocaleController.getString("Cancel", R.string.Cancel), null); | |
fragment.showDialog(builder.create()); | |
return false; | |
} | |
} | |
public static boolean isInternalUri(Uri uri) { | |
String pathString = uri.getPath(); | |
if (pathString == null) { | |
return false; | |
} | |
while (true) { | |
String newPath = Utilities.readlink(pathString); | |
if (newPath == null || newPath.equals(pathString)) { | |
break; | |
} | |
pathString = newPath; | |
} | |
return pathString != null && pathString.toLowerCase().contains("/data/data/" + ApplicationLoader.applicationContext.getPackageName() + "/files"); | |
} | |
public static void lockOrientation(Activity activity) { | |
if (activity == null || prevOrientation != -10) { | |
return; | |
} | |
try { | |
prevOrientation = activity.getRequestedOrientation(); | |
WindowManager manager = (WindowManager)activity.getSystemService(Activity.WINDOW_SERVICE); | |
if (manager != null && manager.getDefaultDisplay() != null) { | |
int rotation = manager.getDefaultDisplay().getRotation(); | |
int orientation = activity.getResources().getConfiguration().orientation; | |
if (rotation == Surface.ROTATION_270) { | |
if (orientation == Configuration.ORIENTATION_PORTRAIT) { | |
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); | |
} else { | |
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); | |
} | |
} else if (rotation == Surface.ROTATION_90) { | |
if (orientation == Configuration.ORIENTATION_PORTRAIT) { | |
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); | |
} else { | |
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); | |
} | |
} else if (rotation == Surface.ROTATION_0) { | |
if (orientation == Configuration.ORIENTATION_LANDSCAPE) { | |
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); | |
} else { | |
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); | |
} | |
} else { | |
if (orientation == Configuration.ORIENTATION_LANDSCAPE) { | |
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE); | |
} else { | |
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT); | |
} | |
} | |
} | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
public static void unlockOrientation(Activity activity) { | |
if (activity == null) { | |
return; | |
} | |
try { | |
if (prevOrientation != -10) { | |
activity.setRequestedOrientation(prevOrientation); | |
prevOrientation = -10; | |
} | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
public static Typeface getTypeface(String assetPath) { | |
synchronized (typefaceCache) { | |
if (!typefaceCache.containsKey(assetPath)) { | |
try { | |
Typeface t = Typeface.createFromAsset(ApplicationLoader.applicationContext.getAssets(), assetPath); | |
typefaceCache.put(assetPath, t); | |
} catch (Exception e) { | |
FileLog.e("Typefaces", "Could not get typeface '" + assetPath + "' because " + e.getMessage()); | |
return null; | |
} | |
} | |
return typefaceCache.get(assetPath); | |
} | |
} | |
public static boolean isWaitingForSms() { | |
boolean value; | |
synchronized (smsLock) { | |
value = waitingForSms; | |
} | |
return value; | |
} | |
public static void setWaitingForSms(boolean value) { | |
synchronized (smsLock) { | |
waitingForSms = value; | |
} | |
} | |
public static boolean isWaitingForCall() { | |
boolean value; | |
synchronized (callLock) { | |
value = waitingForCall; | |
} | |
return value; | |
} | |
public static void setWaitingForCall(boolean value) { | |
synchronized (callLock) { | |
waitingForCall = value; | |
} | |
} | |
public static void showKeyboard(View view) { | |
if (view == null) { | |
return; | |
} | |
try { | |
InputMethodManager inputManager = (InputMethodManager)view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); | |
inputManager.showSoftInput(view, InputMethodManager.SHOW_IMPLICIT); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
public static boolean isKeyboardShowed(View view) { | |
if (view == null) { | |
return false; | |
} | |
try { | |
InputMethodManager inputManager = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); | |
return inputManager.isActive(view); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
return false; | |
} | |
public static void hideKeyboard(View view) { | |
if (view == null) { | |
return; | |
} | |
try { | |
InputMethodManager imm = (InputMethodManager) view.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); | |
if (!imm.isActive()) { | |
return; | |
} | |
imm.hideSoftInputFromWindow(view.getWindowToken(), 0); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
public static File getCacheDir() { | |
String state = null; | |
try { | |
state = Environment.getExternalStorageState(); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
if (state == null || state.startsWith(Environment.MEDIA_MOUNTED)) { | |
try { | |
File file = ApplicationLoader.applicationContext.getExternalCacheDir(); | |
if (file != null) { | |
return file; | |
} | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
try { | |
File file = ApplicationLoader.applicationContext.getCacheDir(); | |
if (file != null) { | |
return file; | |
} | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
return new File(""); | |
} | |
public static int dp(float value) { | |
if (value == 0) { | |
return 0; | |
} | |
return (int) Math.ceil(density * value); | |
} | |
public static int compare(int lhs, int rhs) { | |
if (lhs == rhs) { | |
return 0; | |
} else if (lhs > rhs) { | |
return 1; | |
} | |
return -1; | |
} | |
public static float dpf2(float value) { | |
if (value == 0) { | |
return 0; | |
} | |
return density * value; | |
} | |
public static void checkDisplaySize() { | |
try { | |
Configuration configuration = ApplicationLoader.applicationContext.getResources().getConfiguration(); | |
usingHardwareInput = configuration.keyboard != Configuration.KEYBOARD_NOKEYS && configuration.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO; | |
WindowManager manager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE); | |
if (manager != null) { | |
Display display = manager.getDefaultDisplay(); | |
if (display != null) { | |
display.getMetrics(displayMetrics); | |
display.getSize(displaySize); | |
FileLog.e("tmessages", "display size = " + displaySize.x + " " + displaySize.y + " " + displayMetrics.xdpi + "x" + displayMetrics.ydpi); | |
} | |
} | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
public static float getPixelsInCM(float cm, boolean isX) { | |
return (cm / 2.54f) * (isX ? displayMetrics.xdpi : displayMetrics.ydpi); | |
} | |
public static long makeBroadcastId(int id) { | |
return 0x0000000100000000L | ((long)id & 0x00000000FFFFFFFFL); | |
} | |
public static int getMyLayerVersion(int layer) { | |
return layer & 0xffff; | |
} | |
public static int getPeerLayerVersion(int layer) { | |
return (layer >> 16) & 0xffff; | |
} | |
public static int setMyLayerVersion(int layer, int version) { | |
return layer & 0xffff0000 | version; | |
} | |
public static int setPeerLayerVersion(int layer, int version) { | |
return layer & 0x0000ffff | (version << 16); | |
} | |
public static void runOnUIThread(Runnable runnable) { | |
runOnUIThread(runnable, 0); | |
} | |
public static void runOnUIThread(Runnable runnable, long delay) { | |
if (delay == 0) { | |
ApplicationLoader.applicationHandler.post(runnable); | |
} else { | |
ApplicationLoader.applicationHandler.postDelayed(runnable, delay); | |
} | |
} | |
public static void cancelRunOnUIThread(Runnable runnable) { | |
ApplicationLoader.applicationHandler.removeCallbacks(runnable); | |
} | |
public static boolean isTablet() { | |
if (isTablet == null) { | |
isTablet = ApplicationLoader.applicationContext.getResources().getBoolean(R.bool.isTablet); | |
} | |
return isTablet; | |
} | |
public static boolean isSmallTablet() { | |
float minSide = Math.min(displaySize.x, displaySize.y) / density; | |
return minSide <= 700; | |
} | |
public static int getMinTabletSide() { | |
if (!isSmallTablet()) { | |
int smallSide = Math.min(displaySize.x, displaySize.y); | |
int leftSide = smallSide * 35 / 100; | |
if (leftSide < dp(320)) { | |
leftSide = dp(320); | |
} | |
return smallSide - leftSide; | |
} else { | |
int smallSide = Math.min(displaySize.x, displaySize.y); | |
int maxSide = Math.max(displaySize.x, displaySize.y); | |
int leftSide = maxSide * 35 / 100; | |
if (leftSide < dp(320)) { | |
leftSide = dp(320); | |
} | |
return Math.min(smallSide, maxSide - leftSide); | |
} | |
} | |
public static int getPhotoSize() { | |
if (photoSize == null) { | |
if (Build.VERSION.SDK_INT >= 16) { | |
photoSize = 1280; | |
} else { | |
photoSize = 800; | |
} | |
} | |
return photoSize; | |
} | |
public static String formatTTLString(int ttl) { | |
if (ttl < 60) { | |
return LocaleController.formatPluralString("Seconds", ttl); | |
} else if (ttl < 60 * 60) { | |
return LocaleController.formatPluralString("Minutes", ttl / 60); | |
} else if (ttl < 60 * 60 * 24) { | |
return LocaleController.formatPluralString("Hours", ttl / 60 / 60); | |
} else if (ttl < 60 * 60 * 24 * 7) { | |
return LocaleController.formatPluralString("Days", ttl / 60 / 60 / 24); | |
} else { | |
int days = ttl / 60 / 60 / 24; | |
if (ttl % 7 == 0) { | |
return LocaleController.formatPluralString("Weeks", days / 7); | |
} else { | |
return String.format("%s %s", LocaleController.formatPluralString("Weeks", days / 7), LocaleController.formatPluralString("Days", days % 7)); | |
} | |
} | |
} | |
public static AlertDialog.Builder buildTTLAlert(final Context context, final TLRPC.EncryptedChat encryptedChat) { | |
AlertDialog.Builder builder = new AlertDialog.Builder(context); | |
builder.setTitle(LocaleController.getString("MessageLifetime", R.string.MessageLifetime)); | |
final NumberPicker numberPicker = new NumberPicker(context); | |
numberPicker.setMinValue(0); | |
numberPicker.setMaxValue(20); | |
if (encryptedChat.ttl > 0 && encryptedChat.ttl < 16) { | |
numberPicker.setValue(encryptedChat.ttl); | |
} else if (encryptedChat.ttl == 30) { | |
numberPicker.setValue(16); | |
} else if (encryptedChat.ttl == 60) { | |
numberPicker.setValue(17); | |
} else if (encryptedChat.ttl == 60 * 60) { | |
numberPicker.setValue(18); | |
} else if (encryptedChat.ttl == 60 * 60 * 24) { | |
numberPicker.setValue(19); | |
} else if (encryptedChat.ttl == 60 * 60 * 24 * 7) { | |
numberPicker.setValue(20); | |
} else if (encryptedChat.ttl == 0) { | |
numberPicker.setValue(0); | |
} | |
numberPicker.setFormatter(new NumberPicker.Formatter() { | |
@Override | |
public String format(int value) { | |
if (value == 0) { | |
return LocaleController.getString("ShortMessageLifetimeForever", R.string.ShortMessageLifetimeForever); | |
} else if (value >= 1 && value < 16) { | |
return AndroidUtilities.formatTTLString(value); | |
} else if (value == 16) { | |
return AndroidUtilities.formatTTLString(30); | |
} else if (value == 17) { | |
return AndroidUtilities.formatTTLString(60); | |
} else if (value == 18) { | |
return AndroidUtilities.formatTTLString(60 * 60); | |
} else if (value == 19) { | |
return AndroidUtilities.formatTTLString(60 * 60 * 24); | |
} else if (value == 20) { | |
return AndroidUtilities.formatTTLString(60 * 60 * 24 * 7); | |
} | |
return ""; | |
} | |
}); | |
builder.setView(numberPicker); | |
builder.setNegativeButton(LocaleController.getString("Done", R.string.Done), new DialogInterface.OnClickListener() { | |
@Override | |
public void onClick(DialogInterface dialog, int which) { | |
int oldValue = encryptedChat.ttl; | |
which = numberPicker.getValue(); | |
if (which >= 0 && which < 16) { | |
encryptedChat.ttl = which; | |
} else if (which == 16) { | |
encryptedChat.ttl = 30; | |
} else if (which == 17) { | |
encryptedChat.ttl = 60; | |
} else if (which == 18) { | |
encryptedChat.ttl = 60 * 60; | |
} else if (which == 19) { | |
encryptedChat.ttl = 60 * 60 * 24; | |
} else if (which == 20) { | |
encryptedChat.ttl = 60 * 60 * 24 * 7; | |
} | |
if (oldValue != encryptedChat.ttl) { | |
SecretChatHelper.getInstance().sendTTLMessage(encryptedChat, null); | |
MessagesStorage.getInstance().updateEncryptedChatTTL(encryptedChat); | |
} | |
} | |
}); | |
return builder; | |
} | |
public static void clearCursorDrawable(EditText editText) { | |
if (editText == null) { | |
return; | |
} | |
try { | |
Field mCursorDrawableRes = TextView.class.getDeclaredField("mCursorDrawableRes"); | |
mCursorDrawableRes.setAccessible(true); | |
mCursorDrawableRes.setInt(editText, 0); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
public static void setProgressBarAnimationDuration(ProgressBar progressBar, int duration) { | |
if (progressBar == null) { | |
return; | |
} | |
try { | |
Field mCursorDrawableRes = ProgressBar.class.getDeclaredField("mDuration"); | |
mCursorDrawableRes.setAccessible(true); | |
mCursorDrawableRes.setInt(progressBar, duration); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
private static Intent createShortcutIntent(long did, boolean forDelete) { | |
Intent shortcutIntent = new Intent(ApplicationLoader.applicationContext, OpenChatReceiver.class); | |
int lower_id = (int) did; | |
int high_id = (int) (did >> 32); | |
TLRPC.User user = null; | |
TLRPC.Chat chat = null; | |
if (lower_id == 0) { | |
shortcutIntent.putExtra("encId", high_id); | |
TLRPC.EncryptedChat encryptedChat = MessagesController.getInstance().getEncryptedChat(high_id); | |
if (encryptedChat == null) { | |
return null; | |
} | |
user = MessagesController.getInstance().getUser(encryptedChat.user_id); | |
} else if (lower_id > 0) { | |
shortcutIntent.putExtra("userId", lower_id); | |
user = MessagesController.getInstance().getUser(lower_id); | |
} else if (lower_id < 0) { | |
chat = MessagesController.getInstance().getChat(-lower_id); | |
shortcutIntent.putExtra("chatId", -lower_id); | |
} else { | |
return null; | |
} | |
if (user == null && chat == null) { | |
return null; | |
} | |
String name; | |
TLRPC.FileLocation photo = null; | |
if (user != null) { | |
name = ContactsController.formatName(user.first_name, user.last_name); | |
if (user.photo != null) { | |
photo = user.photo.photo_small; | |
} | |
} else { | |
name = chat.title; | |
if (chat.photo != null) { | |
photo = chat.photo.photo_small; | |
} | |
} | |
shortcutIntent.setAction("com.tmessages.openchat" + did); | |
shortcutIntent.addFlags(0x4000000); | |
Intent addIntent = new Intent(); | |
addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); | |
addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name); | |
addIntent.putExtra("duplicate", false); | |
if (!forDelete) { | |
Bitmap bitmap = null; | |
if (photo != null) { | |
try { | |
File path = FileLoader.getPathToAttach(photo, true); | |
bitmap = BitmapFactory.decodeFile(path.toString()); | |
if (bitmap != null) { | |
int size = AndroidUtilities.dp(58); | |
Bitmap result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888); | |
result.eraseColor(Color.TRANSPARENT); | |
Canvas canvas = new Canvas(result); | |
BitmapShader shader = new BitmapShader(bitmap, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP); | |
if (roundPaint == null) { | |
roundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); | |
bitmapRect = new RectF(); | |
} | |
float scale = size / (float) bitmap.getWidth(); | |
canvas.save(); | |
canvas.scale(scale, scale); | |
roundPaint.setShader(shader); | |
bitmapRect.set(0, 0, bitmap.getWidth(), bitmap.getHeight()); | |
canvas.drawRoundRect(bitmapRect, bitmap.getWidth(), bitmap.getHeight(), roundPaint); | |
canvas.restore(); | |
Drawable drawable = ApplicationLoader.applicationContext.getResources().getDrawable(R.drawable.book_logo); | |
int w = AndroidUtilities.dp(15); | |
int left = size - w - AndroidUtilities.dp(2); | |
int top = size - w - AndroidUtilities.dp(2); | |
drawable.setBounds(left, top, left + w, top + w); | |
drawable.draw(canvas); | |
try { | |
canvas.setBitmap(null); | |
} catch (Exception e) { | |
//don't promt, this will crash on 2.x | |
} | |
bitmap = result; | |
} | |
} catch (Throwable e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
if (bitmap != null) { | |
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, bitmap); | |
} else { | |
if (user != null) { | |
if (user.bot) { | |
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(ApplicationLoader.applicationContext, R.drawable.book_bot)); | |
} else { | |
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(ApplicationLoader.applicationContext, R.drawable.book_user)); | |
} | |
} else if (chat != null) { | |
if (ChatObject.isChannel(chat) && !chat.megagroup) { | |
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(ApplicationLoader.applicationContext, R.drawable.book_channel)); | |
} else { | |
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(ApplicationLoader.applicationContext, R.drawable.book_group)); | |
} | |
} | |
} | |
} | |
return addIntent; | |
} | |
public static void installShortcut(long did) { | |
try { | |
Intent addIntent = createShortcutIntent(did, false); | |
addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); | |
ApplicationLoader.applicationContext.sendBroadcast(addIntent); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
public static void uninstallShortcut(long did) { | |
try { | |
Intent addIntent = createShortcutIntent(did, true); | |
addIntent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT"); | |
ApplicationLoader.applicationContext.sendBroadcast(addIntent); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
public static int getViewInset(View view) { | |
if (view == null || Build.VERSION.SDK_INT < 21 || view.getHeight() == AndroidUtilities.displaySize.y || view.getHeight() == AndroidUtilities.displaySize.y - statusBarHeight) { | |
return 0; | |
} | |
try { | |
Field mAttachInfoField = View.class.getDeclaredField("mAttachInfo"); | |
mAttachInfoField.setAccessible(true); | |
Object mAttachInfo = mAttachInfoField.get(view); | |
if (mAttachInfo != null) { | |
Field mStableInsetsField = mAttachInfo.getClass().getDeclaredField("mStableInsets"); | |
mStableInsetsField.setAccessible(true); | |
Rect insets = (Rect)mStableInsetsField.get(mAttachInfo); | |
return insets.bottom; | |
} | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
return 0; | |
} | |
public static Point getRealScreenSize() { | |
Point size = new Point(); | |
try { | |
WindowManager windowManager = (WindowManager) ApplicationLoader.applicationContext.getSystemService(Context.WINDOW_SERVICE); | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { | |
windowManager.getDefaultDisplay().getRealSize(size); | |
} else { | |
try { | |
Method mGetRawW = Display.class.getMethod("getRawWidth"); | |
Method mGetRawH = Display.class.getMethod("getRawHeight"); | |
size.set((Integer) mGetRawW.invoke(windowManager.getDefaultDisplay()), (Integer) mGetRawH.invoke(windowManager.getDefaultDisplay())); | |
} catch (Exception e) { | |
size.set(windowManager.getDefaultDisplay().getWidth(), windowManager.getDefaultDisplay().getHeight()); | |
FileLog.e("tmessages", e); | |
} | |
} | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
return size; | |
} | |
public static CharSequence getTrimmedString(CharSequence src) { | |
if (src == null || src.length() == 0) { | |
return src; | |
} | |
while (src.length() > 0 && (src.charAt(0) == '\n' || src.charAt(0) == ' ')) { | |
src = src.subSequence(1, src.length()); | |
} | |
while (src.length() > 0 && (src.charAt(src.length() - 1) == '\n' || src.charAt(src.length() - 1) == ' ')) { | |
src = src.subSequence(0, src.length() - 1); | |
} | |
return src; | |
} | |
public static void setListViewEdgeEffectColor(AbsListView listView, int color) { | |
if (Build.VERSION.SDK_INT >= 21) { | |
try { | |
Field field = AbsListView.class.getDeclaredField("mEdgeGlowTop"); | |
field.setAccessible(true); | |
EdgeEffect mEdgeGlowTop = (EdgeEffect) field.get(listView); | |
if (mEdgeGlowTop != null) { | |
mEdgeGlowTop.setColor(color); | |
} | |
field = AbsListView.class.getDeclaredField("mEdgeGlowBottom"); | |
field.setAccessible(true); | |
EdgeEffect mEdgeGlowBottom = (EdgeEffect) field.get(listView); | |
if (mEdgeGlowBottom != null) { | |
mEdgeGlowBottom.setColor(color); | |
} | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
} | |
@SuppressLint("NewApi") | |
public static void clearDrawableAnimation(View view) { | |
if (Build.VERSION.SDK_INT < 21 || view == null) { | |
return; | |
} | |
Drawable drawable; | |
if (view instanceof ListView) { | |
drawable = ((ListView) view).getSelector(); | |
if (drawable != null) { | |
drawable.setState(StateSet.NOTHING); | |
} | |
} else { | |
drawable = view.getBackground(); | |
if (drawable != null) { | |
drawable.setState(StateSet.NOTHING); | |
drawable.jumpToCurrentState(); | |
} | |
} | |
} | |
public static final int FLAG_TAG_BR = 1; | |
public static final int FLAG_TAG_BOLD = 2; | |
public static final int FLAG_TAG_COLOR = 4; | |
public static final int FLAG_TAG_ALL = FLAG_TAG_BR | FLAG_TAG_BOLD | FLAG_TAG_COLOR; | |
public static SpannableStringBuilder replaceTags(String str) { | |
return replaceTags(str, FLAG_TAG_ALL); | |
} | |
public static SpannableStringBuilder replaceTags(String str, int flag) { | |
try { | |
int start; | |
int end; | |
StringBuilder stringBuilder = new StringBuilder(str); | |
if ((flag & FLAG_TAG_BR) != 0) { | |
while ((start = stringBuilder.indexOf("<br>")) != -1) { | |
stringBuilder.replace(start, start + 4, "\n"); | |
} | |
while ((start = stringBuilder.indexOf("<br/>")) != -1) { | |
stringBuilder.replace(start, start + 5, "\n"); | |
} | |
} | |
ArrayList<Integer> bolds = new ArrayList<>(); | |
if ((flag & FLAG_TAG_BOLD) != 0) { | |
while ((start = stringBuilder.indexOf("<b>")) != -1) { | |
stringBuilder.replace(start, start + 3, ""); | |
end = stringBuilder.indexOf("</b>"); | |
if (end == -1) { | |
end = stringBuilder.indexOf("<b>"); | |
} | |
stringBuilder.replace(end, end + 4, ""); | |
bolds.add(start); | |
bolds.add(end); | |
} | |
} | |
ArrayList<Integer> colors = new ArrayList<>(); | |
if ((flag & FLAG_TAG_COLOR) != 0) { | |
while ((start = stringBuilder.indexOf("<c#")) != -1) { | |
stringBuilder.replace(start, start + 2, ""); | |
end = stringBuilder.indexOf(">", start); | |
int color = Color.parseColor(stringBuilder.substring(start, end)); | |
stringBuilder.replace(start, end + 1, ""); | |
end = stringBuilder.indexOf("</c>"); | |
stringBuilder.replace(end, end + 4, ""); | |
colors.add(start); | |
colors.add(end); | |
colors.add(color); | |
} | |
} | |
SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(stringBuilder); | |
for (int a = 0; a < bolds.size() / 2; a++) { | |
spannableStringBuilder.setSpan(new TypefaceSpan(AndroidUtilities.getTypeface("fonts/rmedium.ttf")), bolds.get(a * 2), bolds.get(a * 2 + 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); | |
} | |
for (int a = 0; a < colors.size() / 3; a++) { | |
spannableStringBuilder.setSpan(new ForegroundColorSpan(colors.get(a * 3 + 2)), colors.get(a * 3), colors.get(a * 3 + 1), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); | |
} | |
return spannableStringBuilder; | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
return new SpannableStringBuilder(str); | |
} | |
public static boolean needShowPasscode(boolean reset) { | |
boolean wasInBackground = ForegroundDetector.getInstance().isWasInBackground(reset); | |
if (reset) { | |
ForegroundDetector.getInstance().resetBackgroundVar(); | |
} | |
return UserConfig.passcodeHash.length() > 0 && wasInBackground && | |
(UserConfig.appLocked || UserConfig.autoLockIn != 0 && UserConfig.lastPauseTime != 0 && !UserConfig.appLocked && (UserConfig.lastPauseTime + UserConfig.autoLockIn) <= ConnectionsManager.getInstance().getCurrentTime()); | |
} | |
public static void shakeView(final View view, final float x, final int num) { | |
if (num == 6) { | |
view.setTranslationX(0); | |
return; | |
} | |
AnimatorSet animatorSet = new AnimatorSet(); | |
animatorSet.playTogether(ObjectAnimator.ofFloat(view, "translationX", AndroidUtilities.dp(x))); | |
animatorSet.setDuration(50); | |
animatorSet.addListener(new AnimatorListenerAdapterProxy() { | |
@Override | |
public void onAnimationEnd(Animator animation) { | |
shakeView(view, num == 5 ? 0 : -x, num + 1); | |
} | |
}); | |
animatorSet.start(); | |
} | |
/*public static String ellipsize(String text, int maxLines, int maxWidth, TextPaint paint) { | |
if (text == null || paint == null) { | |
return null; | |
} | |
int count; | |
int offset = 0; | |
StringBuilder result = null; | |
TextView | |
for (int a = 0; a < maxLines; a++) { | |
count = paint.breakText(text, true, maxWidth, null); | |
if (a != maxLines - 1) { | |
if (result == null) { | |
result = new StringBuilder(count * maxLines + 1); | |
} | |
boolean foundSpace = false; | |
for (int c = count - 1; c >= offset; c--) { | |
if (text.charAt(c) == ' ') { | |
foundSpace = true; | |
result.append(text.substring(offset, c - 1)); | |
offset = c - 1; | |
} | |
} | |
if (!foundSpace) { | |
offset = count; | |
} | |
text = text.substring(0, offset); | |
} else if (maxLines == 1) { | |
return text.substring(0, count); | |
} else { | |
result.append(text.substring(0, count)); | |
} | |
} | |
return result.toString(); | |
}*/ | |
/*public static void turnOffHardwareAcceleration(Window window) { | |
if (window == null || Build.MODEL == null) { | |
return; | |
} | |
if (Build.MODEL.contains("GT-S5301") || | |
Build.MODEL.contains("GT-S5303") || | |
Build.MODEL.contains("GT-B5330") || | |
Build.MODEL.contains("GT-S5302") || | |
Build.MODEL.contains("GT-S6012B") || | |
Build.MODEL.contains("MegaFon_SP-AI")) { | |
window.clearFlags(WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED); | |
} | |
}*/ | |
public static void checkForCrashes(Activity context) { | |
CrashManager.register(context, BuildVars.DEBUG_VERSION ? BuildVars.HOCKEY_APP_HASH_DEBUG : BuildVars.HOCKEY_APP_HASH, new CrashManagerListener() { | |
@Override | |
public boolean includeDeviceData() { | |
return true; | |
} | |
}); | |
} | |
public static void checkForUpdates(Activity context) { | |
if (BuildVars.DEBUG_VERSION) { | |
UpdateManager.register(context, BuildVars.DEBUG_VERSION ? BuildVars.HOCKEY_APP_HASH_DEBUG : BuildVars.HOCKEY_APP_HASH); | |
} | |
} | |
public static void unregisterUpdates() { | |
if (BuildVars.DEBUG_VERSION) { | |
UpdateManager.unregister(); | |
} | |
} | |
public static void addToClipboard(CharSequence str) { | |
try { | |
android.content.ClipboardManager clipboard = (android.content.ClipboardManager) ApplicationLoader.applicationContext.getSystemService(Context.CLIPBOARD_SERVICE); | |
android.content.ClipData clip = android.content.ClipData.newPlainText("label", str); | |
clipboard.setPrimaryClip(clip); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
public static void addMediaToGallery(String fromPath) { | |
if (fromPath == null) { | |
return; | |
} | |
File f = new File(fromPath); | |
Uri contentUri = Uri.fromFile(f); | |
addMediaToGallery(contentUri); | |
} | |
public static void addMediaToGallery(Uri uri) { | |
if (uri == null) { | |
return; | |
} | |
try { | |
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); | |
mediaScanIntent.setData(uri); | |
ApplicationLoader.applicationContext.sendBroadcast(mediaScanIntent); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
} | |
private static File getAlbumDir() { | |
if (Build.VERSION.SDK_INT >= 23 && ApplicationLoader.applicationContext.checkSelfPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { | |
return FileLoader.getInstance().getDirectory(FileLoader.MEDIA_DIR_CACHE); | |
} | |
File storageDir = null; | |
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) { | |
storageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Telegram"); | |
if (!storageDir.mkdirs()) { | |
if (!storageDir.exists()){ | |
FileLog.d("tmessages", "failed to create directory"); | |
return null; | |
} | |
} | |
} else { | |
FileLog.d("tmessages", "External storage is not mounted READ/WRITE."); | |
} | |
return storageDir; | |
} | |
@SuppressLint("NewApi") | |
public static String getPath(final Uri uri) { | |
try { | |
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT; | |
if (isKitKat && DocumentsContract.isDocumentUri(ApplicationLoader.applicationContext, uri)) { | |
if (isExternalStorageDocument(uri)) { | |
final String docId = DocumentsContract.getDocumentId(uri); | |
final String[] split = docId.split(":"); | |
final String type = split[0]; | |
if ("primary".equalsIgnoreCase(type)) { | |
return Environment.getExternalStorageDirectory() + "/" + split[1]; | |
} | |
} else if (isDownloadsDocument(uri)) { | |
final String id = DocumentsContract.getDocumentId(uri); | |
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); | |
return getDataColumn(ApplicationLoader.applicationContext, contentUri, null, null); | |
} else if (isMediaDocument(uri)) { | |
final String docId = DocumentsContract.getDocumentId(uri); | |
final String[] split = docId.split(":"); | |
final String type = split[0]; | |
Uri contentUri = null; | |
switch (type) { | |
case "image": | |
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; | |
break; | |
case "video": | |
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; | |
break; | |
case "audio": | |
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; | |
break; | |
} | |
final String selection = "_id=?"; | |
final String[] selectionArgs = new String[] { | |
split[1] | |
}; | |
return getDataColumn(ApplicationLoader.applicationContext, contentUri, selection, selectionArgs); | |
} | |
} else if ("content".equalsIgnoreCase(uri.getScheme())) { | |
return getDataColumn(ApplicationLoader.applicationContext, uri, null, null); | |
} else if ("file".equalsIgnoreCase(uri.getScheme())) { | |
return uri.getPath(); | |
} | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
return null; | |
} | |
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { | |
Cursor cursor = null; | |
final String column = "_data"; | |
final String[] projection = { | |
column | |
}; | |
try { | |
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); | |
if (cursor != null && cursor.moveToFirst()) { | |
final int column_index = cursor.getColumnIndexOrThrow(column); | |
String value = cursor.getString(column_index); | |
if (value.startsWith("content://") || !value.startsWith("/") && !value.startsWith("file://")) { | |
return null; | |
} | |
return value; | |
} | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} finally { | |
if (cursor != null) { | |
cursor.close(); | |
} | |
} | |
return null; | |
} | |
public static boolean isExternalStorageDocument(Uri uri) { | |
return "com.android.externalstorage.documents".equals(uri.getAuthority()); | |
} | |
public static boolean isDownloadsDocument(Uri uri) { | |
return "com.android.providers.downloads.documents".equals(uri.getAuthority()); | |
} | |
public static boolean isMediaDocument(Uri uri) { | |
return "com.android.providers.media.documents".equals(uri.getAuthority()); | |
} | |
public static File generatePicturePath() { | |
try { | |
File storageDir = getAlbumDir(); | |
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); | |
return new File(storageDir, "IMG_" + timeStamp + ".jpg"); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
return null; | |
} | |
public static CharSequence generateSearchName(String name, String name2, String q) { | |
if (name == null && name2 == null) { | |
return ""; | |
} | |
SpannableStringBuilder builder = new SpannableStringBuilder(); | |
String wholeString = name; | |
if (wholeString == null || wholeString.length() == 0) { | |
wholeString = name2; | |
} else if (name2 != null && name2.length() != 0) { | |
wholeString += " " + name2; | |
} | |
wholeString = wholeString.trim(); | |
String lower = " " + wholeString.toLowerCase(); | |
int index; | |
int lastIndex = 0; | |
while ((index = lower.indexOf(" " + q, lastIndex)) != -1) { | |
int idx = index - (index == 0 ? 0 : 1); | |
int end = q.length() + (index == 0 ? 0 : 1) + idx; | |
if (lastIndex != 0 && lastIndex != idx + 1) { | |
builder.append(wholeString.substring(lastIndex, idx)); | |
} else if (lastIndex == 0 && idx != 0) { | |
builder.append(wholeString.substring(0, idx)); | |
} | |
String query = wholeString.substring(idx, end); | |
if (query.startsWith(" ")) { | |
builder.append(" "); | |
} | |
query = query.trim(); | |
builder.append(AndroidUtilities.replaceTags("<c#ff4d83b3>" + query + "</c>")); | |
lastIndex = end; | |
} | |
if (lastIndex != -1 && lastIndex != wholeString.length()) { | |
builder.append(wholeString.substring(lastIndex, wholeString.length())); | |
} | |
return builder; | |
} | |
public static File generateVideoPath() { | |
try { | |
File storageDir = getAlbumDir(); | |
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date()); | |
return new File(storageDir, "VID_" + timeStamp + ".mp4"); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
return null; | |
} | |
public static String formatFileSize(long size) { | |
if (size < 1024) { | |
return String.format("%d B", size); | |
} else if (size < 1024 * 1024) { | |
return String.format("%.1f KB", size / 1024.0f); | |
} else if (size < 1024 * 1024 * 1024) { | |
return String.format("%.1f MB", size / 1024.0f / 1024.0f); | |
} else { | |
return String.format("%.1f GB", size / 1024.0f / 1024.0f / 1024.0f); | |
} | |
} | |
public static byte[] decodeQuotedPrintable(final byte[] bytes) { | |
if (bytes == null) { | |
return null; | |
} | |
final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); | |
for (int i = 0; i < bytes.length; i++) { | |
final int b = bytes[i]; | |
if (b == '=') { | |
try { | |
final int u = Character.digit((char) bytes[++i], 16); | |
final int l = Character.digit((char) bytes[++i], 16); | |
buffer.write((char) ((u << 4) + l)); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
return null; | |
} | |
} else { | |
buffer.write(b); | |
} | |
} | |
byte[] array = buffer.toByteArray(); | |
try { | |
buffer.close(); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
} | |
return array; | |
} | |
public static boolean copyFile(InputStream sourceFile, File destFile) throws IOException { | |
OutputStream out = new FileOutputStream(destFile); | |
byte[] buf = new byte[4096]; | |
int len; | |
while ((len = sourceFile.read(buf)) > 0) { | |
Thread.yield(); | |
out.write(buf, 0, len); | |
} | |
out.close(); | |
return true; | |
} | |
public static boolean copyFile(File sourceFile, File destFile) throws IOException { | |
if (!destFile.exists()) { | |
destFile.createNewFile(); | |
} | |
FileInputStream source = null; | |
FileOutputStream destination = null; | |
try { | |
source = new FileInputStream(sourceFile); | |
destination = new FileOutputStream(destFile); | |
destination.getChannel().transferFrom(source.getChannel(), 0, source.getChannel().size()); | |
} catch (Exception e) { | |
FileLog.e("tmessages", e); | |
return false; | |
} finally { | |
if (source != null) { | |
source.close(); | |
} | |
if (destination != null) { | |
destination.close(); | |
} | |
} | |
return true; | |
} | |
public static byte[] calcAuthKeyHash(byte[] auth_key) { | |
byte[] sha1 = Utilities.computeSHA1(auth_key); | |
byte[] key_hash = new byte[16]; | |
System.arraycopy(sha1, 0, key_hash, 0, 16); | |
return key_hash; | |
} | |
public static void openForView(MessageObject message, Activity activity) throws Exception { | |
File f = null; | |
String fileName = message.getFileName(); | |
if (message.messageOwner.attachPath != null && message.messageOwner.attachPath.length() != 0) { | |
f = new File(message.messageOwner.attachPath); | |
} | |
if (f == null || !f.exists()) { | |
f = FileLoader.getPathToMessage(message.messageOwner); | |
} | |
if (f != null && f.exists()) { | |
String realMimeType = null; | |
Intent intent = new Intent(Intent.ACTION_VIEW); | |
MimeTypeMap myMime = MimeTypeMap.getSingleton(); | |
int idx = fileName.lastIndexOf('.'); | |
if (idx != -1) { | |
String ext = fileName.substring(idx + 1); | |
realMimeType = myMime.getMimeTypeFromExtension(ext.toLowerCase()); | |
if (realMimeType == null) { | |
if (message.type == 9 || message.type == 0) { | |
realMimeType = message.getDocument().mime_type; | |
} | |
if (realMimeType == null || realMimeType.length() == 0) { | |
realMimeType = null; | |
} | |
} | |
if (realMimeType != null) { | |
intent.setDataAndType(Uri.fromFile(f), realMimeType); | |
} else { | |
intent.setDataAndType(Uri.fromFile(f), "text/plain"); | |
} | |
} else { | |
intent.setDataAndType(Uri.fromFile(f), "text/plain"); | |
} | |
if (realMimeType != null) { | |
try { | |
activity.startActivityForResult(intent, 500); | |
} catch (Exception e) { | |
intent.setDataAndType(Uri.fromFile(f), "text/plain"); | |
activity.startActivityForResult(intent, 500); | |
} | |
} else { | |
activity.startActivityForResult(intent, 500); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment