В данной статье я покажу как можно собрать apk файл в Ubuntu используя лишь
утилиты командной строки.
Обычно для создания приложений для Adroid используется Android Studio. Но для сборки небольших программ можно обойтись командной строкой. Например, когда ресурсы компьютера ограничены и ваше приложение очень простое.
В качестве постоянной среды разработки это, возможно, не очень удобно, но если вам нужно
иногда собирать какие-нибудь мелкие утилиты — это в самый раз.
Введение
Разработка под Android не является основным направлением моей деятельности, я иногда делаю какие-то небольшие приложения для своих нужд.
Раньше я использовал QPython, но он достаточно тяжел и неудобен в работе. Поэтому я перешел к разработке нативных программ. Даже при поверхностном знании Java
это не составляет больших трудностей.
Данное руководство в большой степени базируется на этом документе: Building an Android App
from the Command Line. Кому интересны подробности, обращайтесь к первоисточнику.
Похожая статья: Пишем, собираем и запускаем HelloWorld для Android в блокноте уже встречалась на этом ресурсе, но в ней было рассмотрена разработка в Windows.
Здесь же я рассмотрю, как можно собрать приложение в linux.
Железо
Тестирование проводилось на стареньком нетбуке с процессором Атом, 1Гб ОЗУ
и 8Гб SSD диска.
Операционная система
Я тестировал приложение на Ubuntu 17.04. Начиная с Ubunu 16.04 android-sdk можно установить через пакетный менеджер.
В принципе, тот же SDK можно
скачать с сайта.
Качать файл из раздела 'Get just the command line tools'
По сути это не сильно меняет процесс, но через пакетный менеджер все гораздо проще.
Разница будет лишь в путях и установке дополнительных пакетов "android-platform".
Установка пакетов
Итак, приступим к установке.
sudo apt install android-sdk
Будет установлено большое количество пакетов, включая Java.
Далее, в зависимости от требуемой версии Android, необходимо установить нужную
версию пакетов. Для lolipop 5.1 необходимо ставить:
sudo apt install google-android-platform-22-installer
sudo apt install google-android-build-tools-22-installer
Так же необходимо установить дополнительный пакет.
sudo apt install apksigner
Если вы планируете устанавливать apk-пакет через adb, то необходимо немного дополнительных настроек.
Настройка adb
С помощью lsusb найти подключенное устройство
# lsusb
....
Bus 001 Device 004: ID 1782:75b0 MyDevice
....
И создать файл с правилом:
sudo vi /etc/udev/rules.d/51-android.rules
В файл добавить одну строку:
SUBSYSTEM=="usb", ATTR{idVendor}=="1782", MODE="0666", GROUP="plugdev"
Здесь "1782" взято из вывода lsusb.
Перезапускаем сервис
sudo systemctl restart udev
После подключения через adb, на устройстве необходимо подтвердить соединение.
Теперь все готово к работе.
Постановка задачи
Приложение, которое будем собирать немного сложнее, чем 'Hello world'.
- Требуется по нажатию кнопки взять строку из буфера обмена.
- Вырезать подстроку
- Записать подстроку обратно в буфер.
- С помощь Toast вывести подстроку или сообщение об ошибке.
В общем-то все просто.
Я подготовил пример который возьмем за основу.
Создание подписи
Сначала создадим ключ для подписи файла:
keytool -genkeypair -keystore keystore.jks -alias androidkey -validity 10000 -keyalg RSA -keysize 2048 -storepass android -keypass android
Это нам пригодится позже.
Манифест
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="ru.kx13.extractvidid"
versionCode="1"
versionName="0.1">
<uses-sdk android:minSdkVersion="22"/>
<application android:label="EctractId"
android:icon="@drawable/icon" >
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
Здесь указываем имя приложения в атрибуте "android:label". Так же приложение будет использоваться свою иконку, она указана в атрибуте "android:icon". Сама иконка лежит в каталоге "res/drawable-mdpi" файл "icon.png". В качестве иконки можно взять любой небольшой png файл.
Layout
Файл с расположением элементов находится в каталоге "/res/layout/".
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/my_text"/>
<Button
android:id="@+id/button_id"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Извлечь" />
</LinearLayout>
В него можно добавлять виджеты, если вы захотите расширить функционал.
Исходный код приложения
Исходный код приложения находится здесь "java/ru/kx13/extractvidid"
package ru.kx13.extractvidid;
import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Button;
import android.widget.Toast;
import android.view.View;
import android.content.ClipboardManager;
import android.content.ClipData;
public class MainActivity extends Activity {
private static String extract(String s) {
int start = s.indexOf("%3D");
int end = s.indexOf("%26");
if(start == -1 || end == -1) {
return "error";
}
return s.substring(start + 3, end);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView text = (TextView)findViewById(R.id.my_text);
text.setText("Извлечь youtube video id");
Button button = (Button) findViewById(R.id.button_id);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ClipboardManager myClipboard = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
ClipData abc = myClipboard.getPrimaryClip();
ClipData.Item item = abc.getItemAt(0);
String text = item.getText().toString();
String video_id = MainActivity.extract(text);
ClipData myClip = ClipData.newPlainText("text", video_id);
myClipboard.setPrimaryClip(myClip);
Toast toast = Toast.makeText(getApplicationContext(),
video_id, Toast.LENGTH_SHORT);
toast.show();
}
});
}
}
Код весьма прост и примитивен, но этот шаблон можно использовать в других приложениях.
Скрипт для сборки
Я не стал использовать утилит сборки типа make или ant, т.к. весь код находится в одном файле и особых преимуществ это не даст. Поэтому это обычный shell скрипт:
#!/bin/sh
SOURCE=ru/kx13/extractvidid
BASE=/usr/lib
SDK="${BASE}/android-sdk"
BUILD_TOOLS="${SDK}/build-tools/22.0.1"
PLATFORM="${SDK}/platforms/android-22"
mkdir -p build/gen build/obj build/apk
"${BUILD_TOOLS}/aapt" package -f -m -J build/gen/ -S res -M AndroidManifest.xml -I "${PLATFORM}/android.jar"
javac -source 1.7 -target 1.7 -bootclasspath "${JAVA_HOME}/jre/lib/rt.jar" -classpath "${PLATFORM}/android.jar" -d build/obj build/gen/${SOURCE}/R.java java/${SOURCE}/MainActivity.java
"${BUILD_TOOLS}/dx" --dex --output=build/apk/classes.dex build/obj/
"${BUILD_TOOLS}/aapt" package -f -M AndroidManifest.xml -S res/ -I "${PLATFORM}/android.jar" -F build/Extractor.unsigned.apk build/apk/
"${BUILD_TOOLS}/zipalign" -f 4 build/Extractor.unsigned.apk build/Extractor.aligned.apk
apksigner sign --ks keystore.jks --ks-key-alias androidkey --ks-pass pass:android --key-pass pass:android --out build/Extractor.apk build/Extractor.aligned.apk
Некоторые замечания по поводу путей.
- По умолчанию, переменная BASE указывает на путь, в который пакетный менеджер сохраняет файлы. Если вы ставите SDK вручную, то путь надо будет изменить.
- Если вы используете версию API отличную от 22, то вам надо подправить переменные BUILD_TOOLS и PLATFORM
Сборка и установка
Для сборки просто запустите
./build.sh
Если все настроено правильно никаких сообщений не будет выведено, а в каталоге "build" появится файл "Extractor.apk"
Теперь надо установить наше приложение
adb install -r build/Extractor.apk
Если все прошло нормально, на устройстве появится новое приложение. Можно запускать и пользоваться.
В общем случае можно перекинуть файл apk на устройство любым удобным способом.
Заключение
Как видно из статьи начать разработку в консоли совсем несложно.
Консольные утилиты позволяют разрабатывать программы при весьма небольших ресурсах.
Приятной разработки!
Комментарии (11)
nick1990spb
07.08.2017 18:26Как видно из статьи начать разработку в консоли совсем несложно.
но зачем?) нормальную морду без UI не сделаешь (100500 сборок с правками хмл не для меня), а без UI только для себя любимого делать… Я затрудняюсь представить что мне нужно написать для себя без нормального UI, и что не может быть сделано через эмулятор баша…
kx13 Автор
07.08.2017 19:22но зачем?
"Потомучто мы можем!" :)
Я в начале стати написал, что этот способ не годится для сложной разработки.
Но если вам надо сделать что-то простое или, например, собрать чужую программу, то почему бы и нет.
Для этих целей IDE не надо, а gradle устанавливается по зависимостям, при установке SDK.
Или как в моем случае, Android Studio на нетбук не влезет, а программу надо написать очень примитивную.
Поэтому для ряда задач такой способ сорки имеет право на жизнь.
что мне нужно написать для себя без нормального UI, и что не может быть сделано через эмулятор баша…
Я намучался на андройде с эмулятором питона и SL4A и решил переписать тот же код на Java. Мне результат понравился.
fRoStBiT
И чем же это лучше, чем использование Gradle?
juztoss
Ничем, но зато можно понять как работает вся кухня внутри.
fRoStBiT
Каким образом, если в статье нет ничего похожего на объяснение того, что происходит? Только набор действий без комментариев.
kx13 Автор
Если изучить ссылки, которые приведены во "Введении", то там найдете больше подробностей.
Я специально их дал, чтобы не повторяться.
Цель этой статьи показать, что собрать приложение для Android можно собрать используя лишь пакетный менеджер и любой редактор.
kx13 Автор
В том, что писать bash скрипты умеют многие, а умеющих с Gradle работать гораздо меньше.
Я нашел статьи, где были просто набор команд. Их и применил. Для таких примитивных проектов gradle, даже make в общем-то не нужен.
Если покажете статью, где то же самое делают с помощью gradle, мне будет интересно почитать.
kovserg
Тоже писал подобное. Весь toolchain — 14Mb (вместе с libgdx 56Mb) это всё необходимое для сборки ничего и больше качать не надо.
А gradle это минимум 2Гб оверхеда и медленная сборка. AndroidStudio это минимум 3Гб RAM но лучше больше, гиг триграм и других индексов.
а тут слил с флешки 14Мб, распаковал, написал
./ma init-app myapp
./ma build myapp
./ma install myapp
и оно на телефоне и сборка myapp занимает 2сек.
если надо по классам поискать, то весь индекс по всему андройду занимает ~160кб.
./ma find-class Intent | grep android
android.app.IntentService
android.app.PendingIntent
android.app.PendingIntent$CanceledException
android.app.PendingIntent$OnFinished
android.content.Intent
android.content.IntentFilter
android.content.IntentFilter$AuthorityEntry
android.content.Intent$FilterComparison
android.content.IntentFilter$MalformedMimeTypeException
android.content.IntentSender
android.content.IntentSender$OnFinished
android.content.IntentSender$SendIntentException
android.content.Intent$ShortcutIconResource
android.content.pm.LabeledIntent
android.provider.ContactsContract$Intents
android.provider.ContactsContract$Intents$Insert
android.provider.Contacts$Intents
android.provider.Contacts$Intents$Insert
android.provider.Contacts$Intents$UI
android.speech.RecognizerIntent
android.speech.RecognizerResultsIntent
./ma show-class android.content.Intent | grep put | grep double
public android.content.Intent putExtra(java.lang.String, double);
public android.content.Intent putExtra(java.lang.String, double[]);