android工具类总结
2016-07-25 15:25
519 查看
1.获取渠道
public class Channels { private static final String CHANNEL = "META-INF/channel"; private static String channel = ""; public static String getChannel() { return getChannel(BDApplication.getApplication()); } public static String getChannel(Context context) { if (TextUtils.isEmpty(channel)) { channel = getChannelInner(context); } Log.i("niejianjian", "Channels -> channel = " + channel + "VersionName = " + BuildConfig.VERSION_NAME); return channel; } public static String getChannelInner(Context context) { ApplicationInfo appInfo = context.getApplicationInfo(); String sourceDir = appInfo.sourceDir; String ret = ""; ZipFile zipfile = null; try { zipfile = new ZipFile(sourceDir); Enumeration<?> entries = zipfile.entries(); while (entries.hasMoreElements()) { ZipEntry entry = ((ZipEntry) entries.nextElement()); String entryName = entry.getName(); if (entryName.startsWith(CHANNEL)) { ret = entryName; break; } } } catch (IOException e) { e.printStackTrace(); } finally { if (zipfile != null) { try { zipfile.close(); } catch (IOException e) { e.printStackTrace(); } } } String[] split = ret.split("_"); if (split.length >= 2) { return split[1]; } else { return "test"; } } }
2.时间格式化
public class BDDateFormat { /** * 格式化日期 */ public static CharSequence formatDate(long time) { return DateFormat.format("yyyy-MM-dd", time); } public static CharSequence formatTime(long time) { return DateFormat.format("yyyy-MM-dd HH:mm:ss", time); } public static CharSequence formatTimeWithoutYearField(long timeStamp) { return DateFormat.format("MM月dd日 HH:mm:ss", timeStamp); } public static CharSequence formatTimeWithoutYearField2(long timeStamp) { return DateFormat.format("MM月dd日 HH:mm:ss", timeStamp); } public static CharSequence formatTimeWithoutYearSecondField(long timeStamp) { return DateFormat.format("MM月dd日 HH:mm", timeStamp); } public static CharSequence formatTimeWithoutYearSecondField1(long timeStamp) { return DateFormat.format("yyyyMMddHH", timeStamp); } }
3.MD5加密
public class EncryAndDecry { private static final String Encoding = "UTF-8"; /** * 取得按照指定编码方式编码字符串的byte数组的Md5原始数组 * * @param strOrigin 原始字符串 * @param encodings 字符串使用的编码方式 */ public static byte[] getMd5Origin(String strOrigin, String... encodings) { String encoding = Encoding; if (TextUtils.isEmpty(strOrigin)) { return null; } if (encodings != null && encodings.length > 0) { encoding = encodings[0]; } MessageDigest msgDigest = null; try { msgDigest = MessageDigest.getInstance("MD5"); // 注意改接口是按照指定编码形式签名 msgDigest.update(strOrigin.getBytes(encoding)); } catch (Exception e) { Log.e(EncryAndDecry.class.getName(), "不能生成指定的MD5值!", e); return null; } return msgDigest.digest(); } /** * 取得按照指定编码方式编码字符串的byte数组的Md5数组 支付宝是采用该方法进行Md5串的获取 * * @param strOrigin 原始字符串 * @param originStrings 字符串采用的编码方式 */ public static String getMd5String(String strOrigin, String... originStrings) { byte[] orgin = getMd5Origin(strOrigin, originStrings); return encodeHex(orgin); } /** * 将一个byte数组变化为对应的16进制字符串。 */ public static String encodeHex(byte[] data) { /** * Used building output as Hex */ final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; int l = data.length; char[] out = new char[l << 1]; // two characters form the hex value. for (int i = 0, j = 0; i < l; i++) { out[j++] = DIGITS[(0xF0 & data[i]) >>> 4]; out[j++] = DIGITS[0x0F & data[i]]; } return new String(out); } }
4.设备ID
import android.provider.Settings; import android.text.TextUtils; import com.os.aucauc.application.BDApplication; import com.os.soft.rad.utils.SharedPreferencesUtils; import java.io.UnsupportedEncodingException; import java.util.UUID; public class DeviceId { private static final String DEVICE_ID = "device_id"; private static String uuid = ""; public static String getDeviceId() { if (TextUtils.isEmpty(uuid)) { final String savedUUID = SharedPreferencesUtils.getPreference(DEVICE_ID, ""); if (!TextUtils.isEmpty(savedUUID)) { uuid = savedUUID; return uuid; } final String androidId = Settings.Secure.getString(BDApplication.getApplication().getContentResolver(), Settings.Secure.ANDROID_ID); try { uuid = UUID.nameUUIDFromBytes(androidId.getBytes("utf8")).toString(); SharedPreferencesUtils.savePreference(DEVICE_ID, uuid); } catch (UnsupportedEncodingException e) { throw new AssertionError(e); } } return uuid; } }
5.带有样式的文本,基于SpannableString的封装
import android.content.Context; import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.support.annotation.ColorRes; import android.support.annotation.DrawableRes; import android.support.annotation.NonNull; import android.text.SpannableString; import android.text.SpannableStringBuilder; import android.text.TextPaint; import android.text.style.CharacterStyle; import android.text.style.ClickableSpan; import android.text.style.ForegroundColorSpan; import android.text.style.ImageSpan; import android.text.style.RelativeSizeSpan; import android.text.style.StrikethroughSpan; import android.text.style.StyleSpan; import android.text.style.UnderlineSpan; import android.view.View; import java.util.Arrays; public final class Font extends SpannableString { public static Font compose(@NonNull CharSequence... fonts) { return compose(Arrays.asList(fonts)); } private static Font compose(Iterable<? extends CharSequence> fontIterable) { final SpannableStringBuilder builder = new SpannableStringBuilder(); for (CharSequence font : fontIterable) { builder.append(SpannableString.valueOf(font)); } return Font.valueOf(builder); } public static Font valueOf(CharSequence source) { if (source instanceof Font) { return (Font) source; } else { return new Font(source); } } public Font(@NonNull CharSequence content) { super(content); } /** * 设置颜色 */ public Font color(Context context, @ColorRes int res) { applySpan(new ForegroundColorSpan(context.getResources().getColor(res))); return this; } /** * 粗体 */ public Font bold() { applySpan(new StyleSpan(Typeface.BOLD)); return this; } /** * 粗 斜体 */ public Font boldItalic() { applySpan(new StyleSpan(Typeface.BOLD_ITALIC)); return this; } /** * 斜体 */ public Font italic() { applySpan(new StyleSpan(Typeface.ITALIC)); return this; } /** * 设置颜色 */ public Font color(int color) { applySpan(new ForegroundColorSpan(color)); return this; } public Font image(Drawable drawable) { applySpan(new ImageSpan(drawable)); return this; } public Font image(Context context, @DrawableRes int resId) { applySpan(new ImageSpan(context, resId)); return this; } /** * 设置相对大小 */ public Font relativeSize(float size) { applySpan(new RelativeSizeSpan(size)); return this; } public Font strikethrough() { applySpan(new StrikethroughSpan()); return this; } public Font underline() { applySpan(new UnderlineSpan()); return this; } /** * 可点击的 */ public Font clickableWithUnderline(final View.OnClickListener onClickListener, final int linkColor) { applySpan(new ClickableSpan() { @Override public void onClick(View widget) { onClickListener.onClick(widget); } @Override public void updateDrawState(TextPaint ds) { ds.setColor(linkColor); ds.setUnderlineText(true); } }); return this; } /** * 可点击的 */ public Font clickable(final View.OnClickListener onClickListener) { applySpan(new ClickableSpan() { @Override public void onClick(View widget) { onClickListener.onClick(widget); } }); return this; } private void applySpan(CharacterStyle style) { setSpan(style, 0, length(), SPAN_EXCLUSIVE_EXCLUSIVE); } }
6.价格、金钱、格式化
import java.math.BigDecimal; import java.math.RoundingMode; import java.text.NumberFormat; public class MoneyFormatter { private static NumberFormat getFormatWithoutSign() { final NumberFormat format = NumberFormat.getNumberInstance(); format.setRoundingMode(RoundingMode.FLOOR); return format; } /** * 格式化显示钱数 * * @return 输入 12312 输出 12,312 */ public static String formatMoney(int money) { return getFormatWithoutSign().format(money); } /** * 格式化显示钱数 * * @return 输入 324444.234 输出 324,444 */ public static String formatMoney(double money) { return getFormatWithoutSign().format(money); } /** * 格式化显示钱数 * * @return 输入 324444.234 输出 324,444 */ public static String formatMoney(BigDecimal money) { return getFormatWithoutSign().format(money); } /** * 格式化需要显示小数的钱数 * * @param money 123123.234234234234 * @return 123, 123.23 */ public static String formatDecimalMoney(double money) { final NumberFormat format = NumberFormat.getNumberInstance(); format.setMaximumFractionDigits(2); format.setRoundingMode(RoundingMode.FLOOR); return format.format(money); } }
7.资源获取
import android.content.Context; import android.graphics.drawable.Drawable; import android.support.annotation.ColorRes; import android.support.annotation.DimenRes; import android.support.annotation.DrawableRes; import android.support.annotation.StringRes; import com.os.aucauc.application.BDApplication; public class Resources { public static Drawable drawable(@DrawableRes int res) { return getContext().getResources().getDrawable(res); } public static int dimenInPx(@DimenRes int res) { return getContext().getResources().getDimensionPixelSize(res); } public static String string(@StringRes int resId) { return getContext().getResources().getString(resId); } public static float dimen(@DimenRes int res) { return getContext().getResources().getDimension(res); } public static int color(@ColorRes int res){ return getContext().getResources().getColor(res); } private static Context getContext(){ return BDApplication.getApplication(); } }
8.全局设置字体
package com.example.jian.myapplication; import android.app.Activity; import android.app.Dialog; import android.content.Context; import android.graphics.Typeface; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; /** * Created by jian on 2016/9/18. */ public class FontUtil { private static Typeface sTypeface; public static final String FONTS_DIR = "fonts/"; public static final String DEF_FONT = FONTS_DIR + "PingFangMedium.ttf"; /*在application加载的时候,初始化,缓存Typeface对象,因为在文件中加载是要耗时的*/ public static void initFont(Context context) { getCustomTypeface(context); } public static Typeface getCustomTypeface(Context context) { if (sTypeface == null) { sTypeface = Typeface.createFromAsset(context.getAssets(), DEF_FONT); } return sTypeface; // changeFont(rootView, Typeface.createFromAsset(rootView.getContext().getAssets(), DEF_FONT)); } public static void changeFont(View rootView) { final Typeface typeface = getCustomTypeface(rootView.getContext()); if (typeface == null) return; if (rootView instanceof ViewGroup) { ViewGroup group = (ViewGroup) rootView; int count = group.getChildCount(); for (int i = 0; i < count; i++) { changeFont(group.getChildAt(i)); } } else if (rootView instanceof TextView) { ((TextView) rootView).setTypeface(typeface); } } public static void changeFont(Activity activity) { changeFont(activity.findViewById(android.R.id.content)); } public static void changeFont(Dialog dialog) { changeFont(dialog.findViewById(android.R.id.content)); } }
9.单位转换工具类(px,sp,dp)
package com.example.jian.myapplication.util; import android.content.Context; import android.util.TypedValue; /** * Created by jian on 2016/9/27. * dp、sp转换成px的工具类 */ public class DisplayUtil { /** * 将px值转换成dip或者dp,保证尺寸大小不变 * * @param context * @param pxValue (DisplayMetrics类中属性density) * @return */ public static int px2dip(Context context, float pxValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (pxValue / scale + 0.5f); } /** * 将dip或者dp转换成px值,保证尺寸大小不变 * * @param context * @param dipValue (DisplayMetrics类中属性density) * @return */ public static int dip2px(Context context, float dipValue) { final float scale = context.getResources().getDisplayMetrics().density; return (int) (dipValue * scale + 0.5f); } /** * 将px值转换成sp值,保证文字大小不变 * * @param context * @param pxValue * @return */ public static int px2sp(Context context, float pxValue) { final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; return (int) (pxValue / fontScale + 0.5f); } /** * 将sp值转换成px值,保证文字大小不变 * * @param context * @param spValue * @return */ public static int sp2px(Context context, float spValue) { final float fontScale = context.getResources().getDisplayMetrics().scaledDensity; return (int) (spValue * fontScale + 0.5f); } /** * dp2px */ protected int dp2px(Context context, int dp) { return (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP, dp, context.getResources().getDisplayMetrics()); } /** * sp2px */ protected int sp2px(Context context, int sp) { return (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_SP, sp, context.getResources().getDisplayMetrics()); } }
10.事件监听器Barrier
package com.example.jian.myapplication.util; import android.support.annotation.NonNull; import java.util.HashMap; import java.util.Map; /** * 回调同步工具类 全部条件达到 会触发action * Created by jian on 2016/10/13. */ public class Barrier { private volatile boolean hasFinished = false; Runnable mAction; private final Map<String, Boolean> mConditions = new HashMap<>(); public Barrier(Runnable action, @NonNull String[] conditions) { mAction = action; // 将所有的条件遍历出来,当作key,保存到map,value为false,表示未完成条件 for (String condition : conditions) { mConditions.put(condition, false); } } /** * 某个条件满足的回调 * 全部条件满足时会调用 action */ public void onConditionSatisfied(String condition) { synchronized (this) { if (hasFinished) return; // 将满足条件的value置成true mConditions.put(condition, true); // 如果所有条件的value都没有false,说明都完成了,就可以再执行了 if (!mConditions.values().contains(false)) { hasFinished = true; mAction.run(); } } } }使用
public class MainActivity extends Activity { private Barrier mBarrier; private Handler mHandler; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_topbar); mHandler = new Handler(); mBarrier = new Barrier(new Runnable() { @Override public void run() { Log.i("niejianjian", " -> finish ->"); } }, new String[]{"a", "b", "c"}); mHandler.postDelayed(new Runnable() { @Override public void run() { mBarrier.onConditionSatisfied("a"); } }, 2000); mHandler.postDelayed(new Runnable() { @Override public void run() { mBarrier.onConditionSatisfied("b"); } }, 5000); } }
11.dimens.xml生成工具类
package lanyue.reader;import android.os.Environment;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import java.io.File;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
/**
* Created by niejianjian on 2017/12/4.
*/
public class DimensUtil {
/**
* 生成需要的dimens.xml文件
*
* @param length 需要生成的dimen最大数值,一般指定屏幕宽高的最大值即可
* @param density 指定屏幕密度,根据px和density来计算需要的dp值,或者sp值
* @param targetFile 目标存储文件
*/
public static void createDeimensXml(int length, float density, File targetFile) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.newDocument();
Element resources = document.createElement("resources");
for (int i = 1; i <= length; i++) {
Element dimen = document.createElement("dimen");
float f = (float) i / density;
BigDecimal b = new BigDecimal(f);
float dpValue = b.setScale(2, BigDecimal.ROUND_HALF_UP).floatValue();
dimen.setAttribute("name", "dimen_" + i + "px");
dimen.setTextContent(dpValue + "dp");
resources.appendChild(dimen);
}
for (int i = 1; i <= 100; i++) {
Element dimen = document.createElement("dimen");
float f = (float) i / density;
DecimalFormat fnum = new DecimalFormat("##0.00");
String dpValue = fnum.format(f);
dimen.setAttribute("name", "tvSize_" + i + "px");
dimen.setTextContent(dpValue + "sp");
resources.appendChild(dimen);
}
document.appendChild(resources);
// 创建TransformerFactory对象
TransformerFactory tff = TransformerFactory.newInstance();
// 创建Transformer对象
Transformer tf = tff.newTransformer();
// 设置输出数据时换行
tf.setOutputProperty(OutputKeys.INDENT, "yes");
File file;
if (targetFile == null) {
file = new File(Environment.getExternalStorageDirectory() + File.separator + "dimens.xml");
} else {
file = targetFile;
}
if (!file.exists()) file.delete();
// 使用Transformer的transform()方法将DOM树转换成XML
tf.transform(new DOMSource(document), new StreamResult(file));
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}
}
一般调用方法,直接传入设备的屏幕宽高和密度值即可。
DisplayMetrics metrics = getResources().getDisplayMetrics();
int length = metrics.widthPixels >= metrics.heightPixels ? metrics.widthPixels : metrics.heightPixels;
DimensUtil.createDeimensXml(length, metrics.density, null);
结果保留两位小数。dimens.xml的部分内容如下:
<dimen name="dimen_1902px">634.0dp</dimen> <dimen name="dimen_1903px">634.33dp</dimen> <dimen name="dimen_1904px">634.67dp</dimen> <dimen name="dimen_1905px">635.0dp</dimen> <dimen name="dimen_1906px">635.33dp</dimen> <dimen name="dimen_1907px">635.67dp</dimen> <dimen name="dimen_1908px">636.0dp</dimen> <dimen name="dimen_1909px">636.33dp</dimen> <dimen name="dimen_1910px">636.67dp</dimen> <dimen name="dimen_1911px">637.0dp</dimen> <dimen name="dimen_1912px">637.33dp</dimen> <dimen name="dimen_1913px">637.67dp</dimen> <dimen name="dimen_1914px">638.0dp</dimen> <dimen name="dimen_1915px">638.33dp</dimen> <dimen name="dimen_1916px">638.67dp</dimen> <dimen name="dimen_1917px">639.0dp</dimen> <dimen name="dimen_1918px">639.33dp</dimen> <dimen name="dimen_1919px">639.67dp</dimen> <dimen name="dimen_1920px">640.0dp</dimen> <dimen name="tvSize_1px">0.33sp</dimen> <dimen name="tvSize_2px">0.67sp</dimen> <dimen name="tvSize_3px">1.00sp</dimen> <dimen name="tvSize_4px">1.33sp</dimen> <dimen name="tvSize_5px">1.67sp</dimen> <dimen name="tvSize_6px">2.00sp</dimen> <dimen name="tvSize_7px">2.33sp</dimen> <dimen name="tvSize_8px">2.67sp</dimen> <dimen name="tvSize_9px">3.00sp</dimen> <dimen name="tvSize_10px">3.33sp</dimen>
相关文章推荐
- Android Studio实现代码混淆
- Android ListView简单使用
- Android Studio 调试过程中快捷查看断点处变量值(Ctrl+Shift+I无效)?
- Android静态安全检测 -> Hash算法不安全
- Android中onInterceptTouchEvent与onTouchEvent(图文)
- [Android]自动格式化识别银行卡的EditText
- Android个性导航栏效果
- 【Android之实践】adb命令:操作sqlite表
- $ANDROID_HOME is not defined.
- Android 使用Vitamio打造自己的万能播放器(6)――在线播放(播放列表)
- android SQLite疑点分析
- 部分安卓机型 页面无法跳转
- Android 高仿QQ 好友分组列表
- Android中两个控件滑动效果冲突的解决办法
- Android RecyclerView 使用完全解析 体验艺术般的控件
- 【Android】图像压缩 (在GridView等中使用缩略图提高响应速度)
- Android SDK更新下载失败以及Studio首次安装取消自动下载SDK
- 项目所需自己写了个带上拉刷新和加载更多的listview
- 强烈推荐android studio用的几个插件
- Android实现签到日历控件