Синхронизируйтесь, где удобно
Пользуйтесь везде.
Не у всех клиентов (особенно в регионах) есть интернет. Иногда может быть полезно определять порядок и количество обновлений офлайн.
Создано приложение исключительно из любопытства к технологиям php, java, soap и благодаря жажде познания )
Поддерживаются конфигурации:
- "Бухгалтерия Предприятия КОРП 2.0"
"Бухгалтерия Предприятия 2.0"
"Бухгалтерия Предприятия 3.0"
"Управление торговлей 11"
"Управление торговлей 10.3"
"Управление производственным предприятием"
"Управление небольшой фирмой 1.5"
"Управление небольшой фирмой 1.4"
"Розница 2.1"
"Комплексная автоматизация 1.1"
"Зарплата и Управление Персоналом 3"
"Зарплата и Управление Персоналом 2.5"
Буду благодарен за комментарии, конструктивную критику и советы!
Неочевидности (для программиста 1С) и этапы реализации
Пару слов уделю выбору именно java для написания приложения (а не мобильной платформы 1С например). Готовое приложение на java вместе с встроеной начальной базой весит 1.7мб, тогда как то же самое на базе 1С от 30мб. Думаю, этого достаточно, но есть ещё и стремление к изучению новых технологий и языков.
1) Первым делом встал вопрос о создании веб сервиса для обновления данных на мобиле по мере необходимости. Я выбрал NuSoap скорее потому, что, открыв его описание, мне всё показалось почти понятным. Вот хорошая статья с примерами, думаю, каждый с начальными знаниями php сможет создать свой веб сервис. Вот тут wsdl моего веб сервиса
2) Работа с вебсервисом из java сводится к подключению и использованию класса ksoap2
Вот, например, функция получения новых конфигураций с сервера
public void getNewConfFromServer(Vector<String> arrconf,final DB db) { SoapObject soapclient = new SoapObject(NAMESPACE,METHOD_NAME2); SoapObject parameters = new SoapObject(NAMESPACE, METHOD_NAME2); parameters.addProperty("oldConfArr",arrconf); soapclient.addProperty(METHOD_NAME2, parameters); SoapSerializationEnvelope envelope = new SoapSerializationEnvelope(SoapEnvelope.VER11); envelope.setOutputSoapObject(soapclient); HttpTransportSE httpTransportSE = new HttpTransportSE(URL); try { httpTransportSE.call(METHOD_NAME2, envelope); SoapObject response=(SoapObject)envelope.bodyIn; Object property= response.getProperty("return"); Vector vector = (Vector)property; for(int ii=0;ii<vector.size();ii++){ SoapObject response1 =(SoapObject)vector.get(ii); int idconf = (int)response1.getProperty("id"); String nameconf = (String)response1.getProperty("name"); String fnameconf = (String)response1.getProperty("fname"); Log.v("soap", "idconf = " + idconf + " name=" + nameconf+ " fname=" + fnameconf); db.addNewConf(idconf, nameconf, fnameconf); getDataConfFromServer(String.valueOf(idconf), "0", db); } } catch (IOException e) { e.printStackTrace(); } catch (XmlPullParserException e) { e.printStackTrace(); } } |
Отмечу один нюанс. Длительные процедуры (такие, как синхронизация с сервером) необходимо запускать в отдельном потоке, иначе андроид решит, что ваше приложение зависло. Т.е., например, так
Thread thread = new Thread() { public void run () { |
3) Наполнение базы при синхронизации это хорошо. Но если вместе с приложением вы получите пустую базу то а) вы устанете ждать, пока она наполнится б) теоретически пользователь может попробовать приложение без доступа к интернету (и если у него ничего не выйдет, он его просто удалит). Поэтому встала задача при установке приложения заполнять базу начальными данными (это также удобно на этапе тестирования). Сделать это можно так:
а) Создаём и наполняем базу SQLite (я для этого использовал SQLiteStudio). Удобно в случае небольшой начальной базы, или если она нужна нам для тестирования
Можно пойти и другим путём: скопировать заполненную базу с устройства (после синхронизации с сервером). Это удобно, когда начальная база огромна (например, перед публикацией готового приложения).
Скопировать базу можно с помощью adb, набрав в командной строке (устройство естественно должно быть подключено в режиме отладки)
C:\WINDOWS\system32>adb pull /data/data/ПОЛНОЕИМЯВАШЕГОПРИЛОЖЕНИЯ/databases/1cvers.db C:\
в данном случае база скопируется в корень C:\ (лучше все же копировать не в корень диска С:\ т.к. один раз потратил полдня из-за отсутствия прав на запись туда)
б) Создаём папку assets в структуре нашего проекта и кладём туда файл базы
в) В классе, который работает с БД (а работу с БД имеет смысл выделить в отдельный класс) пишем что-то вроде этого
boolean dbexist = checkdatabase(); if (dbexist) { Log.i("Database","База данных существует"); opendatabase(); } else { Log.i("Database","База данных не существует!"); createdatabase(); } |
и функции проверки наличия базы и копирования базы из файла
private boolean checkdatabase() { boolean checkdb = false; try { String myPath = DB_PATH + DB_NAME1; File dbfile = new File(myPath); checkdb = dbfile.exists(); } catch(SQLiteException e) { Log.i("Database", "База данных не существует!"); } return checkdb; } private void copydatabase() { Log.i("Database","Новая база данных копируется на устройство!"); byte[] buffer = new byte[1024]; OutputStream myOutput = null; int length; // Открываем локальную БД как входящий поток InputStream myInput = null; try { myInput = mycontext.getAssets().open(DB_NAME1); // Передаем данные из inputfile в outputfile myOutput = new FileOutputStream(DB_PATH + DB_NAME1); while((length = myInput.read(buffer)) > 0) { myOutput.write(buffer, 0, length); } myOutput.close(); myOutput.flush(); myInput.close(); Log.i("Database","Новая база данных скопирована на устройство"); } catch(IOException e) { e.printStackTrace(); } } |
Как видно, в коде встречается Log.i , намеренно оставил логи, чтобы подчеркунуть их важность для отладки. особенно для заядлого одинэсника, привыкшего держать всё под контролем с помощью отладчика.
Спасибо за внимание!
P.S. В java я недавно, поэтому если что приврал, поправьте в комментариях.
Если общественности будет интересно, то опубликую вторую часть, где планирую описать:
- Публикацию подписанного приложения
- Вставка рекламмы в приложение
- Публикация на google play
- То, что будет интересно народу и мне.
the end