آموزش آپلود عکس به دیتابیس Mysql در اندروید
سلام دوستان امیدوارم حالتون خوب باشد در این سری از آموزش برنامه نویسی اندروید به آموزش آپلود عکس به دیتابیس Mysql در اندروید می پردازیم در آموزش آپلود عکس به سرور ما یک دیتابیس داریم که بعد از آپلود آدرس عکس را برای ما نگه می دارد و این کار توسط یک فایل php انجام می شود در ادامه با ما همراه باشید.
ابتدا به یک دیتابیس نیاز داریم پس یک جدول (table) در mysql به نام check با دو فیلد ایجاد کرده نام فیلد اول را برابر با id و auto increment یا ai قرار داده و فیلد بعدی را برابر با image قرار دهید عکس زیر شاید بتواند به درک بهتر شما کمک کند. id را باید Primary key قرار دهید.
در بالا insert انجام شده است شما نباید مقداری در فیلد های بالا Insert کنید.
خب باید یک فایل php برای آپلود فایل ایجاد کنیم نام فایل ما برابر با Upload.php است بعد از ایجاد فایل کدهای زیر را در آن قرار دهید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | <?php if($_SERVER['REQUEST_METHOD']=='POST'){ $image = $_POST['image']; $user = "root"; $pass = ""; $host= "localhost"; $dbname="check"; $con = mysqli_connect($host,$user,$pass,$dbname); $sql ="SELECT id FROM images ORDER BY id ASC"; $res = mysqli_query($con,$sql); $id = 0; while($row = mysqli_fetch_array($res)){ $id = $row['id']; } $p = "uploads/$id.png"; $mainpath = "http://programchi.ir/myimage/$p"; $sql="insert into images(image) values('".$mainpath."');"; if(mysqli_query($con,$sql)){ file_put_contents($p,base64_decode($image)); echo "Successfully Uploaded"; } mysqli_close($con); }else{ echo "Error"; } ?> |
در بالا عمل post انجام می شود . قبل از توضیح دادن ادامه شما باید یک پوشه داشته باشید مثلا نام پوشه ما در اینجا برابر با myimage است بعد از اینکار یک پوشه دیگر به نام uploads در پوشه قبلی قرار دهید در بالا باید به جای $user یوزنیم دیتابیس خودتان و به جای $pass پسورد دیتابیس را قرار دهید . در صورتی که فایل به درستی آپلود شود پیام Successfully Uploaded و در غیر اینصورت Error نمایش داده می شود. در بالا query که این کار را انجام می دهد یک Insert به دیتابیس انجام میدهد یعنی ابتدا فایل آپلود می شود سپس مسیر آن به دست آمده و در mysql ما insert می شود نام هر فایل هم همان آیدی می شود تا راحتر بشود آنها را مدیریت کنیم.
برویم به سراغ کد های برنامه
ابتدا وارد فایل Build.gradle از نوع Module شده سپس در بخش dependencies کتاب خانه زیر را اضافه کنید.
1 | compile 'com.android.volley:volley:1.0.0' |
پروژه را sync کنید.
وارد فایل AndroidManifest.xml شده و دسترسی های زیر را به آن اضافه کنید.
1 2 3 | <uses-permission android:name="android.permission.INTERNET"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> |
در layout اصلی که در اینجا نام آن برابر با activity_main.xml است یک ImageView و یک Button همانند زیر قرار دهید.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | <?xml version="1.0" encoding="utf-8"/> <RelativeLayout 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:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".MainActivity"/> <Button android:text="Upload Now" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginBottom="25dp" android:id="@+id/upload" android:layout_alignParentBottom="true" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_alignParentRight="true" android:layout_alignParentEnd="true" /> <ImageView android:layout_width="match_parent" android:layout_height="match_parent" app:srcCompat="@mipmap/ic_launcher" android:layout_alignParentTop="true" android:id="@+id/imageview" android:layout_alignParentLeft="true" android:layout_alignParentStart="true" android:layout_above="@+id/upload" /> </RelativeLayout> |
ImageView برای نمایش عکس و Button برای آپلود عکس است.
فایل php در آدرس زیر قرار گرفته است (برای مثال می گوییم همچین فایلی به خاطر مسائل امنیتی قرار گرفته نمی شود)
1 | https://programchi.ir/myimage/upload.php |
و درآخر کدهای زیر را در MainActivity.java قرار دهید (نیازی به کلاس دیگری نیست)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 | package ir.programchi; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.drawable.BitmapDrawable; import android.net.Uri; import android.os.Build; import android.provider.MediaStore; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Base64; import android.util.Log; import android.view.View; import android.widget.Button; 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.HashMap; import java.util.Map; import static android.R.attr.bitmap; public class MainActivity extends AppCompatActivity { Button upload; ImageView imageview; private static final int PERMISSION_REQUEST_CODE = 1; private static final int PICK_IMAGE_REQUEST= 99; Bitmap bitmap; String myurl = "http://programchi/myimage/upload.php"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); upload = (Button) findViewById(R.id.upload); imageview = (ImageView) findViewById(R.id.imageview); imageview.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showFileChooser(); } }); upload.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { uploaduserimage(); } }); if (Build.VERSION.SDK_INT >= 23) { if (checkPermission()) { // Code for above or equal 23 API Oriented Device // Your Permission granted already .Do next code } else { requestPermission(); } } } private void requestPermission() { if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)) { Toast.makeText(MainActivity.this, " Please allow this permission in App Settings.", Toast.LENGTH_LONG).show(); } else { ActivityCompat.requestPermissions(MainActivity.this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, PERMISSION_REQUEST_CODE); } } private boolean checkPermission() { int result = ContextCompat.checkSelfPermission(MainActivity.this, android.Manifest.permission.WRITE_EXTERNAL_STORAGE); if (result == PackageManager.PERMISSION_GRANTED) { return true; } else { return false; } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case PERMISSION_REQUEST_CODE: if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { Toast.makeText(MainActivity.this, "Permission Granted Successfully! ", Toast.LENGTH_LONG).show(); } else { Toast.makeText(MainActivity.this, "Permission Denied :( ", Toast.LENGTH_LONG).show(); } break; } } 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 { bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath); Toast.makeText(this, ""+bitmap, Toast.LENGTH_SHORT).show(); imageview.setImageBitmap(bitmap); } catch (IOException e) { e.printStackTrace(); } } } public void uploaduserimage(){ RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this); StringRequest stringRequest = new StringRequest(Request.Method.POST, myurl, new Response.Listener<String>() { @Override public void onResponse(String response) { Log.i("Myresponse",""+response); Toast.makeText(MainActivity.this, ""+response, Toast.LENGTH_SHORT).show(); } }, new Response.ErrorListener() { @Override public void onErrorResponse(VolleyError error) { Log.i("Mysmart",""+error); Toast.makeText(MainActivity.this, ""+error, Toast.LENGTH_SHORT).show(); } }){ @Override protected Map<String, String> getParams() throws AuthFailureError { Map<String,String> param = new HashMap<>(); String images = getStringImage(bitmap); Log.i("Mynewsam",""+images); param.put("image",images); return param; } }; requestQueue.add(stringRequest); } public String getStringImage(Bitmap bitmap){ Log.i("MyHitesh",""+bitmap); ByteArrayOutputStream baos=new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.PNG,100, baos); byte [] b=baos.toByteArray(); String temp=Base64.encodeToString(b, Base64.DEFAULT); return temp; } } |
برای آپلود فایل ابتدا شما باید بروی ImageView کلیک کنید با کلیک بروی آن Gallery نمایش داده می شود onActivityResult به این منظور است که وقتی عکسی از Gallery انتخاب شد ما آدرس آن عکس را به دست بیاریم و بخش مهم کار این جاست که نمی شود عکس را دیتابیس قرار داد پس باید عکس تبدیل به متن شود برای اینکار ما از Void ی به نام getStringImage استفاده کردیم در این آموزش ما از RunTimePermission نیز استفاده کرده ایم البته در صورتی که api گوشی کاربر بالای 23 باشد نمایش داده می شود در غیر اینصورت اتفاقی نمی افتد. با کلیک بروی Imageview بالا void ی به نام showFileChooser نمایش داده می شود که قبلتر آن را توضیح دادیم برای چه کاری است.
در این آموزش با استفاده از volley عمل آپلود را انجام میدهیم یعنی عکس را به فایل php که ساختیم post کرده سپس از آنجا در mysql قرار می گیرد (منظور همان آدرس است)
این آموزش هم به پایان رسید.
موفق و پیروز باشید.
سلام، متشکر بابت آموزش های خوبتون.
یک سوال داشتم:
وقتی کاربر وارد اپ میشه ما اطلاعات رو از سمت سرور میگیریم و بهش نشون میدیم، حالا هر موقع که کاربر از اپ خارج شد و دوباره وارد شد منطقی اینه که دوباره همه اطلاعات از سرور درخواست نشه و فقط اون اطلاعاتی که جدیدا اضافه شده از سرور گرفته بشه و به recyclerView اضافه بشه که هم سرعت آپدیت اطلاعات بالا بره و هم دیتای کمتری از اینترنت کاربر مصرف بشه.
آیا نیاز هست که اول اطلاعات رو در گوشی کاربر به وسیله SQlite ذخیره کنیم و بعد id اون رو با id سمت سرور مقایسه کنیم یا کار دیگه ای باید انجام بشه؟
روش استاندارد برای این کار چی هست؟
لطف می کنید راه حل رو توضیح مختصر بدید.
سلام
سوال من هم هست 🙂
اگر میشه راهنمایی بفرمایید
سلام دقیقا چیزی که گفتید باید همین کار انجام شود.
یه سوال دیگه هم داشتم، برای آپلود فایل باید چیکار کرد؟ مثلا آپلود فایل pdf و یا word
آیا نحوه ارسال اونها با volley متفاوت هست؟
متشکر
سلام
خیر متفاوت نیست.
سلام
واسه ارسال عکس با حجم بالا باید چیکار کرد؟
من عکس با حجم 2مگ میفرستم برنامه کرش میکنه
ولی عکس زیر 1 مگ رو راحت میفرسته
با سلام وخسته نباشید
آقا آموزش تون واقعا عالی بود.
خواهش می کنم موفق باشید.
دستتون درد نکنه خیلی جالب بود
سلام ممنون از آموزشتون
من طبق آموزش شما پیش رفتم ولی با خطای
BasicNetwork.performRequest: Unexpected response code 500 for …
در logcat مواجه میشم. و در toast هم پیغام ServerError یا TimeoutError میده
میشه راهنمایی کنین مشکل از کجاست؟ ممنون
سلام ممنون بابت اموزش خوبتون
سوالی که داشتم اینه که من با همین روش اپلود میکنم عکسم رو ولی وقتی میرم روی هاست میبینم که عکسم حجمش حدود 10 برابر شده روی هاست
و بهمین دلیل هم در اپلود روی سرور بعضا با ارور null هم روبرو میشم!
میخواستم ببینم علیت این افزایش حجم چیه و چطور میشه مشکل رو حل کرد؟؟