//线程池管理类
public class ThreadManager {
private static ThreadManager mManager;
private final ThreadPoolExecutor mExecutor;
private ThreadManager(){
//创建线程池,用来执行线程,管理线程
mExecutor = new ThreadPoolExecutor(5,//核心线程数量,核心池的大小
20,//线程池最大线程数
30,//表示线程没有任务执行时最多保持多久时间会终止
TimeUnit.SECONDS,//时间单位
new LinkedBlockingQueue<Runnable>(),//任务队列,用来存储等待执行的任务
Executors.defaultThreadFactory(),//线程工厂,如何去创建线程的
new ThreadPoolExecutor.AbortPolicy());
}
//单例模式
public static ThreadManager getInstance(){
if (mManager == null){
synchronized (ThreadManager.class){//上锁,只有第一个线程可以访问
if (mManager == null){
mManager = new ThreadManager();
}
}
}
return mManager;
}
/**
* 执行任务
*/
public void execute(Runnable runnable){
if(runnable==null)return;
mExecutor.execute(runnable);
}
/**
* 从线程池中移除任务
*/
public void remove(Runnable runnable){
if(runnable==null)return;
mExecutor.remove(runnable);
}
}
//原始的http上传
public void uploadForm(Map<String, String> params, String fileFormName, File uploadFile, String newFileName, String urlStr) {
try {
if (newFileName == null || newFileName.trim().equals("")) {
newFileName = uploadFile.getName();
}
StringBuilder sb = new StringBuilder();//比StringBuffer的性能更高,更快 因为是 线程不安全
/**
* 普通的表单数据
*/
if (params != null) {
for (String key : params.keySet()) {
sb.append("--" + BOUNDARY + "\r\n");
sb.append("Content-Disposition: form-data; name=\"" + key + "\"" + "\r\n");
sb.append("\r\n");
sb.append(params.get(key) + "\r\n");
}
}
/**
* 上传文件的头
*/
sb.append("--" + BOUNDARY + "\r\n");
sb.append("Content-Disposition: form-data; name=\"" + fileFormName + "\"; filename=\"" + newFileName + "\""
+ "\r\n");
sb.append("Content-Type: application/octet-stream" + "\r\n");// 如果服务器端有文件类型的校验,必须明确指定ContentType
sb.append("\r\n");
byte[] headerInfo = sb.toString().getBytes("UTF-8");
byte[] endInfo = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("UTF-8");
URL url = new URL(urlStr);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
// 设置传输内容的格式,以及长度
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);
conn.setRequestProperty("Content-Length", String.valueOf(headerInfo.length + uploadFile.length() + endInfo.length));
conn.setDoOutput(true);
OutputStream out = conn.getOutputStream();//得到服务器的输出流
InputStream in = new FileInputStream(uploadFile);//创建文件的输入流,获得上传文件信息,写入到out 输出流,,数据流
//写入的文件长度
float count = 0;
int available = in.available();//文件的总长度
mPb.setMax(available);//把文件的长度,和进度条的最大值同步一致
// 写入头部 (包含了普通的参数,以及文件的标示等)
out.write(headerInfo);
// 写入文件
byte[] buf = new byte[1024];//1k 每次上传1k
int len;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);//读取一次信息,向服务器写入一次信息
count += len;//上传文件的大小的累计
int progress = (int) ((count / available) * 100);//0.111算出上传的百分比,和进度条的总长度相乘,得到进度中的进度值
Log.d(TAG, "上传进度: " + progress + " %");
updateProgress(count);//把上传进度设置给进度条
Thread.sleep(5);//没1秒 上传一次,一部分 1k
}
// 写入尾部
out.write(endInfo);
in.close();
out.close();
if (conn.getResponseCode() == 200) {
System.out.println("文件上传成功");
String s = stream2String(conn.getInputStream());
Log.d(TAG, "uploadForm--上传成功: " + s);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//启动相机的uri
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
//打开相册 action
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,"image/*");
图片的内容提供者的读取
String[] filePathColumn = {MediaStore.MediaColumns.DATA};
//内容解析者,查询系统资源
ContentResolver contentResolver = context.getContentResolver();
// content://xxxxxxx
Cursor cursor = contentResolver.query(contentUri, filePathColumn, null, null, null);
//拍照的内容提供者
<provider
android:authorities="day14.upload"
android:name="android.support.v4.content.FileProvider"
android:exported="false"
android:grantUriPermissions="true"
>
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths"/>
</provider>
//file_paths
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<root-path name="upload" path=""/>
</paths>