- Как блокировать отправку на сервер android studio
- Андрей Алеев
- Установка сертификатов
- Блокировать сообщения в Android
- 2 ответа
- Использование сокетов в Android
- Клиентский android-сокет
- Класс Connection
- Класс активности MainActivity
- Серверное приложение
- Серверный класс
- Как я писал кастомный локер
- Изучаем исходники
- Версия один
- Версия два
Как блокировать отправку на сервер android studio
Андрей Алеев
На днях мне пришлось разворачивать Android Studio IDE на машине с корпоративным прокси. Тема не нова, и уже обсуждалась на stackoverflow и в блогах. Однако, эта задача не решается сходу — приходиться покопаться. Поэтому я решил создать пошаговую инструкцию по настройке IDE Android-разработчика в условиях прокси.
Все действия мы будем проводить на windows-машине. Для linux алгоритм будет аналогичный.
Итак, при первом запуске Android Studio предлагает настроить прокси
Жмем Setup Proxy, вводим адрес прокси-сервера и свои учетные данные:
Адрес прокси можно узнать с помощью команды (windows)
Протестируйте соединение с помощью кнопки Check connection на этом же окне. Если все ок, идем дальше.
Все ок, идем дальше. В появившемся после запуска IDE окне прокси нужно снова прописать параметры proxy для http и https:
Эти же настройки можно прописать в файле gradle.properties:
Однако, имейте ввиду, что настройки прокси IDE перезаписывают настройки проекта .
Если сейчас попытаться собрать проект, то, скорее всего, сборка закончится неуспешно с ошибкой
Gradle пытается достучаться до серверов репозиториев, не имея сертификатов. Нам необходимо добавить их в хранилища. Для этого сначала добавляем в gradle.properties следующие строчки:
Здесь мы указываем путь и пароль к хранилищу сертификатов. Пароль по умолчанию — changeit. Если вы не меняли его, он остался таким же.
Как же добавить сертификаты в хранилище?
Установка сертификатов
При запуске проекте IDE предлагает принять сертификаты. Их следует принять, однако это не поможет автоматически. Нам необходимо импортировать сертификаты в хранилище сертификатов cacerts IDE и JVM. Для этого необходимо выполнить следующие шаги:
- Скачать сертификат. Сделать это можно с помощью браузера или openssl
- Импортировать сертификат в в хранилища с помощью keytool
Чтобы импортировать загруженный на шаге 1 сертификат, на Windows-машине необходимо запустить командную строку от администратора и выполнить:
Также, необходимо добавить этот сертификат в другие хранилища cacerts (JVM и Android Studio):
альтернативно, вместо того, чтобы добавлять, можно копировать сертификаты между хранилищами с помощью команды:
После импорта сертификатов почистите кэш gradle в папке C:\Users\ \.gradle и перезагрузите систему. Если при попытке обратиться к хранилищу cacerts IDE выдает ошибку Access denied, запустите Android Studio от администратора.
Запускаем сборку… Проект успешно собирается!
В случае, если импорт сертификатов не помогает, можно заменить адрес загрузки репозиториев с секьюрного https на обычный http:
Помимо gradle, проблемы могут возникнуть и с системой контроля версий. В случае с git необходимо необходимо добавить в глобальные настройки git параметры proxy. Для этого выполнить команду:
Если при попытке при попытке pull/push из/в GitLab возникает ошибка
SSL certificate problem: self signed certificate in certificate chain
то следует выполнить следующую команду от администратора:
Для возможности push/pull через IDE Android Studio необходимо в настройках Settings->Version Control->Git в пункте SSH executable указать Native
На этом все, можно работать. Надеюсь, статья оказалась полезной для вас. Буду рад вашим мнениям и комментариям!
Блокировать сообщения в Android
Я пишу приложение, которое загружает данные из интерфейса отдыха. для этой задачи я использую службу, которая вызывается действиями. Эти призывы основаны на «Сообщении». Я делаю это так, потому что я думал, что простая отправка сообщения не приводит к блокировке потока пользовательского интерфейса (я использовал большую часть кода примера RemoteService из документации Android). Но похоже, что если поток пользовательского интерфейса, отправляющий сообщение, все еще блокируется (пользовательский интерфейс не обновляется до тех пор, пока поток программы, вызванный сообщением, не остановится).
Я что-то не понимаю в самой идее системы сообщений? мне нужно запускать службу в отдельном потоке, чтобы обойти это ?!
2 ответа
Отправка сообщений с использованием обработчиков не блокируется в зависимости от того, что вы с ними делаете. Если вы отправляете сообщение в Сервис, а затем сразу отправляете HTTP-запрос на сервер, он блокируется. Если вы отправляете сообщение, то пусть служба просто разместит уведомление в панели действий, тогда оно не будет блокироваться.
Службы выполняются в основном потоке пользовательского интерфейса. Они не работают в фоновом режиме, поэтому все, что вы делаете в Службе, будет выполняться в потоке пользовательского интерфейса и может заблокировать его, если Служба выполняет большую работу.
Message обрабатывается потоком, который привязан к Handler , который вы использовали для отправки сообщения. Если вы создали Handler из потока пользовательского интерфейса, то ваши сообщения обрабатываются в потоке пользовательского интерфейса. Вы можете использовать HandlerThread или IntentService .
HandlerThread — это поток, у которого есть собственный петлитель, и вы можете создать из него новый обработчик:
IntentService имеет рабочий поток, и каждая команда запуска обрабатывается из рабочего потока в onHandleIntent(Intent)
Использование сокетов в Android
Создано большое количество приложений как для Android, так и для других ОС, которые взаимодействуют друг с другом с помощью установления соединенией по сети. К таким приложениям относятся, например, мессенджеры социальных сетей WhatsApp, Viber. Как правило, для установления соединения между такими приложениями используются сокеты.
Сокет (socket) — это интерфейс, позволяющий связывать между собой программы различных устройств, находящихся в одной сети. Сокеты бывают двух типов: клиентский (Socket) и серверный (ServerSocket). Главное различие между ними связано с тем, что сервер «открывает» определенный порт на устройстве, «слушает» его и обрабатывает поступающие запросы, а клиент должен подключиться к этому серверу, зная его IP-адрес и порт. В Android сокеты для передачи данных используют по умолчанию протокол TCP/IP, важной особенностью которого является гарантированная доставка пакетов с данными от одного устройства до другого.
Особенности использования сокетов
Что важно знать при использовании сокетов в Android ?
- соединения сокетов отключаются при переходе устройства в спящий режим;
- чтобы не «рвать» соединение при наступлении спящего режима в устройстве можно использовать сервис;
- для использования интернет-сети необходимо Android-приложению предоставить нужные права в манифесте.
Для определения прав в манифесте необходимо в файл AndroidManifest.xml добавить следующую строку :
Теперь android-приложения будет иметь доступ к сети.
Далее в статье рассмотрим пример клиент-серверного сокетного соединения с передачей сообщения. Функции клиента будет выполнять android-приложение. Серверное java-приложение выполним в IDE Eclipse с использованием пакета concurrent. В конце страницы можно скачать оба приложения.
Клиентский android-сокет
Интерфейс andriod-приложения представлен на следующем скриншоте. Форма приложения включает поле ввода текстового сообщения и кнопки установления соединения сервером, передачи сообщения и закрытия соединения.
Клиентское приложение создадим из двух классов : класс взаимодействия с серверным сокетом Connection и класс стандартной активности MainActivity.
Класс Connection
Класс взаимодействия с сервером Connection получает при создании (через конструктор) параметры подключения : host и port. Методы Connection вызываются из активности и выполняют следующие функции :
Метод | Описание |
---|---|
openConnection | Метод открытия сокета/соединения. Если сокет открыт, то он сначала закрывается. |
closeConnection | Метод закрытия сокета |
sendData | Метод отправки сообщения из активности. |
finalize | Метод освобождения ресурсов |
Листинг Connection
Класс активности MainActivity
В активности MainActivity определены параметры сервера : host, port. Помните, что IP-адрес сервера для Вашего android-примера не может быть localhost (127.0.0.1), иначе Вы будете пытаться связаться с сервером внутри Andriod-системы. Кнопки интерфейса связаны с методами обращения к классу Connection. Кнопки отправки сообщения mBtnSend и закрытия соединения mBtnClose с сервером блокируются при старте приложения. После установления соединения с сервером доступ к кнопкам открывается.
Листинг активности
Методы управления сокетным соединением
Ниже представлены методы обработки событий, связанных с нажатием кнопок интерфейса. Обратите внимание, что подключение к серверу выполняется в отдельном потоке, а открытие доступа к кнопкам в основном потоке, для чего вызывается метод runOnUiThread. Для отправки сообщения серверу также создается отдельный поток.
Серверное приложение
Серверное приложение включает 2 класса : Server и ConnectionWorker. Серверный класс Server будет выполнять обработку взаимодействия с клиентом с использованием ConnectionWorker в отдельном потоке. Конструктор ConnectionWorker в качестве параметра получает объект типа Socket для чтения сообщений клиента из потока сокета.
Листинг ConnectionWorker
ConnectionWorker получает входной поток inputStream из клиентского сокета и читает сообщение. Если сообщение отсутствует, т.е. количество прочитанных байт равно -1, то это значит, что соединение разорвано, то клиентский сокет закрывается. При закрытии клиентского соединения входной поток сокета также закрывается.
Серверный класс
Серверный класс Server создадим с использованием многопоточного пакета util.concurrent. На странице описания сетевого пакета java.net и серверного ServerSocket был приведен пример серверного модуля с использованием обычного потока Thread, при работе с которым необходимо решать задачу его остановки : cтарый метод Thread.stop объявлен Deprecated и предан строжайшей анафеме, а безопасная инструкция Thread.interrupt безопасна, к сожалению, потому, что ровным счетом ничего не делает (отправляет сообщение потоку : «Пожалуйста, остановись»). Услышит ли данный призыв поток остается под вопросом – все зависит от разаработчика.
Чтобы иметь возможность остановить сервер «снаружи» в серверный класс Server включим 2 внутренних реализующих интерфейс Callable класса : CallableDelay и CallableServer. Класс CallableDelay будет функционировать определенное время, по истечении которого завершит свою работу и остановит 2-ой серверный поток взаимодействия с клиентами. В данном примере CallableDelay используется только для демонстрации остановки потока, организуемого пакетом util.concurrent.
Листинг CallableDelay
CallableDelay организует цикл с задержками. После завершения последнего цикла cycle поток завершает цикл, останавливает вторую задачу futureTask[1] и закрывает сокет. В консоль выводится соответствующее сообщение.
Листинг CallableServer
Конструктор CallableServer в качестве параметров получает значение открываемого порта для подключения клиентов. При старте (метод call) создается серверный сокет ServerSocket и поток переходит в режим ожидания соединения с клиентом. Остановить поток можно вызовом метода stopTask, либо завершением «задачи» типа FutureTask с данным потоком.
При подключении клиента метод serverSoket.accept возвращает сокет, который используется для создания объекта ConnectionWorker и его запуска в отдельном потоке. А сервер (поток) переходит к ожиданию следующего подключения.
В случае закрытия сокета (завершение внешней задачи FutureTask с данным потоком) будет вызвано исключение Exception, где выполняется проверка закрытия сокета; при положительном ответе основной цикл прерывается и поток завершает свою работу.
Листинг серверного класса Server
Cерверный класс Server создает два потоковых объекта (callable1, callable2), формирует из них две задачи futureTask и запускает задачи на выполнение методом execute исполнителя executor. После этого контролируется завершение выполнение обоих задач методом isTasksDone. При завершении выполнения обеих задач завершается также и цикл работы executor’а.
Два внутренних описанных выше класса (CallableDelay, CallableServer) не включены в листинг.
Источник
Как я писал кастомный локер
Привет хабрастарожилам от хабрановичка. Ровно год назад я решил написать кастомный локер (экран блокировки) для моего старичка Samsung Galaxy Gio в стиле популярного тогда Samsung Galaxy s3. Какие причины заставили меня это сделать, писать не буду, но добавлю лишь то, что в Google Play я программу не собирался выкладывать и каким-либо другим способом заработать на ней не планировал. Данный пост посвящен последствиям моего решения.
Начну издалека. Многие хвалят Android за открытость и возможность заменить и настроить встроенные программы под свои нужды. Что тут сказать? В сравнении с другими популярными ОС, это, безусловно, так, но если копнуть глубже в архитектуру Android возникают трудности и вопросы. Локскрин (в Android это называется keyguard) как раз и вызывает вопросы: почему Google не поступили с ним, так как с лаунчерами, почему не сделали диалог со всеми доступными на устройстве локерами и с возможностью выбрать нужный по умолчанию? Где-то в глубине мозга тихим нерешительным голосом кто-то отвечает: может быть Google (Android Ink. если быть точнее) поступил так из соображений безопасности. Этот голос вероятно прав и многим разработчикам локеров и мне (скромность не позволила приписать себя к их числу) пришлось изобретать велосипед, и не один.
Изучаем исходники
Начал я с использования одного из плюсов Android – из изучения исходников. Я один из тех консерваторов, которые уже 2,5 года сидят на стоковой прошивке (2.3.6), поэтому и исходники изучал соответствующие. Классы, отвечающие за блокировку экрана, лежат в android.policy.jar, что в system/framework. Первоначальной целью было найти «точку входа», т.е. где и когда вызывается локер. Искал здесь.
В классе PhoneWindowManager.java есть метод screenTurnedOff(int why), который вызывает одноименный метод класса KeyguardViewMediator. Проследив, кто кого вызывает, я нашел метод в классе KeyguardViewManager, создающий непосредственно View стокового локера.
Что ж, все гениальное – просто. Решил повторить этот код для своего приложения и получил ошибку – нет нужного permission. Немного погуглив, добавил следующие разрешения: SYSTEM_ALERT_WINDOW и INTERNAL_SYSTEM_WINDOW. Это не помогло.
Вернулся к изучению класса PhoneWindowManager.java:
Для требуемого окна TYPE_KEYGUARD нужно второе из моих добавленных разрешений. Задней точкой тела начал ощущать, что не все так просто, как я себе представлял. Решено было посмотреть на описание этого permission. Вот выдержка из AndroidManifest.xml пакета framework-res.apk.
Вот она – черная полоса в жизни. Ведь я понимал, «signature» – это значит, что использовать этот пермишн может только пакет, подписанный тем же ключом, что и пакет, выдавший это разрешение (в нашем случае — framework-res.apk). Ладно, достаем инструменты для изготовления велосипедов.
Версия один
Первым решением было использовать activity в качестве локскрина. На stackoverflow советуют использовать следующий код:
Признаюсь, в первых версиях я использовал этот метод. У него есть существенные недостатки: статусбар не блокируется, начиная с версии API11 этот метод не работает.
Решение первого недостатка (переполнениестека опять помогло) следующее. Поверх статусбара с помощью WindowManager рисуется прозрачный View, который перехватывает все TouchEvent. Вот служба, реализующая это:
Второго недостатка для меня не существовало, на Gingerbread данный код работал превосходно. На 4pda, куда я опрометчиво выложил свое творение, пользователи жаловались, что на многих телефонах мой локер сворачивался как обычное приложение. Для них найдено такое решение. В качестве стандартного лаунчера устанавливается пустышка. При нажатии кнопки HOME система вызывает мой лаунчер-пустышку. Если кастомный локер активен, лаунчер сразу же закрывается в методе onCreate(), т.е. визуально нажатие кнопки HOME ни к чему не приводит. Если кастомный локер не активен, мой лаунчер тут же вызывает другой правильный лаунчер, который пользователь указал в настройках.
Вот код пустышки:
Выглядело это следующим образом:
Эти велосипеды ездили долго и хорошо, пока я не решил сделать «правильный» локскрин, и уже в стиле Samsung Galaxy S4.
Версия два
Когда системе необходимо запускать кастомный локер? Очевидно, что при выключении экрана. Создадим службу, регистрирующую BroadcastReceiver, т.к. из манифеста данный фильтр не работает.
Необходимо учесть две особенности:
1. Служба должна быть запущена в момент загрузки устройства. Создадим BroadcastReseiver с IntentFilter «android.intent.action.BOOT_COMPLETED». Есть одно НО: служба при запуске должна отключить стандартную блокировку экрана. Особенностью Android является то, что стандартное окно ввода PIN-кода является частью стокового экрана блокировки. Поэтому служба должна запускаться только когда PIN буден введен.
Максимум, на что хватило моей фантазии:
2. Проанализировав PhoneWindowManager видно, что в метод screenTurnedOff(int why) передается переменная why, принимающая 3 значения:
— экран выключился по истечению таймаута (в этом случае стоковый локер запускается с задержкой),
— экран выключился при срабатывании сенсора приближения (во время телефонного разговора),
— экран выключился при нажатии кнопки.
В моем случае такого разнообразия нет. Поэтому служба мониторит состояние телефона, и при входящем звонке или во время разговора экран не блокируется.
Вот основной код службы:
Идея не использовать activity, а использовать WindowManager была еще сильна. Из пяти типов окон, использующих разрешение SYSTEM_ALERT_WINDOW, мне подошел TYPE_SYSTEM_ALERT. Причем у него были очевидные достоинства: блокировался статусбар (по крайней мере, на Gingerbread) и перехватывалось нажатие кнопки HOME (работает даже на Jelly Bean).
Промежуточным звеном между службой и KeyguardView является класс KeyguardMediator:
Дальше история становится менее интересной, так сказать, будничной. На мой локер можно добавлять ярлыки приложений (здесь все стандартно и просто) и виджеты (а вот этот момент достоин отдельной статьи).
Теперь все стало выглядеть современней:
Источник