Отформатировать SD-карту в Android

Вещи должны быть простыми, но, как и в большинстве случаев, в Android это не так. Мне нужно отформатировать SD-карту, если пользователь выбирает опцию в моем приложении. Не спрашивайте меня, зачем мне это нужно, если это уже есть в ОС... нецелесообразно, но это требование, которое мне нужно реализовать. Как вы, возможно, знаете, в разделе Настройки \ Хранилище \ Стереть SD-карту есть опция. Я взглянул на исходный код froyo, и это что-то вроде:

final IMountService service =
         IMountService.Stub.asInterface(ServiceManager.getService("mount"));
        if (service != null) {
            new Thread() {
                public void run() {
                try {
                        service.formatVolume(Environment.getExternalStorageDirectory().toString());
                    } catch (Exception e) {
                        // Intentionally blank - there's nothing we can do here
                    Log.w("MediaFormat", "Unable to invoke IMountService.formatMedia()");
                    }
                }
            }.start();
        } else {
            Log.w("MediaFormat", "Unable to locate IMountService");
        }

Он использует android.os.storage.IMountService и android.os.ServiceManager, и у меня, похоже, нет к нему доступа. Итак, как я это вижу, я мог бы рекурсивно искать каждый файл и удалять его, но это было бы «не в моем вкусе» ... или я мог бы запустить экран с «Стереть SD-карту» для пользователя.

Любая помощь приветствуется, так как я застрял.


person Alin    schedule 13.09.2011    source источник


Ответы (2)


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

Затем,

Попробуйте включить следующие разрешения в свое приложение:

1) MOUNT_FORMAT_FILESYSTEMShttp://developer.android.com/reference/android/Manifest.permission.html#MOUNT_FORMAT_FILESYSTEMS

2) MOUNT_UNMOUNT_FILESYSTEMShttp://developer.android.com/reference/android/Manifest.permission.html#MOUNT_UNMOUNT_FILESYSTEMS

Приложение настроек Android уже использует второе разрешение.

================================================================================

Когда вы выполняете сборку AOSP или любого другого кода дистрибутива, файл IMountService.java создается автоматически. Я думаю, он содержит следующую функцию, которая на самом деле отправляет команды форматирования демону vold:

private static class Proxy implements android.os.storage.IMountService
{
  private android.os.IBinder mRemote;
  Proxy(android.os.IBinder remote)
  {
    mRemote = remote;
  }

  public android.os.IBinder asBinder()
  {
    return mRemote;
  }

  // **** A LOT OF OTHER CODE IS HERE.....

  public int formatVolume(java.lang.String mountPoint) throws android.os.RemoteException
  {
    android.os.Parcel _data = android.os.Parcel.obtain();
    android.os.Parcel _reply = android.os.Parcel.obtain();
    int _result;
    try {
      _data.writeInterfaceToken(DESCRIPTOR);
      _data.writeString(mountPoint);
      mRemote.transact(Stub.TRANSACTION_formatVolume, _data, _reply, 0);
      _reply.readException();
      _result = _reply.readInt();
    }
    finally {
      _reply.recycle();
      _data.recycle();
    }
    return _result;
  }
}
person Abhijeet Pathak    schedule 13.09.2011
comment
Понял, о разрешениях, но до сих пор не знаю, как реализовать фактические операции форматирования. Спасибо за Ваш ответ. - person Alin; 13.09.2011
comment
Планируете ли вы использовать привилегии root (su) в своем приложении? - person Abhijeet Pathak; 13.09.2011
comment
Служба монтирования имеет проверку на MOUNT_UNMOUNT_FILESYSTEMS в коде. Другая возможность заключается в том, что системные приложения подписаны ключом платформы, который нельзя воспроизвести для обычных приложений. - person Abhijeet Pathak; 13.09.2011

Я не могу снова найти вопрос здесь, на SO, но у него было рабочее решение. Так что вся заслуга принадлежит этому парню ;)

public void wipeMemoryCard() {
        File deleteMatchingFile = new File(Environment
                .getExternalStorageDirectory().toString());
        try {
            File[] filenames = deleteMatchingFile.listFiles();
            if (filenames != null && filenames.length > 0) {
                for (File tempFile : filenames) {
                    if (tempFile.isDirectory()) {
                        wipeDirectory(tempFile.toString());
                        tempFile.delete();
                    } else {
                        tempFile.delete();
                    }
                }
            } else {
                deleteMatchingFile.delete();
            }
        } catch (Exception e) {
            Utils.log(e.getMessage());
        }
    }

    private static void wipeDirectory(String name) {
        File directoryFile = new File(name);
        File[] filenames = directoryFile.listFiles();
        if (filenames != null && filenames.length > 0) {
            for (File tempFile : filenames) {
                if (tempFile.isDirectory()) {
                    wipeDirectory(tempFile.toString());
                    tempFile.delete();
                } else {
                    tempFile.delete();
                }
            }
        } else {
            directoryFile.delete();
        }
    }
person Alin    schedule 15.09.2011
comment
Этот метод действительно удаляет файлы. Но этот метод не может помешать программе восстановления даты восстановить исходные данные. Я ищу метод для этого. - person peacepassion; 23.10.2014
comment
@peacepassion Ну, в вашем случае вам нужны специальные алгоритмы. Сложность алгоритма зависит от степени, в которой он должен быть защищен. Проверьте эти ссылки en.wikipedia.org/wiki/Data_erasure и semshred.com/hybrid_hard_drives . - person Saty; 05.06.2015