文件上傳

1.導(dǎo)依賴

 //okhttp
implementation 'com.squareup.okhttp3:okhttp:3.11.0'
    //butterknife
implementation 'com.jakewharton:butterknife:8.8.1'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
    //glide
implementation 'com.github.bumptech.glide:glide:4.8.0'
annotationProcessor 'com.github.bumptech.glide:compiler:4.8.0'
    //gson
implementation 'com.google.code.gson:gson:2.2.4'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0' // 必要依賴嗦玖,解析json字符所用
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.4.0' // 必要依賴又谋,和Rxjava結(jié)合必須用到,下面會(huì)提到
implementation "io.reactivex.rxjava2:rxjava:2.1.3" // 必要rxjava2依賴
implementation "io.reactivex.rxjava2:rxandroid:2.0.1" // 必要rxandrroid依賴墨辛,切線程時(shí)需要用到

2.OK上傳

private void okHttpUpload() {
        //上傳一個(gè)sd卡圖片,處理權(quán)限
        //注意文件位置
        File file = new File("/storage/emulated/legacy/Pictures/g.png");
        //ok 網(wǎng)絡(luò)請(qǐng)求, okhttpclinet.newCall().enqueue()
        //提交文件的請(qǐng)求,里面含文件
        MediaType parse = MediaType.parse("application/octet-stream");
        RequestBody fileBody = RequestBody.create(parse, file);
        //分塊請(qǐng)求的請(qǐng)求體
        RequestBody body = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("key", "857")//指定服務(wù)器保存圖片的文件夾
                .addFormDataPart("file", file.getName(), fileBody)//上傳的文件
                .build();

        Request request = new Request.Builder()
                .url(mUrl)
                .post(body)
                .build();

        mOkHttpClient.newCall(request)
                .enqueue(new Callback() {
                    @Override
                    public void onFailure(Call call, IOException e) {
                        Log.d(TAG, "onFailure: " + e.toString());
                    }

                    @Override
                    public void onResponse(Call call, Response response) throws IOException {
                        Log.d(TAG, "onResponse: " + response.body().string());
                    }
                });
    }

3.Retrofit上傳

//底層是ok
    private void retrofitUpload() {
        File file = new File("/storage/emulated/legacy/Pictures/o.jpg");
        if (!file.exists()) {
            try {
                file.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        MediaType parse = MediaType.parse("application/octet-stream");
        RequestBody requestBody = MultipartBody.create(parse, file);
        MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), requestBody);
        new Retrofit.Builder()
                .baseUrl(ApiService.url_up)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .build()
                .create(ApiService.class)
                .getUp(part)
                .enqueue(new Callback<ResponseBody>() {
                    @Override
                    public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                        try {
                            String string = response.body().string();
                            Log.e(TAG, "onResponse: " + string);
                            String[] split = string.split("<br />");
                            String s = split[split.length - 1];
                            UpBean upBean = new Gson().fromJson(s, UpBean.class);
                            Glide.with(LoadActivity.this).load(upBean.getData().getUrl()).into(iv);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }

                    @Override
                    public void onFailure(Call<ResponseBody> call, Throwable t) {

                    }
                });
    }

4.HttpUrlCollection上傳

HashMap<String, String> map = new HashMap<>();
                map.put("key", "666");
                File file = new File("/storage/emulated/legacy/Pictures/g.png");
                new Thread(new Runnable() {
                    @Override
                    public void run() {
                        uploadForm(null, "file", file, "xxx.jpg", mUrl);
                    }
                }).start();

public void uploadForm(Map<String, String> params, String fileFormName, File uploadFile, String newFileName, String urlStr) {
        if (newFileName == null || newFileName.trim().equals("")) {
            newFileName = uploadFile.getName();
        }
        StringBuilder sb = new StringBuilder();
        /**
         * 普通的表單數(shù)據(jù)
         */
        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");
            }
        }

        try {
            /**
             * 上傳文件的頭
             */
            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");// 如果服務(wù)器端有文件類型的校驗(yà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 = null;
            url = new URL(urlStr);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            // 設(shè)置傳輸內(nèi)容的格式,以及長(zhǎng)度
            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);
            //寫入的文件長(zhǎng)度
            int count = 0;
            //文件的總長(zhǎng)度
            int available = in.available();
            // 寫入頭部 (包含了普通的參數(shù)惫撰,以及文件的標(biāo)示等)
            out.write(headerInfo);
            // 寫入文件
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
                count += len;
                int progress = count * 100 / available;
                Log.d(TAG, "上傳進(jìn)度: " + progress + " %");
            }
            // 寫入尾部
            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();
        }
    }

5.拍照上傳

//拍照上傳,注意危險(xiǎn)權(quán)限處理
    private void takePhoto() {
        if (PackageManager.PERMISSION_GRANTED ==
                ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)) {
            //有權(quán)限
            openCamera();
        } else {
            //沒有權(quán)限
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.CAMERA}, 200);
        }
    }
//開啟相機(jī)
    private void openCamera() {
        //系統(tǒng)所有的界面都是activity,啟動(dòng)activity方式幾種?
        //顯示啟動(dòng):指名道姓的啟動(dòng)
        //new Intent(this,MainActivity.class)
        //隱式啟動(dòng):不指名道姓,匹配的方式,data,category,action,系統(tǒng)的界面一般都是隱式啟動(dòng)
        //創(chuàng)建文件用于保存圖片
        mFile = new File(getExternalCacheDir(), System.currentTimeMillis() + ".jpg");
        if (!mFile.exists()) {
            try {
                mFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        //適配7.0以上
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            mImageUri = Uri.fromFile(mFile);
        } else {
            //第二個(gè)參數(shù)要和清單文件中的配置保持一致
            //私有目錄訪問受限,需要清單文件配置ContentProvider
            //如果不配置,會(huì)報(bào)FileUriExposedException: file:///storage/emulated/0/Android/data/com.xts.upload/cache/1589178590497.jpg
            mImageUri = FileProvider.getUriForFile(this, "com.example.upload", mFile);
        }

        //啟動(dòng)相機(jī)
        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);//將拍照?qǐng)D片存入mImageUri
        startActivityForResult(intent, CAMERA_CODE);
    }

6.相冊(cè)上傳

//開啟相冊(cè)選取圖片上傳
    private void album() {
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        startActivityForResult(intent, ALBUM_CODE);
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌姚建,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件吱殉,死亡現(xiàn)場(chǎng)離奇詭異掸冤,居然都是意外死亡厘托,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門贩虾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來催烘,“玉大人,你說我怎么就攤上這事缎罢∫寥海” “怎么了?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵策精,是天一觀的道長(zhǎng)舰始。 經(jīng)常有香客問我,道長(zhǎng)咽袜,這世上最難降的妖魔是什么丸卷? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮询刹,結(jié)果婚禮上谜嫉,老公的妹妹穿的比我還像新娘。我一直安慰自己凹联,他們只是感情好沐兰,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著蔽挠,像睡著了一般住闯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上澳淑,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天比原,我揣著相機(jī)與錄音,去河邊找鬼杠巡。 笑死量窘,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的氢拥。 我是一名探鬼主播蚌铜,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼畴博,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼涉瘾!你這毒婦竟也來了鞋吉?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤出革,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后渡讼,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體骂束,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡耳璧,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了展箱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片旨枯。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖混驰,靈堂內(nèi)的尸體忽然破棺而出攀隔,到底是詐尸還是另有隱情,我是刑警寧澤栖榨,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布昆汹,位于F島的核電站,受9級(jí)特大地震影響婴栽,放射性物質(zhì)發(fā)生泄漏满粗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一愚争、第九天 我趴在偏房一處隱蔽的房頂上張望映皆。 院中可真熱鬧,春花似錦轰枝、人聲如沸捅彻。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沟饥。三九已至,卻和暖如春湾戳,著一層夾襖步出監(jiān)牢的瞬間贤旷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工砾脑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留幼驶,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓韧衣,卻偏偏與公主長(zhǎng)得像盅藻,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子畅铭,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354