2013-03-08 3 views
3

У нас есть файл расширения размером ~ 600 МБ, который мы используем с помощью механизма APK Expansion APK. Мы также должны разархивировать этот файл для фактического использования. Таким образом, для всего приложения плюс данные требуется около 1,4 ГБ памяти.Местоположение файла расширения Google Play

Насколько я могу судить, Google Play настаивает на загрузке .obb на «внутреннюю» SD, и, похоже, нет никакого способа изменить это. У нас много пользователей с большим количеством свободного места на их «внешней» SD-карте, но ограниченное пространство на внутреннем. Они кричат ​​о приложении, занимающем столько места. Мы можем что-то сделать?

В настоящее время мы расширение файла .obb к:

getExternalStorageDirectory()/Android/данные

Я полагаю, мы могли бы спросить у пользователя, где они хотели, и они могли бы выбрать истинную внешнюю карту SD. Однако это все равно оставит (на самом деле бесполезный) файл .obb на внутренней SD-карте, и Google Play заявляет, что мы не можем удалить это.

Есть ли у кого-нибудь предложения по правильному обращению?

+0

«У нас много пользователей с большим количеством свободного места на их« внешней »SD-карте, но ограниченное пространство на внутреннем», - с точки зрения Android, такой концепции нет. Существует только одно внешнее хранилище, представленное 'getExternalStorageDirectory()'. Все, что выходит за рамки этого, связано с расширением производителя устройств для Android, из которых материал APK расширения воспроизведения ничего не знает. – CommonsWare

ответ

1

согласно Expansion File Storage Location documentation, файлы расширения хранятся в

<shared-storage>/Android/obb/<package-name>/ 

где shared-storage является то, что возвращается getExternalStorageDirectory(), который должен быть на SD карту для пользователей, которые имеют SD-карту.

К сожалению, как указано на той же странице:

Для обеспечения надлежащего поведения, вы не должны удалять, перемещать или переименовывать файлы расширения.

Я хотел бы обратить особое внимание на этот пункт:

Если вы должны распаковать содержимое файлов расширения, не удалить .obb файлы расширения впоследствии и не сохранить распакованные данные в том же каталоге. Вы должны сохранить распакованные файлы в каталоге, указанном getExternalFilesDir(). Однако, если это возможно, лучше всего использовать формат файла расширения, который позволяет вам читать непосредственно из файла, а не требовать, чтобы вы распаковывали данные. Например, мы предоставили библиотечный проект под названием APK Expansion Zip Library, который считывает ваши данные непосредственно из ZIP-файла.

+0

Спасибо за ответ. Проблема в том, что для многих устройств есть 2 SD-карты. Внутренний и внешний (съемный). Кажется, что getExternalStorageDirectory() всегда возвращает внутреннюю SD-карту, которая обычно имеет более ограниченное хранилище. Мы должны иметь очень быстрый доступ к данным в файле .obb (и из кода C), поэтому нам нужно его расширить. – btschumy

1

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

Например, путь, где хранятся OBB файлов обеспечивается com.google.android.vending.expansion.downloader.Helpers:

static public String getSaveFilePath(Context c) { 
    File root = Environment.getExternalStorageDirectory(); 
    String path = root.toString() + Constants.EXP_PATH + c.getPackageName(); 
    return path; 
} 

(Также необходимо изменить getFilesystemRoot(String path) & isFilenameValid(String filename))

Если вы используете расширение Google, ZipFile Lib, а также, то вам также необходимо изменить 3 метода в com.android.vending.expansion.zipfile.APKExpansionSupport, которые определяют Environment.getExternalStorageDirectory() в качестве корневого каталога.

Эти изменения должны по крайней мере получить вас на полпути.

Также обратите внимание, что проблема с внешней SD-картой заключается в том, что их скорость сильно варьируется, обычно внутренняя SD будет иметь как минимум приличную скорость. Возможно, вы можете разделить OBB на 2 файла (при условии, что вам не нужна функция файла обновления) и переместить один из них на внешний SD.

+0

Я не заинтересован в взломе системы, чтобы сделать эту работу. Мой реальный вопрос состоял в том, что я где-то пропустил какую-то настройку, чтобы все это произошло на внешней SD-карте. Из комментариев CommonWare выше это звучит так, как будто нет. – btschumy

+0

Нет. Но это не взламывает систему, потому что она никогда не является частью платформы Android. Это всего лишь набор библиотек и услуг, предоставляемых приложением Google Play. – Kai

0

У меня была такая же проблема, но я нашел способ ее решить.

Если вы удалите OBB, то makeFileExist (в Helpers.java) вернет false. В вашей ExpDownloaderActivity, где вы проверяете расширениеFilesDelivered, вы будете использовать эту информацию для повторной загрузки OBB.

Я изменил doesFileExist и expansionFilesDelivered таким образом, чтобы не возвращать логическое значение, но целое число со следующим значением:

fileStatus == 0: ФЖДА отсутствует (должен быть загружен)

fileStatus == 1: ФЖДА доступен и может быть распакованы в другое место

fileStatus == 2: данные в OBB уже хранится в другое место

Теперь те трик: После распаковки д ata от OBB до моего любимого места, я заменяю оригинальный OBB файлом с тем же именем, которое содержит только размер файла исходного OBB в виде строки. Это освобождает занятое пространство на SD-карте.

Дальнейшие вызовы toFileExist и expandFilesDelivered возвращают filestatus = 2, что означает, что никаких действий не требуется.

Вот мои изменения в Helpers.java:

static public int doesFileExist(Context c, String fileName, long fileSize, 
     boolean deleteFileOnMismatch) { 
    // the file may have been delivered by Market --- let's make sure 
    // it's the size we expect 


    File fileForNewFile = new File(Helpers.generateSaveFileName(c, fileName)); 
    if (fileForNewFile.exists()) { 
     if (fileForNewFile.length() == fileSize) { 
      return 1; 
     } else if (fileForNewFile.length() < 100) { 
      // Read the file and look for the file size inside 
      String content = ""; 
      long isSize = 0; 
      FileInputStream fis = null; 
      try { 
       fis = new FileInputStream(fileForNewFile); 
       char current; 
       while (fis.available() > 0) { 
        current = (char) fis.read(); 
        content = content + String.valueOf(current); 
       } 

      } catch (Exception e) { 
       Log.d("ReadOBB", e.toString()); 
      } finally { 
       if (fis != null) 
        try { 
         fis.close(); 
        } catch (IOException ignored) { 
       } 
      } 
      try { 
       isSize = Long.parseLong(content); 
      } catch(NumberFormatException nfe) { 
       Log.d("ReadOBBtoInt", nfe.toString()); 
      } 
      if (isSize == fileSize) { 
       return 2; 
      } 
     } 
     if (deleteFileOnMismatch) { 
      // delete the file --- we won't be able to resume 
      // because we cannot confirm the integrity of the file 
      fileForNewFile.delete(); 
     } 
    } 
    return 0; 
} 

Если размер файла OBB не совпадают, я прочитал ÖBB и сравнить с размер_файла хранится внутри (это то, что размер файла shouldt быть) , Если это даст совпадение, я знаю, что файл уже обработан.

Это мои изменения в моей ExpDownloaderActivity:

int expansionFilesDelivered() { 
    int fileStatus = 0; 

    for (XAPKFile xf : xAPKS) { 
     if (xf.mFileSize > 0) { 
      String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsMain, xf.mFileVersion); 
      fileStatus = Helpers.doesFileExist(this, fileName, xf.mFileSize, false); 
      if (fileStatus==0) 
       return 0; 
     } 
    } 
    return fileStatus; 
} 

В OnCreate в ExpDownloaderActivity:

initializeDownloadUI(); 

    int fileStatus = expansionFilesDelivered(); 
    if (fileStatus==0) {  // OBB is missing 
      // ... Download the OBB file, same as on Downloader example 
    } else if (fileStatus==1) { 
     validateXAPKZipFiles(); // and, if OBB has no errors, unpack it to my favorite place 
           // if done, create a new OBB file with the original name 
           // and store a string with the original filesize in it. 
    } else { 
     finish();    // No action required  } 

Так что у меня данные распакованы, где я хочу, и - как уже упоминалось ОП - нет необходимо пространство на SD-карте для полного OBB и распакованных данных.

Смежные вопросы