Java tutorial
/* * The MIT License (MIT) * Copyright (c) 2014 longkai * The software shall be used for good, not evil. */ package org.catnut.util; import android.content.ClipData; import android.content.ClipboardManager; import android.content.ContentValues; import android.content.Context; import android.content.CursorLoader; import android.content.Intent; import android.content.SharedPreferences; import android.database.Cursor; import android.graphics.PorterDuff; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Environment; import android.provider.BaseColumns; import android.text.Spannable; import android.text.SpannableString; import android.text.TextUtils; import android.text.style.ImageSpan; import android.text.style.URLSpan; import android.text.util.Linkify; import android.util.DisplayMetrics; import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import org.catnut.R; import org.catnut.core.CatnutApp; import org.catnut.fragment.PluginsPrefFragment; import org.catnut.service.UpgradeService; import org.catnut.support.TweetImageSpan; import org.catnut.support.TweetTextView; import org.catnut.support.TweetURLSpan; import org.json.JSONArray; import org.json.JSONException; import java.io.ByteArrayOutputStream; import java.io.Closeable; import java.io.File; import java.io.IOException; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import static org.catnut.support.TweetTextView.MENTION_FILTER; import static org.catnut.support.TweetTextView.MENTION_PATTERN; import static org.catnut.support.TweetTextView.MENTION_SCHEME; import static org.catnut.support.TweetTextView.TOPIC_FILTER; import static org.catnut.support.TweetTextView.TOPIC_PATTERN; import static org.catnut.support.TweetTextView.TOPIC_SCHEME; import static org.catnut.support.TweetTextView.URL_FILTER; import static org.catnut.support.TweetTextView.WEB_URL; /** * * * @author longkai */ public class CatnutUtils { private static final String TAG = "CatnutUtils"; /** * cursorboolean? * * @param cursor * @param columnName * @return x == 1 ? true : false */ public static boolean getBoolean(Cursor cursor, String columnName) { return cursor.getInt(cursor.getColumnIndex(columnName)) == 1 ? true : false; } /** * int?0?int * * @param real * @param defaultValue * @return int */ public static int optValue(int real, int defaultValue) { return real == 0 ? defaultValue : real; } /** * long?0?long * * @param real * @param defaultValue * @return long */ public static long optValue(long real, long defaultValue) { return real == 0L ? defaultValue : real; } /** * String?null? * * @param real * @param defaultValue * @return String */ public static String optValue(String real, String defaultValue) { return TextUtils.isEmpty(real) ? defaultValue : real; } /** * float?0.0f?float * * @param real * @param defaultValue * @return float */ public static float optValue(float real, float defaultValue) { return real == 0.0F ? defaultValue : real; } /** * double?0.0D?double * * @param real * @param defaultValue * @return double */ public static double optValue(double real, double defaultValue) { return real == 0.0D ? defaultValue : real; } /** * boolean?false?boolean * * @param real * @param defaultValue * @return boolean */ public static boolean optValue(boolean real, boolean defaultValue) { return !real ? defaultValue : real; } /** * ???1234->1.2k34567->3.5w * <p/> * ?0null?w * * @param number * @return ? */ public static String approximate(int number) { if (number == 0) { return null; } if (number < 1000) { return String.valueOf(number); } else if (number < 10000) { float f = number * 1f / 1000; return String.valueOf(Math.round(f * 10) / 10.0) + "k"; } else { float f = number * 1f / 10000; return String.valueOf(Math.round(f * 10) / 10.0) + "w"; } } /** * ?float * * @param num * @param bit ? * @return the you required */ public static float scaleNumber(float num, int bit) { int range = 10 * bit; return (float) Math.round(num * range) / range; } /** * ?view?textviewtext * * @param parent * @param textViewId textviewid * @param text * @return that textview */ public static TextView setText(View parent, int textViewId, CharSequence text) { TextView textView = (TextView) parent.findViewById(textViewId); textView.setText(text); return textView; } /** * raw sql?cursor?havinggroup * * @param context * @param uri * @param projection * @param selection * @param selectionArgs * @param from * @param joinOn * @param sort * @param limit * @return {@link android.content.CursorLoader} */ public static CursorLoader getCursorLoader(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String from, String joinOn, String sort, String limit) { String sql = buildQuery(projection, selection, from, joinOn, sort, limit); return new CursorLoader(context, uri, null, sql, selectionArgs, null); } /** * androidsql???joinonraw-query * * @param projection * @param selection * @param from * @param joinOn joinon(right, full not support) * @param sort * @param limit * @return query sql */ public static String buildQuery(String[] projection, String selection, String from, String joinOn, String sort, String limit) { StringBuilder query = new StringBuilder("SELECT"); if (projection == null) { query.append(" * "); } else { query.append(" ").append(projection(projection)); } query.append(" FROM ").append(from); if (joinOn != null) { // joinjoinon query.append(" ").append(joinOn); } if (selection != null) { query.append(" WHERE ").append(selection); } if (sort != null) { query.append(" ORDER BY ").append(sort); } if (limit != null) { query.append(" LIMIT ").append(limit); } return query.toString(); } /** * ??? */ public static String quote(String string) { return "'" + string + "'"; } /** * sql * * @param projection * @return turn a string[] into xx,xxx,xxx,...,xx */ private static String projection(String[] projection) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < projection.length; i++) { sb.append(projection[i]); if (i != projection.length - 1) { sb.append(","); } } return sb.toString(); } /** * sql */ public static String update(ContentValues values, String from, String where) { StringBuilder sb = new StringBuilder("UPDATE ").append(from).append(" SET"); for (String key : values.keySet()) { sb.append(" ").append(key).append("=").append(reflectString(values.get(key))).append(","); } sb.deleteCharAt(sb.length() - 1); // remove the last ',' if (where != null) { sb.append(" WHERE ").append(where); } return sb.toString(); } /** * ???_id=?? * * @param increment * @param table * @param column * @param _id * @return update sql */ public static String increment(boolean increment, String table, String column, long _id) { return new StringBuilder("UPDATE ").append(table).append(" ").append(" SET ").append(column).append("=") .append(column).append(increment ? "+1" : "-1").append(" WHERE ").append(BaseColumns._ID) .append("=").append(_id).toString(); } private static String reflectString(Object object) { if (object instanceof CharSequence) { return quote(object.toString()); } else { // number return object.toString(); } } /** * simple wrap the keywords with '%xx%' * * @param keywords * @return '%keywords%' */ public static String like(String keywords) { return "'%" + keywords + "%'"; } /** * ??##@ * * @param text ? * @param imageSpan ??null */ public static void vividTweet(TweetTextView text, TweetImageSpan imageSpan) { if (imageSpan != null) { text.setText(imageSpan.getImageSpan(text.getText())); } Linkify.addLinks(text, MENTION_PATTERN, MENTION_SCHEME, null, MENTION_FILTER); Linkify.addLinks(text, TOPIC_PATTERN, TOPIC_SCHEME, null, TOPIC_FILTER); Linkify.addLinks(text, WEB_URL, null, null, URL_FILTER); removeLinkUnderline(text); } /** * textview * * @param textView */ public static void removeLinkUnderline(TextView textView) { Spannable s = Spannable.Factory.getInstance().newSpannable(textView.getText()); URLSpan[] spans = s.getSpans(0, s.length(), URLSpan.class); for (URLSpan span : spans) { int start = s.getSpanStart(span); int end = s.getSpanEnd(span); s.removeSpan(span); span = new TweetURLSpan(span.getURL()); s.setSpan(span, start, end, 0); } textView.setText(s); } /** * list pref?string arrayso * * @param pref * @param key * @param defaultValue * @return key exists ? existed value : defaultValue */ public static int resolveListPrefInt(SharedPreferences pref, String key, int defaultValue) { String value = pref.getString(key, null); if (value == null) { return defaultValue; } return Integer.parseInt(value); } /** * ?edit text?? */ public static boolean hasLength(EditText editText) { // text never null! String str = editText.getText().toString(); if (!TextUtils.isEmpty(str)) { return str.trim().length() > 0; } else { return false; } } /** * ? * * @param boundPx the icon' s rectangle bound, if zero, use the default */ public static SpannableString text2Emotion(Context context, String key, int boundPx) { SpannableString spannable = new SpannableString(key); InputStream inputStream = null; Drawable drawable = null; try { inputStream = context.getAssets().open(TweetImageSpan.EMOTIONS_DIR + TweetImageSpan.EMOTIONS.get(key)); drawable = Drawable.createFromStream(inputStream, null); } catch (IOException e) { Log.e(TAG, "load emotion error!", e); } finally { closeIO(inputStream); } if (drawable != null) { if (boundPx == 0) { drawable.setBounds(0, 0, drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight()); } else { drawable.setBounds(0, 0, boundPx, boundPx); } ImageSpan span = new ImageSpan(drawable, ImageSpan.ALIGN_BASELINE); spannable.setSpan(span, 0, key.length(), Spannable.SPAN_INCLUSIVE_EXCLUSIVE); } return spannable; } /** * get byte[] from input stream * * @param inputStream * @return byte[] * @throws IOException */ public static byte[] getBytes(InputStream inputStream) throws IOException { ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream(); int bufferSize = 2048 * 10; // 2m byte[] buffer = new byte[bufferSize]; int len; while ((len = inputStream.read(buffer)) != -1) { byteBuffer.write(buffer, 0, len); } return byteBuffer.toByteArray(); } public static Uri createImageFile() { // Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); File image; try { image = File.createTempFile(imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ ); } catch (IOException e) { Log.d(TAG, "create tmp file error!", e); return null; } return Uri.fromFile(image); } // ?? public static void checkout(boolean required, Context context, SharedPreferences preferences) { long now = System.currentTimeMillis(); String key = context.getString(R.string.pref_check_upgrade); if (required) { context.startService(new Intent(context, UpgradeService.class)); preferences.edit().putLong(key, now).commit(); } else { long last = preferences.getLong(key, now); if (now - last > (7 * 24 * 60 * 60 * 1000)) { // ? Log.d(TAG, "need upgrade..."); preferences.edit().putLong(key, now).commit(); context.startService(new Intent(context, UpgradeService.class)); } } } /** * ????? * * @param pref * @param key * @param defaultTypeface * @return ??null */ public static Typeface getTypeface(SharedPreferences pref, String key, String defaultTypeface) { Typeface typeface = null; String fontPath = pref.getString(key, null); if (fontPath == null || fontPath.equals(defaultTypeface)) { return null; } else { try { typeface = Typeface.createFromFile(new File(fontPath)); } catch (Exception e) { } } return typeface; } /** * helper method to check whether the typeface is null or not. * * @param textView * @param typeface */ public static void setTypeface(TextView textView, Typeface typeface) { if (typeface != null) { textView.setTypeface(typeface); } } /** * ? * * @param preferences * @param key * @param defaultValue */ public static float getLineSpacing(SharedPreferences preferences, String key, String defaultValue) { return Float.parseFloat(preferences.getString(key, defaultValue)); } public static String mkdir(Context context, String location) throws Exception { // ???sk?... File dir = new File(context.getExternalCacheDir().getPath() + File.separator + location); if (!dir.exists() && !dir.mkdirs()) { throw new RuntimeException(context.getString(R.string.cannot_create_dir)); } return dir.getPath(); } // io public static void closeIO(Closeable... closeables) { for (Closeable closeable : closeables) { if (closeable != null) { try { closeable.close(); } catch (IOException e) { // no-op } } } } /** * copy plain text to clip board * * @param context * @param tag * @param text * @param toastText may null, no toast at all */ public static void copy2ClipBoard(Context context, String tag, String text, String toastText) { ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText(tag, text); clipboard.setPrimaryClip(clip); if (toastText != null) { Toast.makeText(context, toastText, Toast.LENGTH_SHORT).show(); } } /** * ? * * @return plug' s id, or null */ public static ArrayList<Integer> enabledPlugins() { ArrayList<Integer> ids = new ArrayList<Integer>(); if (CatnutApp.getBoolean(R.string.pref_enable_zhihu, R.bool.default_plugin_status)) { ids.add(PluginsPrefFragment.ZHIHU); } if (CatnutApp.getBoolean(R.string.pref_enable_fantasy, R.bool.pref_enable_fantasy)) { ids.add(PluginsPrefFragment.FANTASY); } return ids.size() == 0 ? null : ids; } public static int getScreenWidth(Context context) { DisplayMetrics metrics = context.getResources().getDisplayMetrics(); return metrics.widthPixels; } /** * inject a image touch overley * @param v * @param event */ public static boolean imageOverlay(View v, MotionEvent event) { ImageView view = (ImageView) v; switch (event.getAction()) { case MotionEvent.ACTION_DOWN: // overlay is black with transparency of 0x77 (119) view.getDrawable().setColorFilter(0x77000000, PorterDuff.Mode.SRC_ATOP); view.invalidate(); break; case MotionEvent.ACTION_UP: case MotionEvent.ACTION_CANCEL: { // clear the overlay view.getDrawable().clearColorFilter(); view.invalidate(); break; } } return false; } /** * if pics.len > 1, return the json, or null * @param json * @return */ public static JSONArray optPics(String json) { if (!TextUtils.isEmpty(json)) { try { JSONArray jsonArray = new JSONArray(json); return optPics(jsonArray); } catch (JSONException e) { Log.wtf(TAG, "cannot serialize pics json array!", e); return null; } } return null; } /** * if pics.len > 1, return the json, or null * @param jsonArray * @return */ public static JSONArray optPics(JSONArray jsonArray) { return jsonArray == null ? null : jsonArray.length() > 1 ? jsonArray : null; } }