天天看點

Android開發——常用功能源碼1.三級緩存2.對字元串進行MD5加密3.圖檔相關操作4.中文轉換為拼音5.解析Excel

1.三級緩存

package com.heima.zhbj55.view;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import com.heima.zhbj55.utils.MD5Utils;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap.CompressFormat;
import android.os.Handler;
import android.os.Message;
import android.support.v4.util.LruCache;
import android.util.Log;

public class ImageCache {

	private Context context;
	private LruCache<String, Bitmap> lruCache;
	private ExecutorService newFixedThreadPool;
	private Handler handler;
	
	public static final int SUCCESS = 10;
	public static final int FAIL = 20;
	private static final String tag = "ImageCache";
	

	//handler對象是由使用者傳入過來的,說明處理資料的方法在使用者那邊
	public ImageCache(Context context,Handler handler) {
		this.context = context;

		// 擷取最大記憶體的1/8作為lru最大可使用的記憶體
		int cacSize = (int) (Runtime.getRuntime().maxMemory() / 8);

		// 原理:
		// 如果現在添加某一張圖檔,加上原有已使用記憶體大小以後大于cacSize大小,會自動移除最近最少使用的圖檔,保證記憶體大小不超過cacSize
		lruCache = new LruCache<String, Bitmap>(cacSize) {

			// 想删除某一張圖檔,前提必須知道圖檔的大小
			@Override
			protected int sizeOf(String key, Bitmap value) {
				return value.getRowBytes() * value.getHeight();
			}

		};
		
		this.handler = handler;

		// 建立一個線程池,線程池中可開啟的線程數量(cpu個數*2+1)這是最佳數量的個數
		newFixedThreadPool = Executors.newFixedThreadPool(5);
	}

	/**
	 * 解析指定位址的圖檔并且三級緩存圖檔
	 * @param url 圖檔位址
	 * @param position 圖檔的标示,為了擷取到每一張圖檔所用
	 * @return 傳回Bitmap對象
	 */
	public Bitmap parseUrl(String url, int position) {
		Bitmap cacheBitmap = getBitmapFromCache(url);
		if (cacheBitmap != null) {
			Log.i(tag, "從記憶體中擷取圖檔");
			return cacheBitmap;
		}

		Bitmap localBitmap = getBitmapFromLocal(url);
		if (localBitmap != null) {
			Log.i(tag, "從硬碟中擷取圖檔");
			return localBitmap;
		}

		getBitmapFromNet(url, position);
		Log.i(tag, "從網絡擷取圖檔");

		return null;
	}

	// 從記憶體中擷取圖檔資源
	private Bitmap getBitmapFromCache(String url) {
		Bitmap bitmap = lruCache.get(url);
		return bitmap;
	}

	// 從本地擷取圖檔資源
	private Bitmap getBitmapFromLocal(String url) {
		// 從本地位址中擷取圖檔資源,并且存入記憶體中
		String fileName = MD5Utils.md5(url).substring(10);
		File file = new File(context.getCacheDir(), fileName);
		try {
			Bitmap bitmap = BitmapFactory.decodeStream(new FileInputStream(file));
			lruCache.put(url, bitmap);
			return bitmap;
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}

	// 從網絡擷取圖檔資源
	private void getBitmapFromNet(String url, int position) {
		// 開發中必須以線程池開啟線程,不能自己定義線程開啟,這樣友善管理,增加效率
		newFixedThreadPool.execute(new ThreadTask(url, position));
	}

	/**
	 * 網絡擷取圖檔
	 * @author UPC
	 *
	 */
	private class ThreadTask implements Runnable {

		private String url;
		private int position;

		public ThreadTask(String url, int position) {
			this.url = url;
			this.position = position;
		}

		@Override
		public void run() {
			try {
				URL urlObject = new URL(url);
				HttpURLConnection con = (HttpURLConnection) urlObject.openConnection();
				con.setConnectTimeout(2000);
				con.setReadTimeout(2000);
				con.setRequestMethod("GET");
				int code = con.getResponseCode();
				if (code==200) {
					InputStream in = con.getInputStream();
					Bitmap bitmap = BitmapFactory.decodeStream(in);
					
					//子線程不能更新UI
					Message msg = Message.obtain();
					msg.obj = bitmap;
					msg.what = SUCCESS;
					//儲存圖檔的标示,通過這個标示,然後再通過父控件的fingViewByTag()方法擷取到指定的控件
					msg.arg1 = position;
					
					handler.sendMessage(msg);
					
					//儲存圖檔到記憶體
					lruCache.put(url, bitmap);
					
					//儲存圖檔到本地
					writeToLocal(url, bitmap);
					
					return;
				}
			} catch (MalformedURLException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
			//抛出異常,放松擷取圖檔失敗的消息
			Message msg = Message.obtain();
			msg.what = FAIL;
			handler.sendMessage(msg);
		}
	}
	
	public void writeToLocal(String url,Bitmap bitmap){
		String fileName = MD5Utils.md5(url).substring(10);
		File file = new File(context.getCacheDir(),fileName);
		try {
			FileOutputStream fos = new FileOutputStream(file);
			bitmap.compress(CompressFormat.JPEG, 70, fos);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}
}
           

調用時的邏輯

private Handler handler = new Handler() {

		public void handleMessage(Message msg) {
			switch (msg.what) {
			case ImageCache.SUCCESS:
				// 下載下傳成功
				Bitmap bitmap = (Bitmap) msg.obj;
				// 根據傳遞進去的索引去拿到,顯示這個圖檔的控件
				int position = msg.arg1;
				ImageView imageView = (ImageView) view
						.findViewWithTag(position);

				if (bitmap != null && imageView != null) {
					imageView.setImageBitmap(BitmapUtil.toRoundBitmap(bitmap));
				}

				break;
			case ImageCache.FAIL:
				// 下載下傳失敗
				Toast.makeText(mContext, "頭像擷取失敗", Toast.LENGTH_SHORT).show();
				break;
			}
		}
	};
           

2.對字元串進行MD5加密

package com.heima.zhbj55.utils;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class MD5Utils {

	public static String md5(String source){
		try {
			MessageDigest digest = MessageDigest.getInstance("MD5");
			byte[] md5Source = digest.digest(source.getBytes());
			StringBuilder sb = new StringBuilder();
			for (byte b : md5Source) {
				int i = b & 0xff;// 擷取該位元組的低八位資訊, 11111111

				String hexString = Integer.toHexString(i);

				if (hexString.length() < 2) {
					hexString = "0" + hexString;
				}
				sb.append(hexString);
			}

			return sb.toString();
			
			
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		
		return null;
	}
}
           

3.圖檔相關操作

(1)圖檔縮放

a.縮放圖檔普通

/**
	 * 縮放圖檔多指定比例
	 * @param path 圖檔路徑
	 * @param width 寬
	 * @param height 高
	 * @return
	 */
	public static Bitmap resizeImage(String path, int width, int height) {
		BitmapFactory.Options options = new BitmapFactory.Options();
		options.inJustDecodeBounds = true;// 不加載bitmap到記憶體中
		BitmapFactory.decodeFile(path, options);
		int outWidth = options.outWidth;
		int outHeight = options.outHeight;
		options.inDither = false;
		options.inPreferredConfig = Bitmap.Config.ARGB_8888;
		options.inSampleSize = 1;

		if (outWidth != 0 && outHeight != 0 && width != 0 && height != 0) {
			int sampleSize = (outWidth / width + outHeight / height) / 2;
			options.inSampleSize = sampleSize;
		}

		options.inJustDecodeBounds = false;
		return BitmapFactory.decodeFile(path, options);
	}
	
	//使用Bitmap加Matrix來縮放
    public static Bitmap resizeImage(Bitmap bitmap, int w, int h)  {  
        Bitmap BitmapOrg = bitmap;  
        int width = BitmapOrg.getWidth();  
        int height = BitmapOrg.getHeight();  
        int newWidth = w;  
        int newHeight = h;  
 
        float scaleWidth = ((float) newWidth) / width;  
        float scaleHeight = ((float) newHeight) / height;  
 
        Matrix matrix = new Matrix();  
        matrix.postScale(scaleWidth, scaleHeight);  
        // if you want to rotate the Bitmap   
        // matrix.postRotate(45);   
        Bitmap resizedBitmap = Bitmap.createBitmap(BitmapOrg, 0, 0, width,  
                        height, matrix, true);  
        return resizedBitmap;  
    }
           

b.防止OOM(據說)

/**
	 * 加載本地圖檔 防止oom
	 * 
	 * @param filePath
	 * @param outWidth
	 * @param outHeight
	 * @return
	 */
	public static Bitmap readBitmapAutoSize(Context context, String filePath,
			int outWidth, int outHeight) {
		// outWidth和outHeight是目标圖檔的最大寬度和高度,用作限制
		// BufferedInputStream bs = null;
		FileInputStream fs = null;
		BufferedInputStream bs = null;
		try {
			File newFile = new File(filePath);
			if (!newFile.exists()) {
				return null;
			}
			int rad = readPictureDegree(filePath);

			try {
				fs = new FileInputStream(filePath);
				bs = new BufferedInputStream(fs);
				if (fs != null && bs != null) {
					BitmapFactory.Options options = setBitmapOption(context,
							filePath, outWidth, outHeight);

					if (rad != 0) {
						return rotaingImageView(rad,
								BitmapFactory.decodeStream(bs, null, options));
					} else
						return BitmapFactory.decodeStream(bs, null, options);

				 } else {
					try {
						File file = new File(filePath);
						if (file.exists()) {
							file.delete();
						}
					} catch (Exception e) {
						// TODO: handle exception
					}
					return null;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				bs.close();
				fs.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return null;
	}

	public static Bitmap rotaingImageView(int angle, Bitmap mBitmap) {

		Matrix matrix = new Matrix();
		matrix.postRotate(angle);
		Bitmap b = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(),
				mBitmap.getHeight(), matrix, true);
		return b;
	}

	public static int readPictureDegree(String imagePath) {
		int imageDegree = 0;
		try {
			ExifInterface exifInterface = new ExifInterface(imagePath);
			int orientation = exifInterface.getAttributeInt(
					ExifInterface.TAG_ORIENTATION,
					ExifInterface.ORIENTATION_NORMAL);
			switch (orientation) {
			case ExifInterface.ORIENTATION_ROTATE_90:
				imageDegree = 90;
				break;
			case ExifInterface.ORIENTATION_ROTATE_180:
				imageDegree = 180;
				break;
			case ExifInterface.ORIENTATION_ROTATE_270:
				imageDegree = 270;
				break;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return imageDegree;
	}

           

c.根據指定像素數來縮放

注:調用——opts.inSampleSize = computeSampleSize(opts, -1, 295000);

/**
	 * 縮放圖檔到指定比例
	 * @param options	目标圖檔的屬性對象
	 * @param minSideLength	不知道,用的時候傳入的是-1
	 * @param maxNumOfPixels 目标像素點
	 * @return
	 */
	public static int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) {  
	    int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels);  
	    int roundedSize;  
	    if (initialSize <= 8) {  
	        roundedSize = 1;  
	        while (roundedSize < initialSize) {  
	            roundedSize <<= 1;  
	        }  
	    } else {  
	        roundedSize = (initialSize + 7) / 8 * 8;  
	    }  
	    return roundedSize;  
	}  
  
	private static int computeInitialSampleSize(BitmapFactory.Options options,int minSideLength, int maxNumOfPixels) {  
	    double w = options.outWidth;  
	    double h = options.outHeight;  
	    int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math.sqrt(w * h / maxNumOfPixels));  
	    int upperBound = (minSideLength == -1) ? 128 :(int) Math.min(Math.floor(w / minSideLength), Math.floor(h / minSideLength));  
	    if (upperBound < lowerBound) {  
	        // return the larger one when there is no overlapping zone.  
	        return lowerBound;  
	    }  
	    if ((maxNumOfPixels == -1) && (minSideLength == -1)) {  
	        return 1;  
	    } else if (minSideLength == -1) {  
	        return lowerBound;  
	    } else {  
	        return upperBound;  
	    }  
	}  
           

d.最早自己寫的

(2)圖檔變形

/**
	 * 轉換圖檔成圓形
	 * 
	 * @param bitmap
	 *            傳入Bitmap對象
	 * @return
	 */
	public static Bitmap toRoundBitmap(Bitmap bitmap) {
		int width = bitmap.getWidth();
		int height = bitmap.getHeight();
		float roundPx;
		float left, top, right, bottom, dst_left, dst_top, dst_right, dst_bottom;
		if (width <= height) {
			roundPx = width / 2;
			top = 0;
			bottom = width;
			left = 0;
			right = width;
			height = width;
			dst_left = 0;
			dst_top = 0;
			dst_right = width;
			dst_bottom = width;
		} else {
			roundPx = height / 2;
			float clip = (width - height) / 2;
			left = clip;
			right = width - clip;
			top = 0;
			bottom = height;
			width = height;
			dst_left = 0;
			dst_top = 0;
			dst_right = height;
			dst_bottom = height;
		}

		Bitmap output = Bitmap.createBitmap(width, height, Config.ARGB_8888);
		Canvas canvas = new Canvas(output);

		final int color = 0xff424242;
		final Paint paint = new Paint();
		final Rect src = new Rect((int) left, (int) top, (int) right,
				(int) bottom);
		final Rect dst = new Rect((int) dst_left, (int) dst_top,
				(int) dst_right, (int) dst_bottom);
		final RectF rectF = new RectF(dst);

		paint.setAntiAlias(true);

		canvas.drawARGB(0, 0, 0, 0);
		paint.setColor(color);
		canvas.drawRoundRect(rectF, roundPx, roundPx, paint);

		paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
		canvas.drawBitmap(bitmap, src, dst, paint);
		return output;
	}
           

4.中文轉換為拼音

注:需要第三方jar包【pinyin4j-2.5.0】

/** 
    * 漢字轉換位漢語拼音,英文字元不變 
    * @param chines 漢字 
    * @return 拼音 
    */  
	public static String converterToSpell(String chines){          
	    String pinyinName = "";  
	    char[] nameChar = chines.toCharArray();  
	    HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();  
	    defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);  
	    defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);  
	    for (int i = 0; i < nameChar.length; i++) {  
	        if (nameChar[i] > 128) {  
	            try {  
	                pinyinName += PinyinHelper.toHanyuPinyinStringArray(nameChar[i], defaultFormat)[0];  
	            } catch (BadHanyuPinyinOutputFormatCombination e) {  
	                e.printStackTrace();  
	            }  
	        }else{  
	            pinyinName += nameChar[i];  
	        }  
	    }  
	    return pinyinName;  
	}  
           

5.解析Excel

需要第三方開源包:jxl

File excel = new File(context.getCacheDir(),"areaid_v.xls");
				//建立解析對象
				Workbook book;
				try {
					book = Workbook.getWorkbook(excel);
				} catch (Exception e) {
					throw new RuntimeException("file not found");
				}
				//擷取第一張表格
				Sheet sheet = book.getSheet(0);
				Cell cellCityCode, cellCityName;
				int row = 1;
				while (true) {
					//擷取第幾行第一列内容
					cellCityCode = sheet.getCell(0, row);
					//擷取第幾行第三列内容
					cellCityName = sheet.getCell(2, row);
					
					//這是退出邏輯,因情況而定
					if (cellCityName.getContents().equals(address.getName())) {
						address.setWeatherIndexCode(cellCityCode.getContents());
						break; 
					}
					if ("".equals(cellCityCode.getContents()) == true) //如果讀取的資料為空
						break;
					row++;
				}
				book.close();