2013-02-26 111 views
0

時沒有發現這是我的包名:com.abc.ssAndroid的擴展文件 - 資源測試

我現在已經手動創建與MNT/SD卡/安卓/ OBB包名com.abc.s的文件夾/com.abc.ss/main.2.com.abc.ss.obb

但是當我運行示例應用程序它說下載失敗:

這裏是我的屏幕截圖:

enter image description here

這裏我的代碼;

public class SampleDownloaderActivity extends Activity implements IDownloaderClient { 
    private static final String LOG_TAG = "LVLDownloader"; 
    private ProgressBar mPB; 

    private TextView mStatusText; 
    private TextView mProgressFraction; 
    private TextView mProgressPercent; 
    private TextView mAverageSpeed; 
    private TextView mTimeRemaining; 

    private View mDashboard; 
    private View mCellMessage; 

    private Button mPauseButton; 
    private Button mWiFiSettingsButton; 

    private boolean mStatePaused; 
    private int mState; 

    private IDownloaderService mRemoteService; 

    private IStub mDownloaderClientStub; 

    private void setState(int newState) { 
     if (mState != newState) { 
      mState = newState; 
      mStatusText.setText(Helpers.getDownloaderStringResourceIDFromState(newState)); 
     } 
    } 

    private void setButtonPausedState(boolean paused) { 
     mStatePaused = paused; 
     int stringResourceID = paused ? R.string.text_button_resume : 
       R.string.text_button_pause; 
     mPauseButton.setText(stringResourceID); 
    } 

    /** 
    * This is a little helper class that demonstrates simple testing of an 
    * Expansion APK file delivered by Market. You may not wish to hard-code 
    * things such as file lengths into your executable... and you may wish to 
    * turn this code off during application development. 
    */ 
    private static class XAPKFile { 
     public final boolean mIsMain; 
     public final int mFileVersion; 
     public final long mFileSize; 

     XAPKFile(boolean isMain, int fileVersion, long fileSize) { 
      mIsMain = isMain; 
      mFileVersion = fileVersion; 
      mFileSize = fileSize; 
     } 
    } 

    /** 
    * Here is where you place the data that the validator will use to determine 
    * if the file was delivered correctly. This is encoded in the source code 
    * so the application can easily determine whether the file has been 
    * properly delivered without having to talk to the server. If the 
    * application is using LVL for licensing, it may make sense to eliminate 
    * these checks and to just rely on the server. 
    */ 
    private static final XAPKFile[] xAPKS = { 
      new XAPKFile(
        true, // true signifies a main file 
        2, // the version of the APK that the file was uploaded 
         // against 
        23232840L // the length of the file in bytes 
      ), 
      new XAPKFile(
        false, // false signifies a patch file 
        4, // the version of the APK that the patch file was uploaded 
         // against 
        512860L // the length of the patch file in bytes 
      )    
    }; 

    /** 
    * Go through each of the APK Expansion files defined in the structure above 
    * and determine if the files are present and match the required size. Free 
    * applications should definitely consider doing this, as this allows the 
    * application to be launched for the first time without having a network 
    * connection present. Paid applications that use LVL should probably do at 
    * least one LVL check that requires the network to be present, so this is 
    * not as necessary. 
    * 
    * @return true if they are present. 
    */ 
    boolean expansionFilesDelivered() { 
     for (XAPKFile xf : xAPKS) { 
      String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsMain, xf.mFileVersion); 
      if (!Helpers.doesFileExist(this, fileName, xf.mFileSize, false)) { 
       return false; 
      } 
     } 
     return true; 
    } 

    /** 
    * Calculating a moving average for the validation speed so we don't get 
    * jumpy calculations for time etc. 
    */ 
    static private final float SMOOTHING_FACTOR = 0.005f; 

    /** 
    * Used by the async task 
    */ 
    private boolean mCancelValidation; 

    /** 
    * Go through each of the Expansion APK files and open each as a zip file. 
    * Calculate the CRC for each file and return false if any fail to match. 
    * 
    * @return true if XAPKZipFile is successful 
    */ 
    void validateXAPKZipFiles() { 
     AsyncTask<Object, DownloadProgressInfo, Boolean> validationTask = new AsyncTask<Object, DownloadProgressInfo, Boolean>() { 

      @Override 
      protected void onPreExecute() { 
       mDashboard.setVisibility(View.VISIBLE); 
       mCellMessage.setVisibility(View.GONE); 
       mStatusText.setText(R.string.text_verifying_download); 
       mPauseButton.setOnClickListener(new View.OnClickListener() { 
        @Override 
        public void onClick(View view) { 
         mCancelValidation = true; 
        } 
       }); 
       mPauseButton.setText(R.string.text_button_cancel_verify); 
       super.onPreExecute(); 
      } 

      @Override 
      protected Boolean doInBackground(Object... params) { 
       for (XAPKFile xf : xAPKS) { 
        String fileName = Helpers.getExpansionAPKFileName(
          SampleDownloaderActivity.this, 
          xf.mIsMain, xf.mFileVersion); 
        if (!Helpers.doesFileExist(SampleDownloaderActivity.this, fileName, 
          xf.mFileSize, false)) { 
         return false; 
        } 
        fileName = Helpers 
          .generateSaveFileName(SampleDownloaderActivity.this, fileName); 
        ZipResourceFile zrf; 
        byte[] buf = new byte[1024 * 256]; 
        try { 
         zrf = new ZipResourceFile(fileName); 
         ZipEntryRO[] entries = zrf.getAllEntries(); 
         /** 
         * First calculate the total compressed length 
         */ 
         long totalCompressedLength = 0; 
         for (ZipEntryRO entry : entries) { 
          totalCompressedLength += entry.mCompressedLength; 
         } 
         float averageVerifySpeed = 0; 
         long totalBytesRemaining = totalCompressedLength; 
         long timeRemaining; 
         /** 
         * Then calculate a CRC for every file in the Zip file, 
         * comparing it to what is stored in the Zip directory. 
         * Note that for compressed Zip files we must extract 
         * the contents to do this comparison. 
         */ 
         for (ZipEntryRO entry : entries) { 
          if (-1 != entry.mCRC32) { 
           long length = entry.mUncompressedLength; 
           CRC32 crc = new CRC32(); 
           DataInputStream dis = null; 
           try { 
            dis = new DataInputStream(
              zrf.getInputStream(entry.mFileName)); 

            long startTime = SystemClock.uptimeMillis(); 
            while (length > 0) { 
             int seek = (int) (length > buf.length ? buf.length 
               : length); 
             dis.readFully(buf, 0, seek); 
             crc.update(buf, 0, seek); 
             length -= seek; 
             long currentTime = SystemClock.uptimeMillis(); 
             long timePassed = currentTime - startTime; 
             if (timePassed > 0) { 
              float currentSpeedSample = (float) seek 
                /(float) timePassed; 
              if (0 != averageVerifySpeed) { 
               averageVerifySpeed = SMOOTHING_FACTOR 
                 * currentSpeedSample 
                 + (1 - SMOOTHING_FACTOR) 
                 * averageVerifySpeed; 
              } else { 
               averageVerifySpeed = currentSpeedSample; 
              } 
              totalBytesRemaining -= seek; 
              timeRemaining = (long) (totalBytesRemaining/averageVerifySpeed); 
              this.publishProgress(
                new DownloadProgressInfo(
                  totalCompressedLength, 
                  totalCompressedLength 
                    - totalBytesRemaining, 
                  timeRemaining, 
                  averageVerifySpeed) 
                ); 
             } 
             startTime = currentTime; 
             if (mCancelValidation) { 
              return true; 
             } 
            } 
            if (crc.getValue() != entry.mCRC32) { 
             Log.e(Constants.TAG, 
               "CRC does not match for entry: " 
                 + entry.mFileName); 
             Log.e(Constants.TAG, 
               "In file: " + entry.getZipFileName()); 
             return false; 
            } 
           } finally { 
            if (null != dis) { 
             dis.close(); 
            } 
           } 
          } 
         } 
        } catch (IOException e) { 
         e.printStackTrace(); 
         return false; 
        } 
       } 
       return true; 
      } 

      @Override 
      protected void onProgressUpdate(DownloadProgressInfo... values) { 
       onDownloadProgress(values[0]); 
       super.onProgressUpdate(values); 
      } 

      @Override 
      protected void onPostExecute(Boolean result) { 
       if (result) { 
        mDashboard.setVisibility(View.VISIBLE); 
        mCellMessage.setVisibility(View.GONE); 
        mStatusText.setText(R.string.text_validation_complete); 
        mPauseButton.setOnClickListener(new View.OnClickListener() { 
         @Override 
         public void onClick(View view) { 
          finish(); 
         } 
        }); 
        mPauseButton.setText(android.R.string.ok); 
       } else { 
        mDashboard.setVisibility(View.VISIBLE); 
        mCellMessage.setVisibility(View.GONE); 
        mStatusText.setText(R.string.text_validation_failed); 
        mPauseButton.setOnClickListener(new View.OnClickListener() { 
         @Override 
         public void onClick(View view) { 
          finish(); 
         } 
        }); 
        mPauseButton.setText(android.R.string.cancel); 
       } 
       super.onPostExecute(result); 
      } 

     }; 
     validationTask.execute(new Object()); 
    } 

    /** 
    * If the download isn't present, we initialize the download UI. This ties 
    * all of the controls into the remote service calls. 
    */ 
    private void initializeDownloadUI() { 
     mDownloaderClientStub = DownloaderClientMarshaller.CreateStub 
       (this, SampleDownloaderService.class); 
     setContentView(R.layout.main); 

     mPB = (ProgressBar) findViewById(R.id.progressBar); 
     mStatusText = (TextView) findViewById(R.id.statusText); 
     mProgressFraction = (TextView) findViewById(R.id.progressAsFraction); 
     mProgressPercent = (TextView) findViewById(R.id.progressAsPercentage); 
     mAverageSpeed = (TextView) findViewById(R.id.progressAverageSpeed); 
     mTimeRemaining = (TextView) findViewById(R.id.progressTimeRemaining); 
     mDashboard = findViewById(R.id.downloaderDashboard); 
     mCellMessage = findViewById(R.id.approveCellular); 
     mPauseButton = (Button) findViewById(R.id.pauseButton); 
     mWiFiSettingsButton = (Button) findViewById(R.id.wifiSettingsButton); 

     mPauseButton.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       if (mStatePaused) { 
        mRemoteService.requestContinueDownload(); 
       } else { 
        mRemoteService.requestPauseDownload(); 
       } 
       setButtonPausedState(!mStatePaused); 
      } 
     }); 

     mWiFiSettingsButton.setOnClickListener(new View.OnClickListener() { 

      @Override 
      public void onClick(View v) { 
       startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS)); 
      } 
     }); 

     Button resumeOnCell = (Button) findViewById(R.id.resumeOverCellular); 
     resumeOnCell.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View view) { 
       mRemoteService.setDownloadFlags(IDownloaderService.FLAGS_DOWNLOAD_OVER_CELLULAR); 
       mRemoteService.requestContinueDownload(); 
       mCellMessage.setVisibility(View.GONE); 
      } 
     }); 

    } 

    /** 
    * Called when the activity is first create; we wouldn't create a layout in 
    * the case where we have the file and are moving to another activity 
    * without downloading. 
    */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     /** 
     * Both downloading and validation make use of the "download" UI 
     */ 
     initializeDownloadUI(); 

     /** 
     * Before we do anything, are the files we expect already here and 
     * delivered (presumably by Market) For free titles, this is probably 
     * worth doing. (so no Market request is necessary) 
     */ 
     if (!expansionFilesDelivered()) { 

      try { 
       Intent launchIntent = SampleDownloaderActivity.this 
         .getIntent(); 
       Intent intentToLaunchThisActivityFromNotification = new Intent(
         SampleDownloaderActivity 
         .this, SampleDownloaderActivity.this.getClass()); 
       intentToLaunchThisActivityFromNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | 
         Intent.FLAG_ACTIVITY_CLEAR_TOP); 
       intentToLaunchThisActivityFromNotification.setAction(launchIntent.getAction()); 

       if (launchIntent.getCategories() != null) { 
        for (String category : launchIntent.getCategories()) { 
         intentToLaunchThisActivityFromNotification.addCategory(category); 
        } 
       } 

       // Build PendingIntent used to open this activity from 
       // Notification 
       PendingIntent pendingIntent = PendingIntent.getActivity(
         SampleDownloaderActivity.this, 
         0, intentToLaunchThisActivityFromNotification, 
         PendingIntent.FLAG_UPDATE_CURRENT); 
       // Request to start the download 
       int startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(this, 
         pendingIntent, SampleDownloaderService.class); 

       if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { 
        // The DownloaderService has started downloading the files, 
        // show progress 
        initializeDownloadUI(); 
        return; 
       } // otherwise, download not needed so we fall through to 
        // starting the movie 
      } catch (NameNotFoundException e) { 
       Log.e(LOG_TAG, "Cannot find own package! MAYDAY!"); 
       e.printStackTrace(); 
      } 

     } else { 
      validateXAPKZipFiles(); 
     } 

    } 

    /** 
    * Connect the stub to our service on start. 
    */ 
    @Override 
    protected void onStart() { 
     if (null != mDownloaderClientStub) { 
      mDownloaderClientStub.connect(this); 
     } 
     super.onStart(); 
    } 

    /** 
    * Disconnect the stub from our service on stop 
    */ 
    @Override 
    protected void onStop() { 
     if (null != mDownloaderClientStub) { 
      mDownloaderClientStub.disconnect(this); 
     } 
     super.onStop(); 
    } 

    /** 
    * Critical implementation detail. In onServiceConnected we create the 
    * remote service and marshaler. This is how we pass the client information 
    * back to the service so the client can be properly notified of changes. We 
    * must do this every time we reconnect to the service. 
    */ 
    @Override 
    public void onServiceConnected(Messenger m) { 
     mRemoteService = DownloaderServiceMarshaller.CreateProxy(m); 
     mRemoteService.onClientUpdated(mDownloaderClientStub.getMessenger()); 
    } 

    /** 
    * The download state should trigger changes in the UI --- it may be useful 
    * to show the state as being indeterminate at times. This sample can be 
    * considered a guideline. 
    */ 
    @Override 
    public void onDownloadStateChanged(int newState) { 
     setState(newState); 
     boolean showDashboard = true; 
     boolean showCellMessage = false; 
     boolean paused; 
     boolean indeterminate; 
     switch (newState) { 
      case IDownloaderClient.STATE_IDLE: 
       // STATE_IDLE means the service is listening, so it's 
       // safe to start making calls via mRemoteService. 
       paused = false; 
       indeterminate = true; 
       break; 
      case IDownloaderClient.STATE_CONNECTING: 
      case IDownloaderClient.STATE_FETCHING_URL: 
       showDashboard = true; 
       paused = false; 
       indeterminate = true; 
       break; 
      case IDownloaderClient.STATE_DOWNLOADING: 
       paused = false; 
       showDashboard = true; 
       indeterminate = false; 
       break; 

      case IDownloaderClient.STATE_FAILED_CANCELED: 
      case IDownloaderClient.STATE_FAILED: 
      case IDownloaderClient.STATE_FAILED_FETCHING_URL: 
      case IDownloaderClient.STATE_FAILED_UNLICENSED: 
       paused = true; 
       showDashboard = false; 
       indeterminate = false; 
       break; 
      case IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION: 
      case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION: 
       showDashboard = false; 
       paused = true; 
       indeterminate = false; 
       showCellMessage = true; 
       break; 

      case IDownloaderClient.STATE_PAUSED_BY_REQUEST: 
       paused = true; 
       indeterminate = false; 
       break; 
      case IDownloaderClient.STATE_PAUSED_ROAMING: 
      case IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE: 
       paused = true; 
       indeterminate = false; 
       break; 
      case IDownloaderClient.STATE_COMPLETED: 
       showDashboard = false; 
       paused = false; 
       indeterminate = false; 
       validateXAPKZipFiles(); 
       return; 
      default: 
       paused = true; 
       indeterminate = true; 
       showDashboard = true; 
     } 
     int newDashboardVisibility = showDashboard ? View.VISIBLE : View.GONE; 
     if (mDashboard.getVisibility() != newDashboardVisibility) { 
      mDashboard.setVisibility(newDashboardVisibility); 
     } 
     int cellMessageVisibility = showCellMessage ? View.VISIBLE : View.GONE; 
     if (mCellMessage.getVisibility() != cellMessageVisibility) { 
      mCellMessage.setVisibility(cellMessageVisibility); 
     } 

     mPB.setIndeterminate(indeterminate); 
     setButtonPausedState(paused); 
    } 

    /** 
    * Sets the state of the various controls based on the progressinfo object 
    * sent from the downloader service. 
    */ 
    @Override 
    public void onDownloadProgress(DownloadProgressInfo progress) { 
     mAverageSpeed.setText(getString(R.string.kilobytes_per_second, 
       Helpers.getSpeedString(progress.mCurrentSpeed))); 
     mTimeRemaining.setText(getString(R.string.time_remaining, 
       Helpers.getTimeRemaining(progress.mTimeRemaining))); 

     //mAverageSpeed.setText("" + Helpers.getSpeedString(progress.mCurrentSpeed)); 
     // mTimeRemaining.setText("" + Helpers.getTimeRemaining(progress.mTimeRemaining)); 

     progress.mOverallTotal = progress.mOverallTotal; 
     mPB.setMax((int) (progress.mOverallTotal >> 8)); 
     mPB.setProgress((int) (progress.mOverallProgress >> 8)); 
     mProgressPercent.setText(Long.toString(progress.mOverallProgress 
       * 100/
       progress.mOverallTotal) + "%"); 
     mProgressFraction.setText(Helpers.getDownloadProgressString 
       (progress.mOverallProgress, 
         progress.mOverallTotal)); 
    } 

    @Override 
    protected void onDestroy() { 
     this.mCancelValidation = true; 
     super.onDestroy(); 
    } 

} 

這是什麼問題?

編輯:

XAPKFile [] xAPK是我們已經給像它的一個主要,文件大小和版本代碼

expansionFilesDelivered()的地方是它檢查文件名

+0

你到底在做什麼? – 2013-02-26 10:33:52

+0

@MattTaylor我正在嘗試測試存在於手動添加的SD卡中的obb文件 – Goofy 2013-02-26 10:41:29

+0

你能告訴我我哪裏出錯了嗎?我卡長期 – Goofy 2013-02-26 10:42:28

回答

2

該方法看起來像條件​​未能找到您的文件在SD卡

boolean expansionFilesDelivered() { 
    for (XAPKFile xf : xAPKS) { 
     String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsBase, xf.mFileVersion); 
     if (!Helpers.doesFileExist(this, fileName, xf.mFileSize, false)) 
      return false; 
    } 
    return true; 
} 

已經把假文件放在確切的目錄?

private final static String EXP_PATH = "/Android/obb/"; 

static String[] getAPKExpansionFiles(Context ctx, int mainVersion, int patchVersion) { 
    String packageName = ctx.getPackageName(); 
    Vector<String> ret = new Vector<String>(); 
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 
     // Build the full path to the app's expansion files 
     File root = Environment.getExternalStorageDirectory(); 
     File expPath = new File(root.toString() + EXP_PATH + packageName); 

     // Check that expansion file path exists 
     if (expPath.exists()) { 
      if (mainVersion > 0) { 
       String strMainPath = expPath + File.separator + "main." + 
         mainVersion + "." + packageName + ".obb"; 
       File main = new File(strMainPath); 
       if (main.isFile()) { 
         ret.add(strMainPath); 
       } 
      } 
      if (patchVersion > 0) { 
       String strPatchPath = expPath + File.separator + "patch." + 
         mainVersion + "." + packageName + ".obb"; 
       File main = new File(strPatchPath); 
       if (main.isFile()) { 
         ret.add(strPatchPath); 
       } 
      } 
     } 
    } 
    String[] retArray = new String[ret.size()]; 
    ret.toArray(retArray); 
    return retArray; 
} 

你應該推(OBB文件假貨)文件在這裏(com.your.packagename) enter image description here與你的包名稱(包名稱應該VE編程創建)

String xapkFilePath = getAPKExpansionFiles(SampleDownloaderActivity.this); 
       Log.d("CopyFromAPKEXP", "OBBFileName: " + xapkFilePath); 
       String exportDirectory = Environment 
         .getExternalStorageDirectory().getAbsolutePath() 
         + "/Android/data/" 
         + SampleDownloaderActivity.this.getPackageName() 
         + "/files/"; 
       File exportDirectoryFilepath = new File(exportDirectory); 

       exportDirectoryFilepath.mkdirs(); 
+0

我認爲多數民衆贊成爲什麼它總是返回ture,如果我不添加obb文件,好吧,我需要用我現有的方法取代這個?如果是的話,我需要添加這個?我的意思是在哪個班級? – Goofy 2013-02-26 11:13:41

+0

這個方法哥們在哪裏?我無法找到它? – Goofy 2013-02-26 11:21:13

+0

@Goofy http://developer.android.com/google/play/expansion-files.html – 2013-02-26 11:23:51

0

我有消息從模擬器運行,從一個實際的設備一切都OK了......可能必須與許可證的東西,檢查您的日誌記錄,如果你看到的東西與許可證錯誤,那就是它