رفع ملف الى السيرفر باستخدام Retrofit

تكلممنا في التدوينات السابقة عن طريقة استخدام مكتبة retrofit وقمنا بعمل تطبيق لتسجيل مسخدم جديد وايضا قمنا بانشاء شاشة للقيام بتسجيل الدخول والتاكد من بيانات المستخدم وقلنا سابقا ان retrofit تعتمد على ثلاث اشياء رئيسية وهي

  • POJOs : وهو المسؤل عن استقبال البيانات العائدة من السيرفر.
  • interface : للقيام بعمليات الطلب لـhttp من حيث post,delete,put..
  • retrofit : تهيئة وبناء retrofit للقيام بعمليات الطلب .

راجع التدوينات السابقة الجزء الاول و الجزء الثاني،

سنقوم باذن الله في هذا الدرس بتوضيح مثال لعملية رفع الصور باستخدام retrofit الى السيرفر وستكون الفكرة بالسماح للمستخدم باضافة الصور وتصفحها ولكل مستخدم صور خاصة به ?.

فيديو لنتيجة الدرس :

سنحتاج الى :

  • انشاء ملف PHP لاستقبال الصورة :

انشاء جدول جديد باسم photos واضافة عدة حقول بداخلة كما في امر sql التالي :

CREATE TABLE `photos` (
  `photo_id` int(11) NOT NULL,
  `url` varchar(100) NOT NULL,
  `description` text NOT NULL,
  `user_id` int(10) NOT NULL
) ENGINE=InnoDB AUTO_INCREMENT=71 DEFAULT CHARSET=utf8;

انشاء مجلد باسم uploads داخل ملف السيرفر الخاص بنا وسيكون هو مستودع الصور 

 

سنقوم بكتابة ملف php بسيط والذي سيكون مسؤل عن استقبال الصور وارسالها للمجلد المسؤل عن الصور وتوليد اسم فريد لها وتخزينها في MySql .

<?php
/**/
include 'connect.php';
$user_id = $_POST['id'];
$description = $_POST['description'];
$tmpName = $_FILES['attachment']['tmp_name'];
$fileType = $_FILES['attachment']['type'];
$fileName = uniqid(rand(), true) . '.png'; //use this name
move_uploaded_file($_FILES['attachment']['tmp_name'], "uploads/" . $fileName);

//insert query goes here
$insert = "INSERT INTO photos (url,user_id,description) values('$fileName','$user_id','$description')";
$res_ins = mysqli_query($connection, $insert);
if ($res_ins) {
	$post['result'] = "successfull";
	$data = 'content-type:application/json';
	$data = json_encode($post);
	echo $data;

} else {
	$post['result'] = $connection->error;
	$data = 'content-type:application/json';
	$data = json_encode($post);
	echo $data;
}

?>
  • انشاء التصميم الخاص بالشاشة :

سنقوم بانشاء تصميم بسيط وجميل لواجهة رفع الصور وايضا استخدام بعض خصائص الماتيريال ديزاين الجديدة.

سنحتاج الى :

  • ImageView  : لعرض الصورة التي قام باختيارها المستخدم قبل رفعها الى السيرفر.
  • EditText : لكتابة الوصف الخاص بالصورة .
  • FloatingActionButton : للقيام بعملية رفع الصورة الى السيرفر.

الكود :

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.tatbigy.androidretrofit.ProfileActivity">

    <android.support.design.widget.AppBarLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">

        <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:layout_scrollFlags="scroll|enterAlways"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
    </android.support.design.widget.AppBarLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="?attr/actionBarSize"
        android:orientation="vertical">

        <ImageView
            android:id="@+id/pick_image"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:adjustViewBounds="true"
            android:scaleType="centerInside"
            android:src="@drawable/ic_picture_in_picture_grey_500_24dp" />

        <android.support.v7.widget.AppCompatEditText
            android:id="@+id/description"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:hint="الوصف"
            android:textAppearance="?android:attr/textAppearanceMedium" />
    </LinearLayout>

    <com.github.jorgecastilloprz.FABProgressCircle
        android:id="@+id/fabProgressCircle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center"
        app:arcColor="#05dc69">

        <android.support.design.widget.FloatingActionButton
            android:id="@+id/upload"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:src="@drawable/ic_cloud_upload_white_24dp" />
    </com.github.jorgecastilloprz.FABProgressCircle>
</FrameLayout>
  • القيام بعملية الرفع :

سنقوم الان بالانتقال الى UploadImageActivity وسنقوم بتجهيز

  • POJOs :
    كلاس جافا لاستعادة البيانات من السيرفر لتوضيح هل عملية الرفع ناجحة او لا ؟
  • Interface :
    سنقوم بوضع Http request واسم الملف المسؤل عن الرفع واضافة الصورة والبيانات الخاصة .
  • Retrofit :
    التجهيز لعملية الرفع .

UploadResult.java :

سنقوم في هذا الكلاس باستعادة البيانات القادمة من السيرفر والتعامل معها باستخدا Gson.

package com.tatbigy.androidretrofit.model;

/**
 * Created by Ahmed on 10/19/15.
 * 04
 * Android Retrofit
 */
public class UploadResult {
    
    private String result;

    public void setResult(String result) {
        this.result = result;
    }

    public String getResult() {
        return result;
    }
}

FileUploadService :

انترفيس للتعامل مع http وارسال الصورة والصف الخاص بها.

   public interface FileUploadService {
        @Multipart()
        @POST("upload_file.php")
        Call<UploadResult> upload(@Part("attachment\"; filename=\"image.jpg\" ") RequestBody file,
                                  @Part("description") String description,
                                  @Part("id") String id
        );
    }

Retrofit builder :

سنقوم الان بتجهيز عملية الرفع راضافة الرابط الرئيسي للسيرفر.

final Retrofit uploadimage = new Retrofit.Builder().
                baseUrl(getString(R.string.url))
                .addConverterFactory(GsonConverterFactory.create())
                .build();

بعد التهيئة سنقوم بارسال البيانات :

  RequestBody file = RequestBody.create(MediaType.parse("image/png"), new File(picturePath));
                FileUploadService apiService = uploadimage.create(FileUploadService.class);

                Call<UploadResult> reg = apiService.upload(file, description.getText().toString(), "0");
                reg.enqueue(new Callback<UploadResult>() {

                    @Override
                    public void onResponse(Response<UploadResult> response, Retrofit retrofit) {
                        fabProgressCircle.beginFinalAnimation();
                    }

                    @Override
                    public void onFailure(Throwable t) {
                        // Log error here since request failed
                    }
                });

نلاحظ في الكود السابق هذا السطر :

  RequestBody file = RequestBody.create(MediaType.parse("image/png"), new File(picturePath));

حيث قمنا بتحديد نوع الملف وهو صورة من نوع png وايضا اضفنا new file ووضعنا بداخلة مسار الملف المراد رفعه الى السيرفر.

 

ملاحظة يجب عليك العودة الى ملف المشروع الموجود على Github والاطلاع عليه لاني قمت بشرح اهم النقاط الموجودة فيه.

 

5 تعليقات على “رفع ملف الى السيرفر باستخدام Retrofit”

اترك تعليقاً

لن يتم نشر عنوان بريدك الإلكتروني. الحقول الإلزامية مشار إليها بـ *