کتابخانه Volley + آپلود تصویر و ارسال پارامتر به سرور (جدید) [آموزش]
Volley یک networking library (کتابخانه ای برای ارتباط با شبکه ) در اندروید می باشد. استفاده از این کتابخانه که توسط گوگل توسعه یافته است کار را برای برنامه نویسان اندروید بسیار راحت می کند.
با استفاده از آن دیگر خبری از HttpClient و امثال آن برای ارتباط با سرور و گرفتن اطلاعات نیست، دیگری نیازی نیست اطلاعات دریافت شده از سرور را به فرمت قابل استفاده یا همان String تبدیل کرد.
استفاده از Volley علاوه بر اینکه راحتر می باشد، سرعیتر از روش های قبلی و معمول است.
برخی از ویژگی های Volley از این قبیل می باشند :
- ایجاد صف درخواست (Request Queuing)
- داشتن کنترل روی حافظه و بافرینگ (Cache)
- توانایی لغو درخواست ها در صف (Cancelling Request)
برای استفاده از این کتابخانه بایستی در ابتدا فایل .jar مرتبط با آن را در پوشه libs پروژه خود وارد کنید و آن را به برنامه معرفی کنید (فایل کتابخانه در انتهای آموزش قرار داده می شود. همچنین، IDE پیش فرض ما اندروید استودیو است).
برای معرفی فایل های .jar به پروژه، وارد build.gradle مربوط به app شوید و در قسمت dependencies، کد زیر را وارد کنید و سپس پروژه را sync نمایید:
compile files ('libs/volley.jar')
در مرحله بعد ما به یک Package دیگر نیازی داریم. یک Package با نام utils ایجاد کرده و سپس داخل آن کلاس LruBitmapCache را تعریف می کنیم.
همانطور که در بالا گفتیم یکی از قابلیت های این کتابخانه Caching می باشد، این کلاس در واقع توابع مورد نیاز برای استفاده از این قابلیت را برای ما فراهم می کند.
public class LruBitmapCache extends LruCache<String, Bitmap> implements ImageLoader.ImageCache { public static int getDefaultLruCacheSize() { final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024); final int cacheSize = maxMemory / 8; return cacheSize; } public LruBitmapCache() { this(getDefaultLruCacheSize()); } public LruBitmapCache(int sizeInKiloBytes) { super(sizeInKiloBytes); } @Override protected int sizeOf(String key, Bitmap value) { return value.getRowBytes() * value.getHeight() / 1024; } @Override public Bitmap getBitmap(String s) { return null; } @Override public void putBitmap(String s, Bitmap bitmap) { } }
پس از اضافه کردن این کلاس، کار ما با این Package به اتمام می رسد.
کدهای زیر را به کلاس G خود اضافه می کنیم. توابع این کلاس در ایجاد صف درخواست، اضافه کردن درخواست به صف، دسترسی به درخواست های قرار گرفته در صف، کنسل کردن درخواست های موجود در صف و از این قبیل موارد می باشد (کد زیر، کد کلاس G به طور کامل است. کدهای مشترک را پاک کنید).
public class G extends Application { public static final String TAG = G.class.getSimpleName(); private RequestQueue mRequestQueue; private ImageLoader mImageLoader; private static G mInstance; @Override public void onCreate() { super.onCreate(); mInstance = this; } public static synchronized G getInstance() { return mInstance; } public RequestQueue getRequestQueue() { if (mRequestQueue == null) { mRequestQueue = Volley.newRequestQueue(getApplicationContext()); } return mRequestQueue; } public ImageLoader getImageLoader() { getRequestQueue(); if (mImageLoader == null) { mImageLoader = new ImageLoader(this.mRequestQueue, new LruBitmapCache()); } return this.mImageLoader; } public <T> void addToRequestQueue(Request<T> req, String tag) { // set the default tag if tag is empty req.setTag(TextUtils.isEmpty(tag) ? TAG : tag); getRequestQueue().add(req); } public <T> void addToRequestQueue(Request<T> req) { req.setTag(TAG); getRequestQueue().add(req); } public void cancelPendingRequests(Object tag) { if (mRequestQueue != null) { mRequestQueue.cancelAll(tag); } }
حالا سراغ ایجاد درخواست و گرفتن اطلاعات از سرور می رویم. در این مثال قرار است ما درخواست JsonArray به سرور داشته باشیم و اطلاعات مورد نظر را دریافت کنیم. حال در MainActivity به ترتیب کدهای زیر را وارد می کنیم.
/** * Tag Used To Cancel The Request */ String tag_json_array = "tag_json_array";
همانطور که گفته شد ما توانایی Cancel کردن درخواست هایمان را داریم. این یک متغییر از نوع متن می باشد که با استفاده از آن می توانیم درخواست را Cancel کرده و از انجام آن صرف نظر کنیم.
در ادامه توضیحات تکمیلی آورده می شود.
/** * @url = Url for get json Object */ String url = "http://api.androidhive.info/volley/person_array.json";
در این قسمت آدرس Url مورد نظر برای دریافت JsonArray را تعریف می کنیم.
/** * Create Request For Get Json Array From Server * * Exist To Method In The Request : * 1 : onResponse => That Get Response For Server * If Data Exist In The Server * * 2 : onErrorResponse => That Show Error * If Data Do Not Exist In The Server */ JsonArrayRequest jsonArrReq = new JsonArrayRequest(url, new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray jsonArray) { Log.e("LOG", jsonArray.toString()); for (int i = 0 ; i < jsonArray.length() ; i++) { try { JSONObject jsonObject = jsonArray.getJSONObject(i); Log.e("LOG", "object : " + jsonObject.getString("name")); } catch (JSONException e) { e.printStackTrace(); } } pDialog.hide(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { VolleyLog.e("LOG", volleyError.getMessage()); pDialog.hide(); } });
حال به توضیح کد بالا می پردازیم :
در ابتدا ما یک شی از کلاس JsonArrayRequest را ایجاد می کنیم. چون قرار است ما آرایه دریافت کنیم بایستی از این کلاس یک شی ایجاد کنیم. اگر اطلاعات ما Object بود از JsonObjectRequest استفاده می کنیم.
پارامترهایی که بایستی در ورودی این کلاس وارد کرد شامل موارد زیر می باشد :
url : در واقع این همان آدرس صفحه مورد نظر در سرور می باشد که ما درخواست خود را به این صفحه ارسال می کنیم و پاسخ مورد نظر را نیز دریافت خواهیم کرد.
Listener : پارامتر بعدی یک Listener می باشد. این قسمت در واقع همان پاسخ ما از سرور می باشد. در واقع یک تابع می باشد که با استفاده از آن ما به داده های دریافتی از سرور می توانیم دسترسی داشته باشیم.
در این مثال ما آرایه دریافتی را به Object تبدیل کرده و آن را در خروجی نمایش داده ایم.
ErrorListener : این پارامتر هم یک Listener می باشد اما فقط خطاهای تولید شده از ارتباط با سرور و دریافت اطلاعات را در خروجی به ما اطلاع می دهد.
در نهایت بایستی درخواست را به صف درخواست ها اضافه کنیم.
AppController.getInstance().addToRequestQueue(jsonObjReq, tag_json_obj);
با این کار درخواست ما در صف قرار می گیرد. همانطور که مشاهده می کنید متغییر تعریف شده در بالا به عنوان پارامتر وارد گردیده است. در واقع ما این متغیر را به عنوان نشانه به درخواست در صف وارد می کنیم تا در صورت نیاز بتوانیم به آن دسترسی داشته باشیم.
تا به اینجا ما درخواست جدید را تعریف کرده و آن را به صف درخواست ها اضافه کرده ایم و همچنین پاسخ دریافتی از سرور را نیز در خروجی چاپ کرده ایم.
لغو درخواست :
شاید ما درخواست های زیادی در صف داشته باشیم و یا شاید بخواهیم از اجرا شدن یک درخواست جلوگیری کنیم و از این قبیل موارد. با استفاده از کد زیر می توانیم به صف درخواست ها دسترسی پیدا کرده و با استفاده از شناسه هر درخواست، درخواست مورد نظر را cancel کنیم.
@Override protected void onStop () { super.onStop(); if (requestQueue != null) { requestQueue.cancelAll(tag_json_obj); } }
ارسال پارامتر به سرور :
در مواردی نیاز به ارسال مقادیری به سرور می باشد. با استفاده از این تابع شما می توانید پارامترهای مورد نیاز جهت ارسال به سرور را معرفی و مقدار دهی کنید.
@Override protected Map<String, String> getParams() throws AuthFailureError { Map<String, String> params = new HashMap<String, String>(); params.put("name", "Androidhive"); params.put("email", "abc@androidhive.info"); params.put("password", "password123"); return params; }
در زیر کد کامل آورده شده :
public class JsonArrayActivity extends Activity { TextView txtName; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.json_object_activity); txtName = (TextView) findViewById(R.id.txtName); /** * Tag Used To Cancel The Request */ String tag_json_array = "tag_json_array"; /** * @url = Url for get json Object */ String url = "http://api.androidhive.info/volley/person_array.json"; /** * Show Progress Dialog * Before Get Data From Server * Or * Get Error From Server */ final ProgressDialog pDialog = new ProgressDialog(this); pDialog.setMessage("Loading... "); pDialog.show(); /** * Create Request For Get Json Array From Server * * Exist To Method In The Request : * 1 : onResponse => That Get Response For Server * If Data Exist In The Server * * 2 : onErrorResponse => That Show Error * If Data Do Not Exist In The Server */ JsonArrayRequest jsonArrReq = new JsonArrayRequest(url, new Response.Listener<JSONArray>() { @Override public void onResponse(JSONArray jsonArray) { Log.e("LOG", jsonArray.toString()); for (int i = 0 ; i < jsonArray.length() ; i++) { try { JSONObject jsonObject = jsonArray.getJSONObject(i); Log.e("LOG", "object : " + jsonObject.getString("name")); } catch (JSONException e) { e.printStackTrace(); } } pDialog.hide(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { VolleyLog.e("LOG", volleyError.getMessage()); pDialog.hide(); } }){ @Override protected Map<String, String> getParams() throws AuthFailureError { Map<String, String> params = new HashMap<String, String>(); params.put("name", "Androidhive"); params.put("email", "abc@androidhive.info"); params.put("password", "password123"); return params; } }; AppController.getInstance().addToRequestQueue(jsonArrReq, tag_json_array); } }
استفاده از قابلیت Cache :
هنگامی که شما برای بار اول اطلاعاتی را از یک آدرس از سرور دریافت می کنید، می توانید برای دفعات بعد بدون ارتباط با سرور اطلاعات را دریافت کنید. این قابلیت caching نامیده می شود.
Cache cache = AppController.getInstance().getRequestQueue().getCache(); Cache.Entry entry = cache.get(url); if (entry != null){ try { String data = new String(entry.data, "UTF-8"); txtName.setText(data); pDialog.hide(); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } else { … }
در این قسمت ابتدا آدرس سرور مورد نظر چک می شود که قبلاٌ اطلاعاتی از این آدرس گرفته شده است یا نه، در صورتی که محتوای Cache خالی نباشد، اطلاعات درخواستی از حافظه Cache گرفته می شود و در اختیار کاربر قرار می گیرد.
در صورتی که حافظه Cache خالی باشد، اطلاعات از سرور دریافت می گردد و برای دفعات بعد از Cache دریافت می گردد.
در ادامه، قسمت ImageLoading این کتابخانه توضیح داده خواهد شد.
Volley Image Loading
برای دریافت یک تصویر از سرور و نمایش آن در برنامه به این صورت عمل می شود :
ابتدا یک شی از کلاس ImageLoader ایجاد می کنیم جهت دسترسی به توابع مورد نیاز جهت دریافت و نمایش تصویر مورد نظر از سرور. پس از آن جهت دریافت اطلاعات cache و استفاده از آنها، یک شی هم از کلاس Cache تعریف می کنیم. Url مورد نظر برای دریافت تصویر از سرور را به عنوان ورودی به cache می دهیم تا اطلاعات ذخیره شده را دریافت نماییم.
اگر محتوای حافظه cache خالی نبود، بدین معناست که قبلاٌ این آدرس پیمایش گردیده است و اطلاعات آن در حافظه cache موجود می باشد، پس می توان از همان اطلاعات استفاده کرده و تصویر مورد نظر نمایش داد.
در صورتی که محتوا خالی باشد و یا این آدرس قبلاٌ پیمایش نشده باشد، قسمت دوم یعنی قسمت else اجرا گردیده و اطلاعات از سرور دریافت می گردد. البته دفات بعد دیگر اطلاعات از حافظه cache دریافت می گردد.
imageLoader = G.getInstance().getImageLoader(); Cache cache = G.getInstance().getRequestQueue().getCache(); Cache.Entry entry = cache.get(url); if (entry != null){ ImageLoader.ImageCache imageCache = new LruBitmapCache(); imageLoader = new ImageLoader(Volley.newRequestQueue(G.context), imageCache); imgView.setImageUrl(url, imageLoader); Log.e("LOG", "Load image from cache!"); pDialog.hide(); } else { imageLoader.get(url, new ImageLoader.ImageListener() { @Override public void onResponse(ImageLoader.ImageContainer imageContainer, boolean b) { imgView.setImageUrl(url, imageLoader); pDialog.hide(); Log.e("LOG", "Load image from url!"); } @Override public void onErrorResponse(VolleyError volleyError) { VolleyLog.e("LOG", "Error : " + volleyError.getMessage()); pDialog.hide(); Log.e("LOG", "Load error!"); } }); }
خوش باشید:)
جالبه که دیروز من سوال پرسیدم کسی جواب نداد.
کتابخونه volley با Okhttp تفاوتی دارد؟ و اینکه مزایا و معایب چی هست؟
این کش خیلی جالبه، این کش کجای حافظه ذخیره میشه؟
و جالب اینجاست که وقتی برنامه ران میشه کش کار میکنه وقتی اینترنت رو قطع میکنیم کش دیگه به درد نمیخوره و عکسها رو نشون نمیده!!!
مگه نباید وقتی اینترنت قطع باشه عکسهایی که تو کش ذخیره شده رو به طور کامل نشون بده؟
البته من از این سورس استفاده کردم و کامل مشابه سورس و آموزش شماست.
http://www.androidhive.info/2014/06/android-facebook-like-custom-listview-feed-using-volley/
ارسال پارامتر به سرور به همراه آپلود تصویر با استفاده از کتابخانه Volley
خدمت دوستان عزیز عرض کنم آموزشی که در ابتدای این تاپیک درج شد، مربوط به دریافت اطلاعات از سرور بود. در این قسمت قصد داریم ارسال پارامتر به سرور به همراه آپلود تصویر رو آموزش بدیم.
1) سمت سرور
ابتدا یک Table در phpMyAdmin بسازید و اسمش رو بذارید volley و دوتا فیلد با عنوان image و name داخلش بسازید.
از اونجایی که باید مشخصات دیتابیس رو php معرفی کنیم و در واقع یک connection ایجاد کنیم، پس یک فایل php با نام dbConnect ایجاد کنید و کدهای زیر رو داخلشس قرار بدین:
<?php define('HOST','localhost'); define('USER','root'); define('PASS',''); define('DB','dbname'); $con = mysqli_connect(HOST,USER,PASS,DB) or die('unable to connect to db');
یک فایل php دیگه با نام upload ایجاد کنید و کدهای زیر رو قرار بدین داخلش.
<?php if($_SERVER['REQUEST_METHOD']=='POST'){ $image = $_POST['image']; $name = $_POST['name']; require_once('dbConnect.php'); $sql ="SELECT id FROM volley ORDER BY id ASC"; $res = mysqli_query($con,$sql); $id = 0; while($row = mysqli_fetch_array($res)){ $id = $row['id']; } $path = "uploads/$id.png"; $sql = "INSERT INTO volley (image,name) VALUES ('$path','$name')"; if(mysqli_query($con,$sql)){ file_put_contents($path,base64_decode($image)); echo "Successfully Uploaded"; } mysqli_close($con); }else{ echo "Error"; }
در اینجا ما میخوایم به همراه تصویر، یک اسم هم به سرور بفرستیم. ضمنا، در کنار فایل php تون یک پوشه برای ذخیره تصویر با نام uploads بسازید.
2) سمت کلاینت (اندروید)
در فایل xml اکتیویتی خودتون باید دوتا دکمه (یکی برای انتخاب تصویر از گالری و یکی برای ارسال اطلاعات) و یک ImageView و یک EditText قرار بدین که کدهای xmlش به شرح زیره:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:orientation="vertical" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Choose Image" android:id="@+id/buttonChoose" /> <ImageView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_weight="1" android:id="@+id/imageView" /> <EditText android:id="@+id/editText" android:hint="Enter a Name" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Upload Image" android:id="@+id/buttonUpload" /> </LinearLayout>
سپس، برید داخل اکتیویتی و کدهای زیر رو وارد کنید.
import android.app.ProgressDialog; import android.content.Intent; import android.graphics.Bitmap; import android.net.Uri; import android.provider.MediaStore; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Base64; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.Toast; import com.android.volley.AuthFailureError; import com.android.volley.Request; import com.android.volley.RequestQueue; import com.android.volley.Response; import com.android.volley.VolleyError; import com.android.volley.toolbox.StringRequest; import com.android.volley.toolbox.Volley; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.Hashtable; import java.util.Map; public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button buttonChoose; private Button buttonUpload;
private ImageView imageView; private EditText editTextName; private Bitmap bitmap; private int PICK_IMAGE_REQUEST = 1; private String UPLOAD_URL ="http://127.0.0.1/upload.php"; private String KEY_IMAGE = "image"; private String KEY_NAME = "name"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); buttonChoose = (Button) findViewById(R.id.buttonChoose); buttonUpload = (Button) findViewById(R.id.buttonUpload); editTextName = (EditText) findViewById(R.id.editText); imageView = (ImageView) findViewById(R.id.imageView); buttonChoose.setOnClickListener(this); buttonUpload.setOnClickListener(this); } public String getStringImage(Bitmap bmp){ ByteArrayOutputStream baos = new ByteArrayOutputStream(); bmp.compress(Bitmap.CompressFormat.JPEG, 100, baos); byte[] imageBytes = baos.toByteArray(); String encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT); return encodedImage; } private void uploadImage(){ //Showing the progress dialog final ProgressDialog loading = ProgressDialog.show(this,"Uploading...","Please wait...",false,false); StringRequest stringRequest = new StringRequest(Request.Method.POST, UPLOAD_URL, new Response.Listener<String>() { @Override public void onResponse(String s) { //Disimissing the progress dialog loading.dismiss(); //Showing toast message of the response Toast.makeText(MainActivity.this, s , Toast.LENGTH_LONG).show(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { //Dismissing the progress dialog loading.dismiss(); //Showing toast Toast.makeText(MainActivity.this, volleyError.getMessage().toString(), Toast.LENGTH_LONG).show(); } }){ @Override protected Map<String, String> getParams() throws AuthFailureError { //Converting Bitmap to String String image = getStringImage(bitmap); //Getting Image Name String name = editTextName.getText().toString().trim(); //Creating parameters Map<String,String> params = new Hashtable<String, String>(); //Adding parameters params.put(KEY_IMAGE, image); params.put(KEY_NAME, name); //returning parameters return params; } }; //Creating a Request Queue RequestQueue requestQueue = Volley.newRequestQueue(this); //Adding request to the queue requestQueue.add(stringRequest); } private void showFileChooser() { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST); } @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.getData() != null) { Uri filePath = data.getData(); try { //Getting the Bitmap from Gallery bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath); //Setting the Bitmap to ImageView imageView.setImageBitmap(bitmap); } catch (IOException e) { e.printStackTrace(); } } } @Override public void onClick(View v) { if(v == buttonChoose){ showFileChooser(); } if(v == buttonUpload){ uploadImage(); } } }
کاری که توی این کد انجام میشه اینه که ابتدا روی دکمه Choose Image کلیک میشه و تصویر از گالری انتخاب میشه و بعدش توی EditText نام مورد نظر وارد میکنیم. بعدش که روی دکمه Upload Image کلیک شد، تابع uploadImage اجرا میشه.
توی این تابع، ابتدا تصویر به String تبدیل میشه و بعدش String به سرور ارسال میشه. همچنین، در سمت سرور برای تبدیل String ارسالی به تصویر، از base64_decode در کدهای php استفاده می شود.
آخرین کاری که باید انجام بدین، وارد کردن دسترسی اینترنت به منیفست هست.
موفق باشید...
سلام آقا احسان
دستتون درد نکنه از این وقتی که گذاشتید
من اگه بخوام از این کتابخونه استفاده کنم برای ارتباط با وب سرویس دات نت (SVC) ، چکار باید بکنم
مخصوصا موقع ارسال Json به یک وب سرویس
الان من یه مشکلی دارم . چرا این کد رو اجرا می کنم پیغام ارور میاد؟ ولی اگر آدرس سایتی که بالا دادید رو بزارم اطلاعات میاد؟
final ProgressDialog pDialog = new ProgressDialog(this);
pDialog.setMessage("Loading... ");
pDialog.show();
String url = "http://192.168.1.1/android/note_server/news.php?action=read";
JsonArrayRequest jsonArrReq = new JsonArrayRequest(url, new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray jsonArray) {
// Log.d("LOG", jsonArray.toString());
pDialog.hide();
for (int i = 0; i < jsonArray.length(); i++) {
try {
JSONObject jsonObject = jsonArray.getJSONObject(i);
Log.d("LOG", "Name :" + jsonObject.getString("news_title"));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
VolleyLog.e("LOG", volleyError.getMessage());
pDialog.hide();
}
});
G.getInstance().addToRequestQueue(jsonArrReq);
}
کد php :
function read(){ $connection = connectToDatabase(); $result = mysqli_query($connection,"SELECT * FROM news"); $output = array(); while($row = mysqli_fetch_array($result)) { $record = array(); $record['news_id'] = $row['news_id']; $record['news_title'] = $row['news_title']; $record['news_desc'] = $row['news_desc']; $record['news_date'] = $row['news_date']; $output[] = $record; } echo json_encode($output); mysqli_close($connection); }
احسان جان من یه کم تکمیل تر کردم برای دریافت لیستی از آرایه ها در لیست ویو و کش هم میشه.
فقط اگر تو این کدها اگر مشکلی چیزی میبینید بگید تا حل بشه .
من کد رو میزارم تا شاید کسی بخواد استفاده کنه.
private ArrayAdapter adapter; private ListView lstContent; private ProgressDialog pDialog; private CoordinatorLayout coordinatorLayout; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); setSupportActionBar(toolbar);
coordinatorLayout = (CoordinatorLayout) findViewById(R.id.coordinatorLayout); lstContent = (ListView) findViewById(R.id.lstContent); readNews(); } public void readNews() {
pDialog = new ProgressDialog(this); pDialog.setMessage("Loading... "); pDialog.show();
String url = "http://192.168.1.1/android/note_server/news.php?action=read"; JsonArrayRequest jsonArrReq = new JsonArrayRequest(Request.Method.GET, url, new Response.Listener() { @Override public void onResponse(JSONArray jsonArray) { hidePDialog(); G.newss.clear(); for (int i = 0; i < jsonArray.length(); i++) { try { JSONObject jsonObject = jsonArray.getJSONObject(i); StructNews task = new StructNews(); task.title = jsonObject.getString("news_title"); task.desc = jsonObject.getString("news_desc"); task.date = jsonObject.getString("news_date"); G.newss.add(task); } catch (JSONException e) { e.printStackTrace(); } adapter = new AdapterNews(G.newss); lstContent.setAdapter(adapter); adapter.notifyDataSetChanged(); } } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError volleyError) { // VolleyLog.e("LOG", volleyError.getMessage()); hidePDialog(); Snackbar snackbar = Snackbar .make(coordinatorLayout, "خطا", Snackbar.LENGTH_INDEFINITE) .setAction("سعی مجدد", new View.OnClickListener() { @Override public void onClick(View view) { readNews(); } }); snackbar.show(); } }) { @Override protected Response parseNetworkResponse(NetworkResponse response) { try { Cache.Entry cacheEntry = HttpHeaderParser.parseCacheHeaders(response); if (cacheEntry == null) { cacheEntry = new Cache.Entry(); } final long cacheHitButRefreshed = 3 * 60 * 1000; // in 3 minutes cache will be hit, but also refreshed on background final long cacheExpired = 24 * 60 * 60 * 1000; // in 24 hours this cache entry expires completely long now = System.currentTimeMillis(); final long softExpire = now + cacheHitButRefreshed; final long ttl = now + cacheExpired; cacheEntry.data = response.data; cacheEntry.softTtl = softExpire; cacheEntry.ttl = ttl; String headerValue; headerValue = response.headers.get("Date"); if (headerValue != null) { cacheEntry.serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue); } headerValue = response.headers.get("Last-Modified"); if (headerValue != null) { cacheEntry.lastModified = HttpHeaderParser.parseDateAsEpoch(headerValue); } cacheEntry.responseHeaders = response.headers; final String jsonString = new String(response.data, HttpHeaderParser.parseCharset(response.headers)); return Response.success(new JSONArray(jsonString), cacheEntry); } catch (UnsupportedEncodingException e) { return Response.error(new ParseError(e)); } catch (JSONException e) { return Response.error(new ParseError(e)); } } @Override protected void deliverResponse(JSONArray response) { super.deliverResponse(response); } @Override public void deliverError(VolleyError error) { super.deliverError(error); } @Override protected VolleyError parseNetworkError(VolleyError volleyError) { return super.parseNetworkError(volleyError); } }; G.getInstance().addToRequestQueue(jsonArrReq); } @Override public void onDestroy() { super.onDestroy(); hidePDialog(); } private void hidePDialog() { if (pDialog != null) { pDialog.dismiss(); pDialog = null; } }
سلام جناب منصوری
بفرمایید چطور میشه با Json Array پارامتر ارسال کرد (Post)؟(نحوه ی نوشتن Custom Request رو میشه بفرمایید،ممنون)
دوستان سلام ،
متوجه نشدم AppController چی هست !
با سلام و تشکر از شما به خاطر این آموزش بنده یک سوال داشتم :
من با این کد ها از یک فایل رابط php اطلاعات رو تحت جیسون میگیرم و در یک لیست ویو نشون میدم اما مشکلی که هست اینکه : دفعه اول که اطلاعات رو میگیرم و در لیست نشون داده میده اما وقتی یه اطلاعات جدید تو دیتابیس سرور وارد میکنم و برنامه رو اجرا میکنم دیگه اون اطلاعات نشون داده نمیشه یعنی وقتی اسکرول میکنم به پایین تنها همون اطلاعاتی که قبلا و دفعه اول گرفته بودم نشون داده میشه ، لطفا راهنمایی فرمایید با تشکر از شما
درواقع من میخوام وقتی سری اول داده رو گرفت ( مثلا دفعه اول 10 تا داده) بعد که دوباره اسکرول رو به پایین کشیدم دوباره 10 تا داده دیگه بگیره تا آخر اما نتونستم کدی براش پیدا کنم.
public class newst_frag extends Fragment {
private static final String TAG = MainActivity.class.getSimpleName();
private ListView listView;
private FeedListAdapter listAdapter;
private List<FeedItem> feedItems;
private String URL_FEED = "http://www.mysite.com/test/get_data.php";
public newst_frag() {}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
clear_cache();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.newst_frag, container, false);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
clear_cache();
listView = (ListView)getView().findViewById(R.id.list);
feedItems = new ArrayList<FeedItem>();
listAdapter = new FeedListAdapter(getActivity(), feedItems);
listView.setAdapter(listAdapter);
// We first check for cached request
Cache cache = AppController.getInstance().getRequestQueue().getCache();
Cache.Entry entry = cache.get(URL_FEED);
if (entry != null) {
// fetch the data from cache
try {
String data = new String(entry.data, "UTF-8");
try {
parseJsonFeed(new JSONObject(data));
} catch (JSONException e) {
e.printStackTrace();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
} else {
// making fresh volley request and getting json
JsonObjectRequest jsonReq = new JsonObjectRequest(Request.Method.GET,
URL_FEED, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
VolleyLog.d(TAG, "Response: " + response.toString());
if (response != null) {
parseJsonFeed(response);
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
}
});
// Adding request to volley request queue
AppController.getInstance().addToRequestQueue(jsonReq);
}
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
String str = feedItems.get(position).getSeller();
Toast.makeText(getActivity(),str,Toast.LENGTH_LONG).show();
}
});
}
private void parseJsonFeed(JSONObject response) {
try {
JSONArray feedArray = response.getJSONArray("ads");
for (int i = 0; i < feedArray.length(); i++) {
JSONObject feedObj = (JSONObject) feedArray.get(i);
FeedItem item = new FeedItem();
item.setId(feedObj.getInt("id"));
item.setTitle(feedObj.getString("title"));
// Image might be null sometimes
item.setImage(feedObj.getString("image"));
item.setIntro(feedObj.getString("intro"));
item.setEmail(feedObj.getString("email"));
item.setSeller(feedObj.getString("seller"));
item.setDate(feedObj.getString("date"));
feedItems.add(item);
}
// notify data changes to list adapater
listAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
سلام دوست عزیز به یک ارور برخوردم
if (mImageLoader == null) {
mImageLoader = new ImageLoader(this.mRequestQueue, new LruBitmapCache());
}
اررور میگیره.LruBitmapCache از
در کلاس G
اگر ممکنه یکی سورس کد این اموزش رو روی سایت قرار بده . اخه من چند روز دارم روش کار میکنم ولی هنوز موفق نشدم.
اقا یک دنیا ممنون از توضیحاتتون خیلی عالی و کاربردی بود
فقط یه سوال داشتم چطوری میتونم با کتابخانه volley یک لیست بی پایان endless list بسازم
ممنون میشم اگه توضیح فرمایید
سلام آقا احسان
خواستم بدونم برای کار با متد Put چطور باید عمل کرد و آیا تفاوتی مثلا با متد Post داره؟
و اینکه اگر بخوایم اطلاعاتمون رو با multipart/form-data بفرستیم چگونه این کار رو انجام بدم.
من قبلا هم بصورت پارامتر به پارامتر میفرستادم براساس همون چیزی خودتون آموزش دادین!
آیه اینم به همون صورت هست؟
مثلا اطلاعاتی که بصورت زیر گذاشتم چطور و به چه شکل بفرستم؟
request
پارامتر | مقدار |
method | put |
headers | Content-Type |
content | multipart/form-data |
و مقادیری که میخوام بفرستم به این صورت هستن :
Content-Disposition: form-data; name="firstname"
Content-Disposition: form-data; name="lastname"
Content-Disposition: form-data; name="username"
Content-Disposition: form-data; name="password"
Content-Disposition: form-data; name="email"
Content-Disposition: form-data; name="phonenum"
Content-Disposition: form-data; name="birth_date"
Content-Disposition: form-data; name="promoter"
Content-Disposition: form-data; name="nationalid"
Content-Disposition: form-data; name="avatar"; filename=""
این اطلاعاتی هست که به من دادن که انجام بدم برای ثبت نام
ممنون میشم راهنماییم کنید
سلام . برای اینکار شما باید از volleymultipartRequesr استفاده کنید . به همین سادگی :)
سلام به دوستان عزیز
همونجوری که بالا گفتم من میخوام با volley مقادیری رو با متد Put و با multipart form-data ارسال کنم. با راهنمایی سهیل جان لینکی پیدا کردم ولی برام جای سوال داشت که چطور فایلی که همراه پارامترهامون هست رو بهش بدیم و بفرستیم.
مثلا عکس یه کاربر که موقع ثبت نام میخوایم ازش بگیریم . و کاربر برای انتخاب عکسش اون رو از گالری گوشی میگیره و اون رو با مقادیر دیگه برای ثبت نام به سرور میفرسته و ثبت نام میکنه.
نمیخوام همه کد هارو بذارم. ولی من از این لینک کدهارو گرفتم.
فقط قسمتی که برام سوال هست رو میفرستم
VolleyMultipartRequest multipartRequest = new VolleyMultipartRequest(Request.Method.PUT, url, new Response.Listener<NetworkResponse>() {
@Override
public void onResponse(NetworkResponse response) {
String resultResponse = new String(response.data);
try {
JSONObject result = new JSONObject(resultResponse);
String status = result.getString("status");
String message = result.getString("message");
Log.e("resultResponse","register");
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
NetworkResponse networkResponse = error.networkResponse;
String errorMessage = "Unknown error";
if (networkResponse == null) {
if (error.getClass().equals(TimeoutError.class)) {
errorMessage = "Request timeout";
} else if (error.getClass().equals(NoConnectionError.class)) {
errorMessage = "Failed to connect server";
}
} else {
String result = new String(networkResponse.data);
try {
JSONObject response = new JSONObject(result);
String status = response.getString("status");
String message = response.getString("message");
Log.e("Error Status", status);
Log.e("Error Message", message);
if (networkResponse.statusCode == 404) {
errorMessage = "Resource not found";
} else if (networkResponse.statusCode == 401) {
errorMessage = message+" Please login again";
} else if (networkResponse.statusCode == 400) {
errorMessage = message+ " Check your inputs";
} else if (networkResponse.statusCode == 500) {
errorMessage = message+" Something is getting wrong";
}
} catch (JSONException e) {
e.printStackTrace();
}
}
Log.i("Error", errorMessage);
error.printStackTrace();
}
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("firstname", "mohsen");
params.put("lastname", "ahmadi");
params.put("username", "ahmad1234");
params.put("password", "ahmad4321");
params.put("email", "mosafercv@yahoo.com");
params.put("birth_date", "1990-04-12");
params.put("promoter", "4");
params.put("nationalid", "4171122145");
return params;
}
*****************************************************************************این قسمت چطور عکس رو بهش بدم
@Override
protected Map<String, DataPart> getByteData() {
Map<String, DataPart> params = new HashMap<>();
// file name could found file base or direct access from real path
// for now just get bitmap data from ImageView
params.put("avatar", new DataPart("file_avatar.jpg", AppHelper.getFileDataFromDrawable(getBaseContext(), circleImageView.getDrawable()), "image/jpeg"));
return params;
}
};
VolleySingleton.getInstance(getBaseContext()).addToRequestQueue(multipartRequest);
ممنون میشم بگین به چه شکله
اینم کد متد getFileDataFromDrawable در کلاس AppHelper که بالا در متد getByteData صدا زده شده
public static byte[] getFileDataFromDrawable(Context context, Drawable drawable) {
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayOutputStream);
return byteArrayOutputStream.toByteArray();
}
با تشکر
سلام دوستان
من میخوام به یک سایتی وصل بشم مثلا وقتی دامنه یک سایتی رو داخلش میزنم همه اطلاعات برگشتی رو بهم بر نگردونه فقط دامنه سایت رو بهم بگه ی جورایی جواب برگشتی رو فیلتر کنم و فقط چیزایی که میخوامو بردارم کسی راهنماییم کنه ممنونش میشم
سلام دوستان
برای سرچ در والی به صورت درست چه کار میشه کرد؟
من توی برنامم از این روش استفاده کردم و مشکلی ک دارم برای سرچ فارسی هست یک
دوم برای استفاده از ایتم سرچ در اکشن بار هم نمیدونم به چه شکل استفاده کنم
من یک ادیت تکست گذاشتم و یک دکمه
مقدار ادیت تکستو میگیرم میفرستم سمت سرور و میگم سرچ کن و اطلاعاتو در ریسایکلر ویو نشون بده کدهای من هم به شکل زیر هستن
ممنون میشم یک توضیح کامل بدین چون مشکل خیلی از دوستان هم هست
btn_search.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
searchtxt = edt_search.getText().toString();
final String encodedurl = URLEncoder.encode(searchtxt, "UTF-8");
Log.d("TEST"+"ممد", encodedurl);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
String url = "http://localhost/cart.php?search=" + searchtxt;
recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(ajnas.this,
LinearLayoutManager.VERTICAL, false));
apiService = new ApiService(ajnas.this);
apiService.getData6(searchtxt, new ApiService.onGetData() {
@Override
public void onGet(List<NewsFeed> feeds) {
adapter = new MyRecyclerViewAdapter(feeds, ajnas.this);
recyclerView.setAdapter(adapter);
}
});
}
});
public void getData6(String searchtxt,final onGetData onGetData) {
MainActivity.showDialog();
String url = " http://localhost/search.php?search=" + searchtxt;
final JsonArrayRequest request = new JsonArrayRequest(Request.Method.GET, url,
null, new Response.Listener<JSONArray>() {
@Override
public void onResponse(JSONArray response) {
Log.d(TAG, "onResponse: " + response.toString());
List<NewsFeed> feeds = new ArrayList<>();
for (int i = 0; i < response.length(); i++) {
NewsFeed feed = new NewsFeed();
try {
JSONObject object = response.getJSONObject(i);
feed.setImgUrl(object.getString("img"));
feed.setFeedName(object.getString("name"));
feed.setComment(object.getString("comment"));
feed.setPrice(object.getInt("price"));
feed.setTakhfif(object.getInt("takhfif"));
feed.setId(object.getInt("id"));
Log.e("res",object.getString("name")+"*"+object.getString("comment"));
feeds.add(feed);
} catch (JSONException e) {
e.printStackTrace();
}
}
<?php
$con=mysqli_connect("localhost","user","pass","DB");
mysqli_set_charset($con,"utf8");
$s = $_REQUEST["search"];
$sql = "SELECT * FROM ghaza WHERE (name LIKE N'%$s%')";
$res = mysqli_query($con,$sql);
$result = array();
while ($row = mysqli_fetch_array($res)) {
$item = array();
$item['success']="1";
$item['id'] = $row[0];
$item['name'] = $row[1];
$item['price'] = $row[2];
$item['comment'] = $row[3];
$item['img'] = $row[4];
$item['iddaste'] = $row[5];
$item['takhfif'] = $row[6];
$result[] = $item;
}
echo json_encode($result, JSON_UNESCAPED_UNICODE);
mysqli_close($con);
?>
پاسخگویی و مشاهده پاسخ های این سوال تنها برای اعضای ویژه سایت امکان پذیر است .
چنانچه تمایل دارید به همه بخش ها دسترسی داشته باشید میتوانید از این بخش لایسنس این آموزش را خریداری نمایید .