اتصال به SQLServer در اندروید(بخش سوم)

منتشرشده توسط حامد قنبری در تاریخ

در آموزش های قبلی در مورد نحوه ایجاد دیتابیس در هاست و نوشتن اسکریپت های php  برای ذخیره داده ها در SQLServer  آشنا شدیم. در این پست و در آخرین جلسه آموزشی از این مبحث ، قرار است نحوه برنامه نویسی اندروید برای اتصال به دیتابیس SQLServer  را برای دوستان عزیز ارائه کنیم. اگر در زمینه ایجاد دیتابیس و کار با اسکریپت های php  برای ذخیره داده ها در SQLServer  از اطلاعات کافی یا ناقصی برخوردارید ابتدا پست های قبلی مرتبط با این موضوع را بخوانید و سپس وارد این مبحث شوید . برای شروع کار بهتر است مباحث قبلی مرتبط با این موضوع را ذهن خود مرور کنید ، همانطور که پیشتر بیان گردید برنامه یا اپلیکیشن اندروید ما قرار است متغیرهای name- familyname- phonenumber- email را از کاربر گرفته و به url  مورد نظر ما که اسکریپت های php  در آن قرار دارد به روش post  ارسال کند. در سمت سرور نیز اطلاعات از  کلاینت گرفته می شود و در دیتابیس مورد نظر ما ذخیره شود.

اگر در داخل برنامه اکلیپس یا اندروید استودیو قرار دارید پروژه جدیدی را  ایجاد کنید

   اکلیپس :File ⇒ New Android ⇒ Application Project

اندروید استودیو :File ⇒ New  ⇒ New Project

اما اگر هنوز برنامه خود را باز نکرده اید یکی از برنامه های فوق را باز نموده و بعد از تعیین مشخصات(نامگذاری) ، تعیین حداقل sdk  و نوع اکتیویتی (blank  یا Empty) ، نام اکتیویتی ابتدایی و اصلی خود  را همان MainActivity قرار دهید. بعد از لود کامل برنامه ، در مسیر res ⇒layout لایه متناظر اکتیوتی اصلی یعنی activity_main را پیدا نمود و کدهای مندرج و پیش فرض آن را پاک کرده و کدهای xml  زیر را به آن اضافه کنید:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">


    <EditText
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:id="@+id/editText"
        android:hint="youname"
        android:textSize="16dp"
        android:gravity="center"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="159dp" />
    <EditText
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:id="@+id/editText1"
        android:hint="youfamilyname"
        android:textSize="16dp"
        android:gravity="center"
        android:layout_below="@+id/editText"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginTop="35dp" />
    <EditText
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:id="@+id/editText2"
        android:hint="phonenumber"
        android:textSize="16dp"
        android:gravity="center"
        android:layout_below="@+id/editText1"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginTop="35dp" />
    <EditText
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:id="@+id/editText3"
        android:hint="yourEmail"
        android:textSize="16dp"
        android:gravity="center"
        android:layout_below="@+id/editText2"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_marginTop="35dp" />

    <Button
        android:layout_width="fill_parent"
        android:layout_height="40dp"
        android:text="send"
        android:gravity="center"
        android:textSize="15dp"
        android:id="@+id/btnsend"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="73dp" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="connect  and Save data in Sqlserver "
        android:textSize="20dp"

        android:id="@+id/textView"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="77dp"
        android:textColor="#0814f5" />

</RelativeLayout>

در لایوت فوق ما چهار edittex  و یک button  قرار داده ایم که کاربر مشخصات چهارگانه مذکور را در آن نوشته  و با کلیک بر روی دکمه باتن اطلاعات را  به سرور ارسال خواهد کرد. در ادامه به سراغ  کلاس MainActivity  رفته و کدهای زیر را در به آن اضافه می کنیم.

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Iterator;

import javax.net.ssl.HttpsURLConnection;

public class MainActivity extends AppCompatActivity {
EditText name, familyname, phonenumber, email;
    public static String Name= null;
    public static String Familyname= null;
    public static String PhoneNumber= null;
    public static String Email= null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        name = (EditText) findViewById(R.id.editText);
        familyname = (EditText) findViewById(R.id.editText1);
        phonenumber = (EditText) findViewById(R.id.editText2);
         email = (EditText) findViewById(R.id.editText3);
        Button btnsend = (Button) findViewById(R.id.btnsend);
        btnsend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
             Name =   name.getText().toString();
                Familyname =familyname.getText().toString();
                PhoneNumber =phonenumber.getText().toString();
                Email =email.getText().toString();
               new PostData().execute();
            }
        });
    }

    public class PostData extends AsyncTask<String, Void, String> {
        Context context;

        protected void onPreExecute() {
        }

        protected String doInBackground(String... arg0) {

            try {

                URL url = new URL("http://psrd.ir/app/sqlpost.php"); 

                JSONObject postDataParams = new JSONObject();
                postDataParams.put("name", Name);
                postDataParams.put("familyname", Familyname);
                postDataParams.put("phonenumber",PhoneNumber);
                postDataParams.put("email", Email);
                Log.e("params", postDataParams.toString());

                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(15000 /* milliseconds */);
                conn.setConnectTimeout(15000 /* milliseconds */);
                conn.setRequestMethod("POST");
                conn.setDoInput(true);
                conn.setDoOutput(true);

                OutputStream os = conn.getOutputStream();
                BufferedWriter writer = new BufferedWriter(
                        new OutputStreamWriter(os, "UTF-8"));
                writer.write(getPostDataString(postDataParams));

                writer.flush();
                writer.close();
                os.close();

                int responseCode = conn.getResponseCode();

                if (responseCode == HttpsURLConnection.HTTP_OK) {

                    BufferedReader in = new BufferedReader(new
                            InputStreamReader(
                            conn.getInputStream()));

                    StringBuffer sb = new StringBuffer("");
                    String line = "";

                    while ((line = in.readLine()) != null) {

                        sb.append(line);
                        break;
                    }

                    in.close();
                    return sb.toString();

                } else {
                    return new String("false : " + responseCode);
                }
            } catch (Exception e) {
                return new String("Exception: " + e.getMessage());
            }

        }

        @Override
        protected void onPostExecute(String result) {
            AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);
            alert.setMessage(result );
            alert.setPositiveButton("ok",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog,
                                            int which) {
                            dialog.dismiss();
                        }
                    });
            alert.show();
        }


        public String getPostDataString(JSONObject params) throws Exception {

            StringBuilder result = new StringBuilder();
            boolean first = true;

            Iterator<String> itr = params.keys();

            while (itr.hasNext()) {

                String key = itr.next();
                Object value = params.get(key);

                if (first)
                    first = false;
                else
                    result.append("&");

                result.append(URLEncoder.encode(key, "UTF-8"));
                result.append("=");
                result.append(URLEncoder.encode(value.toString(), "UTF-8"));

            }
            return result.toString();
        }

    }
}

همانطور که می بینید ابتدا  متغیرهایی را به منظور دسترسی در کلاس دیگر بصورت public static  از نوع String  تعریف کرده ام و در درون کلاس مذکور ابتدا  لایوت مورد نظر را برای کلاس مشخص کرده و سپس ابزارهای  موجود در آن لایوت را با فراخوانی id آنها و سپس نامگذاری اختیاری  هریک از آنها ، برای کلاس تعریف نموده ایم. بعد از تعریف ابزارها ، برای برنامه چنین تعیین کرده ایم که در صورت کلیک کردن بر روی button  value فیلد های متنی در edittext  ها تبدیل به نوع string  شده و در متغیرهای کلی ما یعنی Name,FamilyName, PhoneNumber , Email  ذخیره شوند.

public class MainActivity extends AppCompatActivity {
EditText name, familyname, phonenumber, email;
    public static String Name= null;
    public static String Familyname= null;
    public static String PhoneNumber= null;
    public static String Email= null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        name = (EditText) findViewById(R.id.editText);
        familyname = (EditText) findViewById(R.id.editText1);
        phonenumber = (EditText) findViewById(R.id.editText2);
         email = (EditText) findViewById(R.id.editText3);
        Button btnsend = (Button) findViewById(R.id.btnsend);
        btnsend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
             Name =   name.getText().toString();
                Familyname =familyname.getText().toString();
                PhoneNumber =phonenumber.getText().toString();
                Email =email.getText().toString();
               new PostData().execute();
            }
        });
    }

 

 کلاس دیگر ما با عنوان PostData  بصورت کلاس درونی در داخل کلاس MainActivty  تعریف شده است. در این کلاس ما از روش Asynctasc بهره برده ایم.از این رو لازم است متدهای آن نیز باید implement گردد . در این کلاس asynctask  دارای سه متد به شرح زیر می باشد که در

1- ()onPreExecute اشاره به متدی است که تعیین می کند قبل انجام عملیات اصلی در پس زمینه برنامه، چه عملیاتی صورت پذیرد. همانطور که می بینید در این متد هیچ کدی نوشته نشده است. البته می توان در این متد از ابزارهایی همچون progress bar استفاده کرد که نشان دهنده شروع عملیات و تداوم آن  می باشد. سینتکس آن به شرح زیر می باشد.

protected void onPreExecute() {
}

2- doInBackground

در این متد همانطور که از نامش پیداست عملیات اصلی یعنی فراخوانی کلاس JsonObject (کلاسی كه امکان خواندن و نوشتن  و پارس كردن آن را براي ماشين‌ها فراهم می سازد) ، خواندن آدرس(Url) ، کانکت شدن به آن  تعیین مدت زمان وقفه برای خواندن داده ها ، تعیین متد زمان اتصالی در صورت پیش آمدن مشکل در اتصال به سرور، تعیین متد ارسال داده (که به روش post می باشد)   ، فراخوانی کانکشن برای رایت کردن در استریم ،نوشتن داده های پست شده به بافر، inputStream  و  outputStream ، و دریافت کد response  و برگرداندن آن به نوع String  که متد آن در این کلاس نوشته است.  و بطور کلی  چگونگی و کیفیت نوع انجام عملیات در این متد صورت می گیرد.

 protected String doInBackground(String... arg0) {

            try {

                URL url = new URL("http://psrd.ir/fixurl/sqlpost.php"); 

                JSONObject postDataParams = new JSONObject();
                postDataParams.put("name", Name);
                postDataParams.put("familyname", Familyname);
                postDataParams.put("phonenumber",PhoneNumber);
                postDataParams.put("email", Email);
                Log.e("params", postDataParams.toString());

                HttpURLConnection conn = (HttpURLConnection) url.openConnection();
                conn.setReadTimeout(15000 /* milliseconds */);
                conn.setConnectTimeout(15000 /* milliseconds */);
                conn.setRequestMethod("POST");
                conn.setDoInput(true);
                conn.setDoOutput(true);

                OutputStream os = conn.getOutputStream();
                BufferedWriter writer = new BufferedWriter(
                        new OutputStreamWriter(os, "UTF-8"));
                writer.write(getPostDataString(postDataParams));

                writer.flush();
                writer.close();
                os.close();

                int responseCode = conn.getResponseCode();

                if (responseCode == HttpsURLConnection.HTTP_OK) {

                    BufferedReader in = new BufferedReader(new
                            InputStreamReader(
                            conn.getInputStream()));

                    StringBuffer sb = new StringBuffer("");
                    String line = "";

                    while ((line = in.readLine()) != null) {

                        sb.append(line);
                        break;
                    }

                    in.close();
                    return sb.toString();

                } else {
                    return new String("false : " + responseCode);
                }
            } catch (Exception e) {
                return new String("Exception: " + e.getMessage());
            }

        }

3-onPostExecute

این مرحله نیز از زمان اتمام عملیات اصلی شروع می شود . یعنی برنامه نویس در این متد تعیین می کند که بعد از عملیات اصلی که در این مثال پست داده ها به سرور و گرفتن respons  از سرور است  چه واکنشی از طرف برنامه صادر شود. که در این مثال نشان دادن نتیجه response  در قالب یک آلرت دیالوگ است.

 @Override
        protected void onPostExecute(String result) {
            AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);
            alert.setMessage(result );
            alert.setPositiveButton("ok",
                    new DialogInterface.OnClickListener() {
                        @Override
                        public void onClick(DialogInterface dialog,
                                            int which) {
                            dialog.dismiss();
                        }
                    });
            alert.show();
        }

 و در نهایت با افزودن premission زیر به AndroidManifest.xml  مجوز دسترسی اپلیکیشن را به اینترنت را تعریف می کنیم.توجه داشته باشد که در صورت کپی کردن کدها نام پکیج خودرا  با پکیج  ارائه شده در مثال مقایسه کنید و پکیج پروژه خود را در آن لحاظ کنید.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.site.psrd.connectsqlserver">
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

حال پروژه را اجرا کرده و از آن در آموزش هر چه بیشتر خود استفاده کنید. اگر مشکلی در اجرای کدها وجود دارد یا سوال مشخصی از نویسنده سایت دارید سوالات خود را در قسمت دیدگاه ها بیان کنید.

کپی برداری از محتوای سایت psrd، ممنوع بوده و پیگرد قانونی دارد. (تنها استفاده شخصی کاربران ، مجاز است) (کپی برداری توسط سایر وب سایت ها  غیرقانونی بوده و در صورت رویت به ستادسازماندهی اطلاع داده خواهد شد.


11 دیدگاه

حامد قنبری · دسامبر 14, 2017 در 6:34 ق.ظ

مشکل از thread است. یعنی اینکه که شما نیاز دارید برای انجام عملیات جدید یک ترد فرعی تعریف کنید

سعید غفاری · دسامبر 14, 2017 در 10:36 ق.ظ

سلام بنده هم با زدن دکمه send با یک کد html مواجه میشم و با زدن دوباره دکمه با ارور false:400 مواجه میشم در سمت سرور ارتباط با دیتابیسم رو چک کردم درسته

    حامد قنبری · دسامبر 14, 2017 در 1:11 ب.ظ

    مشکل از کدنویسی است که برای سرور قابل پردازش نیست. البته کوکی های مرورگرتان را هم پاک کنید. اگه مشکلت حل نشد کدهاتو بفرست علت خطاشو بهت بگم

سعید غفاری · دسامبر 16, 2017 در 6:20 ق.ظ

package saeed.test.www.myapplication;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.EditText;

import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Iterator;

import javax.net.ssl.HttpsURLConnection;

public class MainActivity extends AppCompatActivity {
EditText name, familyname, phonenumber, email;
public static String Name= null;
public static String Familyname= null;
public static String PhoneNumber= null;
public static String Email= null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
name = (EditText) findViewById(R.id.editText);
familyname = (EditText) findViewById(R.id.editText1);
phonenumber = (EditText) findViewById(R.id.editText2);
email = (EditText) findViewById(R.id.editText3);
Button btnsend = (Button) findViewById(R.id.btnsend);
btnsend.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Name = name.getText().toString();
Familyname =familyname.getText().toString();
PhoneNumber =phonenumber.getText().toString();
Email =email.getText().toString();
new PostData().execute();
}
});
}

public class PostData extends AsyncTask {
Context context;

protected void onPreExecute() {
}

protected String doInBackground(String… arg0) {

try {

URL url = new URL(“http://databasetest.gigfa.com/name.php”);

JSONObject postDataParams = new JSONObject();
postDataParams.put(“name”, Name);
postDataParams.put(“familyname”, Familyname);
postDataParams.put(“phonenumber”,PhoneNumber);
postDataParams.put(“email”, Email);
Log.e(“params”, postDataParams.toString());

HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(15000 /* milliseconds */);
conn.setConnectTimeout(15000 /* milliseconds */);
conn.setRequestMethod(“POST”);
conn.setDoInput(true);
conn.setDoOutput(true);

OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(os, “UTF-8”));
writer.write(getPostDataString(postDataParams));

writer.flush();
writer.close();
os.close();

int responseCode = conn.getResponseCode();

if (responseCode == HttpsURLConnection.HTTP_OK) {

BufferedReader in = new BufferedReader(new
InputStreamReader(
conn.getInputStream()));

StringBuffer sb = new StringBuffer(“”);
String line = “”;

while ((line = in.readLine()) != null) {

sb.append(line);
break;
}

in.close();
return sb.toString();

} else {
return new String(“false : ” + responseCode);
}
} catch (Exception e) {
return new String(“Exception: ” + e.getMessage());
}

}

@Override
protected void onPostExecute(String result) {
AlertDialog.Builder alert = new AlertDialog.Builder(MainActivity.this);
alert.setMessage(result );
alert.setPositiveButton(“ok”,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog,
int which) {
dialog.dismiss();
}
});
alert.show();
}

public String getPostDataString(JSONObject params) throws Exception {

StringBuilder result = new StringBuilder();
boolean first = true;

Iterator itr = params.keys();

while (itr.hasNext()) {

String key = itr.next();
Object value = params.get(key);

if (first)
first = false;
else
result.append(“&”);

result.append(URLEncoder.encode(key, “UTF-8”));
result.append(“=”);
result.append(URLEncoder.encode(value.toString(), “UTF-8”));

}
return result.toString();
}

}
}

سعید غفاری · دسامبر 16, 2017 در 6:23 ق.ظ

البته قبل از اجرا این الرت رو هم میده
All packages are not available for download! The following packages are not available:
– Package id platforms;android-23
ولی وقتی اوکی رو میزنم برنامه ران میشه

    حامد قنبری · دسامبر 16, 2017 در 6:35 ق.ظ

    مجوز اتصال به اینترنت را از قسمت androidmanfest کنترل کن .
    Android Studio > File > Settings > System Settings > HTTP Proxy پروکسی خودتو تنظیم کن
    اگه مشکلت حل نشد : مشکل می تونه از کندی اینترنت یا sdk هم باشه

سعید غفاری · دسامبر 16, 2017 در 7:24 ق.ظ

امکان داره به خاطر محدودیت های گوگل برای ایران باشه ؟ من هیچ فیلتر شکنی ستفاده نکردم و تنظیمات پروکسیم هم روی no proxy هست
آقای قنبری من خیلی برام مهمه از این کد جواب بگیرم میدونم دارم اذیتتون میکنم ولی واقعا ممنون میشم تا گام آخر راهنماییم کنید این شماره تلگرام منه
09193480263 واقعا لطف بزرگی میکنید اگه یه پیام تو تلگرام به بنده بدید تا من بتونم تصاویر رو خدمتتون بفرستم

مهتاب · ژانویه 11, 2018 در 9:45 ب.ظ

سلام وقت بخیر
ببخشید آقا من کد رو زدم اما برنامه تا بازش میکنم بسته میشه کد php هم نوشتم درسته اما برنامه سریع بسته میشه
یه لطفی میکنین سورسشو بذارین

حامد قنبری · ژانویه 18, 2018 در 11:58 ق.ظ

اگر از هاست رایگان استفاده می کنید برخی از این هاست ها اجازه اجرای request ها را برای ذخیره داده ها در دیتابیس SqlServer vh نمی ده . بنابراین یک هاست مطمئن پیدا کنید. یا از هاست های پولی استفاده کنید.

علی · جولای 28, 2018 در 10:20 ق.ظ

سلام من سورس رو زدم ولی این پیغام رو میده:
Exception : Can’t create handler inside thread that has not called lopper.prepre
و از tread فرعی هم استفاده کردم لطفا راهنمای کنید ممنون.

    حامد قنبری · آگوست 24, 2018 در 1:01 ب.ظ

    شما باید بسیاری از توابع دیگر که با UI سروکار دارد را از داخل thread یا موضوع اصلی فراخوانی کنید.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

-- بارگیری کد امنیتی --