说在前面,以下工具类可以大大的提高安卓开发者的开发效率
1、偏好设置(ShareUtils)
import android.content.Context;
import android.content.SharedPreferences;
/**
* Content:偏好设置工具类
* Actor:韩小呆 ヾ(✿゚▽゚)ノ
* Time: 15:44
*/
public class ShareUtils {
public static final String NAME = "config.hxd";
/**
* 存入数据(String)
*/
public static void putString(Context context, String key, String value) {
//获得偏好设置
SharedPreferences spf = context.getSharedPreferences(NAME, Context.MODE_PRIVATE);
//向偏好设置内部添加数据并且提交
spf.edit().putString(key, value).apply();
}
/**
* 取数据(上下文,钥匙,未取得数据返回的默认值)(String)
*/
public static String getString(Context context, String key, String value) {
//获得偏好设置
SharedPreferences spf = context.getSharedPreferences(NAME, Context.MODE_PRIVATE);
//返回需要取得的数据
return spf.getString(key, value);
}
/**
* 存入数据(Int)
*/
public static void putInt(Context context, String key, int value) {
//获得偏好设置
SharedPreferences spf = context.getSharedPreferences(NAME, Context.MODE_PRIVATE);
//向偏好设置内部添加数据并且提交
spf.edit().putInt(key, value).apply();
}
/**
* 取数据(上下文,钥匙,未取得数据返回的默认值)(Int)
*/
public static int getInt(Context context, String key, int value) {
//获得偏好设置
SharedPreferences spf = context.getSharedPreferences(NAME, Context.MODE_PRIVATE);
//返回需要取得的数据
return spf.getInt(key, value);
}
/**
* 存入数据(Int)
*/
public static void putBoolean(Context context, String key, boolean value) {
//获得偏好设置
SharedPreferences spf = context.getSharedPreferences(NAME, Context.MODE_PRIVATE);
//向偏好设置内部添加数据并且提交
spf.edit().putBoolean(key, value).apply();
}
/**
* 取数据(上下文,钥匙,未取得数据返回的默认值)(Int)
*/
public static boolean getBoolean(Context context, String key, boolean value) {
//获得偏好设置
SharedPreferences spf = context.getSharedPreferences(NAME, Context.MODE_PRIVATE);
//返回需要取得的数据
return spf.getBoolean(key, value);
}
/**
* 删除单个偏好设置
*/
public static void deleteShare(Context context, String key) {
//获得偏好设置
SharedPreferences spf = context.getSharedPreferences(NAME, Context.MODE_PRIVATE);
spf.edit().remove(key).apply();
}
/**
* 删除所有偏好设置
*/
public static void deleteShareAll(Context context, String key) {
//获得偏好设置
SharedPreferences spf = context.getSharedPreferences(NAME, Context.MODE_PRIVATE);
spf.edit().clear().apply();
}
}
鸿神的偏好设置工具类
具体地址为:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import android.content.Context;
import android.content.SharedPreferences;
public class SPUtils
{
/**
* 保存在手机里面的文件名
*/
public static final String FILE_NAME = "share_data";
/**
* 保存数据的方法,我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
*
* @param context
* @param key
* @param object
*/
public static void put(Context context, String key, Object object)
{
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if (object instanceof String)
{
editor.putString(key, (String) object);
} else if (object instanceof Integer)
{
editor.putInt(key, (Integer) object);
} else if (object instanceof Boolean)
{
editor.putBoolean(key, (Boolean) object);
} else if (object instanceof Float)
{
editor.putFloat(key, (Float) object);
} else if (object instanceof Long)
{
editor.putLong(key, (Long) object);
} else
{
editor.putString(key, object.toString());
}
SharedPreferencesCompat.apply(editor);
}
/**
* 得到保存数据的方法,我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
*
* @param context
* @param key
* @param defaultObject
* @return
*/
public static Object get(Context context, String key, Object defaultObject)
{
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
if (defaultObject instanceof String)
{
return sp.getString(key, (String) defaultObject);
} else if (defaultObject instanceof Integer)
{
return sp.getInt(key, (Integer) defaultObject);
} else if (defaultObject instanceof Boolean)
{
return sp.getBoolean(key, (Boolean) defaultObject);
} else if (defaultObject instanceof Float)
{
return sp.getFloat(key, (Float) defaultObject);
} else if (defaultObject instanceof Long)
{
return sp.getLong(key, (Long) defaultObject);
}
return null;
}
/**
* 移除某个key值已经对应的值
* @param context
* @param key
*/
public static void remove(Context context, String key)
{
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
SharedPreferencesCompat.apply(editor);
}
/**
* 清除所有数据
* @param context
*/
public static void clear(Context context)
{
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.clear();
SharedPreferencesCompat.apply(editor);
}
/**
* 查询某个key是否已经存在
* @param context
* @param key
* @return
*/
public static boolean contains(Context context, String key)
{
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
return sp.contains(key);
}
/**
* 返回所有的键值对
*
* @param context
* @return
*/
public static Map<String, ?> getAll(Context context)
{
SharedPreferences sp = context.getSharedPreferences(FILE_NAME,
Context.MODE_PRIVATE);
return sp.getAll();
}
/**
* 创建一个解决SharedPreferencesCompat.apply方法的一个兼容类
*
* @author zhy
*
*/
private static class SharedPreferencesCompat
{
private static final Method sApplyMethod = findApplyMethod();
/**
* 反射查找apply的方法
*
* @return
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
private static Method findApplyMethod()
{
try
{
Class clz = SharedPreferences.Editor.class;
return clz.getMethod("apply");
} catch (NoSuchMethodException e)
{
}
return null;
}
/**
* 如果找到则使用apply执行,否则使用commit
*
* @param editor
*/
public static void apply(SharedPreferences.Editor editor)
{
try
{
if (sApplyMethod != null)
{
sApplyMethod.invoke(editor);
return;
}
} catch (IllegalArgumentException e)
{
} catch (IllegalAccessException e)
{
} catch (InvocationTargetException e)
{
}
editor.commit();
}
}
}
2、单位转换和屏幕尺寸获取工具类
import android.app.Activity;
import android.content.Context;
import android.util.DisplayMetrics;
/**
* Content:单位转换和屏幕尺寸获取工具类
* Actor:韩小呆 ヾ(✿゚▽゚)ノ
* Time: 15:44
*/
public class DensityUtil {
/**
* 将px值转换为 dip或dp值,保证尺寸大小不变
*
* @param pxValue 像素值
* @param context Context 对象
* @return dp值
*/
public static int px2dip(float pxValue, Context context) {
float scale = getDensity(context);
return (int) (pxValue / scale + 0.5f);
}
/**
* 将dip或dp值转换为px值,保证尺寸大小不变
*
* @param dipValue dip数值
* @param context Context 对象
* @return 像素值
*/
public static int dip2px(float dipValue, Context context) {
float scale = getDensity(context);
return (int) (dipValue * scale + 0.5f);
}
/**
* 将px值转换为sp值,保证文字大小不变
*
* @param pxValue 像素值
* @param context Context 对象
* @return 返回sp数值
*/
public static int px2sp(float pxValue, Context context) {
float scale = getDensity(context);
return (int) (pxValue / scale + 0.5f);
}
/**
* 将sp值转换为px值,保证文字大小不变
*
* @param spValue sp数值
* @param context Context 对象
* @return 返回像素值
*/
public static int sp2px(float spValue, Context context) {
float scale = getDensity(context);
return (int) (spValue * scale + 0.5f);
}
/**
* 取得手机屏幕的密度
*
* @param context 上下文
* @return 手机屏幕的密度
*/
public static float getDensity(Context context) {
float scale = context.getResources().getDisplayMetrics().density;
return scale;
}
/**
* 获取屏幕高
* @param activity
* @return 手机屏幕的高度
*/
public static int getScreenHeight(Activity activity) {
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
return dm.heightPixels;
}
/**
* 获取屏幕宽
* @param activity
* @return 手机屏幕的宽度
*/
public static int getScreenWidth(Activity activity) {
DisplayMetrics dm = new DisplayMetrics();
activity.getWindowManager().getDefaultDisplay().getMetrics(dm);
return dm.widthPixels;
}
}
3、时间转换工具类
import android.annotation.SuppressLint;
import android.text.format.Time;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Content:时间转换工具类
* Actor:韩小呆 ヾ(✿゚▽゚)ノ
* Time: 15:44
*/
public class DateUtils {
/**
* 获取当前时间
*
* @return 年月日时分秒字符串
*/
public static String getCurrentTime() {
Time time = new Time("GMT+8");
time.setToNow();
String year = "" + time.year;
int imonth = time.month + 1;
String month = imonth > 9 ? "" + imonth : "0" + imonth;
String day = time.monthDay > 9 ? "" + time.monthDay : "0"
+ time.monthDay;
String hour = (time.hour + 8) > 9 ? "" + (time.hour + 8) : "0"
+ (time.hour + 8);
String minute = time.minute > 9 ? "" + time.minute : "0" + time.minute;
String sec = time.second > 9 ? "" + time.second : "0" + time.second;
String currentTime = year + month + day + hour + minute + sec;
return currentTime;
}
//获取 日期/时/分/秒
@SuppressLint("SimpleDateFormat")
public static String getDateTime(long time) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = sdf.format(new Date(time));
return date;
}
//获取 日期/时/分
@SuppressLint("SimpleDateFormat")
public static String getHourMinute(long time) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日HH时mm分");
String date = sdf.format(new Date(time));
return date;
}
//获取 日期年月日
@SuppressLint("SimpleDateFormat")
public static String getYearMonthDay(long time) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
String date = sdf.format(new Date(time));
return date;
}
//获取日期年月
public static String getYearMonth(long time){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月");
String date = sdf.format(new Date(time));
return date;
}
//获取日期年月
public static String getYearMonth2(long time){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM");
String date = sdf.format(new Date(time));
return date;
}
//获取日期年
public static String getYear(long time){
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年");
String date = sdf.format(new Date(time));
return date;
}
//获取 时/分
public static String getTime(long time) {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
String date = sdf.format(new Date(time));
return date;
}
}
4、验证码倒计时及重新发送验证码的工具类
import android.os.CountDownTimer;
import android.widget.Button;
/**
* Content:验证码倒计时及重新发送验证码的工具类
* Actor:韩小呆 ヾ(✿゚▽゚)ノ
* Time: 15:44
*/
public class MyCountDownTimer extends CountDownTimer {
private Button mBtn;
private int mEnable;
private int mDisable;
/**
* @param millisInFuture The number of millis in the future from the call
* to {@link #start()} until the countdown is done and {@link #onFinish()}
* is called.
* @param countDownInterval The interval along the way to receive
* {@link #onTick(long)} callbacks.
*/
public MyCountDownTimer(long millisInFuture, long countDownInterval, Button btn, int enable, int disable) {
super(millisInFuture, countDownInterval);
mBtn = btn;
mEnable = enable;
mDisable = disable;
}
//计时过程
@Override
public void onTick(long l) {
//防止计时过程中重复点击
mBtn.setClickable(false);
mBtn.setText(l / 1000 + "s");
//设置按钮背景色
mBtn.setBackgroundResource(mDisable);
}
//计时完毕的方法
@Override
public void onFinish() {
//重新给Button设置文字
mBtn.setText("重新获取验证码");
//设置可点击
mBtn.setClickable(true);
//设置按钮背景色
mBtn.setBackgroundResource(mEnable);
}
}
6、进度Dialog工具类
import android.app.ProgressDialog;
import android.content.Context;
/**
* Content:进度Dialog工具类
* Actor:韩小呆 ヾ(✿゚▽゚)ノ
* Time: 15:44
*/
public class ProgressDlgUtil {
private static ProgressDialog progressDlg = null;
/**
* 启动进度条
* @param ctx 当前的activity
* @param content 进度条显示的信息
*/
public static void show(Context ctx, String content) {
if (null == progressDlg) {
progressDlg = new ProgressDialog(ctx);
progressDlg.setProgressStyle(ProgressDialog.STYLE_SPINNER);// 设置进度条的形式为圆形转动的进度条
//progressDlg.setTitle("提示");//设置进度条标题
progressDlg.setMessage(content);//提示的消息
progressDlg.setIndeterminate(false);
progressDlg.setCancelable(false);
//progressDlg.setIcon(R.drawable.ic_launcher_scale);
progressDlg.show();
}
}
/**
* 结束进度条
*/
public static void dismiss() {
if (null != progressDlg) {
progressDlg.dismiss();
progressDlg = null;
}
}
}
7、吐司工具类
import android.annotation.SuppressLint;
import android.content.Context;
import android.widget.Toast;
/**
* Content:ToastUtils
* Actor:韩小呆 ヾ(✿゚▽゚)ノ
* Time: 2018/5/17 17:37
*/
public class ToastUtils {
private ToastUtils() {
throw new UnsupportedOperationException("禁止实例化");
}
private static boolean isShow = true;
private static Toast toast;
/**
* 短时间显示Toast
*
* @param context 上下文
* @param msg 显示内容
*/
@SuppressLint("ShowToast")
public static void showToast(Context context, String msg) {
if (isShow && toast == null) {
//第一次创建
toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
} else {
//如果toast存在,只修改文字,防止点的次数多一直弹出
toast.setText(msg);
}
toast.show();
}
/**
* 短时间显示Toast
*
* @param context 上下文
* @param msgResID 显示内容
*/
@SuppressLint("ShowToast")
public static void showToast(Context context, int msgResID) {
if (isShow && toast == null) {
toast = Toast.makeText(context, msgResID, Toast.LENGTH_SHORT);
} else {
toast.setText(msgResID);
}
toast.show();
}
/**
* 长时间显示Toast
*
* @param context 上下文
* @param message 显示内容
*/
@SuppressLint("ShowToast")
public static void showLong(Context context, CharSequence message) {
if (isShow && toast == null) {
toast = Toast.makeText(context, message, Toast.LENGTH_LONG);
} else {
toast.setText(message);
}
toast.show();
}
/**
* 长时间显示Toast
*
* @param context 上下文
* @param message 显示内容
*/
@SuppressLint("ShowToast")
public static void showLong(Context context, int message) {
if (isShow && toast == null) {
toast = Toast.makeText(context, message, Toast.LENGTH_LONG);
} else {
toast.setText(message);
}
toast.show();
}
/**
* 自定义显示Toast时间
*
* @param context 上下文
* @param message 显示内容
* @param duration 显示时间
*/
public static void show(Context context, CharSequence message, int duration) {
if (isShow) Toast.makeText(context, message, duration).show();
}
/**
* 自定义显示Toast时间
*
* @param context 上下文
* @param message 显示内容
* @param duration 显示时间
*/
public static void show(Context context, int message, int duration) {
if (isShow) Toast.makeText(context, message, duration).show();
}
8、软键盘操作工具类
mport android.content.Context;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
/**
* Content:打开关闭软键盘
* Actor:韩小呆 ヾ(✿゚▽゚)ノ
* Time: 2018/5/17 17:37
*/
public class KeyBoardUtils {
/**
* 打卡软键盘
*
* @param mEditText 输入框
* @param mContext 上下文
*/
public static void openKeyBord(EditText mEditText, Context mContext) {
InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
assert imm != null;
imm.showSoftInput(mEditText, InputMethodManager.RESULT_SHOWN);
imm.toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
}
/**
* 关闭软键盘
*
* @param mEditText 输入框
* @param mContext 上下文
*/
public static void closeKeyBord(Context mContext , EditText mEditText ) {
InputMethodManager imm = (InputMethodManager) mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
assert imm != null;
imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
}
/**
* 判断软键盘是否弹出
*
* @param context 上下文
* @param v 控件
* @return 是否关闭
*/
public static boolean isSHowKeyboard(Context context, View v) {
InputMethodManager imm = (InputMethodManager) context.getSystemService(Context.INPUT_METHOD_SERVICE);
assert imm != null;
if (imm.hideSoftInputFromWindow(v.getWindowToken(), 0)) {
imm.showSoftInput(v, 0);
return true;
//软键盘已弹出
} else {
return false;
//软键盘未弹出
}
}
}
9、网络相关工具类
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
/**
* Content:网络相关判断操作
* Actor:鸿神
* Time:2018/3/30
*/
public class NetUtils {
private NetUtils() {
throw new UnsupportedOperationException("cannot be instantiated");
}
/**
* 判断网络是否连接
*
* @param context
* @return
*/
public static boolean isConnected(Context context) {
ConnectivityManager connectivity = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (null != connectivity) {
NetworkInfo info = connectivity.getActiveNetworkInfo();
if (null != info && info.isConnected()) {
if (info.getState() == NetworkInfo.State.CONNECTED) {
return true;
}
}
}
return false;
}
/**
* 判断是否是wifi连接
*/
public static boolean isWifi(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context
.CONNECTIVITY_SERVICE);
if (cm == null) {
return cm.getActiveNetworkInfo().getType() == ConnectivityManager.TYPE_WIFI;
}
return false;
}
/**
* 打开网络设置界面
*/
public static void openSetting(Activity activity) {
Intent intent = new Intent("/");
ComponentName cm = new ComponentName("com.android.settings",
"com.android.settings.WirelessSettings");
intent.setComponent(cm);
intent.setAction("android.intent.action.VIEW");
activity.startActivityForResult(intent, 0);
}
}
10、dp、px、sp之间的转换工具类
import android.content.Context;
import android.util.DisplayMetrics;
/**
* Used 尺寸转换工具类(全)
*/
public class DensityUtil {
public static float RATIO = 0.95F;//缩放比例值
/**
* px 转 dp【按照一定的比例】*/
public static int px2dipRatio(Context context, float pxValue) {
float scale = getScreenDendity(context) * RATIO;
return (int)((pxValue / scale) + 0.5f);
}
/**
* dp转px【按照一定的比例】*/
public static int dip2pxRatio(Context context, float dpValue) {
float scale = getScreenDendity(context) * RATIO;
return (int)((dpValue * scale) + 0.5f);
}
/**
* px 转 dp
* 48px - 16dp
* 50px - 17dp*/
public static int px2dip(Context context, float pxValue) {
float scale = getScreenDendity(context);
return (int)((pxValue / scale) + 0.5f);
}
/**
* dp转px
* 16dp - 48px
* 17dp - 51px*/
public static int dip2px(Context context, float dpValue) {
float scale = getScreenDendity(context);
return (int)((dpValue * scale) + 0.5f);
}
/**获取屏幕的宽度(像素)*/
public static int getScreenWidth(Context context) {
return context.getResources().getDisplayMetrics().widthPixels;//1080
}
/**获取屏幕的宽度(dp)*/
public static int getScreenWidthDp(Context context) {
float scale = getScreenDendity(context);
return (int)(context.getResources().getDisplayMetrics().widthPixels / scale);//360
}
/**获取屏幕的高度(像素)*/
public static int getScreenHeight(Context context) {
return context.getResources().getDisplayMetrics().heightPixels;//1776
}
/**获取屏幕的高度(像素)*/
public static int getScreenHeightDp(Context context) {
float scale = getScreenDendity(context);
return (int)(context.getResources().getDisplayMetrics().heightPixels / scale);//592
}
/**屏幕密度比例*/
public static float getScreenDendity(Context context){
return context.getResources().getDisplayMetrics().density;//3
}
/**获取状态栏的高度 72px
* http://www.2cto.com/kf/201501/374049.html*/
public static int getStatusBarHeight(Context context) {
int statusHeight = -1;
try {
Class<?> aClass = Class.forName("com.android.internal.R$dimen");
Object object = aClass.newInstance();
int height = Integer.parseInt(aClass.getField("status_bar_height").get(object).toString());
statusHeight = context.getResources().getDimensionPixelSize(height);
} catch (Exception e) {
e.printStackTrace();
}
return statusHeight;
//依赖于WMS(窗口管理服务的回调)【不建议使用】
/*Rect outRect = new Rect();
((Activity)context).getWindow().getDecorView().getWindowVisibleDisplayFrame(outRect);
return outRect.top;*/
}
/**
* 指定机型(displayMetrics.xdpi)下dp转px
* 18dp - 50px*/
public static int dpToPx(Context context, int dp) {
return Math.round(((float)dp * getPixelScaleFactor(context)));
}
/**
* 指定机型(displayMetrics.xdpi)下px 转 dp
* 50px - 18dp*/
public static int pxToDp(Context context, int px) {
return Math.round(((float)px / getPixelScaleFactor(context)));
}
/**获取水平方向的dpi的密度比例值
* 2.7653186*/
public static float getPixelScaleFactor(Context context) {
DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
return (displayMetrics.xdpi / 160.0f);
}
}
11、自用Log工具类
import android.util.Log;
/**
* Content:
* Actor:韩小呆 ヾ(✿゚▽゚)ノ
* Time: 2018/6/29 9:31
* Update:
* Time: 2018/6/29 9:31
*/
public class LogUtils {
private static final String TAG = "HXD";
private static final int LOG_LEVEL_VERBOSE = 0;
private static final int LOG_LEVEL_DEBUG = 1;
private static final int LOG_LEVEL_INFO = 2;
private static final int LOG_LEVEL_WARN = 3;
private static final int LOG_LEVEL_ERROR = 4;
private static int outputLevel = LOG_LEVEL_VERBOSE;
private LogUtils() {
super();
}
/**
* 控制原生Log是否打印
* level>4 则不打印原生 日志,反之则打印原生日志
*
* @param level 控制标志位
*/
public static void setOutputLevel(int level) {
outputLevel = level;
}
public static void v(String tag, String msg) {
if (outputLevel <= LOG_LEVEL_VERBOSE) {
Log.v(tag, msg);
}
}
public static void v(String msg) {
v(TAG, msg);
}
public static void d(String tag, String msg) {
if (outputLevel <= LOG_LEVEL_DEBUG) {
Log.d(tag, msg);
}
}
public static void d(String msg) {
d(TAG, msg);
}
public static void i(String tag, String msg) {
if (outputLevel <= LOG_LEVEL_INFO) {
Log.i(tag, msg);
}
}
public static void i(String msg) {
i(TAG, msg);
}
public static void w(String tag, String msg) {
if (outputLevel <= LOG_LEVEL_WARN) {
Log.w(tag, msg);
}
}
public static void w(String msg) {
w(TAG, msg);
}
public static void e(String tag, String msg) {
if (outputLevel <= LOG_LEVEL_ERROR) {
Log.e(tag, msg);
}
}
public static void e(String msg) {
e(TAG, msg);
}
}
12、文字变色工具类
import android.content.Context;
import android.graphics.Color;
import android.text.Spannable;
import android.text.SpannableStringBuilder;
import android.text.style.ForegroundColorSpan;
import android.widget.TextView;
/**
* Content: 一段文字多种颜色
* Actor:韩小呆 ヾ(✿゚▽゚)ノ
* Time: 2018/7/23 17:34
* Update:
* Time:
*/
public class TextColorChangeUtils {
/***
*通过Resources内的颜色实现文字变色龙
*
* @param context 上下文
* @param textView 文字变色控件
* @param textColor 文字固有颜色
* @param startColor 开始半段文字color
* @param endColor 结束半段 文字color
* @param startStart 前半段开始变色文字下标
* @param startEnd 前半段结束变色文字下标
* @param endStart 后半段开始变色文字下标
* @param endEnd 后半段结束变色文字下标
* @param text 变色的文字内容
* @return 返回变色结果
*/
public static TextView interTextColorForResources(Context context, TextView textView, int textColor, int startColor,
int endColor, int startStart, int startEnd, int endStart, int endEnd, String text) {
textView.setTextColor(context.getResources().getColor(textColor));
SpannableStringBuilder style = new SpannableStringBuilder(text);
style.setSpan(new ForegroundColorSpan(context.getResources().getColor(startColor)), startStart, startEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
style.setSpan(new ForegroundColorSpan(context.getResources().getColor(endColor)), endStart, endEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
textView.setText(style);
return textView;
}
/**
* 通过 ParseColor 的形式实现变色
*
* @param textView 文字变色控件
* @param textColor 文字固有颜色
* @param startColor 开始半段文字color
* @param endColor 结束半段文字color
* @param startStart 前半段开始变色文字下标
* @param startEnd 后半段开始变色文字下标
* @param endStart 后半段结束变色文字下标
* @param endEnd 后半段结束变色文字下标
* @param text 变色的文字内容
* @return 返回变色结果
*/
public static TextView interTextColorForParseColor(TextView textView, String textColor, String startColor, String endColor, int startStart, int startEnd, int endStart, int endEnd, String text) {
textView.setTextColor(Color.parseColor(textColor));
SpannableStringBuilder style = new SpannableStringBuilder(text);
style.setSpan(new ForegroundColorSpan(Color.parseColor(startColor)), startStart, startEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
style.setSpan(new ForegroundColorSpan(Color.parseColor(endColor)), endStart, endEnd, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
return textView;
}
}
使用例子
tvHiddenNum = TextColorChangeUtils.interTextColorForResources(this, tvHiddenNum, R.color.colorRed,
R.color.colorBlue, R.color.colorYellow, 0, 2, num.length() - 1, num.length(), num);
使用结果:
13、调用相册获取图片路径
import android.annotation.SuppressLint;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
/**
* Content:从相册内获取照片转化工具类
* Actor:韩小呆 ヾ(✿゚▽゚)ノ
* Time: 2018/08/18 18:54
* Update:
* Time:
*/
public class getPhotoFromPhotoAlbum {
/**
* 根据Uri获取图片的绝对路径
*
* @param context 上下文对象
* @param uri 图片的Uri
* @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
*/
public static String getRealPathFromUri(Context context, Uri uri) {
int sdkVersion = Build.VERSION.SDK_INT;
if (sdkVersion >= 19) {
return getRealPathFromUriAboveApi19(context, uri);
} else {
return getRealPathFromUriBelowAPI19(context, uri);
}
}
/**
* 适配api19以下(不包括api19),根据uri获取图片的绝对路径
*
* @param context 上下文对象
* @param uri 图片的Uri
* @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
*/
private static String getRealPathFromUriBelowAPI19(Context context, Uri uri) {
return getDataColumn(context, uri, null, null);
}
/**
* 适配api19及以上,根据uri获取图片的绝对路径
*
* @param context 上下文对象
* @param uri 图片的Uri
* @return 如果Uri对应的图片存在, 那么返回该图片的绝对路径, 否则返回null
*/
@SuppressLint("NewApi")
private static String getRealPathFromUriAboveApi19(Context context, Uri uri) {
String filePath = null;
if (DocumentsContract.isDocumentUri(context, uri)) {
// 如果是document类型的 uri, 则通过document id来进行处理
String documentId = DocumentsContract.getDocumentId(uri);
if (isMediaDocument(uri)) {
// 使用':'分割
String id = documentId.split(":")[1];
String selection = MediaStore.Images.Media._ID + "=?";
String[] selectionArgs = {id};
filePath = getDataColumn(context, MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection, selectionArgs);
} else if (isDownloadsDocument(uri)) {
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(documentId));
filePath = getDataColumn(context, contentUri, null, null);
}
} else if ("content".equalsIgnoreCase(uri.getScheme())) {
// 如果是 content 类型的 Uri
filePath = getDataColumn(context, uri, null, null);
} else if ("file".equals(uri.getScheme())) {
// 如果是 file 类型的 Uri,直接获取图片对应的路径
filePath = uri.getPath();
}
return filePath;
}
/**
* 获取数据库表中的 _data 列,即返回Uri对应的文件路径
*
*/
private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
String path = null;
String[] projection = new String[]{MediaStore.Images.Media.DATA};
Cursor cursor = null;
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
int columnIndex = cursor.getColumnIndexOrThrow(projection[0]);
path = cursor.getString(columnIndex);
}
} catch (Exception e) {
if (cursor != null) {
cursor.close();
}
}
return path;
}
/**
* @param uri the Uri to check
* @return Whether the Uri authority is MediaProvider
*/
private static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
/**
* @param uri the Uri to check
* @return Whether the Uri authority is DownloadsProvider
*/
private static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
}
14、结局部分手机拍照后照片自动旋转问题
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.support.media.ExifInterface;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
/**
* Content:解决部分手机调用系统相机照片旋转问题
* Actor:韩小呆 ヾ(✿゚▽゚)ノ
* Time: 2018/11/01 09:42
* Update:
* Time:
*/
public class RotatingImagesUtils {
/**
* 获得照片的旋转角度
*
* @param path 待旋转照片路径
* @return 旋转角度
*/
public static int readPictureDegree(String path) {
int degree = 0;
try {
ExifInterface exifInterface = new ExifInterface(path);
int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_90:
degree = 90;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
degree = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_270:
degree = 270;
break;
}
} catch (IOException e) {
e.printStackTrace();
}
return degree;
}
/**
* 旋转bitmap
*
* @param bitmap 传入bitmap
* @param rotate 旋转角度
* @return 返回 bitmap
*/
public static Bitmap rotateBitmap(Bitmap bitmap, int rotate) {
if (bitmap == null)
return null;
int w = bitmap.getWidth();
int h = bitmap.getHeight();
Matrix mtx = new Matrix();
mtx.postRotate(rotate);
return Bitmap.createBitmap(bitmap, 0, 0, w, h, mtx, true);
}
/**
* 把bitmap 转file
*
* @param bitmap 需要存储的 bitmap
* @param filepath 图片的路径
*/
public static File saveBitmapFile(Bitmap bitmap, String filepath) {
File file = new File(filepath);//将要保存图片的路径
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos);
bos.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bos != null) {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return file;
}
/**
* 根据 路径 得到 file 得到 bitmap
*
* @param filePath 路径
* @return bitmap
*/
public static Bitmap decodeFile(String filePath) {
Bitmap b = null;
int IMAGE_MAX_SIZE = 600;
File f = new File(filePath);
//Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
FileInputStream fis = null;
try {
fis = new FileInputStream(f);
BitmapFactory.decodeStream(fis, null, o);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
int scale = 1;
if (o.outHeight > IMAGE_MAX_SIZE || o.outWidth > IMAGE_MAX_SIZE) {
scale = (int) Math.pow(2, (int) Math.round(Math.log(IMAGE_MAX_SIZE / (double) Math.max(o.outHeight, o.outWidth)) / Math.log(0.5)));
}
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
try {
fis = new FileInputStream(f);
b = BitmapFactory.decodeStream(fis, null, o2);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return b;
}
}
15、将崩溃日志打印到手机存储内
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import java.io.File;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.lang.reflect.Field;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* 异常处理
*/
public class CrashHandler implements Thread.UncaughtExceptionHandler {
private String TAG = getClass().getSimpleName();
private static CrashHandler sInstance = new CrashHandler();
//系统默认的异常处理(默认情况下,系统会终止当前的异常程序)
private Thread.UncaughtExceptionHandler mDefaultCrashHandler;
private Context mContext;
private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
private Map<String, String> infos = new HashMap<>();
//构造方法私有,防止外部构造多个实例,即采用单例模式
private CrashHandler() {
}
public static CrashHandler getInstance() {
if (sInstance == null)
sInstance = new CrashHandler();
return sInstance;
}
//这里主要完成初始化工作
public void init(Context context) {
mContext = context;
//获取系统默认的异常处理器
save = false;
mDefaultCrashHandler = Thread.getDefaultUncaughtExceptionHandler();
//将当前实例设为系统默认的异常处理器
Thread.setDefaultUncaughtExceptionHandler(this);
}
/**
* 当程序中有未被捕获的异常,系统将会自动调用#uncaughtException方法
* thread为出现未捕获异常的线程,ex为未捕获的异常,有了这个ex,我们就可以得到异常信息。
*/
@Override
public void uncaughtException(Thread thread, Throwable ex) {
//如果系统提供了默认的异常处理器,则交给系统去结束我们的程序,否则就由我们自己结束自己
saveCrashInfo2File(ex);
try {
if (handleException(ex) && mDefaultCrashHandler != null) {
mDefaultCrashHandler.uncaughtException(thread, ex);
} else {
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
}
android.os.Process.killProcess(android.os.Process.myPid());
System.exit(0);
}
}catch (Exception e){
saveCrashInfo2File(e);
}
}
/**
* 自定义错误处理,收集错误信息,发送错误报告等操作均在此完成
*
* @param ex
* @return true:如果处理了该异常信息;否则返回 false
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return false;
}
// 收集设备参数信息
collectDeviceInfo(mContext);
// 保存日志文件
saveCrashInfo2File(ex);
return true;
}
/**
* 收集设备参数信息
*
* @param ctx
*/
public void collectDeviceInfo(Context ctx) {
try {
PackageManager pm = ctx.getPackageManager();
PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(), PackageManager.GET_ACTIVITIES);
if (pi != null) {
String versionName = pi.versionName == null ? "null" : pi.versionName;
String versionCode = pi.versionCode + "";
infos.put("versionName", versionName);
infos.put("versionCode", versionCode);
}
} catch (PackageManager.NameNotFoundException e) {
}
Field[] fields = Build.class.getDeclaredFields();
for (Field field : fields) {
try {
field.setAccessible(true);
infos.put(field.getName(), field.get(null).toString());
} catch (Exception e) {
Log.e("incarmeida", "an error occured when collect crash info", e);
}
}
}
private static boolean save;
/**
* 保存错误信息到文件中 *
*
* @param ex
* @return 返回文件名称, 便于将文件传送到服务器
*/
private String saveCrashInfo2File(Throwable ex) {
if (save) {
return null;
}
save = true;
StringBuffer sb = new StringBuffer();
for (Map.Entry<String, String> entry : infos.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
sb.append(key + "=" + value + "\n");
}
Writer writer = new StringWriter();
PrintWriter printWriter = new PrintWriter(writer);
ex.printStackTrace(printWriter);
Throwable cause = ex.getCause();
while (cause != null) {
cause.printStackTrace(printWriter);
cause = cause.getCause();
}
printWriter.close();
String result = writer.toString();
sb.append(result);
try {
long timestamp = System.currentTimeMillis();
String time = formatter.format(new Date());
String fileName = "error-" + time + "-" + timestamp + ".log";
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String path = Environment.getExternalStorageDirectory().getPath()+"/";
// Toast.makeText(mContext, path, Toast.LENGTH_LONG).show();
File dir = new File(path);
if (!dir.exists()) {
dir.mkdirs();
}
FileOutputStream fos = new FileOutputStream(path + fileName);
fos.write(String.valueOf(sb).getBytes());
fos.flush();
fos.close();
}
return fileName;
} catch (Exception e) {
Log.e(TAG, "saveCrashInfo2File an error occured while writing file... " + e.getMessage());
}
return null;
}
}
使用方式 在Application 内进行初始化
CrashHandler.getInstance().init(this);
16、 Android 获取手机的厂商、型号、Android系统版本号、IMEI、当前系统语言等工具类
import android.app.Activity;
import android.content.Context;
import android.telephony.TelephonyManager;
import java.util.Locale;
/**
* CreateTime: 2019/6/25 10:56
* Author: hxd
* Content:获取手机系统的相关信息
* UpdateTime:
* UpdateName;
* UpdateContent:
*/
public class SystemUtil {
/**
* 获取当前手机系统语言。
*
* @return 返回当前系统语言。例如:当前设置的是“中文-中国”,则返回“zh-CN”
*/
public static String getSystemLanguage() {
return Locale.getDefault().getLanguage();
}
/**
* 获取当前系统上的语言列表(Locale列表)
*
* @return 语言列表
*/
public static Locale[] getSystemLanguageList() {
return Locale.getAvailableLocales();
}
/**
* 获取当前手机系统版本号
*
* @return 系统版本号
*/
public static String getSystemVersion() {
return android.os.Build.VERSION.RELEASE;
}
/**
* 获取手机型号
*
* @return 手机型号
*/
public static String getSystemModel() {
return android.os.Build.MODEL;
}
/**
* 获取手机厂商
*
* @return 手机厂商
*/
public static String getDeviceBrand() {
return android.os.Build.BRAND;
}
/**
* 获取手机IMEI(需要“android.permission.READ_PHONE_STATE”权限)
*
* @return 手机IMEI
*/
public static String getIMEI(Context ctx) {
TelephonyManager tm = (TelephonyManager) ctx.getSystemService(Activity.TELEPHONY_SERVICE);
if (tm != null) {
return tm.getDeviceId();
}
return null;
}
}
17、获取 Android app相关信息的 工具类
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import com.vehicle.MsApplication;
/**
* CreateTime: 2019/6/19 11:32
* Author: hxd
* Content: 和app 的固件相关的工具类
* UpdateTime:
* UpdateName;
* UpdateContent:
*/
public class AppUtils {
/**
* 获取应用程序名称
*/
public static synchronized String getAppName(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(
context.getPackageName(), 0);
int labelRes = packageInfo.applicationInfo.labelRes;
return context.getResources().getString(labelRes);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* [获取应用程序版本名称信息]
*
* @return 当前应用的版本名称
*/
public static synchronized String getVersionName() {
try {
PackageManager packageManager = MsApplication.getInstance().getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(
MsApplication.getInstance().getPackageName(), 0);
return String.valueOf(packageInfo.versionName);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* [获取应用程序版本名称信息]
*
* @return 当前应用的版本名称
*/
public static synchronized int getVersionCode() {
try {
PackageManager packageManager = MsApplication.getInstance().getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(
MsApplication.getInstance().getPackageName(), 0);
return packageInfo.versionCode;
} catch (Exception e) {
e.printStackTrace();
}
return 0;
}
/**
* [获取应用程序版本名称信息]
*
* @param context
* @return 当前应用的版本名称
*/
public static synchronized String getPackageName(Context context) {
try {
PackageManager packageManager = context.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(
context.getPackageName(), 0);
return packageInfo.packageName;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 获取图标 bitmap
*
* @param context
*/
public static synchronized Bitmap getBitmap(Context context) {
PackageManager packageManager = null;
ApplicationInfo applicationInfo = null;
try {
packageManager = context.getApplicationContext()
.getPackageManager();
applicationInfo = packageManager.getApplicationInfo(
context.getPackageName(), 0);
} catch (PackageManager.NameNotFoundException e) {
applicationInfo = null;
}
Drawable d = packageManager.getApplicationIcon(applicationInfo); //xxx根据自己的情况获取drawable
BitmapDrawable bd = (BitmapDrawable) d;
Bitmap bm = bd.getBitmap();
return bm;
}
}
18、打开 第三方地图(百度、高德、腾讯、浏览器) 并且进行导航
package com.ms.online.utils;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import com.baidu.mapapi.model.LatLng;
import java.io.File;
/**
* CreateTime:2019/12/26 11:29
* Author: hxd
* Content: 打开第三方地图或浏览器 并 导航
* UpdateTime:
* UpdateName;
* UpdateContent:
*/
public class NavigationUtils {
private static final String PN_GAODE_MAP = "com.autonavi.minimap";// 高德地图包名
private static final String PN_BAIDU_MAP = "com.baidu.BaiduMap"; // 百度地图包名
private static final String PN_TENCENT_MAP = "com.tencent.map"; // 腾讯地图包名
/**
* 检查地图应用是否安装
*/
public static boolean isGdMapInstalled() {
return isInstallPackage(PN_GAODE_MAP);
}
public static boolean isBaiduMapInstalled() {
return isInstallPackage(PN_BAIDU_MAP);
}
public static boolean isTencentMapInstalled() {
return isInstallPackage(PN_TENCENT_MAP);
}
private static boolean isInstallPackage(String packageName) {
return new File("/data/data/" + packageName).exists();
}
/**
* 百度转高德
*
* @param bd_lat 经度
* @param bd_lon 纬度
*/
public static double[] bdToGaoDe(double bd_lat, double bd_lon) {
double[] gd_lat_lon = new double[2];
double PI = 3.14159265358979324 * 3000.0 / 180.0;
double x = bd_lon - 0.0065, y = bd_lat - 0.006;
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * PI);
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * PI);
gd_lat_lon[0] = z * Math.cos(theta);
gd_lat_lon[1] = z * Math.sin(theta);
return gd_lat_lon;
}
/**
* 高德、腾讯转百度
*
* @param gd_lon 经度
* @param gd_lat 纬度
*/
private static double[] gaoDeToBaidu(double gd_lon, double gd_lat) {
double[] bd_lat_lon = new double[2];
double PI = 3.14159265358979324 * 3000.0 / 180.0;
double x = gd_lon, y = gd_lat;
double z = Math.sqrt(x * x + y * y) + 0.00002 * Math.sin(y * PI);
double theta = Math.atan2(y, x) + 0.000003 * Math.cos(x * PI);
bd_lat_lon[0] = z * Math.cos(theta) + 0.0065;
bd_lat_lon[1] = z * Math.sin(theta) + 0.006;
return bd_lat_lon;
}
/**
* 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
* 即 百度 转 谷歌、高德
*
* @param latLng 经纬度对象
* @return 使用此方法需要下载导入百度地图的BaiduLBS_Android.jar包
*/
public static LatLng BD09ToGCJ02(LatLng latLng) {
double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
double x = latLng.longitude - 0.0065;
double y = latLng.latitude - 0.006;
double z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_pi);
double theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_pi);
double gg_lat = z * Math.sin(theta);
double gg_lng = z * Math.cos(theta);
return new LatLng(gg_lat, gg_lng);
}
/**
* 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
* 即谷歌、高德 转 百度
*
* @param latLng 经纬度对象
* @return 需要百度地图的BaiduLBS_Android.jar包
*/
public static LatLng GCJ02ToBD09(LatLng latLng) {
double x_pi = 3.14159265358979324 * 3000.0 / 180.0;
double z = Math.sqrt(latLng.longitude * latLng.longitude + latLng.latitude * latLng.latitude) + 0.00002 * Math.sin(latLng.latitude * x_pi);
double theta = Math.atan2(latLng.latitude, latLng.longitude) + 0.000003 * Math.cos(latLng.longitude * x_pi);
double bd_lat = z * Math.sin(theta) + 0.006;
double bd_lng = z * Math.cos(theta) + 0.0065;
return new LatLng(bd_lat, bd_lng);
}
/**
* 打开高德地图导航功能
*
* @param context
* @param slat 起点纬度
* @param slon 起点经度
* @param sname 起点名称 可不填(0,0,null)
* @param dlat 终点纬度
* @param dlon 终点经度
* @param dname 终点名称 必填
*/
public static void openGaoDeNavi(Context context, double slat, double slon, String sname, double dlat, double dlon, String dname) {
String uriString;
StringBuilder builder = new StringBuilder("amapuri://route/plan?sourceApplication=maxuslife");
if (slat != 0) {
builder.append("&sname=").append(sname)
.append("&slat=").append(slat)
.append("&slon=").append(slon);
}
builder.append("&dlat=").append(dlat)
.append("&dlon=").append(dlon)
.append("&dname=").append(dname)
.append("&dev=0")
.append("&t=0");
uriString = builder.toString();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setPackage(PN_GAODE_MAP);
intent.setData(Uri.parse(uriString));
context.startActivity(intent);
}
/**
* 打开腾讯地图
* params 参考http://lbs.qq.com/uri_v1/guide-route.html
*
* @param context
* @param slat 起点纬度
* @param slon 起点经度
* @param sname 起点名称 可不填(0,0,null)
* @param dlat 终点纬度
* @param dlon 终点经度
* @param dname 终点名称 必填
* 驾车:type=drive,policy有以下取值
* 0:较快捷
* 1:无高速
* 2:距离
* policy的取值缺省为0
* &from=" + dqAddress + "&fromcoord=" + dqLatitude + "," + dqLongitude + "
*/
public static void openTencentMap(Context context, double slat, double slon, String sname, double dlat, double dlon, String dname) {
String uriString;
StringBuilder builder = new StringBuilder("qqmap://map/routeplan?type=drive&policy=0&referer=zhongshuo");
if (slat != 0) {
builder.append("&from=").append(sname)
.append("&fromcoord=").append(slat)
.append(",")
.append(slon);
}
builder.append("&to=").append(dname)
.append("&tocoord=").append(dlat)
.append(",")
.append(dlon);
uriString = builder.toString();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setPackage(PN_TENCENT_MAP);
intent.setData(Uri.parse(uriString));
context.startActivity(intent);
}
/**
* 打开百度地图导航功能(默认坐标点是高德地图,需要转换)
*
* @param context
* @param slat 起点纬度
* @param slon 起点经度
* @param sname 起点名称 可不填(0,0,null)
* @param dlat 终点纬度
* @param dlon 终点经度
* @param dname 终点名称 必填
*/
public static void openBaiDuNavi(Context context, double slat, double slon, String sname, double dlat, double dlon, String dname) {
String uriString;
//终点坐标转换
// 此方法需要百度地图的BaiduLBS_Android.jar包
// LatLng destination = new LatLng(dlat,dlon);
// LatLng destinationLatLng = GCJ02ToBD09(destination);
// dlat = destinationLatLng.latitude;
// dlon = destinationLatLng.longitude;
double[] destination = gaoDeToBaidu(dlat, dlon);
dlat = destination[0];
dlon = destination[1];
StringBuilder builder = new StringBuilder("baidumap://map/direction?mode=driving&");
if (slat != 0) {
//起点坐标转换
// LatLng origin = new LatLng(slat,slon);
// LatLng originLatLng = GCJ02ToBD09(origin);
// slat = originLatLng.latitude;
// slon = originLatLng.longitude;
double[] origin = gaoDeToBaidu(slat, slon);
slat = origin[0];
slon = origin[1];
builder.append("origin=latlng:")
.append(slat)
.append(",")
.append(slon)
.append("|name:")
.append(sname);
}
builder.append("&destination=latlng:")
.append(dlat)
.append(",")
.append(dlon)
.append("|name:")
.append(dname);
uriString = builder.toString();
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setPackage(PN_BAIDU_MAP);
intent.setData(Uri.parse(uriString));
context.startActivity(intent);
}
/**
* 打开网页版 导航
*
* @param context
* @param myLatLng 起点经纬度
* @param myAddress 起点地址名展示 可以不写
* @param destination 终点经纬度
* @param destinationAddress 终点地址名展示
*/
public static void openBrowserMap(Context context, LatLng myLatLng, String myAddress, LatLng destination,
String destinationAddress) {
Intent intent = new Intent();
intent.setAction("android.intent.action.VIEW");
intent.setData(Uri.parse("http://uri.amap.com/navigation?" +
"from=" + myLatLng.longitude + "," + myLatLng.latitude + "," + myAddress +
"to=" + destination.longitude + "," + destination.latitude + "," + destinationAddress +
"&mode=car&policy=1&src=mypage&coordinate=gaode&callnative=0"));
context.startActivity(intent);
}
}
调用方法
private void toNav() {
LatLng latLng1 = NavigationUtils.BD09ToGCJ02(mLatLng);
LatLng latLng2 = NavigationUtils.BD09ToGCJ02(endLatLng);
//判断是否安装高德
if (!NavigationUtils.isGdMapInstalled()) {
//判断是否安装百度
if (!NavigationUtils.isBaiduMapInstalled()) {
//判断是否安装腾讯
if (!NavigationUtils.isTencentMapInstalled()) {
// ToastUtils.showLong("您未安装任何 导航应用");
if (getActivity() != null)
NavigationUtils.openBrowserMap(getActivity(), mLatLng, null, endLatLng, mStringName);
} else {
NavigationUtils.openTencentMap(getActivity(), latLng1.latitude, latLng1.longitude, null, latLng2.latitude, latLng2.longitude, mStringName);
}
} else {
NavigationUtils.openBaiDuNavi(getActivity(), mLatLng.latitude, mLatLng.longitude, null, endLatLng.latitude, endLatLng.longitude, mStringName);
}
} else {
NavigationUtils.openGaoDeNavi(getActivity(), latLng1.latitude, latLng1.longitude, null, latLng2.latitude, latLng2.longitude, mStringName);
}
}