Upload multi files using retrofit
Bài đăng này đã không được cập nhật trong 7 năm
Xin chào tất cả các bạn, Ở bài viết đầu tiên mình đã hướng dẫn các bạn sử dụng và upload single file với retrofit Ở bài này mình sẽ hướng dẫn các bạn upload multi files với retrofit
Đầu tiên khởi tạo server.
$data = [];
if(isset($_FILES['uploaded_file']) && is_array($_FILES['uploaded_file'])){
$file=$_FILES['uploaded_file'];
$file_path = "uploads/";
foreach ($file['tmp_name'] as $key => $value) {
$file_path = $file_path . basename($file['name'][$key]);
if(move_uploaded_file($file['tmp_name'][$key], $file_path) ){
$data['message'] = 'success';
$data['url'][$key] = 'http://test.toidicode.com/'.$file_path;
} else{
$data['message'] = 'fail';
}
}
echo json_encode($data);
}
else{
$data['message'] = 'fail';
echo json_encode($data);
}
Đã có server vậy chúng ta bắt đầu thôi.
- Đầu tiên để có thể upload ảnh sử dụng thư viện retrofit chúng ta cần import thư viện retrofit
Thêm compile vào trong file
build.gradle
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
- Tiếp theo để có thể load ảnh thì chúng ta phải chon được ảnh ở trong máy nên ta yêu cầu quyền READ_EXTERNAL_STORAGE và để có thể upload ảnh thì đương nhiên rồi INTERNET
khai báo dòng code sau trong file
manifest
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
- Vậy là đã đủ thư viện và các quyền vậy ta bắt đầu xây dựng giao diện cho app demo, ở đây mình chỉ xây dựng giao diện đơn giản gồm 1 button upload, 1 textview hiển thị danh sách các file sẽ upload và 1 textview hiển thị kết quả trả về.
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/linear_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="5dp"
tools:context="lol.toandoan.com.viblo_022017.MainActivity">
<Button
android:id="@+id/button_select_image"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Select Image"/>
<TextView
android:id="@+id/text_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Input"/>
<TextView
android:id="@+id/text_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:text="Result"/>
</LinearLayout>
- Tiến hành chọn các ảnh để upload
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
// Đây là base url của mình, các bạn thay bằng url của các bạn nhé
public static final String BASE_URL = "http://test.toidicode.com";
public final static int PICK_IMAGE_REQUEST = 1;
public final static int READ_EXTERNAL_REQUEST = 2;
private ProgressDialog mProgressDialog;
private TextView mTextResult;
private TextView mTextInput;
private LinearLayout mLinearMain;
private List<Uri> mUris = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.button_select_image).setOnClickListener(this);
mTextResult = (TextView) findViewById(R.id.text_result);
mTextInput = (TextView) findViewById(R.id.text_input);
}
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.button_select_image:
requestPermionAndPickImage();
break;
default:
break;
}
}
private void requestPermionAndPickImage() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
pickImage();
return;
}
// Các bạn nhớ request permison cho các máy M trở lên nhé, k là crash ngay đấy.
int result = ContextCompat.checkSelfPermission(this,
READ_EXTERNAL_STORAGE);
if (result == PackageManager.PERMISSION_GRANTED) {
pickImage();
} else {
requestPermissions(new String[]{
READ_EXTERNAL_STORAGE}, READ_EXTERNAL_REQUEST);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[],
int[] grantResults) {
if (requestCode != READ_EXTERNAL_REQUEST) return;
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
pickImage();
} else {
Toast.makeText(getApplicationContext(), R.string.permission_denied,
Toast.LENGTH_LONG).show();
}
}
public void pickImage() {
// Gọi intent của hệ thống để chọn ảnh nhé.
Intent intent = new Intent();
intent.setType("image/*");
// Thêm dòng này để có thể select nhiều ảnh trong 1 lần nhé các bạn
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Files to Upload"),
PICK_IMAGE_REQUEST);
}
@RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null &&
data.getClipData() != null) {
ClipData clipData = data.getClipData();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < clipData.getItemCount(); i++) {
ClipData.Item item = clipData.getItemAt(i);
Uri uri = item.getUri();
mUris.add(uri);
builder.append(i + "-")
.append(getRealPathFromURI(uri))
.append("\n");
}
mTextInput.setText(builder.toString());
// Sau khi get đc data thì ta upload thôi
uploadFiles();
}
}
private String getRealPathFromURI(Uri contentURI) {
String result;
Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);
if (cursor == null) {
result = contentURI.getPath();
} else {
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
result = cursor.getString(idx);
cursor.close();
}
return result;
}
- Sau khi chọn được ảnh việc bây giờ của chúng ta là upload ảnh thôi.
- Tạo class UploadService để define api upload của chúng ta nào
public interface UploadService {
@POST("/")
Call<ResponseBody> uploadFileMultilPart(@Body RequestBody files);
}
- Trong
MainActivity
chúng ta bắt đầu gọi hàm xử lý.
public void uploadFiles() {
if (mUris.isEmpty()) {
Toast.makeText(this, "Please select some image", Toast.LENGTH_SHORT).show();
return;
}
// Hàm call api sẽ mất 1 thời gian nên mình show 1 dialog nhé.
showProgress();
// Trong retrofit 2 để upload file ta sử dụng Multipart, khai báo 1 MultipartBody.Builder
// uploaded_file là key mà mình đã định nghĩa trong khi khởi tạo server
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(new OkHttpClient())
.build();
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
for (int i = 0; i < mUris.size(); i++) {
Uri uri = mUris.get(i);
File file = new File(getRealPathFromURI(uri));
// Khởi tạo RequestBody từ những file đã được chọn
RequestBody requestBody = RequestBody.create(
MediaType.parse("image/*"),
file);
// Add thêm request body vào trong builder
builder.addFormDataPart("uploaded_file", file.getName(), requestBody);
}
MultipartBody requestBody = builder.build();
UploadService service = retrofit.create(UploadService.class);
Call<ResponseBody> call = service.uploadFileMultilPart(requestBody);
call.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if (response == null || response.body() == null) {
mTextResult.setText(R.string.upload_media_false);
return;
}
try {
String responseUrl = response.body().string();
mTextResult.setText(responseUrl);
} catch (IOException e) {
e.printStackTrace();
}
dissmissDialog();
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
mTextResult.setText(R.string.upload_media_false);
dissmissDialog();
}
});
}
private void dissmissDialog() {
mProgressDialog.dismiss();
}
private void showProgress() {
if (mProgressDialog == null) {
mProgressDialog = new ProgressDialog(this);
mProgressDialog.setMessage("Uploading...");
}
mProgressDialog.show();
}
Trên đây là bài hướng dẫn upload file sử dụng retrofit, rất mong được sự đóng góp của các bạn để bài viết được cải thiện hơn, Hãy comment vào bên duới để chúng ta cùng thảo luận các bạn nhé Github https://github.com/DoanVanToan/Viblo_022017
All rights reserved