Previous Entry Share Next Entry
Сохранение и работа с метками Яндекс.Карт на Андроиде
nepal
k001

Насколько я понял, реализация мобильных Яндекс.Карт на Андроиде отстаёт от аналогичных решений на, скажем, Симбиане. В частности, вносимые пользователем метки хранятся локально в базе sqlite3, причём хранятся не на SD карточке, а в памяти телефона (на /data).

Проблема в том, что после перепрошивки (скажем, со штатной на CyanogenMod) или хард-ресета (мне приходилось его однажды делать) все ваши метки бесследно исчезают. Конечно, хотелось бы, чтобы они хранились или на SD карточке, или в гуглооблаке, или в яндексе, но увы, пока это не так.

Приходится заботу о метках брать в свои руки. Последующий текст предполагает, что у вас есть компьютер, на котором стоит ADB, а телефон присоединён к компьютеру через USB. Возможно, всё это работает только на рутованном телефоне!

Чтобы скачать метки с телефона на компьютер:
adb -d pull /data/data/ru.yandex.yandexmaps/databases/labels.db

В случае, если вы используете модифицированные Яндекс.Карты' от Александра Хохлова:
adb -d pull /data/data/ru.yandex.yandexmaps.khokhlov/databases/labels.db

Метки можно редактировать с помощью командной строки sqlite, если вы знаете SQL:

sqlite3 labels.db
SQLite version 3.6.23.1
Enter ".help" for instructions
Enter SQL statements terminated with a ";"

sqlite> .mode line

sqlite> SELECT * from sqlite_master;
    type = table
    name = android_metadata
tbl_name = android_metadata
rootpage = 3
     sql = CREATE TABLE android_metadata (locale TEXT)

    type = table
    name = mylabels
tbl_name = mylabels
rootpage = 4
     sql = CREATE TABLE mylabels (_id INTEGER PRIMARY KEY,label_name TEXT,label_name_tolower TEXT,lat LONG,lon LONG,geocode TEXT,date LONG)

sqlite> SELECT * FROM mylabels LIMIT 1;
               _id = 1
        label_name = Офис
label_name_tolower = офис
               lat = 55.8746625377941
               lon = 37.5884219154757
           geocode = Россия, Москва, Алтуфьевское шоссе, 44
              date = 1292572012292

Обратно в телефон labels.db запихиваются тоже через adb, только вместо pull говорим push:
adb -d push labels.db /data/data/ru.yandex.yandexmaps/databases/labels.db
или для карт от Хохлова:
adb -d push labels.db /data/data/ru.yandex.yandexmaps.khokhlov/databases/labels.db


  • 1

root для этих операций обязателен

Спасибо за отличный пост про работу с метками!
Сделал ссылку сюда из вопросов-ответов на странице нМЯК.
Для операций с файлами из /data/data/... действительно необходим root. Без него ничего не получится.

Re: root для этих операций обязателен

Очень жаль, что Яндекс.Разработчики так поступили.

Кстати, а что если сделать симлинку с
/data/data/ru.yandex.yandexmaps/databases/labels.db на /data/data/ru.yandex.yandexmaps.khokhlov/databases/labels.db (или наоборот, неважно) — чтобы не париться синхронизацией меток в Картах и Картах'?

Re: root для этих операций обязателен

Думаю, должно сработать, стоит попробовать :)
При обновлении приложения данные не удаляются, так что должно нормально переживать и установку новых версий.

Re: root для этих операций обязателен

Так как у приложений разный UID, в одной из программ изменение меток не работает ("произошла ошибка при изменении метки" или как-то так). Решается chmod 666, что, конечно, кривовато…

Re: root для этих операций обязателен

не решается chmod 666… впрочем, чёрт с ним

Re: root для этих операций обязателен

Можно было бы решить с пом. ACL — но там нет ACL.

Re: root для этих операций обязателен

Будем ждать синхронизации меток с большими картами...

спасибо за пост!

(Anonymous)
Возможно, скрипт будет полезен:


# converts labels from mobile yandex maps to gpx format
# created by Daniil Smelov, dn.smelov at gmail.com

import sqlite3, time
conn = sqlite3.connect("labels.db")
cursor = conn.cursor()
cursor.execute("SELECT * FROM mylabels;")
lines= cursor.fetchall()
f = open('output.gpx','w')

f.write('\n')
f.write('\n\n')

for line in lines:
lon=line[3]
lat=line[4]
pt_timestruct = time.gmtime(line[6]/1000.)
pt_time = time.strftime('%Y-%m-%dT%H:%M:%SZ',pt_timestruct)

f.write('\n' % (lat,lon))
f.write('%s\n' % pt_time)

name = "" + line[1] + "\n"
name_utf8 = name.encode('UTF-8')
f.write(name_utf8)
f.write('\n\n')

f.write('\n')
f.close()

И так, метки я смог перенести. Для этого использовал Root Explorer (устройство рутованное). Из папки нМЯК /data/data/ru.yandex.yandexmaps.khokhlov/databases/ пенес все файлы в папку МЯК /data/data/ru.yandex.yandexmaps/databases/. Затем изменил права доступа label.db - 777, suggestions.db - 666, uppointssugg.db - 666. И вуаля! Все заработало!

Root нужен обязательно, без него даже в /data зайти не получается.

  • 1
?

Log in