【问题标题】:Android - How to get response from a MySQL Database using PHP?Android - 如何使用 PHP 从 MySQL 数据库中获取响应?
【发布时间】:2017-03-01 03:16:39
【问题描述】:

大家好,

我在从我创建的 php 文件中获取响应时遇到问题。我正在使用 AsyncTask 发送带有 SELECT 语句的请求,然后将其传递到本地 MySQL 数据库。我想将响应作为 JSON 字符串返回给 Android,但我在 Android 中得到的只是一个空字符串。如果我在浏览器中尝试 PHP 文件,我会得到正确的输出。

这是我的代码示例:

我的 AsyncTask 类:

public class DBHelperAsyncTask extends AsyncTask<String, Void, String> {
    private static final String SHARED_PREFERENCE = SharedPreferencesEnum.SHARED_PREFERENCE.getText();
    SharedPreferences prefs;
    final protected Activity currentActivity;
    final protected URL link;
    final protected String fileName;
    private ProgressDialog dialog;

    public DBHelperAsyncTask(Activity currentActivity, URL link, String fileName) throws MalformedURLException
    {
        this.currentActivity = currentActivity;
        this.fileName = fileName;
        this.link = new URL(String.format("http://{0}/{1}", link, fileName));
    }

    public DBHelperAsyncTask(Activity currentActivity, URL link) throws MalformedURLException
    {
        this.currentActivity = currentActivity;
        this.fileName = "uebergabe.php";
        this.link = new URL(String.format("http://{0}/{1}", link, fileName));
    }

    public DBHelperAsyncTask(Activity currentActivity) throws MalformedURLException
    {
        prefs = PreferenceManager.getDefaultSharedPreferences(currentActivity);
        this.currentActivity = currentActivity;
        this.fileName = "uebergabe.php";
        this.link = new URL(String.format("http://%s/%s", prefs.getString(SharedPreferencesEnum.HOST.getText(), "127.0.0.1"), prefs.getString(SharedPreferencesEnum.PFAD.getText(), fileName)));
        AlertDialog.Builder builder = new AlertDialog.Builder(currentActivity);
        builder.setTitle(link.toString());
        Dialog dialog = builder.create();
        dialog.show();


    }

    @Override
    protected void onPreExecute() {
        dialog = new ProgressDialog(currentActivity);
        dialog.setIndeterminate(false);
        dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        dialog.show();
        super.onPreExecute();
    }

    @Override
    protected String doInBackground(String... params) {
        try {
            HttpURLConnection connection = (HttpURLConnection) link.openConnection();
            connection.setDoOutput(true);

            OutputStreamWriter writer = new OutputStreamWriter(connection.getOutputStream());

            if (params.length > 1) return null;
            else
            {
                String data = URLEncoder.encode("Url", "UTF-8") + "=" + URLEncoder.encode(params[0], "UTF-8");
                writer.write(data);
                writer.flush();
                writer.close();
                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                StringBuilder builder = new StringBuilder();
                String line = null;
                while((line = reader.readLine()) != null)
                {
                    builder.append(line);
                    break;
                }
                reader.close();
                return builder.toString().trim();
            }

            //Aufruf bei Verbindungsunterbrechung
        } catch (Exception e) {
            AlertDialog.Builder builder = new AlertDialog.Builder(currentActivity);
            builder.setTitle("Verbindungsfehler");
            builder.setMessage("Die Verbindung mit dem Server hat fehlergeschlagen");
            builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.dismiss();
                }
            });


            Dialog dialog = builder.create();
            dialog.show();
            return null;
        }
    }

    @Override
    protected void onPostExecute(String result) {
        if(dialog.isShowing()) {
            dialog.dismiss();
        }
    }

    //Konventiert ein json String zum ContentValues
    public ContentValues jsonToContentValues(String jsonString) {
        ContentValues output = new ContentValues();
        JSONObject parser = new JSONObject();
        try {
            if (jsonString == null) throw new JSONException(null);
            parser = new JSONObject(jsonString);
            Iterator<String> iterator = parser.keys();
            JSONArray array = parser.names();
            while (iterator.hasNext()) output.put(iterator.next(), array.getString(output.size()));
        } catch (JSONException e) {
            AlertDialog.Builder builder = new AlertDialog.Builder(currentActivity);
            builder.setTitle("Daten-Konvertierungsfehler");
            builder.setMessage("Die Daten konnten nicht richtig gelesen werden\n" + jsonString);
            builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    dialog.dismiss();
                }
            });


            Dialog dialog = builder.create();
            dialog.show();
            return null;
        } finally {
            return output;
        }
    }

}

我的主要活动:

public class MainActivity extends ActionBarActivity {
    private static final String SHARED_PREFERENCE = SharedPreferencesEnum.SHARED_PREFERENCE.getText();
    ContentValues result = null;
    private EditText benutzerEditText;
    private EditText passwortEditText;
    private TextView anmeldenTextView;
    DBHelperAsyncTask asyncTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SharedPreferences prefs = getSharedPreferences(SHARED_PREFERENCE, MODE_PRIVATE);

        String benutzer = prefs.getString(SharedPreferencesEnum.BENUTZER.getText(), null);
        if(benutzer == null) {
            setContentView(R.layout.login_maske);
            benutzerEditText = (EditText) findViewById(R.id.benutzerNameEditText);
            passwortEditText = (EditText) findViewById(R.id.benutzerPasswortEditText);
        }
        else
            setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        Intent intent = null;
        switch(item.getItemId()) {
            case R.id.settings_scan:
                intent = new Intent(Intent.ACTION_VIEW);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                intent.setClassName(this, PreferencesActivity.class.getName());
                break;
            case R.id.settings:
                intent = new Intent(Intent.ACTION_VIEW);
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
                intent.setClassName(this, SettingsActivity.class.getName());
                break;
        }
        startActivity(intent);
        return super.onOptionsItemSelected(item);
    }
    public void onAnmeldenClick(View view) throws MalformedURLException, InterruptedException, ExecutionException
    {
        asyncTask = new DBHelperAsyncTask(this);
        String sql = String.format("SELECT IDBenutzer, Passwort FROM benutzer where Benutzername = '{0}'", benutzerEditText.getText().toString());
        result = asyncTask.jsonToContentValues(asyncTask.execute(sql).get());

        anmeldenTextView = (TextView) findViewById(R.id.anmeldenTextView);
        anmeldenTextView.setText(result.toString());
        /*
        String passwort = result.getAsString("Passwort");
        if(passwortEditText.getText().toString() == passwort)
        {
            SharedPreferences prefs = getSharedPreferences(SHARED_PREFERENCE, MODE_PRIVATE);
            SharedPreferences.Editor editor = prefs.edit();
            editor.putInt(SharedPreferencesEnum.BENUTZER_ID.getText(), result.getAsInteger("IDBenutzer"));
            editor.putString(SharedPreferencesEnum.BENUTZER.getText(), result.getAsString("Benutzer"));
        }*/
    }


    public void onPruefenClick(View view) {
        Intent intent = new Intent("com.google.zxing.client.android.SCAN");
        startActivityForResult(intent, 0);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 0) {
            if (resultCode == RESULT_OK) {

                String contents = data.getStringExtra("SCAN_RESULT");
                AlertDialog dialog = new AlertDialog.Builder(MainActivity.this).create();
                dialog.setTitle("Barcode");
                dialog.setMessage(contents);
                dialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
                        new DialogInterface.OnClickListener(){
                            public void onClick(DialogInterface dialog, int which) {
                                dialog.dismiss();
                            }
                        });
                dialog.show();
                // Handle successful scan

            }
        }
    }


    public void onAbmeldenClick(View view)
    {
        SharedPreferences prefs = getSharedPreferences(SHARED_PREFERENCE, MODE_PRIVATE);
        SharedPreferences.Editor editor = prefs.edit();
        editor.remove(SharedPreferencesEnum.BENUTZER.getText());
        editor.remove(SharedPreferencesEnum.BENUTZER_ID.getText());
        editor.commit();
        restartActivity(this);
    }

    private void restartActivity(Activity restartActivity)
    {
        Intent intent = new Intent();
        intent.setClass(restartActivity, restartActivity.getClass());
        restartActivity.startActivity(intent);
        restartActivity.finish();
    }
}

还有 PHP 文件:

    <?php

    $link = "localhost";
    $user = "root";
    $password = "";
    $dbname = "ProjektZ";

    $conn = mysqli_connect($link,$user,$password,$dbname);

    if ($conn->connect_error) {
                #Script verlassen
                die("Connection failed");
            } 
            $sql = $_POST['Url']; #sql-anfrage erstellen
            $myArray = array();
            if ($result = $conn->query($sql)) #sql-anfrage ausführen und in Variable speichern
            if(is_object($result))
            {
                while($row = $result->fetch_array(MYSQL_ASSOC)) $myArray[] = $row;
                header('Content-type: application/json');
                echo json_encode($myArray);     
            }
            mysqli_close($conn);
?>

我读到的所有地方都表明 echo json_encode($myArray) 应该是将响应传回应用程序的正确方法。

【问题讨论】:

  • IMO 你不应该在客户端(Android)端进行用户验证。您应该在服务器(PHP)端执行此操作。并请散列密码。好像您以纯文本形式存储它们。这里的整个登录过程对我来说似乎很容易受到攻击。
  • 这是一种基本方法,只是为了测试它是否能正常工作。诸如 Encrypiton 之类的其他东西将随之而来。

标签: php android mysql json android-asynctask


【解决方案1】:

我认为您应该考虑使用REST 方法从数据库中获取数据。这对 Android 应用程序来说会更容易,也更安全(SQL 注入是代码中的风险)。 您可以使用 Symfony 之类的 CMS(或您喜欢的任何其他 CMS)来帮助您构建服务器端。

【讨论】:

  • 这是否与例如冲突? XAMPP之类的?更重要的是,这与简单地使用 Apache 和 HTTP-Requests 有很大不同吗?
  • 我看到您已经在使用 XAMP 环境,所以这是一个简单的步骤。不,没有什么不同,它比手动完成所有这些操作更简单、更安全、更快捷。
  • 如果要更改为 REST,您有什么建议可以从哪里开始。使用 REST 需要在服务器上安装除 XAMPP 以外的任何其他设备吗?
  • 您可以阅读本教程:symfony.com/doc/current/bundles/FOSRestBundle/index.html。 XAMP 正是您所需要的。
  • 感谢您的帮助。我去看看。
猜你喜欢
  • 2015-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-13
  • 1970-01-01
  • 2012-01-22
  • 2012-11-20
  • 2019-02-25
相关资源
最近更新 更多