在Android中使用Retrofit进行图片文件上传时没有这样的文件或难以处理的错误 [英] No such file or diectory error in image file upload using Retrofit in Android

查看:216
本文介绍了在Android中使用Retrofit进行图片文件上传时没有这样的文件或难以处理的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个Android应用程序。在我的应用程序中,我使用Retrofit将图像和PDF文件上载到多服务器/表单数据请求中。我是新的改造。

我成功上传了pdf文件和其他字符串数据。但是当我上传图片文件时,即使我做了和上传成功的PDF文件一样的东西,也给了我没有这样的文件或目录的例外。



我的活动上传PDF文件和图像文件

  public class ContributeActivity extends AppCompatActivity {

public static final int SELECT_PICTURE = 2334;
public static final int SELECT_BOOK = 123;

//其他属性
私有文件bookFile;
私有文件imageFile;

@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
app =(AppSingleton)getApplication();
app.initialize();
setContentView(R.layout.activity_contribute);
工具栏工具栏=(工具栏)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar()。setDisplayHomeAsUpEnabled(true);
//执行其他步骤
}

private void saveBtnClick()
{
contributeBook();


private void openImagePicker()
{
Intent intent = new Intent();
intent.setType(image / *);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,Select Picture),SELECT_PICTURE);

$ b $ private void setUpFilePickerImage()
{
ivBookFile.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v){
openBookFilePicker();
}
});


private void openBookFilePicker()
{
Intent intent = new Intent();
intent.setType(* / *);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,Select file),SELECT_BOOK);

$ b $ @覆盖
保护无效onActivityResult(int requestCode,int resultCode,意图数据){
if(resultCode == RESULT_OK){
if (requestCode == SELECT_PICTURE){
Uri selectedImageUri = data.getData();
if(selectedImageUri!= null)
{
try {
bmpCoverImage = MediaStore.Images.Media.getBitmap(getContentResolver(),selectedImageUri);
imageFile = new File(selectedImageUri.getPath());
if(bmpCoverImage!= null)
{
ivCoverImage.setImageBitmap(bmpCoverImage);

$ catch(IOException e)
{
Toast.makeText(getBaseContext(),选中的文件发生错误,Toast.LENGTH_SHORT) 。显示();


$ b else if(requestCode == SELECT_BOOK)
{
Uri bookUri = data.getData();
if(bookUri!= null)
{
String filePath = bookUri.toString(); // bookUri.toString()
String mime = app.getMimeType(filePath);
if(mime!= null&&!mime.isEmpty()& amp;(mime.toLowerCase()==application / pdf|| mime.toLowerCase()==application / txt || mime.toLowerCase()==application / text))
{
bookFile = new File(bookUri.getPath());
ivBookFile.setImageResource(R.drawable.book_selected);
}
else {
Toast.makeText(getBaseContext(),无法处理您选择的文件,Toast.LENGTH_SHORT).show();





私有布尔值validateForm()
{

//验证
返回true;


private void contributeBook()
{
RetrofitService service = RetrofitClient.retrofit.create(RetrofitService.class);
MultipartBody.Part bodyBookFile = null;
if(bookFile!= null)
{
RequestBody requestFile = RequestBody.create(MediaType.parse(multipart / form-data),bookFile);
bodyBookFile = MultipartBody.Part.createFormData(book_file,bookFile.getName(),requestFile);
}

MultipartBody.Part bodyImageFile = null;
if(imageFile!= null)
{
RequestBody requestImageFile = RequestBody.create(MediaType.parse(multipart / form-data),imageFile);
bodyImageFile = MultipartBody.Part.createFormData(image_file,imageFile.getName(),requestImageFile);


RequestBody title = RequestBody.create(MediaType.parse(multipart / form-data),tfTitle.getText()。toString());
RequestBody mmTitle = RequestBody.create(MediaType.parse(multipart / form-data),tfMmTitle.getText()。toString());
RequestBody parentId = RequestBody.create(MediaType.parse(multipart / form-data),String.valueOf(selectedParentId));
RequestBody childId = RequestBody.create(MediaType.parse(multipart / form-data),String.valueOf(selectedChildId));
RequestBody authorName = RequestBody.create(MediaType.parse(multipart / form-data),tfAuthorName.getText()。toString());
RequestBody authorMmName = RequestBody.create(MediaType.parse(multipart / form-data),tfAuthorMmName.getText()。toString());
RequestBody authToken = RequestBody.create(MediaType.parse(multipart / form-data),app.getAuthToken());

呼叫< ResponseBody> call = service.contributeBook(bodyImageFile,bodyBookFile,title,mmTitle,parentId,childId,authorName,authorMmName,authToken);
call.enqueue(new Callback< ResponseBody>(){
@Override
public void onResponse(Call< ResponseBody> call,Response< ResponseBody> response){
if != null&& response.isSuccessful())
{
Toast.makeText(getBaseContext(),Book successfully contribute。Thank you。,Toast.LENGTH_SHORT).show();

else if(response!= null&&!response.isSuccessful()&& response.errorBody()!= null)
{
// server错误
Toast.makeText(getBaseContext(),Validation errors,Toast.LENGTH_SHORT).show();
}
else {
Toast.makeText(getBaseContext(), 服务器发生错误,Toast.LENGTH_SHORT).show();
}
}

@Override
publ ic void onFailure(Call< ResponseBody> call,Throwable t){
Toast.makeText(getBaseContext(),t.getMessage(),Toast.LENGTH_SHORT).show();
}
});




$ b $ p $这是我的改造服务界面

  public interface RetrofitService {
@Multipart
@POST(book / contribution)
Call< ResponseBody>请参阅参考资料(请参阅参考资料部分)。参考资料您可以参阅本文在developerWorks全球站点上的英文原文。 @Part(child_category_id)RequestBody childId
,@ Part(author_name)RequestBody authorName,@ Part(author_mm_name)RequestBody authorMmName,@ Part(auth_token)RequestBody authToken);



$ b $ p
$ b这是我翻新的客户端类

  public class RetrofitClient {
//执行开始 - 应该在不同的类中
public static final Retrofit retrofit = new Retrofit.Builder()
.baseUrl(LinkConfig.API_END_POINT)
.client(RetrofitClient.httpClient())
.addConverterFactory(GsonConverterFactory.create())
.build();
$ b $ public static OkHttpClient httpClient()
{
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor(){
@Override
public response(interceptor.chain chain)throws IOException {
Request original = chain.request();

请求请求= original.newBuilder()
.header(AppSingleton.API_KEY_FIELD,AppSingleton.API_KEY)
.method(original.method(),original.body())
.build();

return chain.proceed(request);
}
});
返回httpClient.build();




$ b $ p
$ b

使用上面的代码,我发送PDF文件与其他字符串字段,但没有图像文件字段。一切正常。 PDF文件成功上传到服务器,数据保存在数据库中。但是,当我选择图像文件,并提交数据到服务器,它给了我错误侦听器改造后的错误。





在我第一次上传pdf文件之前,我得到了这个错误。选择文件后,我必须在活动结果中进行更改。



  uri.toString()



  uri.getPath()

但是正如您所见,我对活动结果中的PDF文件和图像文件做了同样的事情。但是,PDF文件运行良好,图像文件给我错误。

这些是在清单文件中设置的权限

 < uses-permission android:name =android.permission.ACCESS_WIFI_STATE/> 
<使用权限android:name =android.permission.ACCESS_NETWORK_STATE/>
< 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/>


解决方案

 设备版本比Api Level 22多,然后在运行时请求权限,我也面临同样的问题,试着在运行时检查权限
$ b $ private static final REQUEST_EXTERNAL_STORAGE = 3;
private static String [] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};

$ b $ public void checkStoragePermissions(Activity activity,Intent intent){
//检查是否有写权限
int permission = ActivityCompat.checkSelfPermission(activity,Manifest。 permission.WRITE_EXTERNAL_STORAGE);

if(permission!= PackageManager.PERMISSION_GRANTED){
//我们没有权限,所以提示用户
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
} else {
activity.startActivity(intent);
}
}


I am developing an Android app. In my app, I am using Retrofit to upload image and pdf files to server in multipart/form-data request. I am new to Retrofit.

I uploaded pdf file and other string data successfully. But when I upload Image file, it is giving me "No such file or directory" exception even I did the same thing as PDF file that is successfully uploaded.

This is my activity upload pdf file and image file

public class ContributeActivity extends AppCompatActivity {

    public static final int SELECT_PICTURE = 2334;
    public static final int SELECT_BOOK  = 123;

    //other properties
    private File bookFile;
    private File imageFile;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        app = (AppSingleton)getApplication();
        app.initialize();
        setContentView(R.layout.activity_contribute);
        Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        //do other steps
    }

    private void saveBtnClick()
    {
        contributeBook();
    }

    private void openImagePicker()
    {
        Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select Picture"), SELECT_PICTURE);
    }

    private void setUpFilePickerImage()
    {
        ivBookFile.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                openBookFilePicker();
            }
        });
    }

    private void openBookFilePicker()
    {
        Intent intent = new Intent();
        intent.setType("*/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);
        startActivityForResult(Intent.createChooser(intent, "Select file"), SELECT_BOOK);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            if (requestCode == SELECT_PICTURE) {
                Uri selectedImageUri = data.getData();
                if(selectedImageUri!=null)
                {
                    try{
                        bmpCoverImage = MediaStore.Images.Media.getBitmap(getContentResolver(), selectedImageUri);
                        imageFile = new File(selectedImageUri.getPath());
                        if(bmpCoverImage!=null)
                        {
                            ivCoverImage.setImageBitmap(bmpCoverImage);
                        }
                    }
                    catch (IOException e)
                    {
                        Toast.makeText(getBaseContext(),"An error occurred with the file selected",Toast.LENGTH_SHORT).show();
                    }
                }
            }
            else if(requestCode==SELECT_BOOK)
            {
                Uri bookUri = data.getData();
                if(bookUri!=null)
                {
                    String filePath = bookUri.toString();//bookUri.toString()
                    String mime = app.getMimeType(filePath);
                    if(mime!=null && !mime.isEmpty() && (mime.toLowerCase()=="application/pdf" || mime.toLowerCase()=="application/txt" || mime.toLowerCase()=="application/text"))
                    {
                        bookFile = new File(bookUri.getPath());
                        ivBookFile.setImageResource(R.drawable.book_selected);
                    }
                    else{
                        Toast.makeText(getBaseContext(),"Unable to process file you have chosen.",Toast.LENGTH_SHORT).show();
                    }
                }
            }
        }
    }

    private Boolean validateForm()
    {

        // do validation
        return true;
    }

    private void contributeBook()
    {
        RetrofitService service = RetrofitClient.retrofit.create(RetrofitService.class);
        MultipartBody.Part bodyBookFile = null;
        if(bookFile!=null)
        {
            RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), bookFile);
            bodyBookFile = MultipartBody.Part.createFormData("book_file", bookFile.getName(), requestFile);
        }

        MultipartBody.Part bodyImageFile = null;
        if(imageFile!=null)
        {
            RequestBody requestImageFile = RequestBody.create(MediaType.parse("multipart/form-data"), imageFile);
            bodyImageFile = MultipartBody.Part.createFormData("image_file",imageFile.getName(),requestImageFile);
        }

        RequestBody title = RequestBody.create(MediaType.parse("multipart/form-data"), tfTitle.getText().toString());
        RequestBody mmTitle = RequestBody.create(MediaType.parse("multipart/form-data"), tfMmTitle.getText().toString());
        RequestBody parentId = RequestBody.create(MediaType.parse("multipart/form-data"),String.valueOf(selectedParentId));
        RequestBody childId = RequestBody.create(MediaType.parse("multipart/form-data"), String.valueOf(selectedChildId));
        RequestBody authorName = RequestBody.create(MediaType.parse("multipart/form-data"), tfAuthorName.getText().toString());
        RequestBody authorMmName = RequestBody.create(MediaType.parse("multipart/form-data"), tfAuthorMmName.getText().toString());
        RequestBody authToken = RequestBody.create(MediaType.parse("multipart/form-data"),app.getAuthToken());

        Call<ResponseBody> call = service.contributeBook(bodyImageFile,bodyBookFile,title,mmTitle,parentId,childId,authorName,authorMmName,authToken);
        call.enqueue(new Callback<ResponseBody>() {
            @Override
            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
                if(response!=null && response.isSuccessful())
                {
                    Toast.makeText(getBaseContext(),"Book successfully contributed. Thank you.",Toast.LENGTH_SHORT).show();
                }
                else if(response!=null && !response.isSuccessful() && response.errorBody()!=null)
                {
                    //server error
                    Toast.makeText(getBaseContext(),"Validation errors",Toast.LENGTH_SHORT).show();
                }
                else{
                    Toast.makeText(getBaseContext(),"An error occurred in server",Toast.LENGTH_SHORT).show();
                }
            }

            @Override
            public void onFailure(Call<ResponseBody> call, Throwable t) {
                Toast.makeText(getBaseContext(),t.getMessage(),Toast.LENGTH_SHORT).show();
            }
        });
    }
}

This is my retrofit service interface

public interface RetrofitService {
    @Multipart
    @POST("book/contribute")
    Call<ResponseBody> contributeBook(@Part MultipartBody.Part imageFile,@Part MultipartBody.Part bookFile,@Part("title") RequestBody title
    ,@Part("mm_title") RequestBody mmTitle,@Part("parent_category_id") RequestBody parentId,@Part("child_category_id") RequestBody childId
    ,@Part("author_name") RequestBody authorName,@Part("author_mm_name") RequestBody authorMmName,@Part("auth_token") RequestBody authToken);
}

This is my retrofit client class

public class RetrofitClient {
    //implementation starts - should be in different class
    public static final Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(LinkConfig.API_END_POINT)
            .client(RetrofitClient.httpClient())
            .addConverterFactory(GsonConverterFactory.create())
            .build();

    public static OkHttpClient httpClient()
    {
        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
        httpClient.addInterceptor(new Interceptor() {
            @Override
            public Response intercept(Interceptor.Chain chain) throws IOException {
                Request original = chain.request();

                Request request = original.newBuilder()
                        .header(AppSingleton.API_KEY_FIELD, AppSingleton.API_KEY)
                        .method(original.method(), original.body())
                        .build();

                return chain.proceed(request);
            }
        });
        return httpClient.build();
    }
}

With the above code, I send pdf file with other string fields but without image file field. Everything worked fine. PDF file successfully uploaded to server and data are saved in the database. But when I chose the image file and submit data to server, it gives me following error in error listener of retrofit.

I got that error before when I first upload pdf file. I have to change as in activity result after choosing file.

From

uri.toString()

To

uri.getPath()

But as you can see, I did the same thing to both PDF file and Image file in activity result. But PDF file is working well and image file is giving me error.

These are permissions set in manifest file

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <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" />

解决方案

If your device Version Is more then Api Level  22, then ask for permission at runtime, i also face the same problem, try to check permission at run time

  private static final int REQUEST_EXTERNAL_STORAGE = 3;
    private static String[] PERMISSIONS_STORAGE = {
            Manifest.permission.READ_EXTERNAL_STORAGE,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
    };


public  void checkStoragePermissions(Activity activity,Intent intent) {
        // Check if we have write permission
        int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);

        if (permission != PackageManager.PERMISSION_GRANTED) {
            // We don't have permission so prompt the user
            ActivityCompat.requestPermissions(
                    activity,
                    PERMISSIONS_STORAGE,
                    REQUEST_EXTERNAL_STORAGE
            );
        }else{
            activity.startActivity(intent);
        }
    }

这篇关于在Android中使用Retrofit进行图片文件上传时没有这样的文件或难以处理的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆