Не думаю что я буду оригинальным в этой теме так как в интернете полным полно примеров которые должны вроде бы как показать как правильно работать, но у меня как у криворукого говнокодера примеры почему-то запускаются только с сайта stackowerflow, поэтому я решил сделать так называемую заметку на будущее если понадобится работать еще с json и с post / get запросами, всегда будет готовый пример / код под рукой.
И так начнем, для начала нам нужен сервер который нам будет возвращать что либо, для этого нам понадобитсяwamp server который будет эмулировать наш сервер на компьютере, что бы не покупать хостинг за большие деньги, и конечно же нам нужно его настроить, настройка очень простая, запусукаем инсталятор, ждем пока проинсталируется и запускаем наш сервер, дальше по пути где вы установили открываем папку wamp/www/ и закидываем туда login.php к которому мы будем обращаться.
Так как мы пишем приложение с работой с удаленным сервером я напишу небольшой скрипт который будет при правильном логине и пароле выдавать нам json строку которую позже мы будем парсить на телефоне.
Открываем в блокноте наш login.php и пишем вот этот код:
login.php
Тут все просто, при получении данных постом сервер их обрабатывает и сравнивает с теми данными которые у него есть, то есть user и pass, если они сходятся значит все отлично и можно отдавать json.
Теперь закидывайте этот файл в wamp/www/ и можно начинать писать клиентскую часть приложения. Создайте андроид проект и начнем.
Первая активность у нас будет посылать post запрос на сервер с логином и паролем, вторая активность принимает ответ от сервера и обрабатываем его для вывода в листвью.
MainActivity
Комментарии описывают весь функционал, остальное впринципе нам не сильно нужно, его я добавил чисто для карсоты.
Запрос мы выполняем в AsyncTask для меньшей загружености телефона, и что бы он не зависал при обработке запроса.
Главное окно
Ах да, как я забыл про разметочку нашей активити, вот она родимая ниже:
main.xml
Воот, теперь нам нужно создать вторую активность которая будет принимать наш json и парсить его, для вывода в листвью. Там так же не сильно много кода, он простой и понятный, конечно же присутствуют комментарии.
SecondActivity
Опять же в комментариях я максимально пытался объяснить как и что делается в этом коде, надеюсь дальнейшего пояснения он не требует.
Ну и осталось только создать разметку для второй активности, первая у нас главная, в ней listView в который все будет размещаться, а вторая это собственно сама разметка listView так как я захотел что бы он выглядел. В общем смотрите сами.
url.xml
и сама разметка listview
list.xml
Не забываем так же прописать в AndroidManifest доступ в интернет:
И доступ к второй активности:
Вот теперь запускаем и проверяем как оно работает. Исходники я закинул на гит так что у тех у кого не получилось что либо смотрите их.
И так начнем, для начала нам нужен сервер который нам будет возвращать что либо, для этого нам понадобитсяwamp server который будет эмулировать наш сервер на компьютере, что бы не покупать хостинг за большие деньги, и конечно же нам нужно его настроить, настройка очень простая, запусукаем инсталятор, ждем пока проинсталируется и запускаем наш сервер, дальше по пути где вы установили открываем папку wamp/www/ и закидываем туда login.php к которому мы будем обращаться.
Так как мы пишем приложение с работой с удаленным сервером я напишу небольшой скрипт который будет при правильном логине и пароле выдавать нам json строку которую позже мы будем парсить на телефоне.
Открываем в блокноте наш login.php и пишем вот этот код:
login.php
<?php // серверная часть вывода json
$login = $_POST['login'];
$pass = $_POST['pass'];
if($login == "user" & $pass == "pass") {
?> {
"data":[
{
"firstName":"John",
"lastName":"Doe"
},
{
"firstName":"Anna",
"lastName":"Smith"
},
{
"firstName":"Peter",
"lastName":"Jones"
}
]
}<?php }
?>
Тут все просто, при получении данных постом сервер их обрабатывает и сравнивает с теми данными которые у него есть, то есть user и pass, если они сходятся значит все отлично и можно отдавать json.
Теперь закидывайте этот файл в wamp/www/ и можно начинать писать клиентскую часть приложения. Создайте андроид проект и начнем.
Первая активность у нас будет посылать post запрос на сервер с логином и паролем, вторая активность принимает ответ от сервера и обрабатываем его для вывода в листвью.
MainActivity
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import org.apache.http.NameValuePair;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
public EditText login;
public EditText pass;
private ProgressDialog dialog;
private InputStream is;
SecondActivity url;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn = (Button) findViewById(R.id.button1);
login = (EditText) findViewById(R.id.editText1);
pass = (EditText) findViewById(R.id.editText2);
btn.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//тут указываем куда будем конектится, для примера я привел удаленных хост если у вас не получилось освоить wamp (:
new RequestTask().execute("http://myhomepage.hol.es/login.php");
}
});
}
class RequestTask extends AsyncTask<String, String, String> {
@Override
protected String doInBackground(String... params) {
try {
//создаем запрос на сервер
DefaultHttpClient hc = new DefaultHttpClient();
ResponseHandler<String> res = new BasicResponseHandler();
//он у нас будет посылать post запрос
HttpPost postMethod = new HttpPost(params[0]);
//будем передавать два параметра
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
//передаем параметры из наших текстбоксов
//лоигн
nameValuePairs.add(new BasicNameValuePair("login", login.getText().toString()));
//пароль
nameValuePairs.add(new BasicNameValuePair("pass", pass.getText().toString()));
//собераем их вместе и посылаем на сервер
postMethod.setEntity(new UrlEncodedFormEntity(nameValuePairs));
//получаем ответ от сервера
String response = hc.execute(postMethod, res);
//посылаем на вторую активность полученные параметры
Intent intent = new Intent(MainActivity.this, SecondActivity.class);
//то что куда мы будем передавать и что, putExtra(куда, что);
intent.putExtra(SecondActivity.JsonURL, response.toString());
startActivity(intent);
} catch (Exception e) {
System.out.println("Exp=" + e);
}
return null;
}
@Override
protected void onPostExecute(String result) {
dialog.dismiss();
super.onPostExecute(result);
}
@Override
protected void onPreExecute() {
dialog = new ProgressDialog(MainActivity.this);
dialog.setMessage("Загружаюсь...");
dialog.setIndeterminate(true);
dialog.setCancelable(true);
dialog.show();
super.onPreExecute();
}
}
}
Комментарии описывают весь функционал, остальное впринципе нам не сильно нужно, его я добавил чисто для карсоты.
Запрос мы выполняем в AsyncTask для меньшей загружености телефона, и что бы он не зависал при обработке запроса.
Главное окно
Ах да, как я забыл про разметочку нашей активити, вот она родимая ниже:
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<Button
android:id="@+id/button1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_centerVertical="true"
android:text="Залогиниться" />
<EditText
android:id="@+id/editText2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/button1"
android:layout_alignParentLeft="true"
android:text="pass"
android:ems="10" >
<requestFocus />
</EditText>
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/editText2"
android:layout_alignParentLeft="true"
android:text="Пароль" />
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@+id/textView2"
android:layout_alignParentLeft="true"
android:text="user"
android:ems="10" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/editText1"
android:layout_alignParentLeft="true"
android:text="Логин" />
</RelativeLayout>
Воот, теперь нам нужно создать вторую активность которая будет принимать наш json и парсить его, для вывода в листвью. Там так же не сильно много кода, он простой и понятный, конечно же присутствуют комментарии.
SecondActivity
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
public class SecondActivity extends Activity {
public static String JsonURL;
private static ArrayList<HashMap<String, Object>> myBooks;
private static final String FIRST = "firstname";
private static final String LAST = "lastname";
public ListView listView;
/** @param result */
public void JSONURL(String result) {
try {
//создали читателя json объектов и отдали ему строку - result
JSONObject json = new JSONObject(result);
//дальше находим вход в наш json им является ключевое слово data
JSONArray urls = json.getJSONArray("data");
//проходим циклом по всем нашим параметрам
for (int i = 0; i < urls.length(); i++) {
HashMap<String, Object> hm;
hm = new HashMap<String, Object>();
//читаем что в себе хранит параметр firstname
hm.put(FIRST, urls.getJSONObject(i).getString("firstName").toString());
//читаем что в себе хранит параметр lastname
hm.put(LAST, urls.getJSONObject(i).getString("lastName").toString());
myBooks.add(hm);
//дальше добавляем полученные параметры в наш адаптер
SimpleAdapter adapter = new SimpleAdapter(SecondActivity.this, myBooks, R.layout.list,
new String[] { FIRST, LAST, }, new int[] { R.id.text1, R.id.text2 });
//выводим в листвбю
listView.setAdapter(adapter);
listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
}
} catch (JSONException e) {
Log.e("log_tag", "Error parsing data " + e.toString());
}
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.url);
listView = (ListView) findViewById(R.id.list);
myBooks = new ArrayList<HashMap<String, Object>>();
//принимаем параметр который мы послылали в manActivity
Bundle extras = getIntent().getExtras();
//превращаем в тип стринг для парсинга
String json = extras.getString(JsonURL);
//передаем в метод парсинга
JSONURL(json);
}
}
Опять же в комментариях я максимально пытался объяснить как и что делается в этом коде, надеюсь дальнейшего пояснения он не требует.
Ну и осталось только создать разметку для второй активности, первая у нас главная, в ней listView в который все будет размещаться, а вторая это собственно сама разметка listView так как я захотел что бы он выглядел. В общем смотрите сами.
url.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/list"
/>
</LinearLayout>
и сама разметка listview
list.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:orientation="horizontal"
android:layout_height="wrap_content">
<LinearLayout
android:layout_width="265dip"
android:orientation="vertical"
android:layout_height="wrap_content">
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/text1"
android:textSize="25dip"
android:text="This is text1"/>
<TextView android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/text2"
android:text="This is text2"/>
</LinearLayout>
</LinearLayout>
Не забываем так же прописать в AndroidManifest доступ в интернет:
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
И доступ к второй активности:
<activity android:name="my.home.page.SecondActivity"></activity>
Вот теперь запускаем и проверяем как оно работает. Исходники я закинул на гит так что у тех у кого не получилось что либо смотрите их.
Ув. автор подскажите пожалуйста, ну очень надо как сделать чат по wifi. Заранее спасибо
ОтветитьУдалитьПо правде сказать для написания чата, нужна серьезная серверная часть что бы можно было обрабатывать серьезные запросы, я такое никогда не писал, поэтому ищите сперва сервеную часть, а потом уже пишите клиентскую.
УдалитьПросто Мария
УдалитьОтвет классный, сам долго интересовался этим вопросом!
УдалитьА если в ответ сервер будет отдавать урлы по которым лежат изображения. Как их скачать и отобразить?
ОтветитьУдалитьТоже очень интересует вопрос касательно изображений.
Удалитьhttp://nostra13android.blogspot.ru/2012/03/4-universal-image-loader-part-1.html
Удалить"HashMap hm;
ОтветитьУдалитьhm = new HashMap();"
Лучше так: Map hm = new HashMap();
Уважаемый Глеб.
ОтветитьУдалитьХотел бы заказать у Вас исходняки для живых обой под андройд. Занимаетесь ли Вы таким?
darkavega01@gmail.com
Так я вроде бы выкладывал статью про создание обоев. Или вам что-то другое нужно?
УдалитьНаверно несколько другое. Напишите пожалуйста как с вами можно связаться.
Удалитьdajver4 - skype
Удалитьlfqdth5@gmail.com - email
Автор, большое спасибо за статью! Несмотря на то, что одно приложение с json я уже делал, но ваша статья дала намного более качественное понимание.
ОтветитьУдалитьЁмаё. Если автор "криворукий говнокодер", в его проявлении самокритики, то я амеба.
ОтветитьУдалитьСпасибо за Ваш труд!
Пожалуйста! рад был помочь!
УдалитьАвтор молодца! Присоединяюсь!
УдалитьКстати, это отличная идея - писать заметки со сферическими примерами для себя же самого, чтобы потом не забыть. Память не резиновая, да и винты имеют свойство сыпаться, а на сервере оно как то надежнее:) Плюс и людям полезно!
Уважаемый Глеб, у меня такая проблема:
ОтветитьУдалитьС Вашей ссылкой - http://myhomepage.hol.es/login.php - всё работает,
но когда копирую Ваш PHP код на свой сервер - не работает.
В чём может быть проблема?
Спасибо.
Здравствуйте, возможно причина в том что телефон не видит сервера, вы уверены что его видно из интернета? У меня такая проблема была когда я пытался из локалки достать по причине того что роутер не хотел пропускать локалхост в инет. Скрипт я тот же что и на сервере выложил.
Удалитьpublic static void (String[] args){
ОтветитьУдалитьSystem.out.println("Need help!!!")
}
нужно сделать практически тоже ...софтина пишет лог в память.нужно состряпать отправку лога на сервер.(он уже есть) дабы потом смотреть эти файлы.
Помоги со скриптом который бы слушал запросы от приложения и сохранял эти файлы в свой же каталог.
Нужно сохранять на удаленном сервере лог или на телефоне?
Удалить"софтина пишет лог в память.нужно состряпать отправку лога на сервер"
Удалитьотправить на сервер..при чем не только отправить а синкать!
Поспрашивал у знакомых в общем есть такая библиотека которая обеспечивает такой функционал http://dajver.blogspot.com/2013/02/json.html, на сайте есть пример и руководство пользователя
Удалитьэмм простите на каком сайте?
УдалитьЭтот комментарий был удален автором.
ОтветитьУдалитьГлеб,статья очень понравилась, но хотелось бы поинтересоваться каким образом можно добавить сюда динамическое обновление данных(например если на сервере изменилась информация) и вывод русских букв в нормальном виде(а то при попытке клиентом получить данные в русской раскладке появляются одни знаки вопроса)
ОтветитьУдалитьЗаранее спасибо за ответ.
не подскажете, сложно ли в апк файле онлайн игры поменять, чтобы из евро версии она стала обращаться к русерверам ? Просто есть мод онлайн игры под евро сервера, а нужно чтобы работал на ру серверах.
ОтветитьУдалитьэто нужно декомпилировать апк и менять адрес в декомпилированом коде, а потом собрать обратно так что бы оно работало - это довольно сложно. Могу только сказать что капать нужно в сторону apk tool и как с ним работать.
Удалитьспасибо большое
Удалить