пятница, 31 октября 2008 г.

Владельцам нетбуков посвящается: Unetbootin

Хабрахабр

Программа уже упоминалась на Хабре в блоге OpenSource

Unetbootin (http://unetbootin.sourceforge.net/) позволяет создать загрузочную USB-флешку из практически любого дистрибутива Linux/BSD. Впрочем, можно создать и загрузочный жесткий диск.
Существуют версии как для Linux, так и для Windows.
Работать просто до неприличия:
Выбрали источник → Выбрали загрузочное устройство → Нажали OK.
При этом в качестве источника можно выбрать дистрибутив и версию, программа сама скачает нужное. Можно выбрать ISO, а можно указать ядро и initrd руками с нужными опциями.

Окошко:
screenshot
PS. Поддерживается даже только что вышедшая Ubuntu 8.10.

Изменение быстрых клавиш в на лету в gtk приложениях

GiNeR's Blog: Изменение быстрых клавиш в на лету в gtk приложениях

За что я люблю gtk вообще (и Gnome в частности), так это за hotkeys (глобальные горячие клавиши) и accels (быстрые клавиши приложений). Теперь моя любовь стала больше, т.к. я узнал про изменение accels на лету, а именно: подводишь курсор мыши к нужному пункту меню приложения и жмёшь удобное тебе сочетание клавиш, оно тут же запоминается.
Чтобы это стало возможно необходимо включить gtk-can-change-accels в gtk, для этого:

- для Gnome:
gconf
tool -t boolean -s /desktop/gnome/interface/can_change_accels 1

- для других оконных менеджеров и приложений (не использующих gconf2):
echo gtk-can-change-accels = 1 >> ~/.gtkrc-2.0

Enjoy :)

Автор: GiNeR

среда, 29 октября 2008 г.

Установка CentOS 5.2

Linuxoid - все что знаю о Туксе » Архив блога » Установка CentOS 5.2

16.10.2008 от grinder

В последние дни июня месяца обществу была представлена новая версия 5.2 дистрибутива CentOS. Учитывая его популярность (ведь 11 место на Diastrowatch.com что-то говорит) и малоизвесность среди новичков, следует познакомиться с ним ближе.

Кто такой? Почему не знаю?

Давным давно в 1994 году в Америке появилась компания Red Hat (Красная шляпа), которая занялась разработкой одноименного дистрибутива. Нужно сказать, что в отличие от других популярных решений того времени, вроде Slackware и Debian, Red Hat отличался большей направленностью на конечного пользователя. Тому способствовала удобная и простая программа установки сначала псевдографическая, а затем с графическим интерфейсом и пакетная система RPM. Многие пользователи впервые столкнувшиеся с Linux в конце 90x, как правило начинали именно с Red Hat. В 2000 году вышла версия 6.2E ориентированная уже на корпоративный сектор. А через 2 года такой вариант дистрибутива стал называться Red Hat Enterprise Linux (RHEL). Он был свободно доступен на сервере компании, за плату предоставлялась техподдержка. В 2003 году произошло еще одно знаковое событие - разделение проекта на коммерческую и свободную версии. За коммерческим вариантом осталось имя RHEL, а свободная стала называться Fedora Core (сегодня просто Fedora). Многие производители программ и компьютеров сертифицируют свои решения на совместимость с Red Hat. За примером далеко ходить не нужно. Установка сервера групповой работы Scalix Community Edition (www.scalix.com) в RHEL довольно простое задание, чего не скажешь об его установке в Debian и Ubuntu. Дистрибутив RHEL, релизы которого выходят раз в полтора года, не отличаются обычно новизной приложений. Базовая система состоит только из проверенных временем стабильных (для экстремалов - Fedora) утилит. Хотя пользовательские приложения не влияющие на стабильную работу системы, могут иметь самый последний релиз. В RHEL включены в основном свободные программы, выпускаемых под лицензией GNU GPL, но дистрибутив выходит только для платных подписчиков, для которых доступны и обновления в виде бинарных пакетов.

Вот тут и начинается история нашего дистрибутива. Учитывая популярность RHEL, доступность исходных текстов как того требует GPL, сторонние организации стали собирать свою версию этой системы. Такие сборки полностью совместимы с RHEL, но используют собственные репозитарии для установки и обновления программ. Таким образом и появились: CentOS, StartCom Enterprise Linux, Pie Box Enterprise Linux, Scientific Linux, White Box Enterprise Linux и Lineox. Выпустила свой вариант и Oracle (Oracle Enterprise Linux), но все обновления доступны также за плату. Среди всех этих решений CentOS (Community ENTerprise Operating System) самый популярный. Сайт проекта находится по адресу centos.org, русскоязычное сообщество разместилось по адресу www.ruscentos.com. Кроме процего CentOS, сам дал жизнь нескольким дистрибутивам. Среди них самым известным является TrixBox (www.trixbox.org, бывший Asterisk@Home), который предназначен для построения VoIP сервиса.

Версия 5.2

Текущей версией является CentOS 5.2, который представляет собой пересобранный RHEL 5 Update 2. CentOS поддерживает почти те же архитектуры, что и исходный RHEL. Доступны сборки i386 и x86_64, PowerPC, IA64 и Sparc . Дистрибутив распространяется на 6 CD дисках (x86_64 - 7 CD), на отдельных зеркалах доступны и DVD сборки. Как видите LiveCD вариант, не предусмотрен. Для установки достаточно скачать DVD или первый CD диск, но во избежание проблем лучше иметь под рукой полную коллекцию дисков. Кроме этого есть и небольшой (7.7 Мб) образ netinstall, который используется для установки CentOS по сети. В этом варианте можно использовать собственный репозитарий пакетов, но к сожалению нормальная документация по работе с netinstall отсутствует. Возможна закачка образов и через torrent. Скачать нужную версию можно по адресу mirror.centos.org/centos/5/isos, в частности DVD вариант я брал с mirrors.cmich.edu/centos/5.2/isos/i386. Если RHEL доступен в двух версиях: серверной и настольной, то в CentOS нет необходимости разделять репозитарии. Поэтому скачанная версия может использоваться в любом из этих направлений.

Модуль yum-installonlyn отвечающий за установку новых ядер, вместо удаления старых, теперь вкомпилирован в yum. По умолчанию поддерживается добавление 3 ядер. Изменить это значение можно при помощи параметра "installonly_limit = число" в файле yum.conf.

Под капотом в CentOS 5.2 находится: kernel-2.6.18, GLIBC 2.5, Gnome-2.16, KDE-3.5.4, OpenOffice.org-2.3, Evolution-2.12, Firefox-3.0, Thunderbird-2.0. Заявлена улучшенная поддержка Compiz and AIGLX, как и RHEL 5 поддерживается система виртуализации Xen. Другие изменения касаются в основном устранения найденных ошибок и обновления ПО.

Все релизы CentOS имеют долгий срок поддержки. Так обновления для версии 3 будут выпускаться вплоть до 2010, CentOS 4 - 2012 и для CentOS 5 - 2014.

Установка CentOS

Установка в графическом режиме возможна только при наличии 512 Мб ОЗУ, при меньшем ее количестве (256 Мб) следует использовать текстовую установку. Последняя активируется вводом "linux text". Если вы уже используете CentOS 5 ранних версий то можно просто обновиться использовав "yum upgrade". Сценарии Kickstart созданные для CentOS < 5.2 следует, во избежание проблем, перед использованием протестировать. Для более ранних версий системы рекомендована полная переустановка.

Загрузочное меню традиционно для Linux дистрибутивов. Здесь можно ввести дополнительные параметры список которых можно получить нажав F2. Кроме активации тектового режима установки, возможна сетевая установка (linux askmethod), проверка носителя на ошибки (linux mediacheck), тестирование ОЗУ (memtest86). Спасательный режим активируется вводом "linux rescue" или нажатием F5. Через некоторое время после инициализации системы стартует программа установки Anaconda, внешний вид которой стилизован по CentOS.

На первом шаге предлагают ознакомиться с особенностями устанавливаемого релиза. Далее переходим к выбору языка программы установки, в списке доступны русский и украинский. Затем указываем раскладку клавиатуры. И переходим к разметке диска. Здесь нас встречает старый знакомый Disk Druid, который отвечал за эту операцию еще в том старом Red Hat. Для автоматической разметки диска, достаточно нажать кнопку "Удалить разделы Linux на выбранных дисках и создать разбиение по умолчанию". Обратите внимание будут удалены именно разделы, на которых установлен какой-нибуть Linux. Хотя для контроля незабудьте установить флажок "Просмотр и изменение разбиения раздела". Нажав на стрелки справа от надписи, можно получить список других вариантов. Но при автоматическом создании разделов будет использована технология LVM, на десктопе это не всегда нужно. Для ручного создания разделов выбираем "Создать собственное разбиение", есть и вариант использования всего диска. Список файловых систем несколько меньше предлагаемых в большинстве дистрибутивов: ext2 и 3, swap, VFAT, софтовый RAID и LVM. Как видите ReiserFS и XFS в списке нет, хотя если заранее подготовить такой раздел установить на них CentOS можно. Для нового раздела можно задать фиксированный размер или указать на заполнение нужного пространства. Разобраться с работой Disk Druid очень просто. Кнопка "Дополнительная настройка накопителей" позволяет добавить в список дисковые устройства с iSCSI систем хранения.

Анаконда самостоятельно находит все ОС имеющиеся на компьютере и заносит их в список загрузчика. По большому счету на этом этапе достаточно просто просмотреть заданные установки для GRUB. Но при необходимости можно изменить настройки или вообще отказаться от установки загрузчика. По умолчанию сетевой интерфейс настроен на автоматическое получение адреса посредством DCHP, поддержка протокола IPv6 активирована. При необходимости меняем эти установки на следующем шаге установки. Здесь же добавляем адрес шлюза и DNS сервера. Далее стандартные шаги - выбор часового пояса, установка пароля root и приступаем к выбору задач на которые будет ориентирован наш компьютер. По умолчанию предлагается рабочий стол GNOME, все остальные варианты - KDE, Server, Виртуализация, Кластеризация и прочие отключены.

group_packages

В последствии легко добавить нужный вариант при помощи конструкции yum groupinstall. Например:

# yum groupinstall "X Window System" "KDE (K Desktop Environment)" "Office/Productivity"

При необходимости здесь же можно подключить репозитарий Extras в котором находятся дополнительные пакеты. Чтобы настроить индивидуальный список программ установите переключатель внизу страницы в "Настроить сейчас". Например Compiz (его версия 0.0.13 релиз 2006 года) по умолчанию не устанавливается. Язык выбранный в начале установки, будет активирован автоматически. Поддержку остальных можно добавить в подменю Языки. Вот собственно и все. После проверки зависимостей собственно начинается установка, после которой потребуется перезагрузка системы.

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

firewall_setting

Далее мастер позволяет создать еще одну учетную запись для повседневной работы. На этом вроде бы простом этапе, возникла небольшая заминка. Ранее была выбрана русская расскладка клавиатуры, но вот оказалось, что переключатель расскладки не активировался. Пришлось отказаться и завести пользователя в уже рабочей системе. Переходим к настройкам звуковой карты и установке ПО с дополнительных CD. Нажимаем Готово и регистрируемся в системе. Причем в окне регистрации заработала английская расскладка.

Репозитарии

Грузится установленная система довольно быстро. Рабочее окружение в CentOS сюрпризов не преподносит, все находится на своих местах, локализация выполнена корректно.

desktop

Выбранная среда GNOME с приложениями по умолчанию, имеет все необходимое для повседневной работы. Думаю, без труда разберетесь с системой. Поддержки MP3 и других форматов изначально в системе нет, поэтому два слова о самом главном - работе с репозитариями.

В документе Available Repositories for CentOS, который можно найти на сайте проекта есть список дополнительных репозитариев совместимых с CentOS. Например CentOSPlus содержит более новые версии базовых компонент, в Extras находятся дополнительные пакеты расширяющие функциональность системы. Перед тем как попасть в Plus или Extras пакеты попадают в CentOS-Testing, и уже после тестирования будет принято решение об их судьбе. Кроме этого есть репозитарии третьих сторон, которые не поддерживаются официально разработчиками CentOS и используются на свой страх и риск. Но проблем обычно нет. Это RPMForge (rpmforge.net) в котором находится более 4000 пакетов для CentOS. Или два репозитрия содержащие пересобранные пакеты Fedora:

- для RHEL - Extra Packages for Enterprise Linux (EPEL, fedoraproject.org/wiki/EPEL);

- для CentOS - KBS-Extras (centos.karan.org).

Есть и другие. Во избежание проблем следует осторожно использовать сторонние репозитарии. Например подключать одновременно EPEL и KBS-Extras обычно не имеет смысла.

Для примера, добавим поддержку MP3, зашифрованных DVD и видеоформатов подключив EPEL. Вводим как root:

# rpm -Uvh http://download.fedora.redhat.com/pub/epel/5/i386/epel-release-5-3.noarch.rpm

После чего устанавливаем пакеты:

# yum -y install gstreamer-plugins-bad gstreamer-plugins-ugly libdvdcss xine-lib-extras-nonfree
Можно и XMMS.

# yum install xmms xmms-skins xmms-mp3

Кстати имеется польский дистрибутив Jazz Linux (jazz-linux.org), который является комбинацией CentOS и еще одного польского дистрибутива Aurox (www.aurox.org) базирующегося на Fedora. Главный акцент в нем сделан на поддержку мультимедиа, графики и приложений ориентированных на образование. В нем поддержка закрытых форматов реализована изначально.

CentOS вероятно подойдет не всем пользователям. Экстремалы постоянно экспериментирующие с новыми версиями программ, вряд ли оценят состав пакетов. Но если важна в первую очередь стабильность или совместимость с RHEL, то следует обратить внимание на этот простой в работе дистрибутив. Linux forever!

понедельник, 27 октября 2008 г.

Журнал Root@UA #1 (печатная версия)

ЖЖ [Root@UA]Media - Журнал Root@UA #1 (печатная версия)

Вышел новый номер журнала RootUA, в этот раз, уже в долгожданном печатном виде.
Читайте в этом номере:

Мы начинаем
Мир свободного программного обеспечения
События
FOSS Sea 2008
Первые шаги
Установка OpenSUSE 11
Текстовые редакторы. Часть 1.
Сеть.Часть 1.
Профи
Насторойка web-сервера на основе ubuntu
Интеграция Xcache в PHP5
Регулярные Backup при помощи Rsyncbackup на Debian
Установка и настройка OpenVZ на Ubuntu Server
Совет
Команды командира
Вопрос-ответ
Книжная полка
Люди/Мысли
Интервью с разработчиком pc-bsd и рус-bsd
Программирование
Программирование в Unix. Часть 1.
Принципы разработки программ с ОС *nix
Рабочий перерыв
Юмористический перерыв

---------------------------------------

Оформить редакционную подписку на 2009 год можно на сайте по адресу http://www.root.od.ua/podpiska.html

Заказать печатный или электронный номер журнала можно по адресу http://www.root.od.ua/zakazat-nomer.html

Узнать, где можно купить журнал в Вашем городе можно по адресу http://www.root.od.ua/gde-kupit.html

В связи с выходом печатного журнала RootUA мы создаём сеть по его распространению в Украине. Всех, кто готов помочь в распространении журнала у себя в регионе, мы будем рады принять в нашу команду.
Предложения и дружеские советы с благодарностью примем по e-mail: podpiska@root-ua.com

Восстановление данных с Windows-систем с использованием Linux

Юникс и другие » Blog Archive » Восстановление данных с Windows-систем с использованием Linux

У всех бывали случаи, когда Windows отказывается грузиться по той или иной причине. Проблема может заключаться в программном или аппаратном обеспечении компьютера и, зачастую, может показаться безнадежной. Однако во многих случаях вам может помочь Linux, имеющий необходимый комплект утилит для восстановления данных, которые могли быть безвозвратно утеряны.

Другой вариант использования Linux - это создание образа отказавшего HDD для последующего его анализа. Конечно же, эти образы не идеальны (для подобных работ используется специально оборудование), но могут помочь разобраться с причинами выхода из строя.
Предполагается, что все восстанавливаемые данные можно скопировать на машину с Linux либо имеется USB-диск достаточного объема. В любом случае для попытки успешного восстановления данных необходимо иметь объем свободного места, равный объему диска для восстановления и плюсом, по меньшей мере, 2 гигабайта. Чем больше у вас свободного места, тем легче будет работать с данными. В обратном случае вероятность успешного заверешения процесса снижается.
Если ситуация становится совсем критичной, то рекомендую вам попробовать сторонние утилиты, такие как Coroner's Toolkit, но им необходимо гораздо больше свободного места для успешной работы. Как правило, необходимый объем места для подобных программ равняется удвоенному размеру диска, который необходимо восстановить.

Я предполагаю, что читатель свободно себя чувствует в командной строке Linux и может выполнять базовые операции по работе с файловой системой (т.е знаком с такими командами как, например, cp, mv, rm, ls и т.п.) В данном случае командная строка является более предпочтительным интерфейсом, нежели GUI. Когда на карту поставлены данные, лучше пользоваться узкоспециализированными утилитами для выполнения всех действий и иметь полный контроль над процессом.

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

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

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

Создание образа
Первым шагом при восстановлении данных обычно является создание образа восстанавливаемых разделов и сохранение их на другом носителе. Например, на другом винчестере, USB-диске или сетевой папке.

Созданием образа мы преследуем две цели: первое - мы получаем право на ошибку и возможность вернуться к старту процесса в случае неверных действий. И второе - мы перестаем проводить операции ввода/вывода с поврежденным устройством, что необходимо для обеспечения его дальнейшего функционирования.

Самое простое - это создать собственный образ для каждого восстанавливаемого раздела.

Жесткие диски в Linux обычно находятся в каталоге /dev/ и имеют некоторые правила именования, которые нужно запомнить. IDE диски начинаются с букв "hd". Третья буква означает "статус" диска. a (hda) - это primary master, b (hdb) - primary slave, c (hdc) - secondary master и d (hdd) - secondary slave. Все остальные устройства хранения данных (к ним относятся USB, SATA и SCSI-диски) подключаются через SCSI-интерфейс и начинаются с букв "sd" В ядре версии 2.4 была возможность подсоединить IDE-привод через SCSI-интерфейс, но нам это не понадобится.

После подготовки всех "кандидатов" на восстановление, их неплохо бы проверить при помощи команды sfdisk -l Это лучше, чем fdisk, так как посылаемые команды более просты и выполняются в неинтерактивном режиме. Команда требует привилегий суперпользователя.

bash# /sbin/sfdisk -l /dev/hda

Вывод команды содержит информацию о винчестере (количество головок, секторов и цилиндров) и список доступных разделов с краткой информацией о них.
Разделы должны начинаться и заканчиваться на границе цилиндров. К сожалению, старые версии Windows имеют проблемы с дисками, у которых несколько головок и большое количество цилиндров, в результате чего некоторые версии BIOS передавали неверную информацию о реальном положении дел. Поскольку Linux считывает информацию о диске напрямую с винчестера, а windows использует информацию, предоставленную BIOS, то эти данные могут иметь отличаться для различных ОС.

Вот вывод этой команды для винчестера с установленным Linux:

Disk /dev/hda: 9729 cylinders, 255 heads, 63 sectors/track
Units = cylinders of 8225280 bytes, blocks of 1024 bytes,
counting from 0

Device Boot Start End #cyls #blocks Id System
/dev/hda1 * 0+ 12 13- 104391 83 Linux
/dev/hda2 13 9728 9716 78043770 8e Linux LVM
/dev/hda3 0 - 0 0 0 Empty
/dev/hda4 0 - 0 0 0 Empty

А вот для винчестера, на котором Linux и Windows находятся в режиме DualBoot:

Disk /dev/sda: 19457 cylinders, 255 heads, 63 sectors/track
Units = cylinders of 8225280 bytes, blocks of 1024 bytes,
counting from 0
Device Boot Start End #cyls #blocks Id System
/dev/sda1 0+ 891 892- 7164958+ 27 Unknown
/dev/sda2 * 892 10196 9305 74742412+ 6 FAT16
/dev/sda3 10197 10209 13 104422+ 83 Linux
/dev/sda4 10210 19456 9247 74276527+ 5 Extended
/dev/sda5 10210+ 19456 9247- 74276496 8e Linux LVM

Раздел с меткой FAT16 в приведенном примере на самом деле отформатирован в NTFS. Не стоит слишком доверять меткам на разделах. Очень часто windows-разделы имеют метки FAT16, W95 FAT32, NTFS или похожие на них.

Основная команда для создания образа - это:

bash# dd if=[device] of=[imagename] conv=noerror

dd производит чтение из входного файла (if - input file), пропускает данные через указанные фильтры и записывает в конечный файл (of - output file). Если опция of не указана, то вывод производится в стандартный поток. Опция conv=noerror говорит о том, что dd следует продолжить считывание несмотря на ошибки чтения, которые, в большинстве случаев, присутствуют на поврежденных дисках.

Многие руководства по восстановлению данных предупреждают: не делайте образ на восстанавливаемом разделе!!! Мне кажется очевидным хранить образ на другом разделе (а лучше носителе), но подобные ситуации возникают сплошь и рядом, пожтому я счел нужным упомянуть о них.

простейшая команда для переноса образа на примонтированный раздел выглядит так:

bash# dd conv=noerror if=/dev/sda1 of=/root/recovery.img

Эта команда скопирует содержимое раздела /dev/sda1 в файл /root/recovery.img Этот файл может быть примонтирован как стандартное устройство loopback.

Так как dd может писать в стандартный поток, мы можем использовать пайп для передачи информации на удаленную систему, посредством ssh. Это делается так:

bash# dd conv=noerror if=/dev/sda1 | ssh user@host 'cat >
recover.img'

Для уменьшения объема передаваемой информации можно воспользоваться архиватором:

bash# dd conv=noerror if=/dev/sda1 | gzip | ssh user@host
'gunzip > recover.img'

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

Монтирование образа
После создания образа необходимо сделать две папки (для точки монтирования и для восстановления):

bash# mkdir recover_src recover_dst

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

bash# mount -t [type] -o loop /path/to/image recover_src

К примеру, если ваш образ recovery.img снят с NTFS-раздела, то замените [type] на ntfs. Все FAT-разделы монтируются как vfat.

Не все дистрибутивы Linux имеют встроенную поддержку NTFS. Например, у Knoppix она есть, у Fedora нет. Вы можете найти драйвера для поддержки NTFS на сайте сторонних производителей или пересобрать ваше ядро с поддержкой этой файловой системы. (довольно нетривиальная задача для новичка в linux - прим. переводчика) Если вы не можете найти драйвера, используйте Knoppix.

В linux обеспечена поддержка лишь чтения с NTFS-разделов. Запись на них из linux считается небезопасной и может привести к повреждению или полной потере данных. Тем не менее имеются решения для записи на NTFS из linux. Однако их обзор вызодит за рамки этой статьи.

Восстановление данных в безопасное место
Как только образ примонтирован, вы можете использовать cp или подобную команду для копирования ваших данных в безопасное место. Также вы можете записать их на CDROM или перенести на USB-диск.

Или вы можете перенести данные на flash-диск, примонтировать его и продолжать процесс восстановления уже используя его в качестве носителя.

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

Несколько слов о mkisofs и cdrecord
Часто необходимо записать восстановленную информацию на CDROM. Из командной строки это делают с помощью двух утилит: mkisofs и cdrecord На компакт-дисках используется файловая система, определенная стандартом ISO 9660. Это ФС со многими возможностями, но и с довольно большими ограничениями (например на длину имени файла, имена файлов нечувствительны к регистру, не сохраняет права доступа к файлам) Для того, чтобы немного снизить имеющиеся ограничения были разработаны два расширения для нее: это Joilet, используемое в Windows и RockRidge, используемое в UNIX.

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

Следующая команда создает iso-образ recovery.iso из содержимого директории recovery_dst:

bash# mkisofs -JR -o recovery.iso recovery_dst

Однако полученный образ еще и необходимо записать на диск. Это делается при помощи cdrecord:

bash# cdrecord dev=/dev/cdrom –data recovery.iso

Для более подробной информации о процессе копирования можно использовать ключ -v

После проверки записанного диска смонтируйте его и проверьте его читаемость. Я заметил, что некоторые CD-R плохо читаются после записи на высоких скоростях. Поэтому можно искусственно ограничить скорость записи диска:

bash# cdrecord dev=/dev/cdrom speed=4 -v –data recovery.iso

Последние средства
Иногда файловые системы могут быть слишком повреждены или, например, отформатированы. В этом случае штатными средствами решить проблему не удастся. Но есть некоторые приложения, которые способны помочь в решении этой проблемы. Правда понадобится немного больше терпения, времени и дискового пространства.

Coroner's Toolkit (TCT) - так называется набор приложений для работы с теми файловыми системами, которые настолько повреждены (например после "горячего" выключения), что не видятся штатными средствами ОС. Этот набор можно найти на http://www.porcupine.org/forensics/tct.html

В Coroner's Toolkit входит несколько утилит для "экстремального" восстановления данных. Одна из них, lazarus, мощный кроссплатформенный инструмент. Она читает структуры данных напрямую с поверхности диска и пытается восстановить файловую систему по полученным результатам. Иногда она находит фрагменты, которые будут использованы намного позже, а в некоторых случаях, если не было перезаписи, находятся фрагменты удаленных файлов, которые в большинстве случаев могут быть восстановлены.

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

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

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

Оригинальный текст

Многоязычная самообучающаяся система автоматизированного перевода

http://eugene-online.blogspot.com/2008/03/blog-post.html
Евгений Бражко

Буквально сегодня мне понадобилось перевести несколько небольших текстов с украинского языка на русский. Оказывается, ситуация с переводчиками текстов в Linux такая же, как и с системами распознавания - выбора, по большому счету, на данный момент нет никакого. Единственный более-менее вменяемый вариант (которым я и воспользовался) - это "Переводчица" - многоязычная самообучающаяся система автоматизированного перевода. На сайте проекта доступны два вида перевода - перевод текста и перевод файла. В обоих случаях размер переводимого фрагмента/текста ограничен 100 Кб. По сравнению с другими online-переводчиками, где ограничение составляет 500-1000 символов, 100 Кб - очень даже неплохо. Поддерживаемые типы файлов: rtf, xml, html, а также все форматы OpenOffice.org. Поддерживаемые языки для перевода (имеющиеся в наличии): русский, украинский, английский. Но словари можно сделать для любого языка.

Систему можно также установить на локальный компьютер. Со страницы загрузки доступны исходные тексты программы и словарей, а также собранные пакеты для ALT Linux, ASP Linux (Fedora Core), Gentoo Linux и MS Windows. Для Ubuntu/Debian пакетов к сожалению нет.

Следует отметить, что для программы имеется графический интерфейс на wxWidgets.

Перед установкой переводчика необходимо установить несколько пакетов:

 $ sudo apt-get install libarchive-zip-perl libconfig-general-perl libhtml-simpleparse-perl libtext-csv-perl
$ sudo apt-get install ncftp
и модули Perl, которых в репозитории нет:
 $ sudo cpan RTF::Tokenizer
$ sudo cpan Wx
Затем скачиваем пакет Lingua-Pere-0.2.0.tar.gz, распаковываем, собираем и устанавливаем его:
$ tar xvfz Lingua-Pere-0.2.0.tar.gz
$ cd Lingua-Pere-0.2.0
$ perl Makefile.PL
$ make
$ sudo make install
То же самое проделываем с пакетом wxpere-0.2.0.tar.gz:
$ tar xvfz wxpere-0.2.0.tar.gz
$ cd wxpere-0.2.0
$ perl Makefile.PL
$ make
$ sudo make install
Теперь очередь словарей. Словари берем из http://pere.org.ua/dwn/src/dic/ (dmp или src; пакеты src меньше в 3 раза, но их сборка займёт больше времени; у меня русско-украинский словарь собирался из исходников 3,5 часа; за это время я успел скачать архивы с дампами и восстановить словари из них). Для каждого словаря после распаковки выполняем команду вида:
$ ./install.sh ~/dic/en-us_ru-ru_dzer-tyzh en-us_ru-ru_dzer-tyzh.dmp
На этом установка окончена. Теперь можно запустить wxpere:

Если переводить тексты необходимо время от времени, то нет смысла устанавливать "Переводчицу" - намного проще воспользоваться online-переводом.

Установка и настройка Virtualbox

Leolik's blog: Установка и настройка Virtualbox

Часто, мне по работе, необходимо тестировать различные вебпроекты на совместимость с различными браузерами. Если с Firefox и Opera все понятно, то для проверки в IE6 и IE7 мне приходится обращаться к ЗлоОС. Ясно дело ставить ее, как вторую систему, на свой комп я не собираюсь, для этого я воспользовался помощью виртуальных машин. После проверки различных виртуалок, остановился на VirtualBox, так как, по моему мнению, она довольно шустрая и справляется со своими обязанностями на ура.

Приступим к установке.

1. Скачиваем последнюю версию VirtualBox (в моем случае это была версия 1.5.4). Последние версии всегда можете забирать отсюда.

$


1.1. Так же можете установить VirtualBox из репозитория, но учтите, обычно там лежит довольно старая версия:
$
sudo apt-get install virtualbox-ose

2. Устанавливаем скачанную программу
$ $

cd <путь где лежит скачанный файл>
sudo dpkg -i virtualbox_1.5.4-27034_Ubuntu_gutsy_i386.deb

или вместо dpkg, можно использовать gdebi
$
sudo gdebi virtualbox_1.5.4-27034_Ubuntu_gutsy_i386.deb

3. Добавляем себя в группу vboxusers
$
sudo adduser <ваш login> vboxusers

4. Запускаем VirtualBox (Приложения -> Системные -> Innotek VirtualBox)
Во время первого запуска появится Регистрационная форма (Innotek это нужно только для статистики). Можете ее заполнить, а можете и не заполнять :) , но тогда она у вас будет появляться при запуске виртуальной машины.

5. Создаем новую виртуальную машину (нажимаем Создать).
Тут, думаю, никаких трудностей у вас возникнуть не должно. Введете название виртуальной машины, выберите ТипОС (например: Windows XP). Оперативной памяти выставьте по своему желанию. При выборе загрузочного жесткого диска выберите Создать. Размер образа диска, лучше поставить: Динамически расширяющийся образ, это избавит вас от зря занятого свободного места, так как такой образ будет весить столько, сколько занято места внутри образа (например вы зададите для виртуальной машины 10Gb памяти, то она не будет занимать эти 10GB на жестком диске, так как будет весить примерно столько сколько весит ваша виртуальная система с установленными приложениями, и расширяться по мере установки новых приложений в виртуальной ОС)

6. Настроим свойства новой виртуальной машины (нажимаем: Свойства).
Здесь вы можете изменить настройки, которые применяли при создании виртуальной машины (guest), а также изменить другие. Здесь же можно подключить нужные устройства основной машины (host). Что подключить, зависит только от вас.
Тут же можно настроить Общие папки для обоих систем. При добавлении новой папки вы выбираете папку у вас на host-машине, которая в последствии будет отображаться в сети в guest-машине.
Все свойства я описывать не буду, так как мне они не особо нужны, с этим можете поэксперементировать сами.
6.1. Нас интересует настройка 'CD/DVD-ROM'. Если вы будете ставить операционную систему с сд или двд диска, то выберите 'Физический CD/DVD привод' и вставьте диск с ОС в привод, если собираетесь ставить с образа .iso, то соответственно активируете пункт 'Файл ISO образа' и выберите iso-файл с ОС.
Внимание! если вы, при настройке свойств виртуальной машины, включили поддержку 'Устройства USB', то при старте системы - может выскочить ошибка связанная с USB устройствами. Для решения этой проблемы редактируем файл /etc/fstab:
$
sudo nano /etc/fstab

и вставляем в конец файла строку:
none /proc/bus/usb usbfs devgid=46,devmode=664 0 0
7. Запускаем виртуальную машину (нажимаем: Старт)
Первым делом вы увидите предупреждение о том, что, передача управления клавиатурой между host и guest системами, осуществляется с помощью спецклавиши (по умолчанию: Правый Ctrl). Эту клавишу можно сменить в настройках программы.
Внимание! если при запуске у вас вылетает ошибка связанная с правами, проделайте следующее:
$
sudo chmod 666 /dev/vboxdrv

7.1. Дальше вас ждет стандартная установка ОС, так если бы вы делали ее на обычном компе.

8. После установки и входа в систему, первым делом следует установить virtualbox дополнения, которые очень сильно облегчат нам жизнь. Устройства -> Установить Дополнения гостевой ОС.
После установки и перезагрузки guest-системы нам больше нет необходимости использовать спецклавишу 'Правый Ctrl', так как теперь окно получает фокус при наведении курсора мыши в область рабочего стола guest-системы. Плюс ко всему для нас открывается еще одна фича - режим Seamless. С помощью этого режима, guest-система (в моем случае WinXP) интегрируется в host-систему Ubuntu. Это очень прикольная вещь, теперь вы можете работать с окнами винды, так же, как вы работаете с окнами Gnome. Попробуйте, оно того стоит.
Режим Seamless...
. В ролике конечно не ахти видно, но все же...

9. Приступим к настройки сети.
Чаще всего, после создания виртуальной машины, VirtualBox автоматом создает в guest-системе сетевое соединение NAT, чтобы у guest-системы был доступ к интернету.
Дальше описаны мои действия по настройки сети, так, чтобы виртуальная машина была видна, как отдельный комп, в моей домашней сетке.
В кратце опишу мою конфигурацию сети:
Есть два сетевых интерфейса eth0 и eth1.
eth0 подключен к моей домашней сетке (в этой сети пара компов). на eth0 установлен dhcp сервер. eth0 имеет статический адрес 192.168.0.1 .
eth1 подключен к внешней локальной сети моего района, по которой я получаю интернет через впн подключение.
Все свои действия делал по мануалу, который есть в Справке VirtualBox (раздел 6.5.1.1).
9.1. Установил необходимый софт для создания моста:
$
sudo apt-get install bridge-utils

9.2. Отредактировал файл /etc/network/interfaces:
$
sudo nano /etc/network/interfaces

добавив туда описание моста br0 :
auto br0
iface br0 inet static
address 192.168.0.1
netmask 255.255.255.0
bridge_ports eth0
и не забыв закомментировать (или удалить) данные про eth0 интерфейс.
9.3. Перезагрузил сеть (чтобы применились изменения):
$
sudo /etc/init.d/networking restart

9.4. Создал интерфейс vbox0, который будет использовать виртуальная машина:
$
sudo VBoxAddIF vbox0 (user) br0

где (user) - это имя user'а который запускает VirtualBox, в моем случае этой был мой логин.
9.5. Запустил VirtualBox и в Свойствах guest-системы зашел в раздел 'Сеть', отключил, созданный по умолчанию, NAT интерфейс и создал новый интерфейс с такими параметрами:
Присоединен к: Хост-интерфейс
MAC-адрес: сгенерируйте
Имя интерфейса: vbox0
9.6. Поправил настройки своих dhcp-сервера и firehol-файервола, заменив везде etho на br0.
9.7. Стартовал guest-систему.
Вот и все, сетевуха в виртуалке автоматом получила IP с dhcp-сервера, и теперь WinXP guest-машина - стала полноправным членом моей домашней сети.

P.S. Во время написания этой статьи, на сайте VirtualBox лежала программа версии 1.5.6. Но в ней был обнаружен баг с настройкой сети, поэтому я использовал, стабильно работающую версию, 1.5.4.

воскресенье, 26 октября 2008 г.

Знакомство с Android. Часть 4: Использование GridView

Somethings: Знакомство с Android. Часть 4: Использование GridView

Итак, в нашем приложении осталось всего ничего: реализовать собственно алгоритм игры Life и отобразить его в GridView. Этим-то мы сейчас и займёмся.

Класс, реализующий логику Life

Добавим в проект новый класс, назовем его LifeModel. Тут у нас будет реализована вся логика Life

package com.android.life;  import java.util.Random; public class LifeModel {   // состояния клетки   private static final Byte CELL_ALIVE = 1; // клетка жива   private static final Byte CELL_DEAD = 0; // клетки нет      // константы для количества соседей   private static final Byte NEIGHBOURS_MIN = 2; // минимальное число соседей для живой клетки   private static final Byte NEIGHBOURS_MAX = 3; // максимальное число соседей для живой клетки   private static final Byte NEIGHBOURS_BORN = 3; // необходимое число соседей для рождения клетки      private static int mCols; // количество столбцов на карте   private static int mRows; // количество строк на карте   private Byte[][] mCells; // расположение очередного поколения на карте.               //Каждая ячейка может содержать либо CELL_ACTIVE, либо CELL_DEAD      /**   * Конструктор   */   public LifeModel(int rows, int cols, int cellsNumber)   {     mCols = cols;     mRows = rows;     mCells = new Byte[mRows][mCols];          initValues(cellsNumber);   }      /**   * Инициализация первого поколения случайным образом   * @param cellsNumber количество клеток в первом поколении   */   private void initValues(int cellsNumber)   {     for (int i = 0; i < mRows; ++i)       for (int j = 0; j < mCols; ++j)         mCells[i][j] = CELL_DEAD;          Random rnd = new Random(System.currentTimeMillis());     for (int i = 0; i < cellsNumber; ++i)     {       int cc;       int cr;       do       {         cc = rnd.nextInt(mCols);         cr = rnd.nextInt(mRows);       }       while (isCellAlive(cr, cc));       mCells[cr][cc] = CELL_ALIVE;                   }   }      /**   * Переход к следующему поколению   */   public void next()   {     Byte[][] tmp = new Byte[mRows][mCols];          // цикл по всем клеткам     for (int i = 0; i < mRows; ++i)       for (int j = 0; j < mCols; ++j)       {         // вычисляем количество соседей для каждой клетки         int n =           itemAt(i-1, j-1) + itemAt(i-1, j) + itemAt(i-1, j+1) +           itemAt(i, j-1) + itemAt(i, j+1) +           itemAt(i+1, j-1) + itemAt(i+1, j) + itemAt(i+1, j+1);                  tmp[i][j] = mCells[i][j];         if (isCellAlive(i, j))         {           // если клетка жива, а соседей у нее недостаточно или слишком много, клетка умирает           if (n < NEIGHBOURS_MIN || n > NEIGHBOURS_MAX)             tmp[i][j] = CELL_DEAD;         }         else         {           // если у пустой клетки ровно столько соседей, сколько нужно, она оживает           if (n == NEIGHBOURS_BORN)             tmp[i][j] = CELL_ALIVE;                        }       }     mCells = tmp;   }      /**   * @return Размер поля   */   public int getCount()   {     return mCols * mRows;   }      /**   * @param row Номер строки   * @param col Номер столбца   * @return Значение ячейки, находящейся в указанной строке и указанном столбце   */   private Byte itemAt(int row, int col)   {     if (row < 0 || row >= mRows || col < 0 || col >= mCols)       return 0;            return mCells[row][col];   }      /**   * @param row Номер строки   * @param col Номер столбца   * @return Жива ли клетка, находящаяся в указанной строке и указанном столбце   */   public Boolean isCellAlive(int row, int col)   {     return itemAt(row, col) == CELL_ALIVE;   }    /**   * @param position Позиция (для клетки [row, col], вычисляется как row * mCols + col)   * @return Жива ли клетка, находящаяся в указанной позиции   */   public Boolean isCellAlive(int position)   {     int r = position / mCols;     int c = position % mCols;      return isCellAlive(r,c);   } } 

GridView. Отображение первого поколения клеток

Модифицируем разметку run.xml так, чтобы она выглядела следующим образом:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:orientation="vertical"   android:layout_width="fill_parent"   android:layout_height="fill_parent">   <GridView     android:id="@+id/LifeGrid"     android:layout_width="fill_parent"     android:layout_height="wrap_content"          android:padding="1dp"     android:verticalSpacing="1dp"     android:horizontalSpacing="1dp"     android:columnWidth="10dp"      android:gravity="center"   /> 

  <Button     android:id="@+id/CloseButton"     android:text="@string/close"     android:textStyle="bold"     android:layout_width="wrap_content"     android:layout_height="wrap_content"   />

</LinearLayout>

Теперь нам надо отобразить в этом GridView данные. Думаю, вполне логичным для данной задачи было бы отображение клеток в виде графических файлов. Создаем два графических файлика, на одном изображаем черный квадратик, на другом - зелёный. Первый назовём empty.png и он будет обозначать пустую клетку, второй - cell.png, и он будет изображать живую клетку. Оба файлика положим в папку /res/drawable

Нам нужно знать, что именно отображать в гриде. Для этого нужно создать для грида поставщик данных (Adapter). Есть стандартные классы для адаптеров (ArrayAdapter и др.), но нам будет удобнее написать свой, унаследованный от BaseAdapter. Дабы не плодить файлов (да и не нужен он больше никому), поместим его внутрь класса RunScreen. А напишем там следующее:

public class LifeAdapter extends BaseAdapter {   private Context mContext;   private LifeModel mLifeModel;    public LifeAdapter(Context context, int cols, int rows, int cells)   {     mContext = context;     mLifeModel = new LifeModel(rows, cols, cells);   }    public void next()   {     mLifeModel.next();   }    /**   * Возвращает количество элементов в GridView   */   @Override   public int getCount()   {     return mLifeModel.getCount();   }    /**   * Возвращает объект, хранящийся под номером position   */   @Override   public Object getItem(int position)   {     return mLifeModel.isCellAlive(position);   }    /**   * Возвращает идентификатор элемента, хранящегося в под номером position   */   @Override   public long getItemId(int position)   {     return position;   }    /**   * Возвращает элемент управления, который будет выведен под номером position   */   @Override   public View getView(int position, View convertView, ViewGroup parent)   {     ImageView view; // выводиться у нас будет картинка          if (convertView == null)     {       view = new ImageView(mContext);        // задаем атрибуты       view.setLayoutParams(new GridView.LayoutParams(10, 10));       view.setAdjustViewBounds(false);       view.setScaleType(ImageView.ScaleType.CENTER_CROP);       view.setPadding(1, 1, 1, 1);     }     else     {       view = (ImageView)convertView;     }          // выводим черный квадратик, если клетка пустая, и зеленый, если она жива     view.setImageResource(mLifeModel.isCellAlive(position) ? R.drawable.cell : R.drawable.empty);          return view;   } } 

Теперь добавим в класс поля:

private GridView mLifeGrid; private LifeAdapter mAdapter; 
и модифицируем onCreate:

public void onCreate(Bundle savedInstanceState) {   super.onCreate(savedInstanceState);   setContentView(R.layout.run);      mCloseButton = (Button) findViewById(R.id.CloseButton);   mCloseButton.setOnClickListener(this);    Bundle extras = getIntent().getExtras();   int cols = extras.getInt(EXT_COLS);   int rows = extras.getInt(EXT_ROWS);   int cells = extras.getInt(EXT_CELLS); 

  mAdapter = new LifeAdapter(this, cols, rows, cells);      mLifeGrid = (GridView)findViewById(R.id.LifeGrid);   mLifeGrid.setAdapter(mAdapter);   mLifeGrid.setNumColumns(cols);   mLifeGrid.setEnabled(false);   mLifeGrid.setStretchMode(0);

}

Запускаем и видим:

Life для Android: первое поколение

Отображение последующих поколений

Вот мы и добрались почти до самого конца. Осталось отобразить ход игры. Тут стоит воспользоваться таймером. Таймер будет каждую секунду вызывать обработчик, в котором данные в адаптере будут пересчитываться. Сначала добавим в RunScreen поле:

private Timer mTimer; 
а в onCreate - такой код:
mTimer = new Timer("LifeTimer"); mTimer.scheduleAtFixedRate(new SendMessageTask(), 0, 500); 

SendMessageTask - это класс-обработчик таймера. Мы определим его прямо в классе RunScreen следующим образом:

public class SendMessageTask extends TimerTask {   /**   * @see java.util.TimerTask#run()   */   @Override   public void run()   {     Message m = new Message();     RunScreen.this.updateGridHandler.sendMessage(m);   } } 

В RunScreen же добавим такую конструкцию:

Handler updateGridHandler = new Handler() {   public void handleMessage(Message msg)   {     mAdapter.next();     mLifeGrid.setAdapter(mAdapter);      super.handleMessage(msg);   } }; 

Таким образом, по таймауту мы посылаем нашей же форме сообщение, что пора обновиться, и в только обработчике этого сообщения обновляемся. Спрашивается, почему нельзя передать mLifeGrid и mAdapter в класс-обработчик таймера и обновить их там? Ответ - таймер работает в другом потоке, а андроид разрешает модифицировать элементы управления только в том потоке, в котором они были созданы.

Теперь, запустив Life, можно увидеть, например, следующее

Life для Android

Ссылки

Заключение

Итак, мы написали первое приложение для Android, которое уже и не совсем "Hello, World". Лично мне писать для Android понравилось куда больше, чем классические мидлеты. Остался, правда, ряд претензий к Eclipse, но, возможно, это от недостатка опыта.

Спасибо, если кто осилил. Замечания приветствуются.

Исходники примера

Автор: darja на 14:11

Знакомство с Android. Часть 3: Использование диалогов

Somethings: Знакомство с Android. Часть 3: Использование диалогов

В этой части мы сделаем проверку вводимых параметров по следующим правилам:

  • Число столбцов должно быть не меньше 5 и не больше 25.
  • Число строк должно быть не меньше 5 и не больше 35.
  • Начальное количество клеток должно быть не больше, чем ячеек на поле.

Если какое-то из этих условий не выполняется, будем выводить соответствующее предупреждение

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

Простой диалог

Сначала добавим в класс StartScreen.java следующие константы:
// код результата проверки private static final int ALERT_NONE = 0; // параметры введены верно private static final int ALERT_COLUMNS = 1; // некорректное число столбцов private static final int ALERT_ROWS = 2; // некорректное число строк private static final int ALERT_CELLS = 3; // некорректное начальное число клеток  // границы допустимых значений числа столбцов private static final int COLUMNS_MIN = 5; private static final int COLUMNS_MAX = 25;  // границы допустимых значений числа строк private static final int ROWS_MIN = 5; private static final int ROWS_MAX = 35; 

Теперь добавляем метод, осуществляющий проверку введенных параметров:

private int checkInputParameters(int cols, int rows, int cells) {   if (cols < COLUMNS_MIN || cols > COLUMNS_MAX)   {     return ALERT_COLUMNS;   }      if (rows < ROWS_MIN || rows > ROWS_MAX)   {     return ALERT_ROWS;   }      if (cells > rows * cols)   {     return ALERT_CELLS;   }      return ALERT_NONE; } 

Метод onClick теперь должен работать немного по-другому: сначала проверять введенные параметры, и, если проверка прошла (ALERT_NONE), открывать окно RunScreen, иначе же показывать предупреждение. Итак, onClick будет выглядеть так:

public void onClick(View v) {   EditText rowsEditor = (EditText)findViewById(R.id.RowsEditor);   EditText colsEditor = (EditText)findViewById(R.id.ColumnsEditor);   EditText cellsEditor = (EditText)findViewById(R.id.CellsEditor);      int cols = Integer.parseInt(colsEditor.getText().toString());   int rows = Integer.parseInt(rowsEditor.getText().toString());   int cells = Integer.parseInt(cellsEditor.getText().toString()); 

  int alertCode = checkInputParameters(cols, rows, cells);   if (alertCode != ALERT_NONE)   {     showDialog(alertCode);     return;   }

  Intent intent = new Intent();   intent.setClass(this, RunScreen.class);      intent.putExtra(RunScreen.EXT_COLS, cols);   intent.putExtra(RunScreen.EXT_ROWS, rows);   intent.putExtra(RunScreen.EXT_CELLS, cells);   startActivity(intent);   finish(); }

Метод showDialog(id) класса Activity пытается открыть диалог. При этом вызывается метод onCreateDialog, возвращающий объект класса Dialog. Так что нужно перекрыть метод onCreateDialog и сконструировать тот диалог, который нам нужен. Ну у нас тут всё просто, диалоги будут отличаться только выводимым сообщением, так что можно сделать следующее:

@Override protected Dialog onCreateDialog(int id) {   DialogInterface.OnClickListener doNothing = new DialogInterface.OnClickListener()   {     public void onClick(DialogInterface dialog, int whichButton)     {     }   };   int alertMessage;      switch (id)   {     case ALERT_COLUMNS:       alertMessage = R.string.alert_columns;       break;     case ALERT_ROWS:       alertMessage = R.string.alert_rows;       break;     case ALERT_CELLS:       alertMessage = R.string.alert_cells;       break;     default:       return null;   }      return new AlertDialog.Builder(this)     .setMessage(alertMessage)     .setNeutralButton(R.string.ok, doNothing)     .create(); } 

В strings.xml при этом нужно добавить следующие значения:

<string name="alert_columns">Incorrect columns number: should be from 5 to 25</string> <string name="alert_rows">Incorrect rows number: should be from 5 to 35</string> <string name="alert_cells">Number of cells is greater then the size of grid</string> <string name="ok">OK</string> 

Итак, в методе onCreateDialog мы решили, какое сообщение (alertMessage) будем выводить, создали диалог с помощью AlertDialog.Builder, вывели туда сообщение, поставили единственную кнопку OK и привязали к ней обработчик doNothing, который ничего не делает (нам, в принципе, делать ничего и не надо). Аналогичным образом можно добавить иконку формы, добавить ещё кнопок и т.д.

Подробнее про то, как строятся диалоги, можно посмотреть в адроидовских сэмплах - там на самом деле все достаточно понятно и просто.

Теперь при вводе некорректных данных мы видим вот это:

Простейший диалог Android

Диалог для закрытия приложения

Добавим на форму RunScreen кнопку Close. Для этого напишем такую разметку в run.xml:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"   android:orientation="vertical"   android:layout_width="fill_parent"   android:layout_height="fill_parent">   <TextView     android:id="@+id/Message"     android:layout_width="fill_parent"     android:layout_height="wrap_content"     android:paddingBottom="10dip"   />   <Button     android:id="@+id/CloseButton"     android:text="@string/close"     android:textStyle="bold"     android:layout_width="wrap_content"     android:layout_height="wrap_content"   /> </LinearLayout> 

В strings.xml добавим следующие значения:

<string name="yes">yes</string> <string name="no">no</string> <string name="close">Close</string> <string name="submit_close">Are you sure you want to close this wonderful application?</string> 

Теперь вносим изменения в класс RunScreen:

public class RunScreen extends Activity implements OnClickListener { 

  private static final int ALERT_CLOSE = 1;   public static final String EXT_COLS = "cols";   public static final String EXT_ROWS = "rows";   public static final String EXT_CELLS = "cells";   

  Button mCloseButton;

  /** Called when the activity is first created. */   @Override   public void onCreate(Bundle savedInstanceState)   {     super.onCreate(savedInstanceState);     setContentView(R.layout.run);

    mCloseButton = (Button) findViewById(R.id.CloseButton);     mCloseButton.setOnClickListener(this);

    Bundle extras = getIntent().getExtras();     int cols = extras.getInt(EXT_COLS);     int rows = extras.getInt(EXT_ROWS);     int cells = extras.getInt(EXT_CELLS);     TextView message = (TextView)findViewById(R.id.Message);     message.setText("Rows: " + rows + "\nColumns: " + cols + "\nCells: " + cells);   }

  /*   * @see android.view.View.OnClickListener#onClick(android.view.View)   */   @Override   public void onClick(View arg0)   {     showDialog(ALERT_CLOSE);   }

  @Override   protected Dialog onCreateDialog(int id)   {     switch (id)     {       case ALERT_CLOSE:         return new AlertDialog.Builder(this)         .setMessage(R.string.submit_close)         // кнопка "Yes", при нажатии на которую приложение закроется         .setPositiveButton(R.string.yes, new DialogInterface.OnClickListener()           {             public void onClick(DialogInterface dialog, int whichButton)             {               finish();             }           })         // кнопка "No", при нажатии на которую ничего не произойдет         .setNegativeButton(R.string.no, new DialogInterface.OnClickListener()           {             public void onClick(DialogInterface dialog, int whichButton)             {                            }           })         .create();       default:         break;     }     return null;   }

}

Объяснять тут особо нечего, и так все понятно. Теперь, при нажатии на кнопку Close, мы видим следующее:

Диалог Android

При нажатии на yes приложение закроется, на no - продолжит работу.

Ссылки

Исходники примера