• Как передать параметр в граф зависимостей Koin?

    akaish
    @akaish
    Стек Java\Android
    val dataModule = module {
        // Привести к нужному типу явно
        single { params -> A(info = params.get() as String) }
        // или указать тип параметром типа у метода
        single { params -> A(info = params.get<String>()) }
    }
    Ответ написан
  • Можно ли замаскировать android x86?

    akaish
    @akaish
    Стек Java\Android
    Нельзя. Если часть программ не поддерживают x86 архитектуру, то даже если заставить систему выдавать информацию о том, что используется ARM, такие приложения работать не будут. Разные архитектуры.
    Ответ написан
  • Как обновить скачанный файл SharedPreference в Android?

    akaish
    @akaish
    Стек Java\Android
    Ни разу не приходила в голову мысль заменять xml sp. Вроде как для этого API sp и не писались. Плюсом, с высокой долей вероятности, при закрытии объекта SP в файл записываются данные из буффера SharedPreferences.Editor и не факт, что в то же время.
    Зачем вам вообще пытаться использовать этот хак? Храните данные в виде JSON и после скачивания дессериализуйте в POJO c помощью, к примеру, GSON. Ну или используйте Firebase Realtime DB. Или еще пачка стандартных решений. Просто нет гарантии, что даже если Вы сделаете так, что все заработает, работать это будет на всех версиях и устройствах.
    А, и да, хороший тон в SP использовать apply(), commit() сразу пишет изменения в файл.
    Ответ написан
  • Почему приложение вылетает только на Android P (API 28)?

    akaish
    @akaish
    Стек Java\Android
    Мало информации. Ошибка говорит о том, что нет таблички. Вы смотрели, файл бд нормально откопировался? То, что база данных открывается хелпером - ни о чем не говорит, метод openDatabase создает пустую бд, если бд по пути нет и если это возможно. Также, у вас пути сахардкожены до бд, может на Android P изменили путь для баз данных по умолчанию?
    Ответ написан
  • Насколько плохо вызывать метод активити из фрагмента напрямую?

    akaish
    @akaish
    Стек Java\Android
    Не вижу в этом ничего плохого, если фрагмент находится в FragmentManager activty и вы придерживаетесь стандартного андроидовского MVC, но надо понимать, что на разных стадиях жизни фрагмента метод getActivity() может вернуть как и ссылку на активити, так и null.
    Ответ написан
  • Как сделать несколько последовательных GET-запросов с Android с помощью OkHttp?

    akaish
    @akaish
    Стек Java\Android
    RxJava или Java 8 Stream хорошо подходит для таких задач. Лучше RxJava, так как умеет в многопоток. Оба API созданы для удобной работы с входными потоками. API OkHttp не знаю, ибо не писал клиентов магазинов и типичного. Вот туториал: https://www.vogella.com/tutorials/RxJava/article.html

    А вообще, если хочется простого, делаете очередь, что-то типа:
    public class Result {
    	
    	public final static int NEXT = 1;
    	public final static int FINISH = 2;
    	public final static int ERROR = 3;
    	public final static int NO_NEXT = 4;
    
    	public final int result;
    	public final String someData;
    	public final Throwable tr;
    	
    	public Result(int result, String someData, Throwable tr) {
    		this.result = result;
    		this.someData = someData;
    		this.tr = tr;
    	}
    }
    
    public abstract class Operation {
    
    	final Queue queue;
    	
    	public Operation(Queue queue) {
    		this.queue = queue;
    	}
    
        public interface OnExecuted {
            void onExecution(Result result);
        }
    	
        void execute() {
        	executeOperation((result) -> {
            		queue.addResult(result);
            		queue.next();
                }
            );
        }	
        
        abstract public void executeOperation(OnExecuted onExecuted);
    }
    
    public class Queue {
    	
    	public interface OnQueueFinish {
    		void onQueueFinish(LinkedList<Result> results);
    	}
    
    	final LinkedList<Result> results = new LinkedList<>();
    	final LinkedList<Operation> operations = new LinkedList<>();
    	
    	private int currentOperation = -1;
    	
    	final OnQueueFinish onFinish;
    	
    	public Queue(OnQueueFinish onFinish) {
    		this.onFinish = onFinish;
    	}
    	
    	public void addOperation(Operation operation) {
    		operations.addLast(operation);
    	}
    	
    	void addResult(Result result) {
    		results.addLast(result);
    		if(result.result > NEXT) {
    			onFinish.onQueueFinish(results);
    		}
    	}
    	
    	public void next() {
    		currentOperation++;
    		if(currentOperation >= operations.size()) {
    			addResult(new Result(NO_NEXT, null, null));
    		}
    		operations.get(currentOperation).execute();
    	}
    }
    
    public class GetOperation extends Operation {
    
    	final URI uri;
    	final int onSuccessCode;
    	final int onErrorCode;
    	
    	public GetOperation(Queue queue, URI uri, int onSuccessCode, int onErrorCode) {
    		super(queue);
    		this.uri = uri;
    		this.onErrorCode = onErrorCode;
    		this.onSuccessCode = onSuccessCode;
    	}
    
    	@Override
    	public void executeOperation(OnExecuted onExecuted) {
    		// На замыканиях
    		SomeApi.get(uri)
    			   .onSuccess((data, code) -> onExecuted.onExecution(new Result(onSuccessCode, data, null)))
    			   .onError((code, tr) -> onExecuted.onExecution(new Result(onErrorCode, data, null))).run();
    		// По обычному
    		try {
    			Response r = SomeApi.get(uri);
    			onExecuted.onExecution(new Result(onSuccessCode, r.getData(), null));
    		} catch (Throwable tr) {
    			onExecuted.onExecution(new Result(onErrorCode, null, null));
    		}
    	}
    }
    
    public class Something {
    
    	public Something() {}
    	
    	void wreeee() {
    		Queue queue = new Queue(this::onQueueFinished);
    		// очередь будет продолжена даже при ошибке
    		queue.addOperation(new GetOperation(queue, new URI("http://somehub.com"), NEXT, NEXT));
    		// в случае ошибки очередь остановится
    		queue.addOperation(new GetOperation(queue, new URI("http://oldwomenneedyou.com"), NEXT, ERROR));
    		// останавливаем очередь на последнем элементе вручную
    		queue.addOperation(new GetOperation(queue, new URI("http://brotherlove.com"), FINISH, ERROR));
    		// Тут запускаем очередь
    		queue.next();
    	}
    	
    	void onQueueFinished(LinkedList<Result> results) {
    		// Тут список результатов обрабатываете, ошибки и т.п.
    	}
    
    }


    С синхронизаций, аннотациями контрактов, исключениями, таймаутами и прочей шелухой сами разберетесь.
    Ответ написан
  • Разработка приложений под Android без Android Studio?

    akaish
    @akaish
    Стек Java\Android
    Да, можно писать и из eclipse. Раньше Google официально поддерживала плагин на eclipse, около лет пяти - четырех - трех назад точно. Но потом перестали.
    https://marketplace.eclipse.org/content/android-de...
    По идее нужен еще плагин на Gradle, не знаю, включен ли он по умолчанию в сборку Eclipse for Java. На поддержку kotlin, по идее, тоже надо будет плагин ставить. Если kotlin нужен.
    Лично я перешел на android studio, она поудобнее на мой взгляд по подсказкам при наборе кода, не надо заморачиваться с установкой кучи плагинов и модулей.

    Еще в NetBeans был неплохой плагин на Android.

    Но мой совет, пользуйтесь Android Studio. И проще (не надо возиться с кучей плагинов) и у Jet Brains хорошие IDE.

    А по поводу Unresolved Reference - косяк в xml. Поставьте Gradle свежее, там ошибки в новых версиях более информативные.
    Ответ написан
  • Почему не устанавливается apk на некоторые телефоны?

    akaish
    @akaish
    Стек Java\Android
    Надо смотреть следующие вещи:
    1. Логи приложения на устройстве. Вы можете их посмотреть с помощью утилиты а-ля https://play.google.com/store/apps/details?id=com.... по крайней мере у меня на старом ведре Sony Z1 оно работает без рута (кто-то в комментах к вашему вопросу писал о том, что логкэты могут требовать рут прав, этот точно не требует для многих версий андроида). Также, для просмотра логов хватит просто установленного SDK с пакетом сопутствующих утилит на ноуте, к примеру (android sdk tools, ну сколько они занимают, мегабайтов 200 максимум).
    2. Надо смотреть Ваш манифест. Там есть ряд нюансов, на которые может смотреть установщик apk android. Сходу не могу сказать, какие именно нюансы, просто надо документацию почитать.
    3. Если вы используете нативные библиотеки, с некоторой долей вероятности Вы пытаетесь запустить приложение с библиотекой, скомпилированной для другой архитектуры.
    4. Вы можете использовать в своем приложении устаревшие или наоборот, еще не существующие API для конкретной версии.
    5. Если используете multi dex, у меня лично с ним был косяк для одного проекта, не запускался на 5-ке на некоторых устройствах. Плюнул, так как проект влезал в 64K ограничение на методы.
    6. Если качаете приложение с флешки, к примеру, через адаптер, или еще как-то без проверки контрольных сумм, могут быть ошибки, связанные с битым файлом apk.
    7. Приложение может не пропускать, к примеру, антивирус на устройстве. Может стоять запрет на установку приложений из сторонних источников. Может быть так, что существует запрет на установку apk фалов, не подписанных вовсе, или подписанных только debug ключами при отсутствии включенного режима разработчика (гипотеза).

    С Вашей проблемой не сталкивался, накидал гипотетических вариантов.
    Ответ написан
  • Нужна ли совместимость, если приложение пишется под конкретное устройство?

    akaish
    @akaish
    Стек Java\Android

    Может ли при разработке всё равно понадобиться Backward Compability?

    Не знаю, это зависит от ТЗ. Если в ТЗ не предполагается обратной совместимости с предыдущими версиями, то и не надо заморачиваться. Такие вопросы решаются на стадии составления хотелок, но не как во время написания проекта. В зависимости от выбранного ЖЦ, возможно, далее заказчик может захотеть добавить поддержку старых ведер, но это уже не ваша проблема.


    Если нет, но потом перейду на Android 8.0, обратная совместимость понадобиться?

    Обратная совместимость != бинарной совместимости. Вообще, старый код для Android +- полностью запускается на новых версиях, там есть нюансы, но их не много.

    Может какие-то дополнительные советы для такой узконаправленной разработки есть? :)

    Могу посоветовать использование support libraries v7, v4 и т.п. Это хороший тон, сразу писать под максимальное количество версий андроид, если это не предполагает больших трудозатрат. Библиотеки поддержки максимально совместимы с обычными API android и код с использованием библиотек поддержки от кода под определенную версию ОС отличается обычно только разными импортами.
    Ответ написан
  • Как выполняется форматирование номеров телефона в Андроиде?

    akaish
    @akaish
    Стек Java\Android
    Если хотите форматирование, как в системном приложении "контакты" - просто посмотрите, как это сделано в исходниках этого самого приложения.
    Ссылка на git с исходниками
    Ответ написан
  • Почему частично не видно Fragment?

    akaish
    @akaish
    Стек Java\Android
    Есть проблемка, вы выкладываете обрезанный скриншот и лэйаут только элемента списка и не формулируете вопрос по человечески.
    UPD. Скорее всего проблема заключается в том, что некорректно определяется высота вложенного списка в SrollView. Там вообще не очевидный вопрос, с чем-то похожим уже сталкивался, но запамятовал. Если я Вас правильно понимаю, проблема в том, что список, завернутый в ScrollView не скроллится? Если так, копайте в сторону этого ответа на Stack Overflow. Что-то похожее уже решал, но, увы, уже просто не помню и особо не подскажу. Насколько я помню, там все упиралось в некорректную работу метода по определению общей высоты элементов вложенных списков.
    Ответ написан
  • После добавления библиотеки в проект перестало запускаться приложение, в чем может быть проблема?

    akaish
    @akaish
    Стек Java\Android
    Информации мало. Открываете R.class и смотрите по id название переменной, по которому определяете, что за ресурс привязан к этому id. Рассказываете, что за устройство и что за версия android.
    Судя по выдаче гугла - ошибка может быть связана с отсутствием поддержки градиентов для свойства fillColour:

    android:fillColor
    Specifies the color used to fill the path. May be a color or, for SDK 24+, a color state list or a gradient color (See GradientColor and GradientColorItem). If this property is animated, any value set by the animation will override the original value. No path fill is drawn if this property is not specified.

    Но в вашем случае может быть и что-то другое. С Вас полтинник за услуги гадалки.
    Ответ написан
  • Какой алгоритм использовать для получения координат сечения плоскостью многогранника?

    akaish
    @akaish
    Стек Java\Android
    Ммм, далек от царицы всех наук, три идеи, последующая лучше предыдущей.

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

    Вариант два, проверьте фигур на выпуклость, если она таковой не является, разбейте фигуру на отдельные выпуклые фигуры.

    Вариант три, забить на проверки и разбить каждое сечение на гарантированно выпуклый многоугольник (треугольник). Ну или саму фигуру на треугольные пирамиды. И уже считать сумму сечений этих треугольников\треугольных пирамид.

    Но это мысли вслух. Думаю, существует более красивое решение, основанное на какой-нибудь теореме. По сабжу я только помню, что фигура выпуклая, если отрезок, соединяющий любые две точки этой фигуры, лежит внутри этой фигуры.
    Может, если хранить фигуру, как набор векторов, задачу можно будет решить проще через методы векторной алгебры. Но не могу сказать точнее, так как был балбесом и на парах во время учебы в универе занимался чем угодно, кроме самой учебы.
    Ответ написан
  • Как сравнить данные двух массивов текста?

    akaish
    @akaish
    Стек Java\Android
    Ммм, я в алгоритмике не очень (совсем не очень), но как по мне - сортируете второй массив и циклом выбирая из первого массива строки, приводите их к виду, ожидаемому во втором массиве (префикс пути и отбрасывание номерного обозначение) и бинарным поиском ищите вхождение этих строк. Второй массив сортируете, к примеру, quicksort'ом или сортировкой слиянием.
    UPD. А еще лучше приводить во втором и первом массивах строки к единому виду, я так думаю, это в случае, если директория обычно занимает больше символов, чем название файла, отсекая префикс по первому с конца вхождению path separator char. Будет меньше проверок на совпадение символов в двух строках.
    Ответ написан
  • Как создать мобильное приложение-цифровую версию журнала?

    akaish
    @akaish
    Стек Java\Android
    Как вариант - связка Hugo\Hyde\Любой другой генератор статичных сайтов + приложение с использованием WebKit. Делаете тему, исходники перегоняете в .md. Приложение будет состоять из списка журналов, полученных в виде странички с Вашего сайта, со страницей - заглушкой на случай его недоступности. При нажатии на ссылку для скачивания журнала активируется js скрипт, который передает клиентскому приложению ссылку на нужный для скачивания журнал, в клиенте сохраняете его во внутреннюю память телефона и разархивируете.
    В приложении имеете простую табличку со списком скачанных журналов, на её основе в списке помечаете скачанные журналы скачанными, новые - новыми и т.п.
    Рецепт не на скорую руку, но всё же. Другой вариант - используете генератор приложений вроде APPS-TECH или NWICODE.
    Третий рецепт - просто пишете нативное приложение с использованием библиотек для просмотра PDF\другого нужного Вам формата.

    UPD. PDF можно перегнать в Markdown, к примеру, с помощью этого сервиса: http://pdf2md.morethan.io/
    Ответ написан
  • Как лучше всего реализовать приложение чтоб можно было выбирать изображение для imageview, сохранять, и обновлять заново, если нужно?

    akaish
    @akaish
    Стек Java\Android
    Почему не кошерно? Как раз наоборот, сохраняя данные в SQLite БД Вы гарантированно будете в курсе, что с Вашими данными, благодаря механизму транзакций. Да, SQLite БД медленная, но не настолько, чтобы при верном её использовании тормозить приложение.
    Всё зависит от поставленной задачи, в конечном итоге. Если нет необходимости строить огромные списки единым вызовом, а пользоваться подгрузками порций данный в адаптер списка - всё будет хорошо.
    Ответ написан
  • Какой использовать адаптер?

    akaish
    @akaish
    Стек Java\Android
    У Вас размытый вопрос, ну да ладно.
    1) Вам нужно писать свой адаптер, оперирующий POJO с двумя полями, id ресурса и пояснительный текст. Т.е.
    public class YourAdapter extends ArrayAdapter<YourPojo>

    2) Вам нужно повесить на чекбокс Listner на изменение состояния нажатия чекбокса, в теле которого Вы редактируете коллекцию адаптера, устанавливая нужные id иконок ресурсов и уведомляете список о том, что данные адаптера изменились.
    3) Вам нужно отнаследовать onBackPressed() Вашего активити таким образом, чтобы проверять, было ли произведено редактирование списка. Сделать это можно разными способами, к примеру, используйте boolean флаг.
    4) Чтобы сохранять Ваш список, Вы можете сохранять его в качестве JSON массива во внутренней памяти телефона или в таблице SQLite БД. Или еще миллионом способов на Ваш вкус.
    Ответ написан
  • Как выполнить валидацию в EditText в Андроиде?

    akaish
    @akaish
    Стек Java\Android
    Это делается с помощью TextWatcher listener:
    editText.addTextChangedListener(new TextWatcher() {
        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
    
            // TODO Auto-generated method stub
        }
    
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
    
            // TODO Auto-generated method stub
        }
    
        @Override
        public void afterTextChanged(Editable s) {
    
            // TODO Auto-generated method stub
        }
    });

    При каждом изменении поля ввода Вы в одном из данных методов форматируете строку в соответствии с Вашим шаблоном.
    UPD. Если требуется, найду сниппет под форматирование номера телефона, писал аналогичное уже. Вкратце, само форматирование можно произвести с помощью библиотеки гугловской libphonenumber.
    Ответ написан
  • Автоответчик на Android 8?

    akaish
    @akaish
    Стек Java\Android
    К сожалению, проиграть запись в линию невозможно стандартными API Android.
    Люди как только не изгаляются, чтобы проиграть что-либо в линию. Некоторые ребята даже эмулировали bluetooth гарнитуру, просто ради того, чтобы на Android проиграть заранее записанное сообщение.
    В общем, это возможно, но дико сложно.

    А в записи с линии разговора нет ничего сложного. Это делается через стандартные API Android.
    Ответ написан