Розробка програми для операційної системи "Android"

 















Розробка програми для операційної системи «Android»



Вступ


У сучасному світі мобільні електронні пристрої поширюються дуже швидко. Потужності збільшуються в геометричній прогресії. Зявляються нові технології, які дозволяють розмістити ще більші потужності на меншій площі. Компанії зі сфери розробки програмного забезпечення пропонують безліч засобів для розвязання тих чи інших проблем. Проте часто виникає потреба розвязати нетривіальну задачу або просто створити новий продукт. У такому разі єдине, що залишається - це розробка унікального продукту. Для того, щоб він виявився успішним, він повинен відповідати найвищим стандартам своєї галузі. Тому кожний створений продукт повинен бути потрібний користувачам, добре продуманий, спроектований та реалізований. Якщо потрібно, щоб продукт став поширений серед користувачів, він повинен бути також професійно представлений.

Взагалі розробка будь-якого програмного продукту потребує великих затрат: як часу, так і ресурсів (людських та матеріальних). Тому під час розробки чогось нового, потрібно врахувати усі ризики.

Я вибрав тему «Розробка програми для операційної системи Android», так як зараз це найпоширеніша операційна система для мобільних пристроїв. Це відносно нова система, тому кількість якісних програм для неї досить не велика. Багато сайтів та компанії потребують реалізацію їх продуктів для платформи Android.

Метою даної роботи було створити програму для обміну даними з віддаденим сервером. У программі повинна бути реєстрація користувача та можливість доступу до інформації, яка завантажується з серверу.




1.Операційна система android


1.1 Загальні відомості


Android - операційна система від Google для мобільних пристроїв, таких як планшетні компютери, комунікатори, мобільні телефони, камери та багато інших. Вона створена на базі ядра Linux. Android використовує для роботи віртуальну машину Dalvik.

Dalvik - віртуальна машина Java, створена під час розробки Android для мінімального використання ресурсів. Вона, як і звичайна віртуальна машина Java (JVM), інтерпретує байт-код в машинний код. Проте Dalvik використовує свій байт-код, який відрізняється від звичайного байт-коду Java. Причиною цього є те, що в Android використовується своя реалізація Java, відмінна від Java SE чи Java ME. Вихідний код конвертується у байт-код (файли з розширенням.class, які можуть бути обєднані в архіви.jar - Java Archive). Після цього утиліта dx конвертує.class файли у файли з розширенням.dex, які використовує віртуальна машина на Android. При конвертації коду в байт-код всі ідентичні ресурси конвертуються тільки один раз для економії памяті. Так як саму віртуальну машину можна встановити майже на будь-якому пристрої, Android можна запускати навіть на електронних годинниках.


1.2Розробка програмного забезпечення для Android


Для розробки програмного забезпечення для Android використовується Android Software Development Kit (Android SDK). Код пишеться на Java. Для тестування програм можна використовувати як пристрій, підключений до компютера, так і емулятор Android, який іде у пакеті з Android SDK. Також можна використовувати Android Native Development Kit (Android NDK). NDK дозволяє писати програмне забезпечення для Android на C, C++ та інших поширених мовах програмування. Проте у цьому разі при розробці не буде доступне відлагодження. Програми для Android можна розповсюджувати через Android Market (Google Play).

ПЗ (програмне забезпечення) для Android зазвичай розробляється у програмі Eclipse. У пакеті Android SDK є версія даної програми зі всіма потрібними для розробки бібліотеками.

Щоб створити порожній проект, достатньо вибрати відповідний пункт меню. Після цього будуть створені базові папки та файли, необхідні для роботи з проектом. Створюються папки src, gen, assets, bin, libs, res. У папці src (source) знаходяться вихідні коди програми у файлах з розширенням.java. У папці gen (generated) знаходяться автоматично згенеровані файли. Вони присвоюють кожному логічному елементу програми унікальний ідентифікатор, зберігають дані про ресурси та інше. У папці asssets знаходяться додаткові ресурси, якщо вони потрібні. У папці bin розташовані файли компільованого проекту. Також там знаходиться.apk файл, який використовується для встановлення програми на пристрої з Android. У папці libs (libraries) розміщені додаткові бібліотеки, якщо такі використовуються. Щоб додати додаткову бібліотеку, достатньо її завантажити та додати, використовуючи відповідний пункт меню. У останній згенерованій папці res (resources) знаходяться ресурси, потрібні для роботи програми. У цій папці розташовані дочірні папки drawable, layout, menu, values та інші. У папці drawable розміщують графічні ресурси, у папці layout - файли-макети програми, у папці menu - макети меню, у папці values - ресурси, такі як стрічки (Strings), кольори (Colors), розміри (Dimens), стилі макетів (Styles) та інші. Якщо для різних розширень потрібно використати різні ресурси, їх розміщують у відповідних папках з суфіксами. У папках з суфіксом - hdpi - ресурси та макети для великих екранів, - ldpi - не великих екранів, - mdpi - середніх за щільністю екранів. Щільність екрана вимірюється у DPI (dots per inch) - крапках на дюйм. Відповідні розміри: ~120 dpi - невеликий екран (-ldpi), ~160 dpi - середній екран (-mdpi), ~240 dpi - великий екран (-hdpi). З появою екранів з великим розширенням (Retina) були введені ще два розміри екранів: ~260 dpi - дуже великий екран (-xhdpi) та >260 dpi - надвеликий екран (-xxhdpi). Також використовують суфікси, які залежать не від щільності, а від розміру екрану:

- small, - medium, - large, - xlarge.

Якщо програма використовує різні макети для різних положень екранів, файли відповідних макетів розміщують у різних папках. За вертикальне положення відповідає суфікс - port, за горизонтальне - - land. При повороті екрану програма буде використовувати ресурси з відповідних директорій. Для локалізації програми при розробці достатньо продублювати папку values з відповідними суфіксами. Суфікс папки values повинен відповідати міжнародному позначенню країни (ресурси для української версії розміщують у папці values-ua, англійської - values-en). Якщо для країни не вказана відповідна папка, програма буде використовувати ресурси з папки values (без суфікса).

Отже, структура програм для Android добре продумана. Можна легко додати локалізації чи адаптувати програму для різних розмірів екранів. Це надзвичайно важливо, так як існують сотні різних пристроїв на Android з різною конфігурацією та різними розмірами екранів.

операційний програма інтерфейс запит

1.3Створення інтерфейсу користувача


Інтерфейс користувача створюється за допомогою виглядів (View), груп виглядів (ViewGroup), та макетів (Layouts) (рисунок 1.1). Обєкти вигляду зазвичай є елементами інтерфейсу користувача, такими як кнопки, поля для введення інформації, текстові поля та інші. Групи виглядів - невидимі обєкти. Вони є контейнерами, які визначають вигляд дочірніх виглядів, наприклад, сіткою (grid) чи вертикальним списком (vertical list). Весь інтерфейс базується на ієрархії виглядів. Самі вигляди зберігаються у файлах формату.xml.

Рисунок 1.1 - Ієрархія виглядів деякого макету


Вигляди та макети можуть бути задані як у файлах з розширенням.xml, так і програмним шляхом. Але розробники Android пропонують визначати елементи інтерфейсу у файлах макетів, оскільки це забезпечує більш гнучке пристосування до різних екранів: достатньо створити альтернативний макет для іншого розширення та розмістити його у відповідній папці, після чого програму можна буде використовувати на іншому екрані. Визначення інтерфейсу програмним шляхом вимагає дублювання частини коду. Також у програмі Eclipse є візуальний редактор, який дозволяє візуально редагувати файли макетів. Якщо їх визначати програмним шляхом, візуальний редактор буде недоступний.


1.4Основні типи елементів інтерфейсу


Linear Layout - лінійне розташування. У ньому обєкти інтерфейсу розміщуються горизонтально або вертикально у тій послідовності, у якій вони задані. Розробник сам визначає, як відображати обєкти у блоці LinearLayout за допомогою атрибуту android:orientation, який може приймати усього два значення: horizontal(горизонтально) або vertical (вертикально).

При використанні LinearLayout доступний ще один важливий атрибут - android:layout_weight. Він дозволяє задати розміри дочірніх елементів пропорційно батьківському.


Рисунок 1.2 - приклад лінійного розташування


Relative Layout - відносне розташування. У ньому обєкти інтерфейсу розташовуються відносно один одного (справа, зліва, під та інші). Для визначення розміщення використовуються такі атрибути: android: layout_alignParentTop (приймає значення true або false, якщо true, то верхня межа елементу рівняється з верхньою межею батьківського елемента), android:layout_centerVertical (якщо true, то дочірній елемент розміщується вертикально по середині), android:layout_below (аргументом виступає ідентифікатор елементу, під яким буде розташований даний елемент) та багато інших. Всі атрибути такого типу приймають значення boolean (true або false) або ідентифікатор елементу, відносно якого вони мають розташовуватись.



Рисунок 1.3 - відносне розташування


ListView - список, група виглядів (View Group), у якій всі елементи розташовуються у списку з можливістю прокрутки по вертикалі. Для додання елементів у список використовується клас адаптерів (Adapter), який отримує інформацію з деякого джерела (масив, список і т. д.), та конвертує її у елементи списку, які додаються до елементу ListView.


Рисунок 1.4 - приклад списку елементів

Grid View - сітка, група виглядів, яка відображає елементи у вигляді двовимірної сітки, елементи якої можуть прокручуватися вертикально. Для додання елементів до елементу GridView також використовують клас адаптерів.


Рисунок 1.5 - приклад сітки


1.5 Використання адаптерів


Коли інформація для деякого елементу інтерфейсу динамічна, використовують спеціалізований шаблонний клас адаптерів Adapter, та його дочірні класи: Simple Adapter, SimpleCursorAdapter та ArrayAdapter<T>, де T - тип елементів, які будуть використовуватись у списку. Адаптер виступає у ролі буфера між списком та джерелом даних (рисунок 1.6).

adapter = new ArrayAdapter<String> (this, android.R.layout.simple_list_item_1, myStringArray);

Рисунок 1.6


Даний адаптер використовує елементи типу String. Макет для кожного елементу має ідентифікатор android.R.layout.simple_list_item_1. Даний макет стандартний та розташований у стандартній бібліотеці, на що вказує префікс android.R.layout.simple_list_item_1. Якщо потрібно використати власний макет, досить його створити та вказати у якості ідентифікатора R.layout.my_own_item_view. Файл R.java у директорії gen містить автоматично згенеровані ідентифікатори для усіх ресурсів та макетів проекту, тому досить звернутися до нього, щоб отримати адресу потрібного нам елемента. Першим аргументом конструктору є елемент типу Context (контекст активного вікна програми), останнім - масив елементів типу String. Також масив стрічок можна передати у адаптер використовуючи метод createFromResource(), у випадку, якщо він (масив) заданий у файлі ресурсів.

Розглянемо ще один варіант адаптеру - SimpleCursorAdapter. При використанні цього адаптеру, ми повинні вказати ідентифікатор для елемента нашого списку, який, на відміну від попереднього прикладу, може містити декілька елементів (минулий містив тільки один елемент, якому присвоювалося значення елементу String з масиву). Після того, як макет елементу створений, при зберіганні файлу йому автоматично буде наданий ідентифікатор, який, буде збережений у файлі R.java.

Припустимо, що у макеті є два текстових поля для імені та телефону абонентів зі списку контактів. Потрібно сформувати масив даних, та відповідний йому масив ідентифікаторів, куди будуть записані дані (рисунок 1.7).


String[] fromColumns = {ContactsContract. Data.DISPLAY_NAME,

ContactsContract. CommonDataKinds. Phone.NUMBER};

int[] toViews = {R.id.display_name, R.id.phone_number};

Рисунок 1.7



Щоб отримати контакти, потрібно використати обєкт Cursor, що поверне список пар імя - телефон, які будуть використані для запису до макету та формування списку. Далі потрібно створити сам адаптер, вибрати список, та передати йому обєкт адаптера (рисунок 1.7).


SimpleCursorAdapter adapter = new SimpleCursorAdapter (this,

R.layout.person_name_and_number, cursor, fromColumns, toViews, 0);

ListView listView = getListView();

listView.setAdapter(adapter);

Рисунок 1.7


Spinner - елемент інтерфейсу, який створює меню, що випадає. За замовчуванням обраний перший елемент. Для заповнення цього елементу також використовуються адаптери: ArrayAdapter, CursorAdapter та SpinnerAdapter.


1.6 Основні процеси програм для Android


Під час користування програмою, обєкти типу Activity («діяльність») змінюють свої стани, зупиняються, продовжуються та завершуються. Під час написання програми, можна вказати, як повинна поводитись діяльність впродовж своєї роботи. Наприклад, якщо ви створюєте онлайн відео програвач, можна переривати зєднання з Інтернетом та призупиняти мовлення коли користувач згортає програму та переключається на іншу. Це забезпечить економію інтернет-трафіку користувача. Коли користувач знову переключиться на вашу програму, діяльність може відновити підключення та продовжити відео-мовлення з моменту, на якому воно було зупинене. Принцип роботи Activity продемонстровано на рисунку 1.8



Рисунок 1.8


Кожна активність починається з методу void onCreate (Bundle instance). Для того, щоб створити свою активність, потрібно створити клас, який буде розширювати клас Activity, та перевизначити метод onCreate(). У ньому потрібно викликати батьківський конструктор, та передати йому обєкт типу Bundle, який буде передано в перевизначений метод onCreate() автоматично при запуску діяльності. Далі, якщо дана діяльність використовує макет, потрібно його вказати, передавши методу setContentView() ідентифікатор макету. Тільки після цього з ним можна буде працювати. Простий приклад діяльності показаний на рисунку 1.9.


public class Start extends Activity {

@Overridevoid onCreate (Bundle savedInstanceState) {.onCreate(savedInstanceState);(R.layout.activity_start);

}

}

Рисунок 1.9


Важливо, що діяльність перезапускається при повороті екрану. Тому якщо це може вплинути на коректну роботу програми, потрібно обробити такі ситуації. Якщо потрібно, можна заборонити перезапуск діяльності. Для цього досить вказати у файлі маніфесту атрибут для даної діяльності.

.7 ФАЙЛ МАНІФЕСТУ

Файл маніфесту (AndroidManifest.xml) обовязково повинен бути у кожній програмі. Він містить важливу інформацію для системи Android про програму, її вимоги, які діяльності вона включає, назву програми, які можливості пристрою вона буде використовувати, як вона буде взаємодіяти з іншими програмами, а також мінімальну та максимельну версію API, потрібну для коректної роботи системи.



2. Розробка програми


.1 Постановка завдання

операційний програма інтерфейс запит

Моїм завданням було розробити клієнт для роботи з сайтом tokmate.com. Мета цього сайту спростити спілкування між користувачами, що працюють у групах, та спростити їх доступ до спільних ресурсів, таких як спільна пошта. Програма взаємодіє не на пряму з сайтом, а з його базою даних. Сайт використовує базу даних mySql. При компіляції програми, створюється файл з розширенням.apk, який потім може бути відкритий за допомогою архіватору, після чого можна отримати доступ до ресурсів програми. Також можна декомпілювати і сам файл.dex, у якому знаходиться байт-код програми. Через це клієнт не повинен мати доступу до бази даних на пряму. Доступ реалізовано через POST-запити. Це забезпечує достатній рівень безпеки. Скрипти на сервері оброблюють всі запити та відповідно на них відповідають. Також сервер додатково обробляє та перевіряє всю інформацію, яка йому передається, для того, щоб уникнути sql-інєкцій (атак, спрямованих на отримання доступу до бази даних і до даних серверу). Обмін інформації відбувається у формати JSON (JavaScript Object Notation) - це текстовий обмін даними, який походить від JavaScript. Проте він використовується у багатьох мовах програмування через свою лаконічність, зручність та швидкість обробки.


2.2 Структура програми


Нижче приведений список файлів та папок з написаним кодом, створених для нього макетів та ресурсів.

Папка з кодом (src):

-Aboout.java

-Main.java

-MainListItem.java

-Register.java

-SimpleAlert.java

-SingleLetter.java

-SpinnerArrayAdapter.java

-SpinnterItem.java

-Start.java

-StaticFunctions.java

Папка з макетам (layout):

about.xml

-activity_start.xml

-custom_dialog.xml

-list_item.xml

-main.xml

-registration.xml

-single_letter.xml

-spin_row.xml

Папка ресурсів (values):

colors.xml

-dimens.xml

-strings.xml

-styles.xml


2.3 Файл «about.java»


Цей файл відповідає за діяльність «Про програму». Він лише виводить на екран макет, у якому вказана інформація про автора та програму. Відповідний макет (about.xml) задається, як показано на прикладі нижче (рисунок 2.1):


public class About extends Activity {


@Overridevoid onCreate (Bundle savedInstanceState) {.onCreate(savedInstanceState);(R.layout.about);

}

}

Рисунок 2.1


2.4 Файл «start.java»


У файлі Start.java знаходиться діяльність, яка запускається при відкритті програми. Для того, щоб діяльність запускалась першою, для неї потрібно вказати відповідний фільтр (intent-filter) у файлі маніфесту (Рисунок 2.2):


<activity:name= «com.tokmate. Start»:label= "@string/app_name» >

<intent-filter>

<action android:name= «android.intent.action.MAIN» />

<category android:name= «android.intent.category.LAUNCHER» />

</intent-filter>

</activity>

Рисунок 2.2


У файлі макету діяльності Start розташовані такі елементи: текстове поле, два поля для вводу даних (логіну та паролю), приховане текстове поле, у якому у разі потреби, зявляється попередження про відсутність доступу до мережі, та дві кнопки («Увійти» - у разі наявності аккаунта, «Створити» - у разі потреби створити новий аккаунт). Макет має відносне розташування (RelativeLayout). Розташування елементів задане у файлі стилів. Відповідні стилі підключені до кожного елементу макету.

Також даний файл містить меню. Меню працює за таким принципом: кожному елементу меню задаємо елемент Intent - обєкт операції, яку потрібно виконати, та перевизначаємо метод, який відповідає за вибір деякого пункту меню. Після вибору пункту потрібно дістати обєкт Intent з вибраного елементу, та почати нову діяльність, передавши методу запуску діяльності (void startActivity (Intent intent)) цей обєкт.

Щоб створити меню, потрібно перевизначити метод батьківського класу public boolean onCreateOptionsMenu (Menu menu) вказати макет меню, що знаходиться у папці menu, та присвоїти кожному елементу свою операцію (рисунок 2.3).


@Overrideboolean onCreateOptionsMenu (Menu menu) {().inflate (R.menu.start, menu);.findItem (R.id.action_about).setIntent (new Intent (this, About.class));

true;

}

Рисунок 2.3


Далі перевизначаємо метод, що відповідає за вибір окремого пункту меню. Йому передається елемент меню (обєкт MenuItem), який потрібно передати батьківському методу вибору елемента меню, а далі розпочати діяльність, використовуючи обєкт операції Intent, який знаходиться у цьому елементі меню (рисунок 2.4).


@Overrideboolean onOptionsItemSelected (MenuItem item) {.onOptionsItemSelected(item);(item.getIntent());

true;

}

Рисунок 2.4


Далі потрібно ініціалізувати кнопки. Під час натискання на кнопку, виникає подія OnClick. Для того, щоб її обробити, кожна кнопка повинна мати обєкт OnClickListener, метод якого (public void onClick (View v)) викликається у разі виникнення події OnClick. При викликанні цього методу, йому автоматично передається вигляд (View) елементу, на який натиснув користувач, після чого з цим виглядом можна виконати потрібні нам операції (наприклад отримати введений текст, вивести текст в текстове поле чи просто виконати потрібні нам дії) (рисунок 2.5).

. OnClickListener regOnClickListener = new View. OnClickListener() {

@Overridevoid onClick (View v) {regIntent = new Intent (v.getContext(),.class);(regIntent);

}

};

Рисунок 2.5


Для того, щоб оперувати текстовими полями, кнопками та подібними елементами, потрібно створити для них обєкти відповідних типів, та присвоїти їм потрібні вигляди, які можна отримати методом findViewById (int id). Цьому методу потрібно передати ідентифікатор елементу, після чого він поверне обєкт View, що відповідає цьому елементу. Для всіх типів елементів повертається однаковий обєкт View (обєкт їх батьківського класу). Тому перед присвоєнням, нам необхідно привести елемент до потрібного нам типу. Створення всіх елементів сторінки та присвоєння деяким елементам обєктів типу OnClickListener відбувається у методі private final void setViewsandButtons().

final void setViewsandButtons() {= (Button) findViewById (R.id.button_register);.setOnClickListener(regOnClickListener);= (Button) findViewById (R.id.button_login);.setOnClickListener(loginOnClickListener);

= (TextView) findViewById (R.id.login_alert_msg);

}

Рисунок 2.6 - вибір обєктів


Обєкт netAlert - текстове поле, у якому зявляється попередження, у разі виникнення проблем підключення до мережі. Для того, щоб перевірити стан підключення, потрібно отримати обєкт ConnectivityManager. Він відповідає за запити щодо стану мережі та інформує програму, коли стан мережі змінюється. У цього обєкту є метод, який в свою чергу повертає обєкт NetworkInfo, в якому знаходиться інформація про підключення до мережі. Щоб дізнатись, чи пристрій підключений до мережі, потрібно перевірити, чи обєкт не пустий, чи пристрій підключений до мережі та чи мережа доступна. За це відповідає метод private final boolean isOnline().

private final boolean isOnline() {cm =

(ConnectivityManager) getSystemService (Context.CONNECTIVITY_SERVICE);netInfo = cm.getActiveNetworkInfo();(netInfo!= null && netInfo.isConnectedOrConnecting()

&& netInfo.isAvailable()) {true;

}

false;

}

Рисунок 2.7 - реалізація методу isOnline()


Якщо мережа не доступна, потрібно проінформувати про це користувача. Для цього потрібно вставити повідомлення про помилку у текстове поле для попередження, та зробити його видимим. Щоб дістати повідомлення (чи будь-який інший ресурс), потрібно створити обєкт потрібного типу, та за допомогою методу getResources() вибрати за ідентифікатором ресурс. Метод private final void connectionCkeck() - метод, який відповідає за перевірку стану мережі та попередження користувача.

final void connectionCkeck() {= getResources().getString (R.string.no_connection);(! isOnline()) {.setText(alertMsg);.setVisibility (View.VISIBLE);

}

}

Рисунок 2.8 - метод перевірки зєднання

2.5 Файл «register.java»


Файл Register.java відповідає за реєстрацію нових користувачів. У макеті цієї діяльності є чотири поля для вводу інформації, два списки, що випадають, кнопка для продовження реєстрації та текстове поле з назвою сторінки. Користувачу потрібно ввести імя, прізвище, телефон та пароль. Зі списків, що випадають потрібно вибрати навчальний заклад та групу. Якщо користувачем заповнено не всі поля, програма не продовжить роботу та покаже попередження, що потрібно заповнити усі поля, за допомогою діалогу (AlertDialog). Якщо ж усі поля заповнені, данні з них будуть асинхронно (у паралельному потоці) відправлені на сервер на перевірку. Сервер отримує данні, перевіряє їх, після чого додає до бази даних. Якщо дані були занесені до бази успішно, користувачу, на вказаний при реєстрації номер телефону, буде відправлене текстове повідомлення з кодом підтвердження свого аккаунту. Підтвердження номеру телефону потрібно тому, що цей номер буде надалі використовуватися для входу в систему, для відновлення паролю та отримання різних оповіщень. Після того, як програма отримає відповідь від серверу про успішну реєстрацію, зявиться діалог, у якому користувачу потрібно буде ввести код, отриманий у текстовому повідомленні. Після натискання на кнопку підтвердження номеру, до серверу надсилається ще один асинхронний POST-запит, з кодом. Сервер перевіряє, чи співпадає код з кодом у базі даних. Якщо співпадає, то аккаунт користувача активується. Після активації аккаунту, користувач отримує доступ до головної діяльності (Main Activity).


2.6 Асинхронні запити


Усі http запити в програмах Android повинні відбуватись асинхронно (у окремому потоці, незалежно від основного потоку). Для таких запитів є клас AsyncTask<T, T, T>. Все, що відбувається асинхронно, повинно бути вказано у методі protected T doInBackground (T2… params) де Т2 - перший з трьох параметрів класу. Другий тип потрібний, якщо використовується діалог для відображення прогресу запиту. В даній програмі це не використовується, тому другий параметр буде параметр типу Void. Третій тип параметру повертає метод protected T doInBackground (T2… params), та приймає метод protected void onPostExecute (T result).


2.7 Діалоги


Класи діалогових вікон наслідують класи FragmentDialog. Обєкт FragmentDialog показує діалогове вікно поверх головного вікна діяльності. Для настроювання конкретного діалогу потрібно перевизначити метод public View onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState). Якщо потрібно використати свій макет для діалогу, його потрібно вказати у цьому методі. Також у ньому потрібно додати до потрібний елементів обєкти типу Listener.


@OverrideView onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {().setTitle (getArguments().getString («title»));

v = inflater.inflate (R.layout.custom_dialog, container, false);button = (Button) v.findViewById (R.id.dialog_but);EditText cod = (EditText) v.findViewById (R.id.dialog_text);

.setOnClickListener (new OnClickListener() {void onClick (View v) {(cod.getText().toString());task = new CheckTask();.execute(requeslUrl);

}

});

v;

}

Рисунок 2.9


2.8 Обробка відповіді серверу


Відповідь сервера приходить у формати JSON. Для подальшої роботи програми, потрібно обробити відповідь. Для цього потрібно дістати інформацію, яка міститься у масиві JSON. Для цього був написаний спеціальний клас, який отримує JSON масив та повертає обєкт ArrayList, з яким зручно працювати стандартними методами Java. Структура масиву JSON показана на рисунку 2.10.


Рисунок 2.10


Метод обробки такого масиву знаходиться у файлі StaticFunctions.java. Він зроблений статично, так як використовується часто. Створювати кожний раз не має необхідності та це вимагає надлишкових витрат памяті. Метод public static ArrayList<HashMap<String, String>> parse (String str, String jsonArrName, String[] fields). Він приймає три параметри. Перший параметр - сам масив у вигляді стрічки. Його повертає метод doInBackground() після успішного виконання запиту до сервера. Другий параметр - назва масиву. Це константне значення, як вказується у глобальній стрічковій змінній. Третій параметр - масив з назвами ключів, які потрібно дістати з масиву JSON. Метод повертає обєкт типу ArrayList, кожним елементом якого є обєкт типу HashMap<String, String> - структура пар ключ - значення, де ключами є елементи з масиву ключів, що були передані методу parse() останнім параметром, а значеннями - відповідні значення, взяті з масиву JSON. Для того, щоб отримати дані з масиву, створюється обєкт JSONObject, конструктору якому передаємо стрічку масиву. Далі створюється обєкт JSONArray. Йому присвоюється значення, яке повертає метод обєкту JSONObject - JSONArray getJSONArray (String jsonArrName), якому передаємо назву массиву, з якого потрібно дістати дані. Обєкт JSONArray - масив обєктів JSON, з яких за ключем можна отримати потрібні нам дані.


public static ArrayList<HashMap<String, String>> parse (String str, String jsonArrName, String[] fields)JSONException

{json = new JSONObject(str);jsonArr = json.getJSONArray(jsonArrName);<HashMap<String, String>> dataList = new ArrayList<HashMap<String, String>>();


(int i = 0; i < jsonArr.length(); i++) {row = jsonArr.getJSONObject(i);<String, String> map = new HashMap<String, String>();

(int j = 0; j < fields.length; j++) {.put (fields[j], row.getString (fields[j]));

}.add(map);

}dataList;

}

Рисунок 2.11 - метод обробки массиву JSON


Відповідь від сервера отримаємо у форматі InputStream. Для отримання стрічки, використовується статичний метод public static String isToString (InputStream is). Для спрощення коду методу можна було використати бібліотеку Apache, але метод був реалізований стандартними методами Java для зменшення розміру програми.

static String isToString (InputStream is) throws IOException {r = new BufferedReader (new InputStreamReader(is));total = new StringBuilder();line;((line = r.readLine())!= null) {.append(line);

}total.toString();

}

Рисунок 2.12 - метод повернення стрічки з потоку


2.9 Випадаючі списки


При запуску діяльності Register програма асинхронно отримує від серверу список навчальних закладів та їх ідентифікатори в базі даних. Через обєкти MainListItem які передаються адаптеру, значення назв та ідентифікаторів передаються відповідним текстовим полям.

class MainListItem {String name;String id;

(String name, String id) {.name = name;.id = id;

}

String getName() {this.name;

}

String getId() {this.id;

}

}

Рисунок 2.13 - приклад елементу адаптеру


Доки навчальний заклад не вибраний, список груп пустий. Це зроблено з метою економії мережного трафіку, так як кожний заклад може містити безліч груп. Тому тільки після вибору навчального закладу програма передає його ідентифікатор серверу та отримує у відповідь список груп. Після цього користувач має змогу вибрати потрібну групу та завершити реєстрацію. Програма передає серверу дані обєктом ArrayList<HashMap<String, String>> dataList, ключами виступають назви параметрів, які відомі серверу. Сервер, знаючи назви параметрів що передаються у POST-запиті, отримує потрібні йому значення, на основі яких формує відповідь.


@Overridevoid onItemSelected (AdapterView<?> parent, View view, int position, long id) {currId = (TextView) view.findViewById (R.id.spinner_row_id);= new HashMap<String, String>();.put («mode», «getGroup»);.put («institution», currId.getText().toString());task = new Retreiver();.execute («groups», requeslUrl);

}

Рисунок 2.14 - метод що викликається при виборі елменту зі списка


2.10 Файл «main.java»


Діяльність Main - це головна діяльність користувача. У ній користувач отримує доступ до потрібної йому інформації. При запуску діяльності, відсилається запит серверу, у відповідь отримуються останні дані з серверу та формується список елементів (ListView) з заголовків листів. У заголовку міститься ідентифікатор листа, його автор та тема. Сам лист не завантажується, так як завантаження кожного листа створить великі витрати трафіку (при завантаженні сотень листів, та розмірі одного близько 10 кб, загальний трафік буде дуже великий). Після вибору потрібного заголовку, метод, який спрацьовує при виникненні події OnClick отримує ідентифікатор вибраного листа, та передає його у діяльність, у якій запускаються окремі листи. Щоб передати дані діяльності, їх потрібно додати до обєкту операції (Intent), який передається діяльності. Це можна зробити за допомогою методу putExtra(). Даному методу потрібно передати назву елемента (ключ), та його значення. Знаючи ключ, значення можна буде отримати у новій діяльності. Нова діяльність отримує ідентифікатор листа, після чого завантажує його вміст з серверу. Після цього користувач має змогу отримати всю потрібну йому інформацію. Інші діяльності мають аналогічну чи простішу структуру та використовують розглянуті елементи та методи.



Висновок


В результаті роботи була створення програма для Android, яка взаємодіє з віддаленим сервером, та обмінюється з ним інформацією у POST-запитах. Всі запити відбуваються у паралельному потоці. У разі виникнення помилок програма повідомляє про це користувача за допомогою діалогових вікон. Програма протестована на планшетному компютері Ainol Novo 9 Spark (Android 4.3), смартфоні Sony Ericsson Xperia Arc (Android 2.3) та ще одному планшетному компютері Ainol Novo 7 (Android 4.0). На всіх пристроях програма коректно встановлювалась та працювала. За рахунок використаних алгоритмів збереження мережного трафіку, програма швидко отримувала потрібну інформацію від серверу навіть при повільній швидкості підключення.

У програмі може бути покращений інтерфейс користувача - можна додати більше функції у випадаюче меню. Також можна максимально ефективно використовувати екран якщо використовується пристій з великим екраном. Для цього потрібно додати декілька макетів та задати їм відповідну поведінку в залежності від розміру екрану. Також замість стандартних макетів можна використовувати фрагментацію інтерфейсу. Ця технологія дозволяє більш гнучко керувати розміщенням елементів на екрані користувача.

Для збільшення швидкості роботи у програму можна додати кешування заголовків листів, які програма отримує від серверу. Кешування у Android відбувається за допомогою запису потрібної інформації до бази даних SQLite. SQLite - база даних, яка для зберігання інформації використовує текстові файли. При запуску програмі потрібно буде лише зрівняти останній ідентифікатор листа з останнім ідентифікатором листа на сервері, та, якщо вони різні, підвантажити потрібні заголовки. При першому запуску програми будуть завантажені лише 30 останніх заголовків. Якщо користувачу потрібно отримати доступ до старіших листів, йому достатньо прокрутити блок заголовків униз. Під час прокрутки старіші заголовки будуть кешовані та надалі доступні користувачу без потреби взаємодії з мережею. Також можна додати кешування прочитаних листів. Кешування всіх листи може вимагати забагато памяті. Тому лише після того, як користувач відкриє окремий лист, програма його завантажить з серверу, збереже та покаже користувачу. Тому якщо у користувача виникне потреба переглянути уже прочитаний лист, це можна буде зробити без підключення до мережі.

У програму також можна додати коментарі до листів. Вони будуть кожний раз завантажуватися з серверу у JSON - масиві, після чого користувач зможе їх прочитати та додати свій. Це дасть змогу користувачам зручно коментувати листи, які їх зацікавили.



Список літератури


1. Брюс Еккель. Філосовія Java. «Питер» - 2006. - 648 с.

. Офіційна документація операційної системи Android [Електронний ресурс]. Режим доступу до ресурсу: #"justify">Додаток А


Вихідний код програми

«About.java»

package com.tokmate;

import android.app. Activity;

import android.os. Bundle;class About extends Activity {

@Overridevoid onCreate (Bundle savedInstanceState) {.onCreate(savedInstanceState);(R.layout.about);

}

}


«Main.java»

com.tokmate;java.io. InputStream;org.apache.http. HttpResponse;org.apache.http.client.methods. HttpPost;org.apache.http.impl.client. DefaultHttpClient;org.json.JSONException;android.app. Activity;android.content. Context;android.content. Intent;android.net. ConnectivityManager;android.net. NetworkInfo;android.os. AsyncTask;android.os. Bundle;android.view. View;android.widget. AdapterView;android.widget. ListAdapter;android.widget. ListView;android.widget. TextView;java.util. ArrayList;java.util. HashMap;java.util. Map;android.widget. SimpleAdapter;android.widget. AdapterView. OnItemClickListener;

class Main extends Activity {ListAdapter adapter = null;ListView list = null;final String lettersURL = «#"justify">jsonArrName = «mail_data»;<String, String> dataToSend= null;start = 0;<HashMap<String, String>> dataList = null;[] fields = {«subject», «from», «uid»};[] ids = {R.id.item_subj, R.id.item_from, R.id.item_id};

@Overridevoid onCreate (Bundle savedInstanceState) {.onCreate(savedInstanceState);(R.layout.main);= (ListView) findViewById (R.id.list_headers);.setOnItemClickListener (new OnItemClickListener() {

@Overridevoid onItemClick (AdapterView<?> parent, View view, int position, long id) {

sb = ((TextView) view.findViewById (R.id.item_subj)).getText().toString();fr = ((TextView) view.findViewById (R.id.item_from)).getText().toString();idL = ((TextView) view.findViewById (R.id.item_id)).getText().toString();in = new Intent (getApplicationContext(), SingleLetter.class);.putExtra («subj», sb);.putExtra («from», fr);.putExtra («id», idL);(in);

}

});(isOnline())();

}void loadLetters() {= new HashMap<String, String>();.put («start», start.toString());

task = new LetterRetreiver();.execute();

}

class LetterRetreiver extends AsyncTask<Void, Void, String> {

@OverrideString doInBackground (Void… params) {response = «»;client = new DefaultHttpClient();httpPost = new HttpPost(lettersURL);{.setEntity (StaticFunctions.setEntity(dataToSend));execute = client.execute(httpPost);content = execute.getEntity().getContent();= StaticFunctions.isToString(content);

} catch (Exception e) {.printStackTrace();

}response;

}

@Overridevoid onPostExecute (String result) {{= StaticFunctions.parse (result, jsonArrName, fields);

} catch (JSONException e) {.printStackTrace();

}();

}

}

void setData() {= new SimpleAdapter (this, dataList,.layout.list_item,, ids);.setAdapter(adapter);

}final boolean isOnline() {cm =

(ConnectivityManager) getSystemService (Context.CONNECTIVITY_SERVICE);netInfo = cm.getActiveNetworkInfo();(netInfo!= null && netInfo.isConnectedOrConnecting() && netInfo.isAvailable()) {true;

}false;

}

}


«MainListItem.java»

com.tokmate;class MainListItem {String name;String id;(String name, String id) {.name = name;.id = id;

}String getName() {this.name;

}String getId() {this.id;

}

}

«Register.java»com.tokmate;java.io. InputStream;java.io. UnsupportedEncodingException;java.math. BigInteger;java.net.URLEncoder;java.security. MessageDigest;java.security. NoSuchAlgorithmException;java.util. ArrayList;java.util. HashMap;java.util. List;java.util. Map;org.apache.http. HttpResponse;org.apache.http.client.methods. HttpPost;org.apache.http.impl.client. DefaultHttpClient;org.apache.http.params. BasicHttpParams;org.apache.http.params. HttpParams;org.apache.http.params. HttpProtocolParams;org.apache.http.protocol.HTTP;org.json.JSONException;android.app. Activity;android.app. DialogFragment;android.content. Context;android.content. Intent;android.net. ConnectivityManager;android.net. NetworkInfo;android.os. AsyncTask;android.os. Bundle;android.view. LayoutInflater;android.view. Menu;android.view. View;android.view. ViewGroup;android.view. View. OnClickListener;android.widget. AdapterView;android.widget. AdapterView. OnItemSelectedListener;android.widget. Button;android.widget. EditText;android.widget. Spinner;android.widget. TextView;

class Register extends Activity {List<SpinnerItem> instAdapter;List<SpinnerItem> groupAdapter;Button reg;Spinner spinInst;Spinner spinGroup;EditText firstName;EditText lastName;EditText phone;EditText pass;View. OnClickListener nextOnclickListener;String locale;static Map<String, String> dataToSend;final static String requeslUrl = «#"justify">@Overridevoid onCreate (Bundle savedInstanceState) {.onCreate(savedInstanceState);(R.layout.registration);();{();

} catch (JSONException e) {.printStackTrace();

}();

}

void formList (String[] names, String[] ids, int type) {(names.length == ids.length)(type) {1:= new ArrayList<SpinnerItem>();(int i = 0; i < names.length; i++) {.add (new SpinnerItem (names[i], ids[i]));

};


2:= new ArrayList<SpinnerItem>();(int i = 0; i < names.length; i++) {.add (new SpinnerItem (names[i], ids[i]));

};

}

}void init() {= (Spinner) findViewById (R.id.input_facility);= (Spinner) findViewById (R.id.input_group);= (EditText) findViewById (R.id.input_first_name);= (EditText) findViewById (R.id.input_last_name);= (EditText) findViewById (R.id.input_phone);= (EditText) findViewById (R.id.input_reg_pass);= (Button) findViewById (R.id.button_register_action);= this.getResources().getConfiguration().locale.getCountry();= null;= getResources().getString (R.string.hint_facility);= getResources().getString (R.string.hint_group);= getResources().getString (R.string.no_connection);= getResources().getString (R.string.fill_all);_info = getResources().getString (R.string.code_info);= getResources().getString (R.string.exists);= getResources().getString (R.string.okAct);= getResources().getString (R.string.errAct);(new String[] {defInstVal}, new String[] {«0»});(new String[] {defGroupVal}, new String[] {«0»});


}

@Overrideboolean onCreateOptionsMenu (Menu menu) {().inflate (R.menu.start, menu);.findItem (R.id.action_about).setIntent (new Intent (this, About.class));true;

}void setListeners() {= new View. OnClickListener() {

@Overridevoid onClick (View v) {name = null;{= URLEncoder.encode (firstName.getText().toString(), «UTF-8»);

} catch (UnsupportedEncodingException e) {

// TODO Auto-generated catch block.printStackTrace();

}nameL = null;{= URLEncoder.encode (lastName.getText().toString(), «UTF-8»);

} catch (UnsupportedEncodingException e1) {

// TODO Auto-generated catch block.printStackTrace();

}password = pass.getText().toString();telephone = phone.getText().toString();instId = ((TextView) spinInst.findViewById (R.id.spinner_row_id)).getText().toString();groupId = ((TextView) spinGroup.findViewById (R.id.spinner_row_id)).getText().toString();

(name.matches(«») || nameL.matches(«») || password.matches(«») || telephone.matches(«»)

|| instId.equals («0») || groupId.equals («0»))(fillAll);(isOnline()) {m = null;{= MessageDigest.getInstance («MD5»);

} catch (NoSuchAlgorithmException e) {.printStackTrace();

}.update (password.getBytes(), 0, password.length());= new BigInteger (1, m.digest()).toString(16);= new HashMap<String, String>();.put («mode», «register»);.put («firstName», name);.put («lastName», nameL);.put («pass», password);.put («phone», telephone);.put («institution», instId);.put («group», groupId);task = new Retreiver();.execute («register», successUrl);

} else {(conError);

}


}

};

.setOnClickListener(nextOnclickListener);.setOnItemSelectedListener (new OnItemSelectedListener() {

@Overridevoid onItemSelected (AdapterView<?> parent, View view, int position, long id) {currId = (TextView) view.findViewById (R.id.spinner_row_id);= new HashMap<String, String>();.put («mode», «getGroup»);.put («institution», currId.getText().toString());task = new Retreiver();.execute («groups», requeslUrl);

}

@Overridevoid onNothingSelected (AdapterView<?> arg0) {

}

});

}

final boolean isOnline() {cm =

(ConnectivityManager) getSystemService (Context.CONNECTIVITY_SERVICE);netInfo = cm.getActiveNetworkInfo();(netInfo!= null && netInfo.isConnectedOrConnecting() && netInfo.isAvailable()) {true;

}false;

}

void getInts() throws JSONException {= new HashMap<String, String>();.put («mode», «getInst»);task = new Retreiver();.execute («ints», requeslUrl);

}void setInstAdapter (String[] names, String[] ids) {(names, ids, 1);.setAdapter (new SpinnerArrayAdapter (this, instAdapter));

}void setGroupAdapter (String[] names, String[] ids) {(names, ids, 2);.setAdapter (new SpinnerArrayAdapter (this, groupAdapter));

}class Retreiver extends AsyncTask<String, Void, String> {String mode;String url;


@OverrideString doInBackground (String… params) {response = «»;= params[0];= params[1];httpParameters = new BasicHttpParams();.setContentCharset (httpParameters, HTTP.UTF_8);.setHttpElementCharset (httpParameters, HTTP.UTF_8);client = new DefaultHttpClient(httpParameters);.getParams().setParameter («http.protocol.content-charset», HTTP.UTF_8);httpPost = new HttpPost(url);{.setEntity (StaticFunctions.setEntity(dataToSend));execute = client.execute(httpPost);content = execute.getEntity().getContent();= StaticFunctions.isToString(content);

} catch (Exception e) {.printStackTrace();

response;

}


@Overridevoid onPostExecute (String result) {{(mode.equals («ints»)) {= StaticFunctions.parse (result, instArrName, instFields);[] institutions = new String [dataList.size() + 1];[] instIds = new String [dataList.size() + 1];

[0] = defInstVal;[0]= «0»;

nameField = «name»;(locale.equalsIgnoreCase («ru»)) {+= «_ru»;

}(int i = 0; i < dataList.size(); i++) {[i+1] = dataList.get(i).get(nameField);[i+1] = dataList.get(i).get(idField);

}(institutions, instIds);

}(mode.equals («groups»)) {

= StaticFunctions.parse (result, groupArrName, groupFields);

[] groups = new String [dataList.size() + 1];[] groupIds = new String [dataList.size() + 1];[0] = defGroupVal;[0] = «0»;nameField = «name»;(locale.equalsIgnoreCase («ru»)) {+= «_ru»;

}(int i = 0; i < dataList.size(); i++) {[i+1] = dataList.get(i).get(nameField);[i+1] = dataList.get(i).get(idField);

}(groups, groupIds);

}

(mode.equals («register»)) {(result.equals («success»)) {();

}(result.equals («exists»)) {(userExists);

}

}



} catch (JSONException e) {.printStackTrace();

}

}

}

void showDialog (String error) {newFragment = SimpleAlert.newInstance(error);.show (getFragmentManager(), «dialog»);

}void regDialog() {newFragment = RegDialog.newInstance (code_info);.show (getFragmentManager(), «dialog»);

}static void ckeckCode (String code) {= new HashMap<String, String>();.put («mode», «check»);.put («code», code);

}static class RegDialog extends DialogFragment {static RegDialog newInstance (String title) {frag = new RegDialog();args = new Bundle();.putString («title», title);.setArguments(args);frag;

}


@Overridevoid onCreate (Bundle savedInstanceState) {.onCreate(savedInstanceState);


}


@OverrideView onCreateView (LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {().setTitle (getArguments().getString («title»));

v = inflater.inflate (R.layout.custom_dialog, container, false);button = (Button) v.findViewById (R.id.dialog_but);EditText cod = (EditText) v.findViewById (R.id.dialog_text);.setOnClickListener (new OnClickListener() {void onClick (View v) {(cod.getText().toString());task = new CheckTask();.execute(requeslUrl);

}

});v;

}class CheckTask extends AsyncTask<String, Void, String> {String url;

@OverrideString doInBackground (String… params) {response = «»;= params[0];httpParameters = new BasicHttpParams();.setContentCharset (httpParameters, HTTP.UTF_8);.setHttpElementCharset (httpParameters, HTTP.UTF_8);

client = new DefaultHttpClient(httpParameters);.getParams().setParameter («http.protocol.content-charset», HTTP.UTF_8);httpPost = new HttpPost(url);{.setEntity (StaticFunctions.setEntity(dataToSend));execute = client.execute(httpPost);content = execute.getEntity().getContent();= StaticFunctions.isToString(content);

} catch (Exception e) {.printStackTrace();

}

response;

}

@Overridevoid onPostExecute (String result) {(result.equals («success»)) {newFragment = SimpleAlert.newInstance(okAct);.show (getFragmentManager(), «dialog»);

} else {newFragment = SimpleAlert.newInstance(errAct);.show (getFragmentManager(), «dialog»);

}

}

}

}

}


«SimpleAlert.java»com.tokmate;android.app. AlertDialog;android.app. Dialog;android.app. DialogFragment;android.content. DialogInterface;android.os. Bundle;class SimpleAlert extends DialogFragment {static SimpleAlert newInstance (String title) {frag = new SimpleAlert();args = new Bundle();.putString («title», title);.setArguments(args);frag;

}


@Overridevoid onCreate (Bundle savedInstanceState) {.onCreate(savedInstanceState);

}


@OverrideDialog onCreateDialog (Bundle savedInstanceState) {title = getArguments().getString («title»);

new AlertDialog. Builder (getActivity())(title)(«OK»,DialogInterface. OnClickListener() {void onClick (DialogInterface dialog, int whichButton) {

}

}

).create();

}

}


«SingleLetter.java»com.tokmate;java.io. InputStream;java.util. HashMap;java.util. Map;org.apache.http. HttpResponse;org.apache.http.client.methods. HttpPost;org.apache.http.impl.client. DefaultHttpClient;android.app. Activity;android.content. Context;android.content. Intent;android.net. ConnectivityManager;android.net. NetworkInfo;android.os. AsyncTask;android.os. Bundle;android.text. Html;android.widget. TextView;class SingleLetter extends Activity {String requeslUrl = «#"justify">@Overridevoid onCreate (Bundle savedInstanceState) {.onCreate(savedInstanceState);(R.layout.single_letter);= (TextView) findViewById (R.id.single_letter_header);= (TextView) findViewById (R.id.single_letter_from);= (TextView) findViewById (R.id.single_letter_body);in = getIntent();sb = in.getStringExtra («subj»);fr = in.getStringExtra («from»);= in.getStringExtra («id»);

.setText(sb);.setText(fr);(isOnline()) {();

}

}void setResponse (String str) {.setText (Html.fromHtml(str));

}void postData() {= new HashMap<String, String>();.put («mode», «getLetterById»);.put («letterId», idL);task = new SingleLetterRetreiver();.execute();

}class SingleLetterRetreiver extends AsyncTask<Void, Void, String> {

@OverrideString doInBackground (Void… params) {client = new DefaultHttpClient();httpPost = new HttpPost(requeslUrl);result = null;{.setEntity (StaticFunctions.setEntity(dataToSend));execute = client.execute(httpPost);content = execute.getEntity().getContent();= StaticFunctions.isToString(content);

} catch (Exception e) {.printStackTrace();

}result;

}


@Overridevoid onPostExecute (String result) {(result);

}

}final boolean isOnline() {cm =

(ConnectivityManager) getSystemService (Context.CONNECTIVITY_SERVICE);netInfo = cm.getActiveNetworkInfo();(netInfo!= null && netInfo.isConnectedOrConnecting() && netInfo.isAvailable()) {true;

}false;

}


}


«SpinnerArrayAdapter.java»com.tokmate;java.util. List;android.app. Activity;android.view. View;android.view. ViewGroup;android.widget. ArrayAdapter;android.widget. TextView;android.view. LayoutInflater;class SpinnerArrayAdapter extends ArrayAdapter<SpinnerItem> {final List<SpinnerItem> list;final Activity context;SpinnerArrayAdapter (Activity context, List<SpinnerItem> list) {(context, R.layout.spin_row, list);.context = context;.list = list;

}class ViewHolder {TextView idView;TextView nameView;

}

@OverrideView getDropDownView (int position, View convertView, ViewGroup parent) {

// TODO Auto-generated method stubgetView (position, convertView, parent);

}

@OverrideView getView (int position, View convertView, ViewGroup parent) {holder;rowView = convertView;(rowView == null) {inflater = context.getLayoutInflater();= inflater.inflate (R.layout.spin_row, null, true);= new ViewHolder();.idView = (TextView) rowView.findViewById (R.id.spinner_row_id);.nameView = (TextView) rowView.findViewById (R.id.spinner_row_name);.setTag(holder);

} else {= (ViewHolder) rowView.getTag();

}.idView.setText (this.list.get(position).getId());.nameView.setText (this.list.get(position).getName());rowView;

}

}


«Start.java»com.tokmate;android.net. ConnectivityManager;android.net. NetworkInfo;android.os. Bundle;android.app. Activity;android.content. Context;android.content. Intent;android.view. Menu;android.view. MenuItem;android.view. View;android.widget. Button;android.widget. TextView;class Start extends Activity {reg;login;netAlert;alertMsg;. OnClickListener regOnClickListener = new View. OnClickListener() {

@Overridevoid onClick (View v) {regIntent = new Intent (v.getContext(), Register.class);(regIntent);

}

};

. OnClickListener loginOnClickListener = new View. OnClickListener() {

@Overridevoid onClick (View v) {regIntent = new Intent (v.getContext(), Main.class);(regIntent);

}

};

@Overridevoid onCreate (Bundle savedInstanceState) {.onCreate(savedInstanceState);(R.layout.activity_start);();();

}

@Overrideboolean onCreateOptionsMenu (Menu menu) {().inflate (R.menu.start, menu);.findItem (R.id.action_about).setIntent (new Intent (this, About.class));true;

}


@Overrideboolean onOptionsItemSelected (MenuItem item) {.onOptionsItemSelected(item);(item.getIntent());true;

}final void connectionCkeck() {= getResources().getString (R.string.no_connection);(! isOnline()) {.setText(alertMsg);.setVisibility (View.VISIBLE);

}

}

final void setViewsandButtons() {= (Button) findViewById (R.id.button_register);.setOnClickListener(regOnClickListener);= (Button) findViewById (R.id.button_login);.setOnClickListener(loginOnClickListener);= (TextView) findViewById (R.id.login_alert_msg);

}final boolean isOnline() {cm =

(ConnectivityManager) getSystemService (Context.CONNECTIVITY_SERVICE);netInfo = cm.getActiveNetworkInfo();(netInfo!= null && netInfo.isConnectedOrConnecting()

&& netInfo.isAvailable()) {true;

}false;

}


}


«Staticfunctions.java»com.tokmate;java.io. BufferedReader;java.io.IOException;java.io. InputStream;java.io. InputStreamReader;java.io. UnsupportedEncodingException;java.util. ArrayList;java.util. HashMap;java.util. Map;org.apache.http. NameValuePair;org.apache.http.client.entity. UrlEncodedFormEntity;org.apache.http.message. BasicNameValuePair;org.json.JSONArray;org.json.JSONException;org.json.JSONObject;class StaticFunctions {static ArrayList<HashMap<String, String>> parse (String str, String jsonArrName, String[] fields)JSONException

{json = new JSONObject(str);jsonArr = json.getJSONArray(jsonArrName);<HashMap<String, String>> dataList = new ArrayList<HashMap<String, String>>();(int i = 0; i < jsonArr.length(); i++) {row = jsonArr.getJSONObject(i);<String, String> map = new HashMap<String, String>();(int j = 0; j < fields.length; j++) {.put (fields[j], row.getString (fields[j]));

}.add(map);

}dataList;

}static UrlEncodedFormEntity setEntity (Map<String, String> dataToSend)UnsupportedEncodingException

{entity = null;<NameValuePair> parameters = new ArrayList<NameValuePair>();(Map. Entry<String, String> entry: dataToSend.entrySet()) {.add (new BasicNameValuePair (entry.getKey(), entry.getValue()));

}= new UrlEncodedFormEntity(parameters);entity;

}

static String isToString (InputStream is) throws IOException {r = new BufferedReader (new InputStreamReader(is));total = new StringBuilder();line;((line = r.readLine())!= null) {.append(line);

}total.toString();

}

}


Розробка програми для операційної системи «Android» Вступ У сучасному світі

Больше работ по теме:

КОНТАКТНЫЙ EMAIL: [email protected]

Скачать реферат © 2017 | Пользовательское соглашение

Скачать      Реферат

ПРОФЕССИОНАЛЬНАЯ ПОМОЩЬ СТУДЕНТАМ