文件上传

依赖

   //gson
    implementation 'com.google.code.gson:gson:2.8.5'
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
    //glide
    implementation 'com.github.bumptech.glide:glide:4.8.0'
    //OkHttp
    implementation 'com.squareup.okhttp3:okhttp:3.12.0'
    //RxJava
    implementation 'io.reactivex.rxjava2:rxjava:2.2.4'
    implementation 'io.reactivex.rxjava2:rxandroid:2.1.0'
    implementation 'com.squareup.retrofit2:retrofit:2.5.0'//retrofit 库
    implementation 'com.squareup.retrofit2:converter-gson:2.5.0'//转换器,请求结果转换成Model
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.5.0'//配合Rxjava 使用
    //权限
    implementation 'com.github.dfqin:grantor:2.5'

添加权限

  <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

获取危险权限

  private void getPermission() {
        PermissionsUtil.requestPermission(this, new PermissionListener() {
            @Override
            public void permissionGranted(@NonNull String[] permission) {

            }

            @Override
            public void permissionDenied(@NonNull String[] permission) {

            }
        }, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE});
    }

文件路径

private File file = new File(Environment.getExternalStorageDirectory() + "/Pictures/a.jpg");

bean类

public class UploadBean {
    /**
     * code : 200
     * res : 上传文件成功
     * data : {"url":"http://yun918.cn/study/public/uploadfiles/1908A/b.jpg"}
     */

    private int code;
    private String res;
    private DataBean data;

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getRes() {
        return res;
    }

    public void setRes(String res) {
        this.res = res;
    }

    public DataBean getData() {
        return data;
    }

    public void setData(DataBean data) {
        this.data = data;
    }

    public static class DataBean {
        /**
         * url : http://yun918.cn/study/public/uploadfiles/1908A/b.jpg
         */

        private String url;

        public String getUrl() {
            return url;
        }

        public void setUrl(String url) {
            this.url = url;
        }
    }
}

一、Ok上传

   //获取OK对象
        OkHttpClient okHttpClient = new OkHttpClient.Builder().build();
        //获取请求体
        RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpg"), file);
        //多类型请求体
        MultipartBody body = new MultipartBody.Builder()
                .setType(MultipartBody.FORM)
                .addFormDataPart("key", "tian")
                .addFormDataPart("file", file.getName(), requestBody)
                .build();
        //获取request对象
        Request request = new Request.Builder()
                .url("http://yun918.cn/study/public/file_upload.php")
                .post(body)
                .build();
        //获取call对象
        Call call = okHttpClient.newCall(request);
        //call执行请求
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Log.e("TAG", "onFailure: 网络错误" + e.getMessage());
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                String json = response.body().string();
                UploadBean uploadBean = new Gson().fromJson(json, UploadBean.class);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        Toast.makeText(MainActivity.this, uploadBean.getRes(), Toast.LENGTH_SHORT).show();
                        Glide.with(MainActivity.this).load(uploadBean.getData().getUrl()).into(ivImg);
                    }
                });
            }
        });

二、Retrofit上传文件

·接口

public interface ApiService {
    String baseUrl = "http://yun918.cn/";

    @POST("study/public/file_upload.php")
    @Multipart
    Observable<UploadBean> upLoad(@Part("key") RequestBody key, @Part MultipartBody.Part file);
}

·上传

   //创建retrofit对象
        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(ApiService.baseUrl)
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .build();
        //创建接口service对象
        ApiService apiService = retrofit.create(ApiService.class);
        //封装请求体
        RequestBody body= RequestBody.create(MediaType.parse("image/png"), file);
        //文件封装
        MultipartBody.Part file = MultipartBody.Part.createFormData("file", this.file.getName(), body);
        //文本封装
        RequestBody requestBody  = body.create(MediaType.parse("multipart/form-data"), "tian");
        Observable<UploadBean> observable = apiService.upLoad(requestBody , file);
        //发送网络请求并处理结果
        observable
                .subscribeOn(Schedulers.io())//子线程请求
                .observeOn(AndroidSchedulers.mainThread())//主线程操作
                .subscribe(new Observer<UploadBean>() {
                    @Override
                    public void onSubscribe(Disposable d) {

                    }

                    @Override
                    public void onNext(UploadBean uploadBean) {
                        Toast.makeText(MainActivity.this, uploadBean.getRes(), Toast.LENGTH_SHORT).show();
                        Glide.with(MainActivity.this).load(uploadBean.getData().getUrl()).into(ivImg);
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e("TAG", "onError: 网络错误" + e.getMessage());
                    }

                    @Override
                    public void onComplete() {

                    }
                });

三、拍照(album)上传文件

访问相机权限
<uses-permission android:name="android.permission.CAMERA"/>

获取权限

/**
     * 获取权限
     */
    private void getPermission() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
            //如果有就打开相机
            openCamera();
        } else {
            //获取相机权限
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 100);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //打开相机
            openCamera();
        }
    }

打开相机

 /**
     * 打开相机
     */
    private void openCamera() {
        //创建文件用于保存图片
        cameraFile = new File(getCacheDir(), System.currentTimeMillis() + ".jpg");
        //如果不存在
        if (!cameraFile.exists()) {
            try {
                cameraFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //判断兼容7.0设备
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
            imgUri = Uri.fromFile(cameraFile);
        } else {
            imgUri = FileProvider.getUriForFile(this, "com.tianyu.upload_album.provider", cameraFile);
        }

        Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, imgUri);//将拍好的图片存入指定的uri
        startActivityForResult(intent, 200);
    }

    /**
     * 获取拍照结果
     */
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == 200) {
            //OK
            uploadOk(cameraFile);
        }
    }

4.清单文件中配置FileProvider:

     <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.tianyu.upload_album.provider"
            android:exported="false"
            android:grantUriPermissions="true">

            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />

        </provider>

5.需要在res/xml下创建一个file_paths.xml文件

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <root-path name="upload" path=""/>
</paths>

4相册选取照片

1.跳转相册

   private void opAlbum() {
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        startActivityForResult(intent, 300);
    }

2.处理回传数据

 @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
       if (requestCode == 300) {
            Uri uri = data.getData();
            File file = getFileFromUri(uri);
            if (file.exists()) {
                uploadOk(file);
            }
        }
    }

3.判断接收回来的uri不为空 处理版本

private File getFileFromUri(Uri uri) {

        if (uri == null) {
            return null;
        }
        //处理uri,7.0以后的fileProvider 把URI 以content provider 方式 对外提供的解析方法
        switch (uri.getScheme()) {
            case "content"://7.0以后
                return getFileFromContentUri(uri);
            case "file"://7.0以前
                return new File(uri.getPath());
            default:
                return null;
        }
    }

4.如果是7.0以后的内容提供者解析内容

private File getFileFromContentUri(Uri uri) {
        File file = null;
        String filePath = null;
        ContentResolver resolver = getContentResolver();
        String[] filePathColumn = {MediaStore.MediaColumns.DATA};

        Cursor cursor = resolver.query(uri, filePathColumn, null, null, null);
        if (cursor.moveToNext()) {

            filePath = cursor.getString(cursor.getColumnIndex(filePathColumn[0]));
        }
        cursor.close();

        if (!TextUtils.isEmpty(filePath)) {
            file = new File(filePath);
        }
        return file;

    }

注意事项

  1. Android P全面禁止了非https链接
    我们需要在自己设置非安全连接。
    非安全连接设置:在清单列表加一句
    默认允许所有网址使用非安全连接
android:usesCleartextTraffic="true"
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,137评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,824评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,465评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,131评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,140评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,895评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,535评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,435评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,952评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,081评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,210评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,896评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,552评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,089评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,198评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,531评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,209评论 2 357