Протоколом cifs в Android или как я файлы из сломанного телефона извели

Протоколом cifs в Android или как я файлы из сломанного телефона извели

420
ПОДЕЛИТЬСЯ

Но, видимо, создателей Нексуса 4 были ярыми противниками nidubrolu, как с разбитым экраном, на сто процентов отказал сенсорный экран. Сейчас я один из тех подонков, с разбитым экраном!». Так вышло, что я разбил экран собственного возлюбленного Нексуса 4. В общем, ничего ужасного, принимают телефон в ремонт и все. Но получить их можно лишь тогда, когда экран разблокирован, телефон не желал демонстрировать содержимое SD-карты без разблокировки экрана “супер секрет” жест. Моя 1-ая мысль была «блин! Но, на телефоне были файлы которые мне необходимы были на данный момент, а не через пару недель.

Незначительно покопавшись с АБР я плюнул на пробы разблокировки экрана через консоль. Все советы взлом экрана блокировки подходящего корня, и мой телефон не один из их. Выбор пал на библиотеку JCIFS, ведь в прошедшем мне приходилось работать с ней и заморочек в его использовании не появилось. Было решено действовать изнутри.
Нам пришлось написать заявление, что бы без помощи других скопировать файлы с телефона на rassharennuju WiFi на папку. Неотклонимые условия для такового трюка: включена отладка по USB и комп, к которому телефон уже выдала разрешение на отладку, и наличие Wi-Fi сеть, к которой телефон подключается, как лишь вы видите ее (у меня дома есть Wi-Fi Веб).
Хоть она и не увидит белоснежный свет из-за блокировки экрана, но чтоб запустить сервис, который будет делать огромную часть работы, она будет нужна.MainActivity.javaфайл mainactivity открытый класс расширяет активность {

@Переопределить
защищенный способ oncreate недействительными(Bundle, его savedInstanceState) {
супер.способ oncreate(savedInstanceState);
startService(новое намерение(это, SynchronizeService.class));
}
} Предварительные работы
Сделайте проект с одним видом деятельности.
Копирование файлов будет делать отдельный сервис. Так как активности не видно, ее жизнеспособность рассчитывать не стоит, но сервис выполняются на переднем плане, непревзойденно справляется с данной задачей.
строчкой.synchronize_service_message))
.setContentIntent(getDummyContentIntent())
.помощью setcolor(Цвет.Голубий)
.setProgress(1000, 0, истина);
startForeground(FOREGROUND_NOTIFY_ID, строитель.выстроить());

// Это держит процессор пробудился
В powermanager на powermanager = (в powermanager) getSystemService(POWER_SERVICE);
финал сна сна = в powermanager.newWakeLock(powermanager на.PARTIAL_WAKE_LOCK, «SynchronizeWakelockTag»);
wakelock-ов.приобрести();
}

@Переопределить
публичный Тип int onStartCommand(намерение намерение, внутр флаги, Тип int startId) {
возвращение START_NOT_STICKY;
}

@Переопределить
общественная IBinder onBind(намерение намерение) {
возвращать значение NULL;
}
}
До этого чем двигаться далее, давайте добавим зависимость, файл сборки.gradle в, который добавляют в проект на библиотеку JCIFS. В конечном счете, AndroidManifest.xml я смотрелась вот так. строчкой.имя_приложения -))
.setContentText(способа getstring(р. SynchronizeService.javaобщественный класс расширяет сервис SynchronizeService {
Личная статической окончательного int в FOREGROUND_NOTIFY_ID = 1;

@Переопределить
публичного недействительными способ oncreate() {
супер.способ oncreate();
окончательное NotificationCompat.Построитель построитель = новейший NotificationCompat.Строитель(этот)
.setSmallIcon(р. зависимостей {
… компиляция ‘jcifs:jcifs:1.3.17’
}
Также необходимо добавить некие разрешения в манифесте и не забудьте написать о нашей Службе. мипмап.ic_launcher)
.setContentTitle(способа getstring(р.
<употребляет-разрешение Android:имя=»дроида.разрешение.Веб»/>

// Чтения с карты SD. <употребляет-разрешение Android:имя=»дроида.разрешение.РАЗГАДЫВАНИЯ»/>

// Нужно для работы с сетью. <употребляет-разрешение Android:имя=»дроида.разрешение.Не имеют»/>

<приложение
android:label=»@string/app_name»
android:icon=»@mipmap/ic_launcher»>

<активности дроид:имя=».деятельности.Файл mainactivity»>
<намерение-фильтр>
<действие дроид:имя=»дроида.намерениях.действий.Основная» />
<Категория дроид:имя=»дроида.намерениях.Категория.Пусковая установка» />
</намерение-фильтр>
</деятельность>

<сервис дроид:имя=».услуг.SynchronizeService»/>

</заявка>
</манифест>
Копирование файлов
Итак, все приготовления окончены. Сейчас, раз запустить приложение, в перечне уведомлений будет сообщение сервис (начиная с Android 5, вы сможете установить демонстрировать сообщение на экране блокировки. Раз версия дроида меньше вы этого сообщения не увидите), а это означает, приложение работает как нужно и вы сможете начать самые вкусные — передача файлов. AndroidManifest.xml<манифест атрибутов xmlns:ОС Android=»http://в схемах.дроид.ком/АПК/рес/ОС Android»
пакет=»ру.kamisempai.wifisynchronizer»>

// Необходимости держать телефон от сна.
Этот логин и пароль для сетевого ресурса, который будет употребляться для сотворения NtlmPasswordAuthentication. В целях выполнения сетевых операций в главном потоке, поставит его в AsyncTask. новейшие NtlmPasswordAuthentication(юзер + «:» + пароль)
: NtlmPasswordAuthentication.Анонимно;
mFileFilter = fileFilter;
}
}
Особенное внимание следует направить на характеристики юзера и пароль. Раз доступ к папке без пароля, в качестве проверки подлинности нужно применять NtlmPasswordAuthentication.Анонимно. Как правило, большая часть заморочек лежат в не правильной настройке политики сохранности на компе. открытый класс CopyFilesToSharedFolderTask расширяет AsyncTask<недействительным, двухместный, строчка> {

Личная окончательного файла mFolderToCopy;
Личная заключительная строчка mSharedFolderUrl;
Личная окончательного NtlmPasswordAuthentication городке маут, район;

Личная FileFilter mFileFilter;

общественная CopyFilesToSharedFolderTask(файл folderToCopy, sharedFolderUrl строчку, строчку юзера, строчка пароль, FileFilter fileFilter) {
супер();
mFolderToCopy = folderToCopy; // папки, которые должны быть скопированы. mSharedFolderUrl = sharedFolderUrl; // URL-адресок в сетевую папку, в которую требуется скопировать файлы с вашего телефона. Наилучший метод проверить опции заключается в попытке открыть сетевую папку на вашем телефоне с помощью хоть какого файлового менеджера, который поддерживает работу по сети. городке маут, район = (юзер != нуль && пароль != нуль)? Смотрится просто, но аутентификации самой большой неувязкой вы сможете столкнуться при работе с сетевыми папками.
пустоты) {
mMaxProgress = getFilesSize(mFolderToCopy);
mProgress = 0;
publishProgress(0д);

попытайтесь {
SmbFile общественная_папка = новейший SmbFile(mSharedFolderUrl, городке маут, район);
раз (общественная_папка.существует() && общественная_папка.isDirectory()) {
copyfiles в(mFolderToCopy, общественная_папка);
}
} изловить (е наличие исключений malformedurlexception) {
возвращение «недопустимый URL-адресок.»;
} изловить (е возвращает экземпляр) {
е.печатные издания();
обратный e.способа getmessage();
}

возвращать значение NULL;
}
Способ doInBackground возвращает сообщение о ошибке. личный двухместный mMaxProgress;
личный двухместный mProgress;

… И еще, чтоб сделать объект SmbFile нужна информация для проверки подлинности, который мы сделали ранее. @Переопределить
охраняемых строчка doInBackground(пустоты… На удивление, в JCIFS чрезвычайно просто работать с файлами. Единственное, что кидается в глаза, является наличие управляемых исключениях в практически всех способов класса. SmbFile файл для работы с сетевыми файлами. Вы не почувствуете фактически никакой различия меж SmbFile и обыденный файл. Раз NULL ворачивается, тогда все прошло гладко и без ошибок.
Рекурсивный способ getFilesSize вычисляет суммарный размер файлов, которые будут нужны для расчета общего прогресса. Файлов может быть много… Потому, чтоб показать прогресс-это жизненно принципиальная функция. нет, не так. К примеру, вы сможете исключить все папки, начинающиеся с точки (либо добавить в темный перечень папку «дроид». личный двухместный getFilesSize(файл) {
раз (!checkFilter(файл))
возврат 0;

раз (файл.isDirectory()) {
Размер типа int = 0;
Файл[] filesList = файл.в listFiles();
для (файл innerFile : filesList)
Размер += getFilesSize(innerFile);
вернуть Размер;
}

возвращение (Double) в файл.длина();
}

Личная boolean значение checkFilter(файл) {
возвращение mFileFilter == нуль || mFileFilter.принимаем(файл);
}
Передают конструктору фильтра помогает избавиться от ненадобных файлов и папок. Они могут быть чрезвычайно много!
Как я уже говорил ранее, работа с SmbFile не различается от работы с одним файлом, потому процесс передачи данных с телефона на ПК не различается оригинальностью. Я даже упрятать код под спойлер, чтоб не загромождать статью еще наиболее тривиальный код.
mProgress += (Double) с fileToCopy.длина();
publishProgress(mProgress / mMaxProgress * 100d);
}
}
}

// Ничем не приметный способ для копирования файлов. раз (fileToCopy.существует()) {
раз (fileToCopy.isDirectory()) {
Файл[] filesList = fileToCopy.в listFiles();

// Создание каталога в конце ставить «/». Дело в том, что JCIFS принимает не все файлы, заканчивающиеся на «/» знак лишь в виде файла, а не каталога. А конкретно, «some_foldel» будут отброшены, и новенькая папка будет иметь URL-адресок: «файл://мой-ПК/общий/новейшей папке», заместо ожидаемого «файл://мой-ПК/общий/some_foldel/новейшей папке». Способы и copyfiles в copySingleFileЧастная статические Заключительные строчки LOG_TAG = «WiFiSynchronizer»;

Личная copyfiles в пустоту(файл fileToCopy, SmbFile общественная_папка) кидает ioexception {
раз (!checkFilter(fileToCopy))
Return; // раз файл либо папка не проходит фильтр, а не копировать его. Потому, раз URL-Адресок из сетевой папки будет смотреться вот так: «файл://мой-ПК/общий/some_foldel», каких-или неудач при разработке новейшей папки в папке «some_foldel». SmbFile newSharedFolder = новейший SmbFile(общественная_папка, fileToCopy.способ getname() + «/»);
раз (!newSharedFolder.существует()) {
newSharedFolder.команды mkdir();
Журнальчик.д(LOG_TAG, «сотворена папка:» + newSharedFolder.getPath());
}
еще
Журнальчик.д(LOG_TAG, «папка уже существует:» + newSharedFolder.getPath());
для (файла файла : filesList)
copyfiles в(файл, newSharedFolder); // Рекурсивный вызов
} еще {
SmbFile newSharedFile = новейший SmbFile(общественная_папка, fileToCopy.способ getname());

// Раз файл уже сотворен, он не будет копией. раз (!newSharedFile.существует()) {
copySingleFile(fileToCopy, newSharedFile);
Журнальчик.д(LOG_TAG, «скопировать файл:» + newSharedFile.getPath());
}
еще
Журнальчик.д(LOG_TAG, «файл уже существует:» + newSharedFile.getPath());

// Обновление прогресс. Личная недействительными copySingleFile(файл-файл, SmbFile sharedFile) кидает ioexception {
Возвращает экземпляр исключение = нуль;
Входной поток inputstream inputstream в = нуль;
OutputStream outputStream = NULL;в
попытайтесь {
outputStream = новейший SmbFileOutputStream(sharedFile);
inputstream в = новейший fileinputstream из(файла);

б[] bytesBuffer = новейший б[1024];
Тип int bytesRead;
пока ((bytesRead = класса inputstream.читать(bytesBuffer)) > 0) {
outputStream.писать(bytesBuffer, 0, bytesRead);
}
} изловить (е возвращает экземпляр) {
исключение = е;
} в конце концов, {
раз (класса inputstream != нуль)
попытайтесь {
класса inputstream.закрыть();
} изловить (е возвращает экземпляр) {
е.печатные издания();
}
раз (outputStream != нуль)
попытайтесь {
outputStream.закрыть();
} изловить (е возвращает экземпляр) {
е.печатные издания();
}
}
раз (исключением != нуль)
кидать исключение;
}
Код тривиальный, но в нем есть один не полностью естественным является добавление знака «/» в конце имени папки при разработке новейшего SmbFile. // Естественно, в иной ситуации, вы могли бы желать добавить проверку на хэш, но в моем случае это было бы лишним. Таковым образом, для таковых папок, способы isDirectory, команды mkdir либо listFiles будет работать верно.
// Служба никогда не остановится опосля закрытия таска. строчкой.synchronize_service_success), Цвет.Зеленоватый);
еще
showNotification(errorMessage, Цвет.Красноватый);
stopSelf();
wakelock-ов.релиз(); // не забудьте высвободить сна
}

@Переопределить
охраняемых недействительными onCancelled(строчка errorMessage) {
// Этот код никогда не выполнится. Сейчас запустите задачку в oncreate сервиса. строчкой.synchronize_service_progress), значения[0]) + «%»);
mNotifyManager.уведомить(FOREGROUND_NOTIFY_ID, строитель.выстроить());
}

@Переопределить
охраняемых недействительными onPostExecute(строчка errorMessage) {
stopForeground(истина);
раз (errorMessage == NULL)и
showNotification(способа getstring(р. значения) {
строитель.setProgress(100, значения[0].intValue(), ересь)
.setContentText(строчка.Формат(«%s в %.3ф», способа getstring(р. Личная статической окончательного int в FOREGROUND_NOTIFY_ID = 1;
Личная статической окончательного int в MESSAGE_NOTIFY_ID = 2;

личные статические Заключительные строчки SHARED_FOLDER_URL = «файл://192.168.0.5/общие/»;
… Способ onProgressUpdate переопределен для отображения состояния прогресса и onPostExecute показывает сообщение опосля завершения загрузки либо возникает ошибка, и потом завершает работу службы. stopSelf();
wakelock-ов.высвободить();
}
};
задачка.выполнить();
В моем случае, имя юзера и пароль не требуется, фильтр я тоже указывать не стал. окончательный файл folderToCopy = getFolderToCopy();
CopyFilesToSharedFolderTask задачка = новейший CopyFilesToSharedFolderTask(folderToCopy, SHARED_FOLDER_URL, нуль, нуль, нуль) {
@Переопределить
охраняемых недействительными onProgressUpdate(двойной… Но вы никогда не понимаете, вдруг я желаю что-то поменять. Практически готов.
Там было сообщение от запущенной службы. Запустить приложение. В то время как вычисления общего размера файлов отображается неопределенное состояние прогресса. Но индикатор указывает 0%, позже полоса медлительно, малеханькими, еле видными шажками, начинает двигаться к 100%.

Когда работа была завершена, на мониторе отображается сообщение о успешном итоге, и я имел все нужные файлы, предварительно заточенным на сломанный телефон.
Выручает лишь то, что единственное, жира в защите от взлома это необходимо для компа, который уже имеет права на отладку. Невзирая на то, что телефон был мой, и доступа к файлам на нем не противоречит российскому законодательству, я получил их без использования пароля! Но, подождите! Это значит, что раз лишь один включен режим отладки не трудно получить доступ к содержимому SD-карты, даже не зная пароля. Нежданные выводы
То, что было необходимо, я получил. В данном случае, телефон был не корень. В это время заварить чаю, развалиться на диванчике и включить какой-нибудь сериальчик.
В то же время, Android-Разраб, быть на охраннике, раз Вы не желаете, чтоб ваши обнаженные фото увидел кто-то иной. Представлена не так издавна, в новейшей версии Android, вы сможете закрыть этот пробел, так как для доступа к нужной разрешительной документации, будет нужно доказательство юзера, что нереально, когда экран заблокирован. И помню, позволяя хоть какому компу USB отладки сделайте другую лазейку, чтоб взломать свой телефон.
Спасибо за внимание. Буду рад узреть Ваши мысли в комментах. Начальный код можно отыскать по последующей ссылке: github.com/KamiSempai/WiFiFolderSynchronizer

habrahabr.ru К огорчению изредка можно применять АБР и узенький взор на делему не разрешить мне приехать к нему. А конкретно применять АБР тянуть команду. УПД: как я и ждал, есть наиболее обычное решение моей трудности. Я попробовал разблокировать экран и нет загрузки файлов. EvgenT спасибо за неплохой комментарий.