Обзор сетевого хранилища Fantec CL-35B2 RAID

Я думаю, что нет смысла объяснять хабраюзерам, зачем нужно сетевое хранилище. Скорее всего, многие уже используют этот способ хранения данных у себя дома. Это же категорически удобно – все мультимедийные файлы собраны в одном месте, не нужно таскать фильмы на флешках между рабочим компьютером, ноутбуком и телевизором. Вдобавок ко всему и скачивать файлы существенно проще – компы выключены, в доме тишина, а под столом стоит маленькая коробочка, которая в поте лица качает и раздает торренты. Я долго пользовался однодисковым QNAP TS-119 с диском на 3 терабайта, но желание проапгрейдится на двухдисковое хранилище и увеличить объем было непреодолимо. В итоге в мои руки попал Fantec CL-35B2 RAID, о нем и пойдет речь под катом. В первую очередь девайс удивил своими габаритами, я ожидал увидеть существенно бОльшую коробку. Рассказывать подробно о коробке, честно говоря, не хочется. Просто приведу несколько фотографий с акцентом на технологии, которые Fantec считает нужным выделить в своем устройстве: поддержка двух жестких дисков и гигабитный интерфейс.



Упакован NAS качественно, при транспортировке вряд ли что-то может случится с пустым хранилищем. Но в случае, если вы заказываете NAS с установленными дисками, масса устройства возрастает существенно и тогда почтовые службы существенно увеличивают свои шансы на разгром посылки.
В комплекте поставки: собственно сетевое хранилище, адаптер питания, сетевой кабель RJ -45, диск с программным обеспечением.
NAS выглядит вполне симпатично. Передняя панель выполнена из глянцевого черного пластика, сам корпус – из крашеного алюминия. Решение вполне логичное, корпус выполняет также функции радиатора для дополнительного охлаждения жестких дисков. Передняя панель сетвеого хранилища отведена под кнопочки и индикаторы. Здесь расположились кнопка включения, индикатор питания системы, индикаторы активности жестких дисков (по одному для каждого из дисков), индикатор ошибок, индикатор копирования с USB носителя, кнопка копирования с USB накопителя и разъём USB для подключения устройств с информацией.
Обратная сторона NAS отведена под вентилятор системы охлаждения, гнездо для подключения блока питания, разъём для подключения локальной сети RJ-45, USB разъём, кнопка Reset и гнездо для Kensington lock.
Нижняя панель кроме резиновых ножек также содержит элементы, ответственные за работу NAS, а именно защелку для передней панели и два отверстия для крепления установленных жестких дисков.

После снятия передней панели в конце туннеля можно увидеть плату, на которой расположены управляющие элементы сетевого хранилища.

После снятия алюминиевого корпуса остается весьма жалкая конструкция, вовсе не напоминающая сетевое хранилище или какой-либо компьютер в принципе.
Основа NAS Fantec CL-35<span style=«mso-ansi-language:EN-US» lang=«EN-US»>B2 RAID — чип PLX NAS 7821. Обращение к Гуглю приводит на сайт производителя этого контроллера: http://www.plxtech.com/products/consumer/nas7821 — по ссылочке можно посмотреть документацию, а при наличии подписанного NDA с PLX скачать киты для разработки. У меня никаких соглашений с вендором нет, поэтому почитаем только то, что доступно всем. Тут начинаются первые сюрпризы, например поддерживается только интерфейс SATA 3 ГБит/с. Не то, чтобы очень надо было или пропускная способность гигабитного Ethernet позволяла прокачивать через себя больше одного гигабита, но тем не менее, хотелось бы видеть SATA III (6 ГБит/с) интерфейс.  Внутрь NAS тем не менее буду ставить диски SATA III — специально обученные для работы в сетевых хранилищах, прошедшие спецподготовку на секретных базах и получившие красные наклейки — Western Digital WD30EFRX NASware или по-простому — WD Red.
Установка проходит очень просто и беспроблемно — вставляем диск нужной стороной в отсек (наклейкой к центру NAS) и фиксируем одним винтом с нижней панели — вуаля, NAS собран и готов к работе.
После включения в сеть (220В) и сеть (LAN) девайсу будет назначен IP и по нему можно зайти в веб-интерфейс.  Изначально предлагается определиться с тем, какой массив вы хотите создать из дисков, установленных в NAS. Я построил RAID 1.

Программа для входа на веб-интерфейс называется iSharing (тут автора скрутило в судорогах, интересно мне одному надоела буква i, добавленная спереди к чему-либо).
После того как iSharing нашел ваш NAS открывается главный экран веб-интерфейса. Linux, как Linux.
Захожу в MyCloud (хорошо, что не iMyCloud) — четыре стандартных папки Документы, Музыка, Фото, Видео.

В настройках все намного интереснее: тут есть адресная книга, приложения, информация и управление дисками, медиаплеер, разнообразные возможности кастомизации, втом числе и внешнего вида.
Для интерфейса доступно 11 языков, среди которых есть великий и могучий русский язык. Если посмотреть информацию о дисках, то можно увидеть абсолютную правду — два диска по 3 Тб в массиве RAID 1 общим объёмом 3 Тб.

Системная информация предлагает большое количество настроек, в которых лично мне наиболее интересны службы. Отлично, медиасервер включен. Никаких сложностей, все очень просто и быстро. Кино и музыка из корневой папки транслируется в локальную сеть и мой телевизор уже готов к показу фильмов. iTunes тоже настраивается просто и музыкальный плеер уже проигрывает все что накачано непосильным трудом.
FTP без проблем, работает, правда, если говорить начистоту я не пользуюсь этим протоколом дома. Так что, скриншот для галочки.
Вот и информация о системе. Скрывать мне тут нечего, так что смотрите ).
Для доступа к NAS из Интернет можно зарегистрировать имя на сайте myisharing.com и  коннектиться с работы к домашней хранилке. Возможность назначить внешний IP отсутствует, или, по крайней мере, я ее не нашел. На QNAP она есть и очень легко настраивается.
Мастер закачек имеет одну очень неприятную особенность — он понимает только http адреса. Если вы захотите качать торренты, необходимо искать и ставить дополнительные программы.
Итак, вроде о девайсе все. Пожалуюсь еще на систему обновления программного обеспечения. Эта нетривиальная, как выяснилось, задача под силу только самым настойчивым пользователям. Автоматическое обновление тупо не работает. Страница на английском языке на которую посылают для скачивания firmware не работает. И лишь при серфингу по немецкой версии сайта (благо ваш покорный слуга немного шпрехает на этом языке) удалось раздобыть новую прошивку. Аналогичная ситуация происходит и с дополнительными модулями для улучшения функционала. Теперь подведу итоги и расскажу о том, почему устройство не осталось жить у меня. Плюсы: невысокая цена (я нашел одно девайс в магазине примерно за 6400 рублей), компактные размеры, поддержка двух дисков, поддержка RAID 0/1. Минусы: отсутствие SATA III, отсутствие возможности присвоить внешний IP, отсутствие врожденной поддержки торрентов, отсутствие регулярных обновлений. Что здесь для меня критично? Ну, во-первых, конечно торренты. Причины думаю ясны всем. Во-вторых, внешний IP. У многих на работе стоят прокси, секущие всякие файлопомойки, но они бессильны перед простым обращением по IP к домашнему NAS. Эти две причины собственно и стали поводом для расставания с Fantec. Ругать и говорить, что вещь негодная не стану, для простого файлохранилища дома — она подойдет, но ИМХО не более того.

ссылка на оригинал статьи http://habrahabr.ru/company/ulmart/blog/192106/

Pro Core Data for iOS. Глава №2. Практическая часть

Хабралюди, добрый день!
Сегодня хочу начать вольный перевод книги Михаеля Привата и Роберта Варнера «Pro Core Data for iOS», которую можете скачать по этой ссылке. Каждая глава будет содержать теоретическую и временами практическую часть.

image

Содержание:

  • Глава №1. Приступаем (Практическая часть)
  • Глава №2. Усваиваем Core Data (Практическая часть)
  • Глава №3. Хранение данных: SQLite и другие варианты
  • Глава №4. Создание модели данных
  • Глава №5. Работаем с объектами данных
  • Глава №6. Обработка результатирующих множеств
  • Глава №7. Настройка производительности и используемой памяти
  • Глава №8. Управление версиями и миграции
  • Глава №9. Управление таблицами с использованием NSFetchedResultsController
  • Глава №10. Использование Core Data в продвинутых приложениях

Вступление

Будем мы создавать вот такую модель:
image

Затем добавим несколько записей и запросим их. Вывод будет производиться в консоль, чтобы мы не задавались еще и вопросами визуальными.
Готовы? Тогда поехали!

Описание

Будем создавать объектный граф нашего любимого ресурса — Хабра.
Есть N основных объектов:

  • Запись в блоге
  • Пользователь
  • Теги
  • Хабы
  • Вопросы
  • Ответы
  • Учетная запись компании

Этого будет достаточно.

Какие данные содержит каждый из объектов?

  • Запись в блоге — заголовок, текст
  • Пользователь — ник, карма, рейтинг, пол, аватар, почтовый ящик
  • Тег — наименование
  • Хаб — наименование, профильный ли хаб
  • Вопрос — заголовок, текст
  • Ответ — текст
  • Учетная запись компании — наименование организации, рейтинг
Приступаем к работе

Открываем XCode и создаём новый проект Single View Application:

Вводим наименование проекта, префиксы и прочее:
image

Знакомое окно:
image

Добавляем Core Data

Добавляем Core Data Framework в проект:
image

Создаем модели

Добавить новый файл -> iOS -> CoreData -> Data Model
image
image

Начнём с записи в блоге.
Создаем новую сущность и называем её Blogpost, добавляем два атрибута caption (String) и text (String).
image

Создаем новую сущность и называем её User, добавляем атрибуты avatar (String), email (String), gender (Decimal), karma (Integer 16), nickname (String), rating (Integer 16).
image

Создаем новую сущность и называем её Tag, добавляем всего один атрибут name (String).
image

Создаем новую сущность и называем её Hab, добавляем два атрибута name (String), target (Boolean).
image

Создаем новую сущность и называем её Question, добавляем два атрибута caption (String), text (String).
image

Создаем новую сущность и называем её Response, добавляем один атрибут text (String).
image

Создаем новую сущность и называем её Organization, добавляем два атрибута name (String), rating (Integer 16).
image

Вот что у нас есть в итоге:
image

Теперь займемся установкой отношений между объектами.
У учетной записи компании есть множество пользователей (сотрудников).
У пользователя есть множество записей в блоге, у записи в блоге есть множество тегов и хабов.
У пользователя есть множество вопросов, а у вопроса множество ответов.

Начнем с построение связи «учетная запись компании» (один-ко-многим) «пользователи».
Выбираем из списка сущностей Organization и добавляем новую связь нажав на "+" в разделе Relationships:
image

Так как по умолчанию XCode создаёт связь один-к-одному мы должны изменить тип связи:
image

Теперь у каждой организации есть множество пользователей. Поле Inverse (обратная связь) мы сейчас тоже установим, но предварительно добавим новую связь в сущность Пользователя и назовем её organization (организация в которой работает пользователь, а если он не работает нигде, то поле будет null):
image

Теперь вновь откроем редактирование сущности Organization и установим поле Inverse в organization:
image

Вот как стал выглядеть теперь объектный граф:
image

Попробуйте расставить остальные связи сами, а затем сверьте с тем, что у меня получилось.
Вы знаете как создать связь, вы знаете как изменить тип связи с один-к-одному на один-ко-многим — этого будет достаточно.
Итоговая картина:
image

Создаем организацию

Уже имеем в AppDelegate.h такое:

// //  TMAppDelegate.h //  Habrahabr // //  Created by AndrewShmig on 8/31/13. //  Copyright (c) 2013 TM. All rights reserved. //  #import <UIKit/UIKit.h> #import <CoreData/CoreData.h>  @class TMViewController;  @interface TMAppDelegate : UIResponder <UIApplicationDelegate>  @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) TMViewController *viewController;  @property (nonatomic, strong) NSManagedObjectModel *managedObjectModel; @property (nonatomic, strong) NSPersistentStoreCoordinator *persistentStoreCoordinator; @property (nonatomic, strong) NSManagedObjectContext *managedObjectContext;  @end 

И в AppDelegate.m:

// //  TMAppDelegate.m //  Habrahabr // //  Created by AndrewShmig on 8/31/13. //  Copyright (c) 2013 TM. All rights reserved. //  #import "TMAppDelegate.h"  @implementation TMAppDelegate  - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {     return YES; }  #pragma mark - Core Data Stack  - (NSManagedObjectModel *)managedObjectModel {     if(nil != _managedObjectModel)         return _managedObjectModel;          _managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];          return _managedObjectModel; }  - (NSPersistentStoreCoordinator *)persistentStoreCoordinator {     if(nil != _persistentStoreCoordinator)         return _persistentStoreCoordinator;          NSURL *storeURL = [[[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory                                                                inDomains:NSUserDomainMask] lastObject] URLByAppendingPathComponent:@"Habrahabr.sqlite"];          NSError *error = nil;     _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:self.managedObjectModel];     if(![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]){         NSLog(@"Unresolved error %@, %@", error, [error userInfo]);         abort();     }          return _persistentStoreCoordinator; }  - (NSManagedObjectContext *)managedObjectContext {     if(nil != _managedObjectContext)         return _managedObjectContext;          NSPersistentStoreCoordinator *store = self.persistentStoreCoordinator;     if(nil != store){         _managedObjectContext = [[NSManagedObjectContext alloc] init];         [_managedObjectContext setPersistentStoreCoordinator:store];     }          return _managedObjectContext; }  @end 

Перепишем метод application:didFinishLaunchingWithOptions: таким образом:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //    Создаем организацию     NSManagedObject *yandex = [NSEntityDescription insertNewObjectForEntityForName:@"Organization"                                                             inManagedObjectContext:self.managedObjectContext];     [yandex setValue:@"Yandex Inc." forKey:@"name"];     [yandex setValue:@672 forKey:@"rating"];      //    создаем сотрудников Yandex     NSManagedObject *pupkin = [NSEntityDescription insertNewObjectForEntityForName:@"User"                                                             inManagedObjectContext:self.managedObjectContext];     [pupkin setValue:@"VaseaPup" forKey:@"nickname"];     [pupkin setValue:@"vasilisa@yandex.ru" forKey:@"email"];     [pupkin setValue:@1 forKey:@"gender"]; // 0 - unknown, 1 - male, 2 - female     [pupkin setValue:@0 forKey:@"karma"];     [pupkin setValue:@0 forKey:@"rating"];          NSManagedObject *gosha = [NSEntityDescription insertNewObjectForEntityForName:@"User"                                                            inManagedObjectContext:self.managedObjectContext];     [gosha setValue:@"Goshka" forKey:@"nickname"];     [gosha setValue:@"gosha.k@yandex.ru" forKey:@"email"];     [gosha setValue:@0 forKey:@"gender"];     [gosha setValue:@0 forKey:@"karma"];     [gosha setValue:@0 forKey:@"rating"];      //    связываем сотрудников с компанией     NSMutableSet *employees = [yandex mutableSetValueForKey:@"employees"];     [employees addObject:pupkin];     [employees addObject:gosha];      //    сохраняем данные в хранилище     [self saveContext];          NSLog(@"Finish!");          return YES; } 

Запустим приложение. Данные должны были быть сохранены. Проверим это.
Найдем файл Habrahabr.sqlite:
image

Запустим терминал и проверим структуру БД:

AndrewShmigs-MacBook-Pro:~ new$ cd "/Users/new/Library/Application Support/iPhone Simulator/6.1/Applications/95B0716A-9C2C-4BD8-8117-62FB46BB5879" AndrewShmigs-MacBook-Pro:95B0716A-9C2C-4BD8-8117-62FB46BB5879 new$ ls Documents	Habrahabr.app	Library		tmp AndrewShmigs-MacBook-Pro:95B0716A-9C2C-4BD8-8117-62FB46BB5879 new$ cd Documents/ AndrewShmigs-MacBook-Pro:Documents new$ ls Habrahabr.sqlite AndrewShmigs-MacBook-Pro:Documents new$ sqlite3 Habrahabr.sqlite  SQLite version 3.7.12 2012-04-03 19:43:07 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> .schema CREATE TABLE ZBLOGPOST ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZAUTHOR INTEGER, ZCAPTION VARCHAR, ZTEXT VARCHAR ); CREATE TABLE ZHAB ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZTARGET INTEGER, ZBLOGPOSTS INTEGER, ZNAME VARCHAR ); CREATE TABLE ZORGANIZATION ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZRATING INTEGER, ZNAME VARCHAR ); CREATE TABLE ZQUESTION ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZAUTHOR INTEGER, ZCAPTION VARCHAR, ZTEXT VARCHAR ); CREATE TABLE ZRESPONSE ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZQUESTION INTEGER, ZTEXT VARCHAR ); CREATE TABLE ZTAG ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZBLOGPOST INTEGER, ZNAME VARCHAR ); CREATE TABLE ZUSER ( Z_PK INTEGER PRIMARY KEY, Z_ENT INTEGER, Z_OPT INTEGER, ZKARMA INTEGER, ZRATING INTEGER, ZORGANIZATION INTEGER, ZGENDER DECIMAL, ZAVATAR VARCHAR, ZEMAIL VARCHAR, ZNICKNAME VARCHAR ); CREATE TABLE Z_METADATA (Z_VERSION INTEGER PRIMARY KEY, Z_UUID VARCHAR(255), Z_PLIST BLOB); CREATE TABLE Z_PRIMARYKEY (Z_ENT INTEGER PRIMARY KEY, Z_NAME VARCHAR, Z_SUPER INTEGER, Z_MAX INTEGER); CREATE INDEX ZBLOGPOST_ZAUTHOR_INDEX ON ZBLOGPOST (ZAUTHOR); CREATE INDEX ZHAB_ZBLOGPOSTS_INDEX ON ZHAB (ZBLOGPOSTS); CREATE INDEX ZQUESTION_ZAUTHOR_INDEX ON ZQUESTION (ZAUTHOR); CREATE INDEX ZRESPONSE_ZQUESTION_INDEX ON ZRESPONSE (ZQUESTION); CREATE INDEX ZTAG_ZBLOGPOST_INDEX ON ZTAG (ZBLOGPOST); CREATE INDEX ZUSER_ZORGANIZATION_INDEX ON ZUSER (ZORGANIZATION); sqlite> select * from ZORGANIZATION; 1|3|1|672|Yandex Inc. sqlite> select * from ZUSER; 1|7|1|0|0|1|0||gosha.k@yandex.ru|Goshka 2|7|1|0|0|1|1||vasilisa@yandex.ru|VaseaPup sqlite>  

Добавим теперь одному из сотрудников вопрос и создадим какой-то пост.

//    добавляем сотруднику Гоше вопрос     NSManagedObject *whoAmI = [NSEntityDescription insertNewObjectForEntityForName:@"Question"                                                             inManagedObjectContext:self.managedObjectContext];     [whoAmI setValue:@"Who am I?" forKey:@"caption"];     [whoAmI setValue:@"Помогите мне узнать себя лучше." forKey:@"text"];          NSMutableSet *goshasQuestions = [gosha mutableSetValueForKey:@"questions"];     [goshasQuestions addObject:whoAmI]; 

Запустим приложение и проверим БД:

sqlite> select * from ZQUESTION; 1|4|1|4|Who am I?|Помогите мне узнать себя лучше. sqlite>  

Добавим блогпост сотруднику Васе Пупкину:

//    добавляем сотруднику Васе Пупкину новый блогпост     NSManagedObject *newPost = [NSEntityDescription insertNewObjectForEntityForName:@"Blogpost"                                                              inManagedObjectContext:self.managedObjectContext];     [newPost setValue:@"yandex.Деньги & yandex.Карты & yandex.ДваСтвола" forKey:@"caption"];     [newPost setValue:@"Some text" forKey:@"text"];      //    добавляем два Хаба     NSManagedObject *hab1 = [NSEntityDescription insertNewObjectForEntityForName:@"Hab"                                                           inManagedObjectContext:self.managedObjectContext];     [hab1 setValue:@"iOS" forKey:@"name"];     [hab1 setValue:@YES forKey:@"target"];          NSManagedObject *hab2 = [NSEntityDescription insertNewObjectForEntityForName:@"Hab"                                                           inManagedObjectContext:self.managedObjectContext];     [hab2 setValue:@"Objective-C" forKey:@"name"];     [hab2 setValue:@YES forKey:@"target"];          NSMutableSet *habs = [newPost mutableSetValueForKey:@"habs"];     [habs addObject:hab1];     [habs addObject:hab2];          [[pupkin mutableSetValueForKey:@"blogposts"] addObject:newPost]; 

И вывод:

sqlite> select * from ZBLOGPOST; 1|1|1|5|yandex.Деньги & yandex.Карты & yandex.ДваСтвола|Some text sqlite> select * from ZHAB; 1|2|1|1|1|iOS 2|2|1|1|1|Objective-C sqlite>  
Вывод данных

Выведем всех сотрудников и наименования компаний в которых они работают. Код для чтения данных будем писать в том же методе в котором писали и запись данных.

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"User"];     NSArray *allUsers = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil];          for(NSManagedObject *user in allUsers){         NSString *nickname = [user valueForKey:@"nickname"];         NSString *organization = [user valueForKeyPath:@"organization.name"];                  NSLog(@"%@ works at %@", nickname, organization);     } 

Получим примерно такой вывод (приложение у меня запускалось несколько раз и данные тоже несколько раз были добавлены):

2013-08-31 13:00:27.255 Habrahabr[18148:c07] Goshka works at Yandex Inc. 2013-08-31 13:00:27.257 Habrahabr[18148:c07] VaseaPup works at Yandex Inc. 2013-08-31 13:00:27.258 Habrahabr[18148:c07] VaseaPup works at Yandex Inc. 2013-08-31 13:00:27.258 Habrahabr[18148:c07] Goshka works at Yandex Inc. 2013-08-31 13:00:27.259 Habrahabr[18148:c07] VaseaPup works at Yandex Inc. 2013-08-31 13:00:27.259 Habrahabr[18148:c07] Goshka works at Yandex Inc. 2013-08-31 13:00:27.260 Habrahabr[18148:c07] Finish! 

Обратите внимание на то, как мы получили наименование организации в которой работает пользователь. Как Вам? А? Я так и думал, что понравится!

В завершение

Экспериментируйте! Не бойтесь, если что-то сломается, полный проект находится по этой ссылке.

Удачи и благодарю за внимание!
Надеюсь вам понравилась практическая часть.

ссылка на оригинал статьи http://habrahabr.ru/post/192090/

27-29 октября 2013: Конференция для разработчиков Samsung Developer Conference

Привет, Хабр!

Мы рады сообщить, что c 26 августа открыта регистрация на первую ежегодную конференцию для разработчиков, которую организует компания Samsung Electronics и которая пройдёт в Сан-Франциско в Westin St. Francis Hotel в период с 27 по 29 октября 2013 года.



Во время конференции лучшие специалисты со всего мира выступят с десятками технических сессий на следующие темы:

  • Новые средства разработки Samsung, такие как S Pen, и новые возможности;
  • Погружение в Samsung Service Platform, API для ChatON, Group Play, Samsung AdHub, Context Aware и многое-многое другое;
  • Мастер-классы по разработке приложений для Smart TV с поддержкой дисплеев различных размеров и разрешений;
  • Новые возможности в разработке игр;
  • Кросс-платформенная разработка HTML5-приложений;
  • Разработка Web-приложений для Tizen;
  • Специальные сессии для B2B-разработчиков, где будет рассказано о программе для мобильных партнёров, о создании сертифицированных приложений, KNOX, Enterprise SDK и многом другом.

Стоимость участия в конференции составляет $299. Подробности можно узнать на официальном сайте мероприятия: samsungdevcon.com Также уже доступна предварительная программа мероприятия.

Приглашаем всех желающих принять участие в этом знаменательном событии!

ссылка на оригинал статьи http://habrahabr.ru/company/samsung/blog/192056/

В Google обосновали свой проект планетарного интернета Loon с точки зрения распределения воздушных шаров в стратосфере

В августовском интервью Bloomberg Билл Гейтс грубовато дал понять, что он думает по поводу проекта Google, известного как Project Loon — речь идёт о системе воздушных шаров для возможности подключения к интернету жителей удалённых районов планеты:

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

Оригинал

When you’re dying of malaria, I suppose you’ll look up and see that balloon, and I’m not sure how it’ll help you. When a kid gets diarrhea, no, there’s no website that relieves that.

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

Один из сотрудников проекта (его почему-то называют просто Ден (Dan)) выполнил компьютерную симуляцию проекта и теперь его результаты доступны публично. Главный ответ — да, устойчивое покрытие вполне возможно.

Располагая доступной информацией относительно ветрового режима на разных уровнях стратосферы, Ден задал для каждого шара некоторые физические параметры и запустил симуляцию для оценки динамики движения шаров и их распределения во времени. Снимок экрана с симуляцией представлен ниже:

Шары на схеме окрашены разный цвет в зависимости от высоты их положения в стратосфере и, как видно, если подобрать определённые физические параметры шаров в соответствии с направлением воздушных потоков стратосферы, то их распределение будет достаточно «плотным» (правда, масштаб схемы не известен) для качественного покрытия радиосигналами определённой площади.

Таким образом был сделан вывод, что наименее предсказуемая часть проекта на самом деле таковой не является, и как таковых физических препятствий (с точки зрения атмосферы) не существует.

Видео с объяснением самого Дена можно посмотреть ниже:

[Источник]

ссылка на оригинал статьи http://habrahabr.ru/post/192094/

AndEngine GLES2 — Живые обои

Зимой прошлого года (скорее всего в солнечный день:) я заинтересовался графической библиотекой AndEngine, так как захотелось поработать с двумерной графикой на мобильном телефоне (с использованием OpenGL), и это решение мне показалось наиболее интересным и доступным. Сделав несколько графических приложений, я решил создать живые обои, тем более что в поставке с AndEngine идёт специальная библиотека для создания таковых. Теперь поделюсь своим опытом создания живых обоев с вами.
Специально для этого я подготовил проект (обладает обильными комментариями), «шаблон» для показа принципа работы живых обоев.
image

Подготовка
Прежде всего необходимо установить сам AndEngine и в частности библиотеку AndEngineLiveWallpaperExtension (рекомендую сразу установить все доступные библиотеки) так как она будет являться базой. Так как эта статья не является базовой для изучения AndEngine я не буду рассказывать как установить библиотеки, тем более что данную информацию вы можете легко найти, например здесь — http://www.matim-dev.com/how-to-setup-andengine.html. Теперь вам необходимо открыть прилагаемый проект и запустить его. Если он сразу не запустится, то скорее всего вам необходимо проверить подключенные библиотеки к проекту. В итоге у вас должно получиться что то типа этого — http://youtu.be/HRKzBma9vz0

Функционал
А теперь кратко и по порядку (большая часть функционал также относится ко всем другим AndEngine GLES2 приложениям). Предком главного класса проекта является «BaseLiveWallpaperService», именно этот класс отвечает за всю работу с GLES2. Обязательными для переопределения являются функции:

onSurfaceChanged onCreateEngineOptions onCreateResources onCreateScene 

public void onSurfaceChanged(final GLState pGLState, final int pWidth, final int pHeight) — функция определения размера экрана и установки камеры.
public EngineOptions onCreateEngineOptions() — функция настройки работы движка живых обоев. Данная функция возвращает в систему выбранные параметры для настройки GLES2.
public void onCreateResources(OnCreateResourcesCallback pOnCreateResourcesCallback) — как понятно из названия, данная функция предназначена для создания всех (медиа) ресурсов которые будут участвовать в работе приложения.
public void onCreateScene(OnCreateSceneCallback pOnCreateSceneCallback) — функция создания сцены и размещения на ней всех желаемых объектов.

Загрузка тестур
Загрузка текстуры происходит в три этапа: определение атласа; определение текстуры; загрузка текстуры в атлас. Рассмотрим их на примере загрузки заднего фона:

this.mOnScreenControlTexture0 = new BitmapTextureAtlas(this.getTextureManager(), 1930, 1050, TextureOptions.BILINEAR_PREMULTIPLYALPHA); this.bg_TextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mOnScreenControlTexture0,this,"gfx/bg.jpg", 0, 0); this.getEngine().getTextureManager().loadTexture(this.mOnScreenControlTexture0); 

В первой строке определяется размер для атласа текстур. Нужно заранее определить какие текстуры и в каком порядке расположатся на данном атласе и рассчитать его размер. Если неправильно рассчитать положение текстур в атласе или сделать его меньше требуемого размера, то программа будет работать не корректно. В нашем случае в атласе будет располагаться всего одна картинка (спрайт) и поэтому размер атласа будет ровняться размеру картинки.
В случае если требуется загрузить две картинки (спрайта) и более, то размер атласа придётся высчитывать. Например: Мы хотим загрузить две картинки размером 60*60 и 80*75 пикселей. Для нахождения ширины атласа сложим ширину первой и второй картинки, получим 140. При этом высота атласа должна ровняться наибольшей из этих картинок. При необходимости компоновка атласа может быть любой сложности, всё ограничивается только фантазией программиста и максимальными размерами (2048*2048).
image
Во второй строке определяется объект через который в дальнейшем можно получить интересующую текстуру. Аргументы конструктора следующие: атлас для хранения текстуры; контекст; адрес расположения текстуры; координата по Х, начиная с которой располагается текстура; координата по Y, начиная с которой располагается текстура. Все текстуры должны храниться в парке «gfx» (проект/assets/gfx).
В третьей строке находится сам загрузчик, с помощью которого загружается вся графика в атлас.

Создание сцены
Сцена создается всего одной строкой — mScene= new Scene(), далее происходит самое интересное — размещение всех нужных объектов на сцене. Главной строительной единицей всех приложений строящихся с помощью AndEngine, являются спрайты (так как библиотека работает исключительно с двумерными объектами). Рассмотрим пример создания простого спрайта:

bg = new Sprite(0, 0, this.bg_TextureRegion, getVertexBufferObjectManager()); bg.setSize(bg.getWidth() * 2, bg.getHeight() * 2); bg.setPosition(10, 20); mScene.attachChild(bg); 

В первой строке создаётся спрайт. У конструктора следующие аргументы: положение на сцене по оси Х; положение на сцене по оси Y; объект текстуры; менеджер буфера. Во второй строке переопределяется размер спрайта, по умолчанию он равен размеру текстуры. В третьей строке переопределяется позиция спрайта на экране. В четвертой строке спрайт непосредственно добавляется на экран.
Если вы посмотрите код прилагаемого примера, то заметите что в нем определен класс Sun. Он является потомком класса Sprite. В этом классе прописана логика анимации объекта, которая заключается в повороте объекта относительно своего центра.
Также определен класс LiveWallpapperSettings, который отвечает за настройку живых обоев. Так как это достаточно стандартная вещь, логику работы настроек описывать не буду (интересующую информацию вы легко найдете в Яндексе либо в других поисковых машинах).

Заключение
Библиотека очень проста в использовании и функциональна. Главным её недостатком является механизм замораживания, который срабатывает при скрытии обоев и не всегда отключается при продолжении их показа. Данный минус явно прослеживается когда обои имеют относительно большое количество спрайтов на сцене (как например здесь — https://play.google.com/store/apps/details?id=com.livewallpaper.summermeado_wfull). Если кто-то решил проблему с замораживанием, пожалуйста поделитесь решением.
Я намеренно не стал раздувать пример и добавлять максимальное количество функционала чтобы показать, что графические приложения для Android это быстро и просто.
Удачного тестирования!

Проект живых обоев — http://www.anprog.com/documents/AE_gles2_LiveWallpaper.zip

ссылка на оригинал статьи http://habrahabr.ru/post/192092/