@Override protected Payload doInBackground(Payload... args) { Payload data = doInBackgroundLoadDeck(args); if (data.returnType == DeckTask.DECK_LOADED) { double now = System.currentTimeMillis(); HashMap<String, Object> results = (HashMap<String, Object>) data.result; Deck deck = (Deck) results.get("deck"); // deck.beforeUpdateCards(); // deck.updateAllCards(); SharedDeckDownload download = (SharedDeckDownload) args[0].data[0]; SharedPreferences pref = PrefSettings.getSharedPrefs(getBaseContext()); String updatedCardsPref = "numUpdatedCards:" + mDestination + "/tmp/" + download.getTitle() + ".anki.updating"; long totalCards = deck.retrieveCardCount(); download.setNumTotalCards((int) totalCards); long updatedCards = pref.getLong(updatedCardsPref, 0); download.setNumUpdatedCards((int) updatedCards); long batchSize = Math.max(100, totalCards / 200); mRecentBatchTimings = new long[sRunningAvgLength]; mTotalBatches = ((double) totalCards) / batchSize; int currentBatch = (int) (updatedCards / batchSize); long runningAvgCount = 0; long batchStart; mElapsedTime = 0; while (updatedCards < totalCards && download.getStatus() == SharedDeckDownload.STATUS_UPDATING) { batchStart = System.currentTimeMillis(); updatedCards = deck.updateAllCardsFromPosition(updatedCards, batchSize); Editor editor = pref.edit(); editor.putLong(updatedCardsPref, updatedCards); editor.commit(); download.setNumUpdatedCards((int) updatedCards); publishProgress(); estimateTimeToCompletion( download, currentBatch, runningAvgCount, System.currentTimeMillis() - batchStart); currentBatch++; runningAvgCount++; } if (download.getStatus() == SharedDeckDownload.STATUS_UPDATING) { data.success = true; } else if (download.getStatus() == SharedDeckDownload.STATUS_PAUSED) { Editor editor = pref.edit(); String pausedPref = "paused:" + mDestination + "/tmp/" + download.getTitle() + ".anki.updating"; editor.putBoolean(pausedPref, true); editor.commit(); data.success = false; Log.i(AnkiDroidApp.TAG, "pausing deck " + download.getTitle()); } else if (download.getStatus() == SharedDeckDownload.STATUS_CANCELLED) { data.success = false; } // Log.i(AnkiDroidApp.TAG, "Time to update deck = " + download.getEstTimeToCompletion() + " // sec."); // deck.afterUpdateCards(); } else { data.success = false; } return data; }
/** * Posting feedback or error info to the server. This is called from the AsyncTask. * * @param url The url to post the feedback to. * @param type The type of the info, eg Feedback.TYPE_CRASH_STACKTRACE. * @param feedback For feedback types this is the message. For error/crash types this is the path * to the error file. * @param groupId A single time generated ID, so that errors/feedback send together can be grouped * together. * @param index The index of the error in the list * @return A Payload file showing success, response code and response message. */ public static Payload postFeedback( String url, String type, String feedback, String groupId, int index, Application app) { Payload result = new Payload(null); List<NameValuePair> pairs = null; if (!isErrorType(type)) { pairs = new ArrayList<NameValuePair>(); pairs.add(new BasicNameValuePair("type", type)); pairs.add(new BasicNameValuePair("groupid", groupId)); pairs.add(new BasicNameValuePair("index", "0")); pairs.add(new BasicNameValuePair("message", feedback)); addTimestamp(pairs); } else { pairs = Feedback.extractPairsFromError(type, feedback, groupId, index, app); if (pairs == null) { result.success = false; result.result = null; } } HttpClient httpClient = new DefaultHttpClient(); HttpPost httpPost = new HttpPost(url); httpPost.addHeader("User-Agent", "AnkiDroid"); try { httpPost.setEntity(new UrlEncodedFormEntity(pairs)); HttpResponse response = httpClient.execute(httpPost); Log.e(AnkiDroidApp.TAG, String.format("Bug report posted to %s", url)); int respCode = response.getStatusLine().getStatusCode(); switch (respCode) { case 200: result.success = true; result.returnType = respCode; result.result = Utils.convertStreamToString(response.getEntity().getContent()); Log.i(AnkiDroidApp.TAG, String.format("postFeedback OK: %s", result.result)); break; default: Log.e( AnkiDroidApp.TAG, String.format( "postFeedback failure: %d - %s", response.getStatusLine().getStatusCode(), response.getStatusLine().getReasonPhrase())); result.success = false; result.returnType = respCode; result.result = response.getStatusLine().getReasonPhrase(); break; } } catch (ClientProtocolException ex) { Log.e(AnkiDroidApp.TAG, "ClientProtocolException: " + ex.toString()); result.success = false; result.result = ex.toString(); } catch (IOException ex) { Log.e(AnkiDroidApp.TAG, "IOException: " + ex.toString()); result.success = false; result.result = ex.toString(); } return result; }
private Payload doInBackgroundLoadDeck(Payload... params) { Payload data = params[0]; SharedDeckDownload download = (SharedDeckDownload) data.data[0]; String deckFilename = mDestination + "/tmp/" + download.getFilename() + ".anki.updating"; Log.i(AnkiDroidApp.TAG, "doInBackgroundLoadDeck - deckFilename = " + deckFilename); Log.i(AnkiDroidApp.TAG, "loadDeck - SD card mounted and existent file -> Loading deck..."); try { // Open the right deck. Decks deck = null; // DeckManager.getDeck(deckFilename, // DeckManager.REQUESTING_ACTIVITY_DOWNLOADMANAGER); // Start by getting the first card and displaying it. // Card card = deck.getCard(); Log.i(AnkiDroidApp.TAG, "Deck loaded!"); // Set the result // data.returnType = DeckTask.DECK_LOADED; HashMap<String, Object> results = new HashMap<String, Object>(); results.put("deck", deck); // results.put("card", card); results.put("position", download.getNumUpdatedCards()); data.result = results; return data; } catch (SQLException e) { Log.i( AnkiDroidApp.TAG, "The database " + deckFilename + " could not be opened = " + e.getMessage()); data.success = false; // data.returnType = DeckTask.DECK_NOT_LOADED; data.exception = e; return data; } catch (CursorIndexOutOfBoundsException e) { // XXX: Where is this exception thrown? Log.i(AnkiDroidApp.TAG, "The deck has no cards = " + e.getMessage()); data.success = false; // data.returnType = DeckTask.DECK_EMPTY; data.exception = e; return data; } }