#java #php #android #mysql
#java #php #Android #mysql
Вопрос:
Я написал приложение, которое подключается к серверу wamp (с базой данных MySQL, в одной из строк которой в таблице users есть Username = «pooriya» и Password = «123»). Это приложение проверяет, существует ли имя пользователя «pooriya», затем произносит пароль, и если не существует, произносит «нет пользователя».
Когда я запускаю это приложение на эмуляторе, оно должно отображать «123», но отображается пустой Toast. Почему? Даже когда я меняю пользователя на несуществующее имя пользователя, например «poori», снова отображается пустой Toast . Почему? имя базы данных «note_test_2_db», И когда я ввожу адрес «http://127.0.0.1:8080/mysite1/index.php «в моем браузере отображается «нет пользователя», тогда я предполагаю, что файл php работает правильно, и проблема в моем коде Android. Спасибо
package com.example.GetDataFromServer;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
public class MyActivity extends Activity {
public static String res = "";
Button btn;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button);
new getdata("http://127.0.0.1:8080/mysite1/index.php", "pooriya").execute();
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getApplicationContext(), res, Toast.LENGTH_LONG).show();
}
});
}
}
package com.example.GetDataFromServer;
import android.os.AsyncTask;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
/**
* Created with IntelliJ IDEA.
* User: Farid
* Date: 3/15/19
* Time: 4:09 PM
* To change this template use File | Settings | File Templates.
*/
public class getdata extends AsyncTask {
private String Link = "";
private String User = "";
public getdata(String link, String user) {
Link = link;
User = user;
}
@Override
protected String doInBackground(Object... objects) {
try {
String data = URLEncoder.encode("username", "UTF8") "=" URLEncoder.encode(User, "UTF8");
URL mylink = new URL(Link);
URLConnection connect = mylink.openConnection();
connect.setDoOutput(true);
OutputStreamWriter wr= new OutputStreamWriter(connect.getOutputStream());
wr.write(data);
wr.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(connect.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
MyActivity.res = sb.toString();
} catch (Exception e) {
}
return ""; //To change body of implemented methods use File | Settings | File Templates.
}
}
$con=mysql_connect("localhost","root","");
mysql_select_db("note_test_2_db",$con);
$user=$_POST['username'];
$sqlQ="select * from users where Username='$user'";
$result= mysql_Query($sqlQ);
$row=mysql_fetch_array($result);
if($row[0]){
print $row[1];
}
else{
print "no user";
}
mysql_close($con);
Комментарии:
1. Добавили ли вы разрешение доступа в Интернет в свой файл манифеста?
2. Проверьте это следующим образом и дайте мне знать, если это не сработает
Toast.makeText(MyActivity.this, "Hello this is toast", Toast.LENGTH_LONG).show();
3.
http://127.0.0.1:8080
это не тот IP-адрес, который вам нужно использовать. 127.0.0.1 — это адрес самого эмулятора. Кроме того, вы игнорируете исключение, поэтому вы не знаете, что что-то не так.4. НИКОГДА, НИКОГДА, НИКОГДА не доверяйте пользовательскому вводу! Строка
$user=$_POST['username'];
может быть использована для выполнения SQLInjection! Экранируйте данные с помощьюmysql_real_escape_string
или используйтеPDO
5. ваше сообщение toast пустое. Что вы хотите показать пользователю, если сообщение пустое???
Ответ №1:
Проблема: Кажется, что ваш код для отображения Toast
неверен.
new getdata("http://127.0.0.1:8080/mysite1/index.php", "pooriya").execute();
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(getApplicationContext(), res, Toast.LENGTH_LONG).show();
}
});
Когда будет выполнена первая строка, приложение запустит, AsyncTask
которое подключается к вашему серверу, чтобы получить ответ ( "123"
или "No User"
).
Если вы нажмете на кнопку btn
перед AsyncTask
завершением, в это время значение res
равно ""
, вот почему вы всегда получаете пустое Toast
.
Решение: Вы можете выполнить следующие шаги
Шаг 1: Потому что getdata
это отдельный класс, поэтому вам нужно определить интерфейс для передачи данных ( "123"
или "No User"
любого значения) обратно в MyActivity
.
public interface OnDataListener {
void onData(String result);
}
Шаг 2: Изменить getdata
класс
public class getdata extends AsyncTask<Object, Void, String> {
private String Link = "";
private String User = "";
private WeakReference<OnDataListener> mListener;
public getdata(String link, String user, OnDataListener listener) {
Link = link;
User = user;
mListener = new WeakReference<>(listener);
}
@Override
protected String doInBackground(Object... objects) {
try {
String data = URLEncoder.encode("username", "UTF8") "=" URLEncoder.encode(User, "UTF8");
URL mylink = new URL(Link);
URLConnection connect = mylink.openConnection();
connect.setDoOutput(true);
OutputStreamWriter wr = new OutputStreamWriter(connect.getOutputStream());
wr.write(data);
wr.flush();
BufferedReader reader = new BufferedReader(new InputStreamReader(connect.getInputStream()));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line);
}
// This string will pass as param of onPostExecute method.
return sb.toString(); // Will return "123" or "No User" if there is no exception occurs.
} catch (Exception e) {
}
// If your app reach this line, it means there is an exception occurs, using a unique string for debugging.
// This string will pass as param of onPostExecute method
return "An exception has been caught!!!";
}
@Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
// Pass the result back to MyActivity's onData method.
if (mListener != null amp;amp; mListener.get() != null) {
mListener.get().onData(result);
}
}
}
Шаг 3: Пусть MyActivity
реализуется OnDataListener
интерфейс.
public class MyActivity extends AppCompatActivity implements OnDataListener {
public static String res = "";
Button btn;
/**
* Called when the activity is first created.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn = (Button) findViewById(R.id.button);
new getdata("http://127.0.0.1:8080/mysite1/index.php", "pooriya", this).execute();
// TODO: Comment-out this code
// btn.setOnClickListener(new View.OnClickListener() {
// @Override
// public void onClick(View view) {
// Toast.makeText(getApplicationContext(), res, Toast.LENGTH_LONG).show();
// }
// });
}
@Override
public void onData(String result) {
// result is passed from the AsyncTask's onPostExecute method.
Toast.makeText(getApplicationContext(), result, Toast.LENGTH_LONG).show();
}
}
Примечание: Поскольку вы не используете индикатор загрузки при подключении к серверу, поэтому вам нужно подождать несколько секунд, чтобы увидеть Toast на экране.
Ответ №2:
Я решил проблему. Я должен использовать
вместо