1. 程式人生 > >在fragment中實現Android上傳圖片至本地JavaWeb服務器

在fragment中實現Android上傳圖片至本地JavaWeb服務器

prop prefix adt ilo err 1.10 response try 轉換成

服務器端:

需要一個接受文件的servlet,以及導入兩個包:commons-fileupload-1.3.1.jar 和 commons-io-2.4.jar

import java.io.File;  
import java.io.FileOutputStream;  
import java.io.IOException;  
import java.io.InputStream;  
import java.io.PrintWriter;  
import java.util.List;  
 
import javax.servlet.ServletException;  
import
javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileItemFactory; import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload; public class Upload extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ try{ request.setCharacterEncoding(
"UTF-8"); // 設置處理請求參數的編碼格式 response.setContentType("text/html;charset=UTF-8"); // 設置Content-Type字段值 PrintWriter out = response.getWriter(); //下面的代碼開始使用Commons-UploadFile組件處理上傳的文件數據 FileItemFactory factory = new DiskFileItemFactory(); // 建立FileItemFactory對象 ServletFileUpload upload = new ServletFileUpload(factory); //分析請求,並得到上傳文件的FileItem對象 List<FileItem> items = upload.parseRequest(request); //從web.xml文件中的參數中得到上傳文件的路徑 String uploadPath = "E:\\A_HW\\"; File file = new File(uploadPath); if (!file.exists()) { file.mkdir(); } String filename = ""; // 上傳文件保存到服務器的文件名 InputStream is = null; // 當前上傳文件的InputStream對象 //循環處理上傳文件 for (FileItem item : items) { //處理普通的表單域 if (item.isFormField()) { if (item.getFieldName().equals("imageFile")) //圖片文件的name { //如果新文件不為空,將其保存在filename中 if (!item.getString().equals("")) filename = item.getString("UTF-8"); } } //處理上傳文件 else if (item.getName() != null && !item.getName().equals("")) { //從客戶端發送過來的上傳文件路徑中截取文件名 filename = item.getName().substring( item.getName().lastIndexOf("\\") + 1); is = item.getInputStream(); // 得到上傳文件的InputStream對象 } } //將路徑和上傳文件名組合成完整的服務端路徑 filename = uploadPath + filename; //如果服務器已經存在和上傳文件同名的文件,則輸出提示信息 if (new File(filename).exists()) { new File(filename).delete(); } //開始上傳文件 if (!filename.equals("")) { //用FileOutputStream打開服務端的上傳文件 FileOutputStream fos = new FileOutputStream(filename); byte[] buffer = new byte[8192]; // 每次讀8K字節 int count = 0; //開始讀取上傳文件的字節,並將其輸出到服務端的上傳文件輸出流中 while ((count = is.read(buffer)) > 0) { fos.write(buffer, 0, count); // 向服務端文件寫入字節流 } fos.close(); // 關閉FileOutputStream對象 is.close(); // InputStream對象 out.println("文件上傳成功!"); } }catch (Exception e) { e.printStackTrace(); } } }
註意:imageFile要和之後Android端名字的對應

客戶端:

我是直接通過拍照獲取的圖片,所以首先獲取圖片的位置

private void doTakePhoto() {
        Intent intent = new Intent();
        // 指定開啟系統相機的Action
        intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        String time = String.valueOf(System.currentTimeMillis());
        // 根據文件地址創建文件
        File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
                + "/M2_test/" + time + ".jpg");
        Log.i("Environment_path", Environment.getExternalStorageDirectory().getAbsolutePath());
        file.getParentFile().mkdirs();
        if (file.exists()) {
            file.delete();
        }
        // 把文件地址轉換成Uri格式
        Uri uri2 = Uri.fromFile(file);
        Uri uri = FileProvider.getUriForFile(getContext(), "com.f.myapplication", file);
        //添加權限
        Log.i("uri",uri.toString());
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //臨時授權
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
        startActivityForResult(intent, REQUEST_CAMERA);


        String imagePath = Environment.getExternalStorageDirectory().getAbsolutePath()
                + "/M2_test/" + time + ".jpg";

        imageCheck(uri2,imagePath);

        iniLocationMap();

//        uploadImage(imagePath);
    }

獲取到的圖片進行查看,通過bundle傳遞image的uri

private void imageCheck(Uri uri,String img) {

        String imagepath = uri.toString();
        Image_check image_check = new Image_check();
        Bundle bundle = new Bundle();
        bundle.putString("imagepath", imagepath);
        bundle.putString("img",img);
        image_check.setArguments(bundle);
        ft.replace(R.id.fragment_content,image_check);  //這個是我fragment替換
        ft.addToBackStack(null);
        ft.commit();
    }
Image_check是一個Fragment可以查看圖片並通過點擊按鈕實現上傳文件(需要點擊預覽圖片,獲取到圖片位置,才能上傳圖片)
技術分享圖片
public class Image_check  extends Fragment {

    private EditText et_beizhu;
    private Button btn_upload;
    private Button btn_look_pic;
    private ImageView iv;
    private FragActivity_Map fragActivity_map;
    String imagepath="";
    String img;
    private FragmentManager fm;
    private FragmentTransaction ft;
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.image_check, container, false);
        fm = getFragmentManager();
        ft = fm.beginTransaction();
        fragActivity_map=new FragActivity_Map();
        iv=view.findViewById(R.id.imageView);
        btn_upload= view.findViewById(R.id.btn_upload);
        btn_look_pic= view.findViewById(R.id.btn_look_pic);
        if (getArguments() != null) {
            imagepath = getArguments().getString("imagepath");
            Log.i("image_check_image",imagepath);
        }

        btn_look_pic.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                iv.setImageURI( Uri.parse(imagepath) );
            }
        });
        btn_upload.setOnClickListener(new View.OnClickListener() {
            @Override

            public void onClick(View v) {
                uploadImage(imagepath);
                FragActivity_Map frag_map = new FragActivity_Map();
                Bundle bundle = new Bundle();
                bundle.putString("result_image", "ok_upload");
                frag_map.setArguments(bundle);
                fm.beginTransaction().hide(Image_check.this).show(fragActivity_map).commit();
//                ft.replace(R.id.fragment_content,frag_map);
                ft.addToBackStack(null);
                ft.commit();
            }
        });


        return view;
    }

    //線程上傳圖片
    private void uploadImage(String imagePath) {
        Log.i("start upload", "start upload");
        Log.i("start upload_path", "imagePath" + imagePath);
        NetworkTask networkTask = new NetworkTask();
        networkTask.execute(imagePath);
    }

    public static Image_check newInstance(String text) {
        Image_check fragment = new Image_check();
        Bundle bundle = new Bundle();
        bundle.putString("imagepath", text);
        fragment.setArguments(bundle);
        return fragment;
    }
}

NetworkTask 是一個實現連接javaweb服務器的線程並調用上傳文件的工具類 UploadUtil
class NetworkTask extends AsyncTask<String, Integer, String> {
// 這裏就是JavaWeb服務器地址,servlet
    private final String ServerURL="http://192.168.1.105:8080/File_upload/Upload";
    @Override
    protected void onPreExecute() {
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... params) {
//        return doPost(params[0]);
        String uri = (params[0]);
        Uri u=Uri.parse((String) uri);
        File file = new File(u.getPath());
        return UploadUtil.uploadFile(file, ServerURL);
    }
    @Override
    protected void onPostExecute(String result) {
        if (UploadUtil.SUCCESS.equalsIgnoreCase(result)) {
            Log.i("上傳結果", "上傳成功 ");
        } else {
            Log.i("上傳結果", "上傳失敗 ");
        }
    }
}
UploadUtil工具類(啊哈,網上找的)


public class UploadUtil {
    private static final int TIME_OUT = 10 * 10000000;   //超時時間
    private static final String CHARSET = "utf-8"; //設置編碼
    public static final String SUCCESS = "1";
    public static final String FAILURE = "0";

    public static String uploadFile(File file, String RequestURL) {
        String BOUNDARY = UUID.randomUUID().toString();  //邊界標識   隨機生成
        String PREFIX = "--", LINE_END = "\r\n";

        try {
            URL url = new URL(RequestURL);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setReadTimeout(TIME_OUT);
            conn.setConnectTimeout(TIME_OUT);
            conn.setDoInput(true);  //允許輸入流
            conn.setDoOutput(true); //允許輸出流
            conn.setUseCaches(false);  //不允許使用緩存
            conn.setRequestMethod("POST");  //請求方式
            conn.setRequestProperty("Charset", CHARSET);  //設置編碼
            conn.setRequestProperty("connection", "keep-alive");
            conn.setRequestProperty("Content-Type", "multipart/form-data" + ";boundary=" + BOUNDARY);
            if (file != null) {
                OutputStream outputSteam = conn.getOutputStream();
                DataOutputStream dos = new DataOutputStream(outputSteam);
                StringBuffer sb = new StringBuffer();
                sb.append(PREFIX);
                sb.append(BOUNDARY);
                sb.append(LINE_END);
                /**
                 * 這裏重點註意:
                 * name裏面的值為服務器端需要key   只有這個key 才可以得到對應的文件
                 * filename是文件的名字,包含後綴名的   比如:abc.png
                 */

                Log.i("file.getName()",file.getName());
                sb.append("Content-Disposition: form-data; name=\"imageFile\"; filename=\"" + file.getName() + "\"" + LINE_END);
                sb.append("Content-Type: application/octet-stream; charset=" + CHARSET + LINE_END);
                sb.append(LINE_END);
                dos.write(sb.toString().getBytes());
                InputStream is = new FileInputStream(file);
                byte[] bytes = new byte[1024];
                int len = 0;
                while ((len = is.read(bytes)) != -1) {
                    dos.write(bytes, 0, len);
                }
                is.close();
                dos.write(LINE_END.getBytes());
                byte[] end_data = (PREFIX + BOUNDARY + PREFIX + LINE_END).getBytes();
                dos.write(end_data);
                dos.flush();
                dos.close();
                /**
                 * 獲取響應碼  200=成功
                 * 當響應成功,獲取響應的流
                 */
                int res = conn.getResponseCode();
                Log.e("response code", "response code:" + res);
                if (res == 200) {
                    return SUCCESS;
                }
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return FAILURE;
    }
}





當然當中遇到了很多問題,必須要仔仔細細看錯誤提示啊
註意
    • 開了Tomcat服務器後,要關閉電腦的防火墻,要不然可能連接不上
 

在fragment中實現Android上傳圖片至本地JavaWeb服務器