Поиск по этому блогу

воскресенье, 2 февраля 2014 г.

Android. Добавляем splash-screen к нашему приложению

Создание экрана загрузки (Splash Screen) для Android-приложения при помощи таймера. 


1. Для создания экрана загрузки (Splash Screen Activity) создадим класс SplashScreenActivity.java

2. Откроем наш AndroidManifest.xml файл и убедимся, что splash screen activity является стартовой активити проекта.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="pro.newapp.MarkXWallpapers"
          android:versionCode="1"
          android:versionName="1.0">
    <uses-sdk android:minSdkVersion="8"/>
    <application android:label="@string/app_name" 
        android:icon="@drawable/icon_markx">
        <activity android:name="MainActivity"
                  android:label="@string/app_name"
                  android:configChanges="orientation"
                  android:screenOrientation="portrait">
        </activity>
        <activity android:name=".SplashScreenActivity"
                  android:configChanges="orientation"
                  android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
        </activity>
    </application>
</manifest>

3. Создадим layout-файл для заставки (для splash screen) в папке res/layout. Я назвал этот файл splash_screen.xml. В мое заставке содержится изображение из приложения и логотип нашей компании, а также адрес сайта.

<?xml version="1.0" encoding="utf-8"?>
 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="match_parent"
              android:layout_height="match_parent">
 
    <ImageView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:src="@drawable/new_app_logo"
            android:layout_centerHorizontal="true"
            android:layout_marginTop="50dp"/>
 
    <ImageView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/markx_logo"
            android:layout_centerInParent="true"
            android:layout_weight="1"/>
 
    <TextView android:layout_width="match_parent"
              android:layout_height="wrap_content"
              android:gravity="center_horizontal"
              android:text="@string/new_app_site"
              android:textSize="22dp"
              android:layout_marginBottom="20dp"
              android:height="50dp"/>
 
</LinearLayout>

4. Добавим следующий код в класс SplashScreenActivity.java. В этом фрагменте кода используется handler, который будет ждать в течении заданного времени и по истечению таймера будет запускаться главная активити проекта.

public class SplashScreenActivity extends Activity {
 
    private static int SPLASH_SCREEN_TIMEOUT = 2500;
 
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
 
        setContentView(R.layout.splash_screen);
 
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(SplashScreenActivity.this, MainActivity.class);
                startActivity(intent);
                finish();
            }
        }, SPLASH_SCREEN_TIMEOUT);
    }
 
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    }
 
}

Как это работает в настоящем приложении вы можете посмотреть тут



суббота, 1 февраля 2014 г.

Android. Как заблокировать автоповорот экрана

Перехват события разворота экрана


Для того, чтобы самому перехватывать событие, которое будет происходить при автоповороте экрана устройства необходимо в файле AndroidManifest.xml в соответствующей активити прописать следующий атрибут

android:configChanges="orientation">

Описание активити будет выглядеть так

<activity android:name="MainActivity"
          android:label="@string/app_name"
          android:configChanges="orientation">
</activity>

Теперь необходимо в файле java класса соответствующей активити переопределить метод

onConfigurationChanged

и в этом методе задать какую ориентацию экрана мы хотим

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

Метод будет выглядеть вот так

@Override
public void onConfigurationChanged(Configuration newConfig) {
  super.onConfigurationChanged(newConfig);
  setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}

Задаем ориентацию экрана при запуске приложения


Если вы хотите, чтобы активити всегда была в определенной ориентации, то необходимо в файле AndroidManifest.xml для соответствующей активити прописать атрибут

android:screenOrientation="portrait">

Вот так будет выглядеть описание активити

<activity android:name="MainActivity"
          android:label="@string/app_name"
          android:configChanges="orientation"
          android:screenOrientation="portrait">
</activity>

Как это работает в настоящем приложении вы можете посмотреть тут



среда, 25 декабря 2013 г.

Android. Получаем Google Account пользователя

Необходимо получить данные об аккаунте (или аккаунтах) пользователя Android устройства. Для этого необходимо использовать класс AccountManager.


1. Добавим необходимое разрешение в файл AndroidManifest.xml

<?xml version='1.0' encoding='utf-8'?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
  ..
  <uses-permission android:name="android.permission.GET_ACCOUNTS" />
</manifest>

2. Получаем аккаунты всех пользователей

AccountManager accountManager = (AccountManager)getSystemService(ACCOUNT_SERVICE);
Account[] accounts = manager.getAccounts();

3. Получаем только аккаунты, которые email

Pattern emailPattern = Patterns.EMAIL_ADDRESS;
AccountManager accountManager = (AccountManager)getSystemService(ACCOUNT_SERVICE);
Account accounts[] = accountManager.getAccounts();
for (Account account : accounts) {
  if (emailPattern.matcher(account.name).matches()) {
    String accountName = account.name;
    ...
  }
}

4. Получаем только гугловые аккаунты

AccountManager accountManager = (AccountManager) getSystemService(ACCOUNT_SERVICE);
Account accounts[] = accountManager.getAccountsByType("com.google");
Account account;
if (accounts.length > 0) {
  account = accounts[0];
} else {
  account = null;
}

воскресенье, 22 декабря 2013 г.

Ресурсы для изучения разработки под Android


Указаны в порядке полезности для меня при изучении.

1. Startandroid - полезные уроки от самого начала (для тех кто никогда не писал для Android)

http://startandroid.ru/ru/uroki/vse-uroki-spiskom.html

2. DevColibri - очень много полезных рецептов

 http://devcolibri.com/category/android/

3. Developer.Android - официальное руководство от Google

 http://developer.android.com/training/basics/firstapp/index.html

суббота, 7 декабря 2013 г.

Полезные книги по Web Технологиям

Решил публиковать полезные книги по Web -технологиям. Ведь настоящий мастер всегда должен читать много литературы по своему профилю. Так как последнее время занимаюсь jQuery Mobile, то первая книга это

1. Pro jQuery Mobile

Официальный сайт издательства http://www.apress.com/9781430239666
Год: 2011
Автор: Brad Broulik
Издательство: Apress
Язык: Английский
Количество страниц 268 
Уровень пользователя: От среднего до продвинутого
Доступные форматы: EPUB, MOBI, PDF

пятница, 6 декабря 2013 г.

jQuery Mobile: Обработка динамически добавляемых элементов

В jQuery Mobile при динамическом добавлении элементов на страницу может возникнуть проблема с корректным отображением добавленных элементов. Любой виджет ('элемент) jQuery Mobile может быть динамически обновлен после добавления.

Динамически добавленный список до обновления

Динамически добавленный список после обновления


Кросбраузерный скроллинг с библиотекой iscroll 5


1. Сайт автора  и небольшая инструкция http://cubiq.org/iscroll-5-ready-for-beta-test

2. Ссылка на GitHub https://github.com/cubiq/iscroll

3. Очень интересный пример, в котором добавляется горизонтальная прокрутка при помощи iscroll, но при этом сохраняется нативная вертикальная прокрутка. Такую реализацию удобно использовать, если приложение будет запускаться на мобильном устройстве.

 http://lab.cubiq.org/iscroll5/demos/event-passthrough/


четверг, 5 декабря 2013 г.

Save application data on mobile device in phonegap with WebSQL

Как хранить настройки приложения сделанного в PhoneGap. Например, необходимо чтобы пользователь ввел какие-то настройки в приложении, сохранил их и при следующем запуске программы настройки загрузились и выставились в приложении. Для этого нам понадобится WebSQL.



Сохраняем параметры в базу данных. Открываем соединение с базой и пытаемся добавить данные.
saveSearchSetting: function () {
 
   ... 
 
   var db = window.openDatabase("saved_settings", "1.0", "SEARCH_SETTINGS DB", 1000000);
   db.transaction(page.populateDB, page.errorCB);
 
}

Заполняем базу данных.
populateDB: function (tx) {
  tx.executeSql('DROP TABLE IF EXISTS SEARCH_SETTINGS');
  tx.executeSql('CREATE TABLE IF NOT EXISTS SEARCH_SETTINGS (id unique, paramName, paramValue)');
  tx.executeSql('INSERT INTO SEARCH_SETTINGS (id, paramName, paramValue) VALUES (1, "fromCity", "' + page.fromCity + '")');
  tx.executeSql('INSERT INTO SEARCH_SETTINGS (id, paramName, paramValue) VALUES (2, "toCity", "' + page.toCity + '")');
  tx.executeSql('INSERT INTO SEARCH_SETTINGS (id, paramName, paramValue) VALUES (3, "deviceName", "' + page.deviceName+ '")');
  tx.executeSql('INSERT INTO SEARCH_SETTINGS (id, paramName, paramValue) VALUES (4, "categories", "' + page.categories+ '")');
  tx.executeSql('INSERT INTO SEARCH_SETTINGS (id, paramName, paramValue) VALUES (5, "types", "' + page.types+ '")');
  tx.executeSql('INSERT INTO SEARCH_SETTINGS (id, paramName, paramValue) VALUES (6, "pageNumber", "' + page.pageumber+ '")');
}

Загружаем сохраненные настройки. Пытаемся подключится к базе данных.
loadSavedSearchSettings: function () {
  var db = window.openDatabase("saved_settings", "1.0", "SEARCH_SETTINGS DB", 1000000);
  db.transaction(page.queryDB, page.errorCB);
}

Если подключится к базе удалось, тогда пытаемся выполнить запрос к базе данных.
queryDB: function(tx) {
  tx.executeSql('SELECT * FROM SEARCH_SETTINGS', [], page.querySuccess, page.errorCB);
}

Обработчик в случае ошибки при обращении к базе данных.
errorCB: function (err) {
  page.findGeolocation();
}

Если удалось получить данные в результате запроса к базе, то тогда сохраняем эти данные в переменные, которые потом используем для заполнения форм ввода на экране.
querySuccess: function(tx, results)  {
  var len = results.rows.length;
  for (var i=0; i<len; i++){
    if (results.rows.item(i).id == 1) {
      page.fromCity =  results.rows.item(i).paramValue;
    }
    if (results.rows.item(i).id == 2) {
      page.toCity =  results.rows.item(i).paramValue;
    }
    if (results.rows.item(i).id == 3) {
      page.deviceName=  results.rows.item(i).paramValue;
    }
    if (results.rows.item(i).id == 4) {
      var str =  results.rows.item(i).paramValue;
      page.categories = str.split(",");
    }
    if (results.rows.item(i).id == 5) {
      var str =  results.rows.item(i).paramValue;
      page.types = str.split(",");
    }
    if (results.rows.item(i).id == 6) {
      page.pageNumber = results.rows.item(i).paramValue;
    }
  }
  page.fillForm();
}

PhoneGap findGeoLocation script and GeoLocationPlugin

Необходимо было встроить в мобильное приложение определение текущей геопозиции, причем не просто координат, а именно название населенного пункта. Отыскал скрипт, который определяет геокоординаты  и на основании этих геокоординат определяет название населенного пункта. Исходный скрипт был предназначен для работы только в браузере. Функциональность этого скрипта нужно было использовать в нашем мобильном приложении, которое делается с применением технологии Phonegap.


понедельник, 2 декабря 2013 г.

jQuery Post Request with $.ajax

Как передать JSON на сервер с помощью jQuery. Для этого нам понадобится отправить на сервер POST-запрос и прикрепить к нему нужный нам JSON. Допустим надо отправить на сервер JSON следующего вида {"userEmail": "xxx@xx.xx", "password":"xxxx"}. Для этого нам понадобится метод jQuery $.ajax().
1. Указываем тип запроса type: "POST"
2. Указываем тип пересылаемых и принимаемых данных 
accept: "application/json",
contentType:"application/json",
dataType:"json",
3. Формируем JSON, который будем отправлять
data:JSON.stringify({ "userEmail": "xxx@xx.xx", "password":"xxxxxx" })

Клиентская часть на jQuery
$.ajax(
  {
    type: "POST",
    accept: "application/json",
    contentType:"application/json",
    dataType:"json",
    data:JSON.stringify({ "userEmail": "xxx@xx.xx", "password":"xxxxxx" }),
    url:"http://someservice/rest/users/authorize",
    success: function(response) {
    },
    error: function() {
      alert("LOGIN FAIL");
    }
  }
);

Серверная часть на Java
@Path("/users")
public class UserResource extends AbstractCrudResource<User> {
 
  private UserManager manager = UserManager.getInstance();
 
  private UserDao userDao = UserDao.getInstance();
 
  @POST
  @Produces(MediaType.APPLICATION_JSON)
  @Path("/authorize")
  public Response authorize(@Context HttpServletRequest request, 
    UserDTO userDTO) {
    if (userDTO.getUserEmail() != null) {
      User user = manager.retrieveUserByEmail(userDTO.getUserEmail());
      if (user != null) {
        if (user.getPassword().equals(
          userDao.getPasswordMD5Hash(userDTO.getPassword()))) {
 
          ...
 
        }
      }
    }
  }
}

Модель данных JSON которой пересылается 
public class UserDTO {
 
  private Long id;
 
  private String password;
 
  private String userEmail;
 
}