суббота, 18 мая 2013 г.

Android Studio установка

На днях прошла конференция Google I/O 2013 на которой было много всяких вкусностей . Но меня привлекла новая среда разработки Android Studio на основе Intellij Idea. Я не долго думая скачал ее и начал устанавливать . И тут начались проблемы , на мою Windows 7 x64 она не захотела ставиться. Ей не хватало JDK. Я решил данную траблу так :
1) Качнул и поставил JDK http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html
2) Прописал переменные среды (Свойства компьютера - Дополнительные параметры системы - Переменные среды )
3) И вуаля , студия работает :)

среда, 8 мая 2013 г.

Lifecycle Activity

Привет, сегодня хочу рассказать про Lifecycle Activity. Одна из фундаментальных вещей при разработке Android приложений. Activity может быть в трех состояниях в приложении.

  1. Running (Resumed) - когда Activity видно на экране , пользователь может с ним взаимодействовать.
  2. Paused - Activity не в фокусе , его видно , но пользователь не может с ним взаимодействовать(перекрыто другим Activty или полупрозрачно). 
  3. Stopped - Activity не видно , пользователь не может с ним взаимодействовать. 




Всего есть 7 методов у Activity : onCreate, onStart, on Resume, onPause, onStop , onDestroy, onRestart

  • onCreate() - вызывается при первом создании Activity 
  • onStart() - вызывается перед тем как Activity видно пользователю 
  • onResume() - вызывается перед тем как Activity уже видно пользователю 
  • onPause() - вызывается перед тем как будет показано другое Activity 
  • onStop() - вызывается когда Activity будет не видно пользователю.
  • onDestroy() - вызывается перед тем как уничтожить Activity из стека. 
  • onRestart() - вызывается при возвращение Activity из остановленного состояния . Обязательно после вызова onStop.

вторник, 7 мая 2013 г.

BroadcastReceiver в Android

Продолжаем разбирать полезные вещи в Android и сегодняшний урок я хотел бы посвятить такой вещи как BroadcastReceiver.
BroadcatReceiver(приемник широковещательных сообщений) - это компонент для получения внешних событий и реакции на них. BroadcastReceiver это объект, который начинает выполнять действия, по получению какого нибудь сигнала (Intent). Сервис в отличии от BroadcastReceiver работает сразу после того как его запустили. У данного класса только один метод onReceive.

 void onReceive(Context curContext, Intent broadcastMsg)   

Когда широковещательное сообщение прибывает для получателя сообщения, Android вызывает его методом onReceive() и передает в него объект Intent, содержащий сообщение. Приемник широковещательных сообщений является активным только во время выполнения этого метода.

Android использует широковещательные сообщения для системных событий, таких как уровень зарядки батареи, сетевые подключения, входящие звонки, изменения часового пояса, состояние подключения данных, входящие сообщения SMS или обращения по телефону.

Рассмотрим такой пример : 
 import android.os.Bundle;  
 import android.app.Activity;  
 import android.content.BroadcastReceiver;  
 import android.content.Context;  
 import android.content.Intent;  
 import android.content.IntentFilter;  
 import android.widget.ProgressBar;  
 import android.widget.TextView;  
 public class BatteryIndicatorActivity extends Activity {  
   private BroadcastReceiver mBatInfoReceiver = new BroadcastReceiver() {  
     @Override      
     public void onReceive(Context c, Intent i) {  
       int level = i.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);  
       ProgressBar pb = (ProgressBar) findViewById(R.id.progressbar);  
       pb.setProgress(level);  
       TextView tv = (TextView) findViewById(R.id.textfield);  
       tv.setText("Battery Level: " + Integer.toString(level) + "%");  
     }  
   };  
   @Override  
   public void onCreate(Bundle savedInstanceState) {  
     super.onCreate(savedInstanceState);  
     setContentView(R.layout.main);  
     registerReceiver(mBatInfoReceiver, new IntentFilter(  
         Intent.ACTION_BATTERY_CHANGED));  
   }  
 }  

Так а теперь разберемся что я здесь "накалякал". Создаем обьект mBatInfoReceiver , в onReceive получаем уровень батареи через системный Intent  BatteryManager.EXTRA_LEVEL и после этого отображаем информацию в ProgressBar и TextView .  Для того чтобы данный "ресивер" заработал его нужно зарегить. Делается это двумя способами или в onCreate (как сделано у меня выше) или в AndroidManifest.

 <receiver android:name=".SimpleBroadcater" android:label="Simple">  
    <intent-filter>  
     <action android:name="android.intent.action.BATTERY_CHANGED"/>  
    </intent-filter>  
   </receiver>  

Вроде все что хотел в данном уроке описал . Если будут вопросы пишите в комментариях , с удовольствием отвечу.

воскресенье, 5 мая 2013 г.

Подгрузка категорий через AsyncTask

Сегодня как и обещал хотел посвятить статью работой с AsyncTask. AsyncTask - это класс который предназначен для выполнения операций отдельно от UI потока и передача результатов выполнения в основной поток.
Продолжим реализацию CategoryActivity , мы хотим подгрузить категории и отобразить их в ListView.


 private class AsyncCaller extends AsyncTask<Void, Void, Void> {  
           ProgressDialog pdLoading = new ProgressDialog(CategoryActivity.this);  
           @Override  
           protected void onPreExecute() {  
                super.onPreExecute();  
                pdLoading.setMessage("\tЗагрузка...");  
                pdLoading.show();  
           }  
           @Override  
           protected Void doInBackground(Void... params) {  
                api = new API();  
                categoriesArr = api.getCategoryQuiz();  
                Log.d("size", categoriesArr.size() + "");  
                for (int i = 0; i < categoriesArr.size(); i++) {  
                     Map<String, String> category = new HashMap<String, String>();  
                     category.put("category_id",  
                               String.valueOf(categoriesArr.get(i).getCategoryId()));  
                     category.put("category_name", categoriesArr.get(i)  
                               .getCategoryName());  
                     categoryList.add(category);  
                }  
                return null;  
           }  
           @Override  
           protected void onPostExecute(Void v) {  
                pdLoading.dismiss();  
                SimpleAdapter sAdapter = new SimpleAdapter(CategoryActivity.this,  
                          categoryList, android.R.layout.simple_list_item_1,  
                          new String[] { "category_name" },  
                          new int[] { android.R.id.text1 });  
                lvCategory.setAdapter(sAdapter);  
           }  
      }  

Как видим данный класс имеет три основных метода onPreExecute(выполняется перед doInBackground, имеет доступ к UI), doInBackground(выполняется в новом потоке, здесь мы и выполняем основную работу), onPostExecute(после выполнения doInBackground,не выполняется если AsyncTask отменен).
В нашем примере мы получаем данные в doInBackground и onPostExecute создаем SimpleAdapter для ListView. Затем в onCreate запускаем наш AsyncTask и делаем обработчик для ListView :


 @Override  
      protected void onCreate(Bundle savedInstanceState) {  
           super.onCreate(savedInstanceState);  
           setContentView(R.layout.category);  
           lvCategory = (ListView) findViewById(R.id.lvCategories);  
           lvCategory.setOnItemClickListener(new OnItemClickListener() {  
                @Override  
                public void onItemClick(AdapterView<?> parent, View view,  
                          int position, long id) {  
                     Toast.makeText(getApplicationContext(),  
                               categoryList.get(position).get("category_id"),  
                               Toast.LENGTH_SHORT).show();  
              }  
           });  
           new AsyncCaller().execute();  
      }  

В общем как-то так . Это лишь небольшая часть информации которая посвящена работе с AsyncTask , но и ее будет достаточно для выполнения большинства тривиальных задач. 

суббота, 4 мая 2013 г.

Взаимодействие с API и как правильно разбирать JSON в Android

Вообще этот проект я делал для диплома , который еще кстати не защитил :) Так для начала опишу серверную часть .
Имеем БД MySQL с таблицей categories внутри , чтобы получить содержимое таблицы и закодировать в JSON выполним следующее

function getCategories(){
  if(isset($_GET['format']) && intval($_GET['num'])) { 
          $format = strtolower($_GET['format']); 
          $num = intval($_GET['num']); 
  mysql_query('SET NAMES \'UTF8\''); 
  $result = mysql_query('SELECT * FROM categories ORDER BY `category_id` DESC      LIMIT ' . $num) or die('MySQL Error.'); 
  if($format == 'json') { 
      $сategories = array(); 
  while($category = mysql_fetch_array($result, MYSQL_ASSOC)) { 
       $categories[] = array('category'=>$category); } 
       $output = json_encode($categories); echo $output; 
  }
 } 
}

if($_REQUEST['function']=='getCategories') 
   getCategories();



То есть чтобы сделать запрос и получить ответ в JSON в браузере делаем следующее :
http://superquiz.zz.mu/api.php?format=json&num=10&function=getCategories

Так теперь перейдем к клиентской части. Я делал общий класс API у которого будут методы для получения категорий , списка тестов , статистики и т.д . Опишу метод получения категорий.


public class API {    
     private HttpClient client; 
     private HttpGet httpGet; 
     private BufferedReader in; 
     private JSONObject mainJsonObject, innerJsonObject; 
     private ArrayList<Categories> categoriesArr = new ArrayList<Categories>(); 
     private static final String TAG_CATEGORY = "category"; 
     private static final String TAG_CATEGORY_ID = "category_id"; 
     private static final String TAG_CATEGORY_NAME = "category_name"; 
    
     public API() { 
        client = new DefaultHttpClient(); 
     } 
    
     public ArrayList getCategoryQuiz() { 
          httpGet = new HttpGet( "http://superquiz.zz.mu/api.php?  format=json&num=10&function=getCategories"); 
    
     try { 
           HttpResponse response = client.execute(httpGet); 
           in = new BufferedReader(new InputStreamReader(response.getEntity() .getContent())); 
           StringBuffer sb = new StringBuffer(""); 
           String line = ""; 
           while ((line = in.readLine()) != null) { 
                 sb.append(line + "\n"); 
           } 
           in.close(); 
           String result = sb.toString(); 
          
           JSONArray jsonMainArr = new JSONArray(result); 
           for (int i = 0; i < jsonMainArr.length(); i++) { 
           mainJsonObject = jsonMainArr.getJSONObject(i); 
           innerJsonObject = mainJsonObject.getJSONObject(TAG_CATEGORY); 
           int id = Integer.parseInt(innerJsonObject.getString(TAG_CATEGORY_ID));                             String name =  innerJsonObject.getString(TAG_CATEGORY_NAME); 
           categoriesArr.add(new Categories(id, name)); } 
     } catch (Exception e) { 
          e.printStackTrace(); 
     } return categoriesArr; 
 }

Теперь разберем что мы здесь наделали. Делаем GET запрос и получаем JSON ответ записывая его в StringBuilder. Затем формируем JSONArray из нашего ответа. После этого "растаскиваем" наш JSONArray на объекты и добавляем его в ArrayList из категорий. Кому не понятно как создать класс категорий выкладываю. 


public class Categories { 
   private int categoryId; 
   private String categoryName; 
  
   public Categories(int categoryId, String categoryName) { 
       this.categoryId = categoryId; 
       this.categoryName = categoryName; 
   } 

   public int getCategoryId() { 
       return categoryId; 
   } 
  
   public void setCategoryId(int categoryId) { 
       this.categoryId = categoryId; 
   } 
  
   public String getCategoryName() { 
      return categoryName; 
   } 
  
   public void setCategoryName(String categoryName) { 
      this.categoryName = categoryName; 
   } 
 }

Чтобы потом воспользоваться данным методом который мы написали делаем следующее.  API api = new API(); categoriesArr = api.getCateroiesQuiz();
Вроде все что хотел написал , за серверную часть не пинать :) В PHP особо никогда не углублялся , поэтому написал просто , без аутентификаций и т.д. В следующем уроке планирую разобрать AsyncTask и как отобразить полученные данные в ListView.

I`ll be back :)

Уже почти год ничего сюда не писал . За этот год скилл повысился , однако я так и не работал в офисе . Работал на удаленке. У данной работы есть много плюсов , кроме одного . Когда ты один разработчик под данную платформу , то часто бывает что не с кем посоветоваться как реализовать ту или иную фичу . Смотрел свои предыдущие посты в блоге , и писал что буду брать Galaxy S3 , но в итоге взял HTC One X . Еще ни разу не пожалел. Сейчас хочу написать урок по взаимодействию с простейшим самописным API на PHP с помощью Android.

вторник, 19 июня 2012 г.

Батл Samsung Galaxy S3 vs HTC One X

Хочу к концу лета взять себе новый телефон вот думаю между Samsung Galaxy S3 или HTC One X. Оба аппарата довольно интересные , но безусловно у каждого есть свои плюсы и минусы
Далее хочу представить обзор в котором сравниваются данные аппараты.



P.S Лично я наверно склонюсь все таки к Samsung Galaxy S3 , так как у него более емкая батарея , что для меня немаловажно , а у HTC как обычно больное место батарея :( . Хотя может к концу лета выйдет более интересный вариант и буду уже рассматривать его.