常用 Android 代码片段

  • 通过一个 String 类型的 imgUrl 获得文件字节数组
            try {
                URL url = new URL(imgUrl);
                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setRequestMethod("GET");
                conn.setReadTimeout(10000);
                if (conn.getResponseCode() == 200) {
                    InputStream in = conn.getInputStream();
                    ByteArrayOutputStream out = new ByteArrayOutputStream();
                    byte[] bytes = new byte[1024];
                    int length = -1;
                    while ((length = in.read(bytes)) != -1) {
                        out.write(bytes, 0, length);
                    }
                    picByte = out.toByteArray();
                    in.close();
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
  • BaseActivity 类文件
public abstract class BaseActivity extends AppCompatActivity implements View.OnClickListener{

    protected Context mContext;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(getLayoutId());

        mContext = this;
        initDataBeforeView();
        initView();
        initData();
        initEvent();
    }
    //必须复写的方法
    protected abstract int getLayoutId();
    protected abstract void initView();
    protected abstract void initData();

    //可选复写的方法
    protected void initDataBeforeView() {
    }
    protected  void initEvent(){
    }
}
  • BaseFragment 类文件
public abstract class BaseFragment extends Fragment{
    protected BaseActivity mActivity;//这里不理解为什么一定要强转成BaseActivity,意义是什么???

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        mActivity = (BaseActivity) this.getActivity();
    }

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(getLyoutId(),container,false);
    }

    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        initView(view);
    }

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        initData(savedInstanceState);
    }

    protected abstract int getLyoutId();

    protected abstract void initView(View view);

    protected abstract void initData(Bundle savedInstanceState);
}
  • 正则表达式工具类
public class RegexUtils {
    /**
     * 匹配全网IP的正则表达式
     */
    public static final String IP_REGEX = "^((?:(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d)))\\.){3}(?:25[0-5]|2[0-4]\\d|((1\\d{2})|([1-9]?\\d))))$";

    /**
     * 匹配手机号码的正则表达式
     * <br>支持130——139、150——153、155——159、180、183、185、186、188、189号段
     */
    public static final String PHONE_NUMBER_REGEX = "^1{1}(3{1}\\d{1}|5{1}[012356789]{1}|8{1}[035689]{1})\\d{8}$";


    /**
     *
     */
//    、((^(13|15|18)[0-9]{9}$)|(^0[1,2]{1}\d{1}-?\d{8}$)|(^0[3-9] {1}\d{2}-?\d{7,8}$)|(^0[1,2]{1}\d{1}-?\d{8}-(\d{1,4})$)|(^0[3-9]{1}\d{2}-? \d{7,8}-(\d{1,4})$))
    public static final String PHONE_NUMBER_FULL = "((^(13|15|18|17)[0-9]{9}$)|(^0[1,2]{1}\\d{1}-?\\d{8}$)|(^0[3-9] {1}\\d{2}-?\\d{7,8}$)|(^0[1,2]{1}\\d{1}-?\\d{8}-(\\d{1,4})$)|(^0[3-9]{1}\\d{2}-? \\d{7,8}-(\\d{1,4})$))";


    /**
     * 匹配邮箱的正则表达式
     * <br>"www."可省略不写
     */
    public static final String EMAIL_REGEX = "^(www\\.)?\\w+@\\w+(\\.\\w+)+$";

    /**
     * 匹配汉子的正则表达式,个数限制为一个或多个
     */
    public static final String CHINESE_REGEX = "^[\u4e00-\u9f5a]+$";

    /**
     * 匹配正整数的正则表达式,个数限制为一个或多个
     */
    public static final String POSITIVE_INTEGER_REGEX = "^\\d+$";

    /**
     * 匹配身份证号的正则表达式
     */
    public static final String ID_CARD = "^(^[1-9]\\d{7}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}$)|(^[1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])((\\d{4})|\\d{3}[Xx])$)$";

    /**
     * 匹配邮编的正则表达式
     */
    public static final String ZIP_CODE = "^\\d{6}$";

    /**
     * 匹配URL的正则表达式
     */
    public static final String URL = "^(([hH][tT]{2}[pP][sS]?)|([fF][tT][pP]))\\:\\/\\/[wW]{3}\\.[\\w-]+\\.\\w{2,4}(\\/.*)?$";

    /**
     * 匹配给定的字符串是否是一个邮箱账号,"www."可省略不写
     *
     * @param string 给定的字符串
     * @return true:是
     */
    public static boolean isEmail(String string) {
        return string.matches(EMAIL_REGEX);
    }

    /**
     * 匹配给定的字符串是否是一个手机号码,支持130——139、150——153、155——159、180、183、185、186、188、189号段
     *
     * @param string 给定的字符串
     * @return true:是
     */
    public static boolean isMobilePhoneNumber(String string) {
        return string.matches(PHONE_NUMBER_REGEX);
    }

    /**
     * 匹配给定的字符串是否是一个全网IP
     *
     * @param string 给定的字符串
     * @return true:是
     */
    public static boolean isIp(String string) {
        return string.matches(IP_REGEX);
    }

    /**
     * 匹配给定的字符串是否全部由汉子组成
     *
     * @param string 给定的字符串
     * @return true:是
     */
    public static boolean isChinese(String string) {
        return string.matches(CHINESE_REGEX);
    }

    /**
     * 验证给定的字符串是否全部由正整数组成
     *
     * @param string 给定的字符串
     * @return true:是
     */
    public static boolean isPositiveInteger(String string) {
        return string.matches(POSITIVE_INTEGER_REGEX);
    }

    /**
     * 验证给定的字符串是否是身份证号
     * <br>
     * <br>身份证15位编码规则:dddddd yymmdd xx p
     * <br>dddddd:6位地区编码
     * <br>yymmdd:出生年(两位年)月日,如:910215
     * <br>xx:顺序编码,系统产生,无法确定
     * <br>p:性别,奇数为男,偶数为女
     * <br>
     * <br>
     * <br>身份证18位编码规则:dddddd yyyymmdd xxx y
     * <br>dddddd:6位地区编码
     * <br>yyyymmdd:出生年(四位年)月日,如:19910215
     * <br>xxx:顺序编码,系统产生,无法确定,奇数为男,偶数为女
     * <br>y:校验码,该位数值可通过前17位计算获得
     * <br>前17位号码加权因子为 Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 ]
     * <br>验证位 Y = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ]
     * <br>如果验证码恰好是10,为了保证身份证是十八位,那么第十八位将用X来代替 校验位计算公式:Y_P = mod( ∑(Ai×Wi),11 )
     * <br>i为身份证号码1...17 位; Y_P为校验码Y所在校验码数组位置
     *
     * @param string
     * @return
     */
    public static boolean isIdCard(String string) {
        return string.matches(ID_CARD);
    }

    /**
     * 验证给定的字符串是否是邮编
     *
     * @param string
     * @return
     */
    public static boolean isZipCode(String string) {
        return string.matches(ZIP_CODE);
    }

    /**
     * 验证给定的字符串是否是URL,仅支持http、https、ftp
     *
     * @param string
     * @return
     */
    public static boolean isURL(String string) {
        return string.matches(URL);
    }

}
  • 获取SD卡的状态
public class SDCardUtils {
    /**
     * 获取SD卡的状态
     */
    public static String getState() {
        return Environment.getExternalStorageState();
    }


    /**
     * SD卡是否可用
     *
     * @return 只有当SD卡已经安装并且准备好了才返回true
     */
    public static boolean isAvailable() {
        return getState().equals(Environment.MEDIA_MOUNTED);
    }


    /**
     * 获取SD卡的根目录
     *
     * @return null:不存在SD卡
     */
    public static File getRootDirectory() {
        return isAvailable() ? Environment.getExternalStorageDirectory() : null;
    }


    /**
     * 获取SD卡的根路径
     *
     * @return null:不存在SD卡
     */
    public static String getRootPath() {
        File rootDirectory = getRootDirectory();
        return rootDirectory != null ? rootDirectory.getPath() : null;
    }
    /**
     *获取sd卡路径
     * @return Stringpath
     */
    public static String getSDPath(){

        File sdDir = null;
        boolean sdCardExist = Environment.getExternalStorageState()
                .equals(Environment.MEDIA_MOUNTED);   //判断sd卡是否存在
        if   (sdCardExist)
        {
            sdDir = Environment.getExternalStorageDirectory();//获取跟目录
        }
        return sdDir.toString();

    }
}
  • 时间格式工具类
public class TimeUtils {
    public static final SimpleDateFormat DEFAULT_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    public static final SimpleDateFormat DATE_FORMAT_DATE = new SimpleDateFormat("yyyy-MM-dd");
    public static final SimpleDateFormat DATE_IMG_DATE = new SimpleDateFormat("yyyyMMdd_hhmmss");

    private TimeUtils() {
        throw new AssertionError();
    }

    /**
     * long time to string
     *
     * @param timeInMillis timeInMillis
     * @param dateFormat   dateFormat
     * @return String
     */
    public static String getTime(long timeInMillis, SimpleDateFormat dateFormat) {
        return dateFormat.format(new Date(timeInMillis));
    }

    /**
     * 获取系统时间 格式 20160101_112233
     *
     * @return
     */

    public static String getTimeForImg() {
        return  getTime(getCurrentTimeInLong(), DATE_IMG_DATE);

    }


    /**
     * long time to string, format is {@link #DEFAULT_DATE_FORMAT}
     *
     * @param timeInMillis time
     * @return String
     */
    public static String getTime(long timeInMillis) {
        return getTime(timeInMillis, DEFAULT_DATE_FORMAT);
    }

    /**
     * get current time in milliseconds
     *
     * @return long
     */
    public static long getCurrentTimeInLong() {
        return System.currentTimeMillis();
    }

    /**
     * get current time in milliseconds, format is {@link #DEFAULT_DATE_FORMAT}
     *
     * @return String
     */
    public static String getCurrentTimeInString() {
        return getTime(getCurrentTimeInLong());
    }

    /**
     * get current time in milliseconds
     *
     * @param dateFormat dateFormat
     * @return String
     */
    public static String getCurrentTimeInString(SimpleDateFormat dateFormat) {

        return getTime(getCurrentTimeInLong(), dateFormat);
    }
}
  • 图片工具类
public class Utils {

    /**
     * Map a value within a given range to another range.
     * @param value the value to map
     * @param fromLow the low end of the range the value is within
     * @param fromHigh the high end of the range the value is within
     * @param toLow the low end of the range to map to
     * @param toHigh the high end of the range to map to
     * @return the mapped value
     */
    public static double mapValueFromRangeToRange(
            double value,
            double fromLow,
            double fromHigh,
            double toLow,
            double toHigh) {
        double fromRangeSize = fromHigh - fromLow;
        double toRangeSize = toHigh - toLow;
        double valueScale = (value - fromLow) / fromRangeSize;
        return toLow + (valueScale * toRangeSize);
    }

    /**
     * set margins of the specific view
     * @param target
     * @param l
     * @param t
     * @param r
     * @param b
     */
    public static void setMargin(View target, int l, int t, int r, int b){
        if (target.getLayoutParams() instanceof ViewGroup.MarginLayoutParams) {
            ViewGroup.MarginLayoutParams p = (ViewGroup.MarginLayoutParams) target.getLayoutParams();
            p.setMargins(l, t, r, b);
            target.requestLayout();
        }
    }

    /**
     * convert drawable to bitmap
     * @param drawable
     * @return
     */
    public static Bitmap drawableToBitmap(Drawable drawable) {
        int width = drawable.getIntrinsicWidth();
        int height = drawable.getIntrinsicHeight();
        Bitmap bitmap = Bitmap.createBitmap(width, height, drawable.getOpacity() != PixelFormat.OPAQUE ? Bitmap.Config.ARGB_8888 : Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, width, height);
        drawable.draw(canvas);
        return bitmap;
    }
}
  • 网络状态工具类
public class NetworkUtils {

    public static boolean isNetWorkConnet(Context context){
        ConnectivityManager con=(ConnectivityManager)context.getSystemService(Activity.CONNECTIVITY_SERVICE);
        boolean wifi=con.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnectedOrConnecting();
        boolean internet=con.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnectedOrConnecting();
        if(wifi|internet){
            //执行相关操作
            return true;
        }else{
            Toast.makeText(context, "网络连了么?", Toast.LENGTH_LONG)
                    .show();
            return false;
        }//else
    }//isNetWorkConnect
}
  • Toast 工具类
public class MyToast {

    private static Toast toast;
    public static void showToast(Context context, String msg) {
        if(toast==null){// many times click for only one show,not a lot of shows
            toast=Toast.makeText(context, msg, Toast.LENGTH_SHORT);
        }else
            toast.setText(msg);

        toast.show();

    }//showToast
}
  • 文件存储工具类
public class FileUtil {

    private static String TAG = "图片相关:";
    /**
     * 生成文件夹
     *
     * @param filePath
     */
    public static void makeRootDirectory(String filePath) {
        File file = null;
        try {
            file = new File(filePath);
            if (!file.exists()) {
                file.mkdir();
//                T.showShort(App.getContext(),"文件夹创建成功");
            } else {
//                T.showShort(App.getContext(),"文件夹已存在");
            }
        } catch (Exception e) {
            Log.i("error:", e + "");
        }
    }

    /**
     * 生成文件
     *
     * @param filePath
     * @param fileName
     * @return
     */
    public static File makeFilePath(String filePath, String fileName) {
        File file = null;
        makeRootDirectory(filePath);
        try {
            file = new File(filePath + fileName);
            if (!file.exists()) {
                file.createNewFile();
            }
        } catch (Exception e) {
            Log.e(TAG, "图片保存出错:" + e.toString());
        }
        return file;
    }
}
  • 倒计时工具类
public class Countdown implements Runnable {
    private int remainingSeconds;
    private int currentRemainingSeconds;
    private boolean running;
    private String defaultText;
    private String countdownText;
    private TextView showTextView;
    private Handler handler;
    private CountdownListener countdownListener;
    private TextViewGetListener textViewGetListener;

    /**
     * 创建一个倒计时器
     *
     * @param showTextView     显示倒计时的文本视图
     * @param countdownText    倒计时中显示的内容,例如:"%s秒后重新获取验证码",在倒计时的过程中会用剩余描述替换%s
     * @param remainingSeconds 倒计时秒数,例如:60,就是从60开始倒计时一直到0结束
     */
    public Countdown(TextView showTextView, String countdownText, int remainingSeconds) {
        this.showTextView = showTextView;
        this.countdownText = countdownText;
        this.remainingSeconds = remainingSeconds;
        this.handler = new Handler();
    }

    /**
     * 创建一个倒计时器
     *
     * @param textViewGetListener 显示倒计时的文本视图获取监听器
     * @param countdownText       倒计时中显示的内容,例如:"%s秒后重新获取验证码",在倒计时的过程中会用剩余描述替换%s
     * @param remainingSeconds    倒计时秒数,例如:60,就是从60开始倒计时一直到0结束
     */
    public Countdown(TextViewGetListener textViewGetListener, String countdownText, int remainingSeconds) {
        this.textViewGetListener = textViewGetListener;
        this.countdownText = countdownText;
        this.remainingSeconds = remainingSeconds;
        this.handler = new Handler();
    }

    /**
     * 创建一个倒计时器,默认60秒
     *
     * @param showTextView  显示倒计时的文本视图
     * @param countdownText 倒计时中显示的内容,例如:"%s秒后重新获取验证码",在倒计时的过程中会用剩余描述替换%s
     */
    public Countdown(TextView showTextView, String countdownText) {
        this(showTextView, countdownText, 60);
    }

    /**
     * 创建一个倒计时器,默认60秒
     *
     * @param textViewGetListener 显示倒计时的文本视图获取监听器
     * @param countdownText       倒计时中显示的内容,例如:"%s秒后重新获取验证码",在倒计时的过程中会用剩余描述替换%s
     */
    public Countdown(TextViewGetListener textViewGetListener, String countdownText) {
        this(textViewGetListener, countdownText, 60);
    }

    private TextView getShowTextView() {
        if (showTextView != null) {
            return showTextView;
        }

        if (textViewGetListener != null) {
            return textViewGetListener.OnGetShowTextView();
        }

        return null;
    }

    @Override
    public void run() {
        if (currentRemainingSeconds > 0) {
            getShowTextView().setEnabled(false);
            getShowTextView().setText(
                    String.format(countdownText, currentRemainingSeconds));
            if (countdownListener != null) {
                countdownListener.onUpdate(currentRemainingSeconds);
            }
            currentRemainingSeconds--;
            handler.postDelayed(this, 1000);
        } else {
            stop();
        }
    }

    public void start() {
        defaultText = (String) getShowTextView().getText().toString();
        currentRemainingSeconds = remainingSeconds;
        handler.removeCallbacks(this);
        handler.post(this);
        if (countdownListener != null) {
            countdownListener.onStart();
        }
        running = true;
    }

    public void stop() {
        getShowTextView().setEnabled(true);

        Spanned htmlStr = Html.fromHtml("<font color=#000000>"+defaultText+"</font>");
        getShowTextView().setText(htmlStr);

//        getShowTextView().setText(defaultText);
        handler.removeCallbacks(this);
        if (countdownListener != null) {
            countdownListener.onFinish();
        }
        running = false;
    }

    public boolean isRunning() {
        return running;
    }

    public int getRemainingSeconds() {
        return remainingSeconds;
    }

    public String getCountdownText() {
        return countdownText;
    }

    public void setCountdownText(String countdownText) {
        this.countdownText = countdownText;
    }

    public void setCurrentRemainingSeconds(int currentRemainingSeconds) {
        this.currentRemainingSeconds = currentRemainingSeconds;
    }

    public void setCountdownListener(CountdownListener countdownListener) {
        this.countdownListener = countdownListener;
    }

    /**
     * 倒计时监听器
     */
    public interface CountdownListener {
        /**
         * 当倒计时开始
         */
        public void onStart();

        /**
         * 当倒计时结束
         */
        public void onFinish();

        /**
         * 更新
         *
         * @param currentRemainingSeconds 剩余时间
         */
        public void onUpdate(int currentRemainingSeconds);
    }

    public interface TextViewGetListener {
        public TextView OnGetShowTextView();
    }
}
  • 图片处理工具类
public class BitmapUtil {
    private static String TAG = BitmapUtil.class.getSimpleName();

    private static int calculateInSampleSize(BitmapFactory.Options options,
                                             int reqWidth, int reqHeight) {
        final int height = options.outHeight;
        final int width = options.outWidth;
        int inSampleSize = 1;
        if (height > reqHeight || width > reqWidth) {
            final int halfHeight = height / 2;
            final int halfWidth = width / 2;
            while ((halfHeight / inSampleSize) > reqHeight
                    && (halfWidth / inSampleSize) > reqWidth) {
                inSampleSize *= 2;
            }
        }
        return inSampleSize;
    }

    // 如果是放大图片,filter决定是否平滑,如果是缩小图片,filter无影响
    private static Bitmap createScaleBitmap(Bitmap src, int dstWidth,
                                            int dstHeight) {
        Bitmap dst = Bitmap.createScaledBitmap(src, dstWidth, dstHeight, false);
        if (src != dst) { // 如果没有缩放,那么不回收
            src.recycle(); // 释放Bitmap的native像素数组
        }
        return dst;
    }

    // 从Resources中加载图片
    public static Bitmap decodeSampledBitmap(Resources res,  int resId, int reqWidth, int reqHeight) {
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeResource(res, resId, options); // 读取图片长款
        options.inSampleSize = calculateInSampleSize(options, reqWidth,
                reqHeight); // 计算inSampleSize
        options.inJustDecodeBounds = false;
        Bitmap src = BitmapFactory.decodeResource(res, resId, options); // 载入一个稍大的缩略图
        return createScaleBitmap(src, reqWidth, reqHeight); // 进一步得到目标大小的缩略图
    }

    public static Bitmap decodeSampledBitmap(Bitmap bitmap, int quality, int reqWidth, int reqHeight) {
        //先进行质量压缩
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bos);
        if (bos != null) {
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
        if (bis != null) {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //再进行尺寸压缩
        return createScaleBitmap(BitmapFactory.decodeStream(bis), reqWidth, reqHeight);
    }


    // 从sd卡上加载图片
    public static Bitmap decodeSampledBitmap(String pathName, int reqWidth, int reqHeight) {
        /**
         * 设置inJustDecodeBounds为true后,decodeFile并不分配空间,但可计算出原始图片的长度和宽度,
         * 即opts.width和opts.height。
         * 有了这两个参数,再通过一定的算法,即可得到一个恰当的inSampleSize。
         */
        final BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeFile(pathName, options);
        options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
        options.inJustDecodeBounds = false;
        Bitmap src = BitmapFactory.decodeFile(pathName, options);
        return createScaleBitmap(src, reqWidth, reqHeight);
    }


    /**
     * 从sd卡上加载图片
     *
     * @param pathName  文件路径
     * @param zoomScale 缩放比例
     *                  表示缩略图大小为原始图片大小的几分之一,即如果这个值为2,
     *                  则取出的缩略图的宽和高都是原始图片的1/2,图片大小就为原始大小的1/4
     * @return
     */
    public static Bitmap decodeSampledBitmap(String pathName, int zoomScale) {
        /**
         * 设置inJustDecodeBounds为true后,decodeFile并不分配空间,但可计算出原始图片的长度和宽度,
         * 即opts.width和opts.height。
         * 有了这两个参数,再通过一定的算法,即可得到一个恰当的inSampleSize。
         */
        final BitmapFactory.Options options = new BitmapFactory.Options();
//        options.inJustDecodeBounds = true;
//        BitmapFactory.decodeFile(pathName, options);
        options.inSampleSize = zoomScale;
        options.inJustDecodeBounds = false;
        Bitmap src = BitmapFactory.decodeFile(pathName, options);
        return src;
    }


    public static void saveBitmapFile(Bitmap bitmap, String filePath, String fileName) {

        File f = FileUtil.makeFilePath(filePath, fileName);
        FileOutputStream fOut = null;
        try {
            fOut = new FileOutputStream(f);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
        try {
            fOut.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            fOut.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static void saveBitmapFile(Bitmap bitmap, File file) {

        FileOutputStream fOut = null;
        try {
            fOut = new FileOutputStream(file);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fOut);
        try {
            fOut.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            fOut.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 图片旋转
     *
     * @param bmp    要旋转的图片
     * @param degree 图片旋转的角度,负值为逆时针旋转,正值为顺时针旋转
     * @return
     */
    public static Bitmap rotateBitmap(Bitmap bmp, float degree) {
        Matrix matrix = new Matrix();
        matrix.postRotate(degree);
        return Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
    }

    public static String bitmapBase64(Bitmap bitmap) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
        byte[] bytes = baos.toByteArray();
        return Base64.encodeToString(bytes, 0);
    }

    public static Bitmap base64ToBitmap(String iconBase64) {
        byte[] bitmapArray;
        bitmapArray = Base64.decode(iconBase64, 0);
        return BitmapFactory
                .decodeByteArray(bitmapArray, 0, bitmapArray.length);
    }

    /**
     * 通过图片路径获得bitmap(无压缩形式)
     *
     * @param path 图片路径
     * @return Bitmap
     */
    public static Bitmap getBitmapFromLocal(String path) {
        Bitmap bitmap = BitmapFactory.decodeFile(path);
        return bitmap;
    }

    /**
     * 通过bitmap得到输出流(无压缩形式)
     *
     * @param bitmap bitmap对象
     * @return OutputStream
     */
    public static ByteArrayOutputStream getOutStreamFromBitmap(Bitmap bitmap) {
        return getOutStreamFromBitmap(bitmap, 100);
    }

    /**
     * 通过bitmap得到输出流(质量压缩)
     *
     * @param bitmap  bitmap对象
     * @param quality 要压缩到的质量(0-100)
     * @return OutputStream
     */
    public static ByteArrayOutputStream getOutStreamFromBitmap(Bitmap bitmap, int quality) {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.JPEG, quality, bos);
        if (bos != null) {
            try {
                bos.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bos;
    }

    /**
     * 通过流获得bitmap
     *
     * @param os 输出流
     * @return Bitmap
     */
    public static Bitmap getBitmapFromOutStream(ByteArrayOutputStream os) {
        ByteArrayInputStream bis = new ByteArrayInputStream(os.toByteArray());
        if (bis != null) {
            try {
                bis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return BitmapFactory.decodeStream(bis);
    }

    /**
     * 通过路径得到图片并对图片进行压缩,并再生成图片(质量压缩)
     *
     * @param imagePath 图片的路径
     * @param savePath  新图片的保存路径
     * @param quality   要压缩到的质量
     * @return Boolean true 成功false失败
     */
    public static boolean writeCompressImage2File(String imagePath, String savePath, int quality) {
        if (TextUtils.isEmpty(imagePath)) {
            return false;
        }
        String path = savePath.substring(0, savePath.lastIndexOf("/"));
        String filename = savePath.substring(savePath.lastIndexOf("/") + 1, savePath.length());
        return writeImage2File(getOutStreamFromBitmap(getBitmapFromLocal(imagePath), quality), path, filename);
    }

    /**
     * 把bitmap写入指定目录下,重新生成图片
     *
     * @param bitmap    bitmap对象
     * @param savePath  新图片保存路径
     * @param imageName 新图片的名字,会根据时间来命名
     * @return Boolean true 成功false失败
     */
    public static boolean writeImage2File(Bitmap bitmap, String savePath, String imageName) {
        return writeImage2File(getOutStreamFromBitmap(bitmap), savePath, imageName);
    }

    /**
     * 通过输出流,重组图片,并保存带指定目录下
     *
     * @param bos       图片输入流
     * @param savePath  新图片的保存路径
     * @param imageName 新图片的名字,字段为空时,会根据时间来命名
     * @return Boolean true 成功false失败
     */
    public static boolean writeImage2File(ByteArrayOutputStream bos, String savePath, String imageName) {
        if (TextUtils.isEmpty(savePath)) {
            return false;
        }
        File file = new File(savePath);
        if (!file.exists()) {
            file.mkdirs();
        }
        FileOutputStream fos;
        try {
//            if(TextUtils.isEmpty(imageName)){
//                imageName = System.currentTimeMillis()+"";
//            }
            File f = new File(file, imageName);
            fos = new FileOutputStream(f);
            fos.write(bos.toByteArray());
            fos.flush();
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }


    public Bitmap ratio(Bitmap image, float pixelW, float pixelH) {
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.JPEG, 100, os);
        if (os.toByteArray().length / 1024 > 1024) {//判断如果图片大于1M,进行压缩避免在生成图片(BitmapFactory.decodeStream)时溢出
            os.reset();//重置baos即清空baos
            image.compress(Bitmap.CompressFormat.JPEG, 50, os);//这里压缩50%,把压缩后的数据存放到baos中
        }
        ByteArrayInputStream is = new ByteArrayInputStream(os.toByteArray());
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        //开始读入图片,此时把options.inJustDecodeBounds 设回true了
        newOpts.inJustDecodeBounds = true;
        newOpts.inPreferredConfig = Bitmap.Config.RGB_565;
        Bitmap bitmap = BitmapFactory.decodeStream(is, null, newOpts);
        newOpts.inJustDecodeBounds = false;
        int w = newOpts.outWidth;
        int h = newOpts.outHeight;
        float hh = pixelH;// 设置高度为240f时,可以明显看到图片缩小了
        float ww = pixelW;// 设置宽度为120f,可以明显看到图片缩小了
        //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
        int be = 1;//be=1表示不缩放
        if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
            be = (int) (newOpts.outWidth / ww);
        } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
            be = (int) (newOpts.outHeight / hh);
        }
        if (be <= 0) be = 1;
        newOpts.inSampleSize = be;//设置缩放比例
        //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
        is = new ByteArrayInputStream(os.toByteArray());
        bitmap = BitmapFactory.decodeStream(is, null, newOpts);
        //压缩好比例大小后再进行质量压缩
//      return compress(bitmap, maxSize); // 这里再进行质量压缩的意义不大,反而耗资源,删除
        return bitmap;
    }

}

猜你喜欢

转载自blog.csdn.net/baidu_33221362/article/details/80099263