private static File getBackupDirectory() {
   SharedPreferences prefs =
       AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext());
   File directory =
       new File(prefs.getString("deckPath", AnkiDroidApp.getStorageDirectory()) + BACKUP_SUFFIX);
   if (!directory.isDirectory()) {
     directory.mkdirs();
   }
   return directory;
 }
 public void setCard(Card card) {
   mCurrentCard = card;
   Long cardId = 0l;
   if (card != null) {
     cardId = card.getId();
   }
   AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext())
       .edit()
       .putLong("lastWidgetCard", cardId)
       .commit();
 }
 @Override
 public void onCreate() {
   super.onCreate();
   SharedPreferences prefs =
       AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext());
   String path = prefs.getString("lastWidgetDeck", "");
   if (path != null && path.length() > 0 && AnkiDroidApp.isSdCardMounted()) {
     Log.i(AnkiDroidApp.TAG, "BigWidget: reloading deck " + path);
     mCol = Collection.currentCollection();
     if (mCol != null) {
       mCurrentCard = mCol.getSched().getCard();
     }
   }
 }
 @Override
 protected void onResume() {
   super.onResume();
   ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE))
       .cancel(SIMPLE_NOTIFICATION_ID);
   // Show any pending dialogs
   Message handlerMsg = AnkiDroidApp.getStoredDialogHandlerMessage();
   if (handlerMsg != null) {
     // TODO: Confirm whether or not it's ok to send the message without checking if the collection
     // is open.
     mHandler.sendMessage(handlerMsg);
     AnkiDroidApp.setStoredDialogHandlerMessage(null);
   }
 }
Beispiel #5
0
 private void disableDrawerSwipeOnConflicts() {
   SharedPreferences preferences = AnkiDroidApp.getSharedPrefs(getBaseContext());
   boolean gesturesEnabled = AnkiDroidApp.initiateGestures(preferences);
   if (gesturesEnabled) {
     int gestureSwipeUp = Integer.parseInt(preferences.getString("gestureSwipeUp", "9"));
     int gestureSwipeDown = Integer.parseInt(preferences.getString("gestureSwipeDown", "0"));
     int gestureSwipeRight = Integer.parseInt(preferences.getString("gestureSwipeRight", "17"));
     if (gestureSwipeUp != GESTURE_NOTHING
         || gestureSwipeDown != GESTURE_NOTHING
         || gestureSwipeRight != GESTURE_NOTHING) {
       mHasDrawerSwipeConflicts = true;
       super.disableDrawerSwipe();
     }
   }
 }
Beispiel #6
0
 @Override
 protected void setTitle() {
   try {
     String[] title = {""};
     if (AnkiDroidApp.colIsOpen()) {
       title = getCol().getDecks().current().getString("name").split("::");
     } else {
       Timber.e("Could not set title in reviewer because collection closed");
     }
     AnkiDroidApp.getCompat().setTitle(this, title[title.length - 1], mNightMode);
     super.setTitle(title[title.length - 1]);
   } catch (JSONException e) {
     throw new RuntimeException(e);
   }
   AnkiDroidApp.getCompat().setSubtitle(this, "", mNightMode);
 }
Beispiel #7
0
  /**
   * Factory for AnkiFont creation. Creates a typeface wrapper from a font file representing.
   *
   * @param ctx Activity context, needed to access assets
   * @param path Path to typeface file, needed when this is a custom font.
   * @param fromAssets True if the font is to be found in assets of application
   * @return A new AnkiFont object or null if the file can't be interpreted as typeface.
   */
  public static AnkiFont createAnkiFont(Context ctx, String path, boolean fromAssets) {
    File fontfile = new File(path);
    String name = Utils.splitFilename(fontfile.getName())[0];
    String family = name;
    List<String> attributes = new ArrayList<>();

    if (fromAssets) {
      path = fAssetPathPrefix.concat(fontfile.getName());
    }
    Typeface tf = getTypeface(ctx, path);
    if (tf == null) {
      // unable to create typeface
      return null;
    }

    if (tf.isBold() || name.toLowerCase(Locale.US).contains("bold")) {
      attributes.add("font-weight: bolder;");
      family = family.replaceFirst("(?i)-?Bold", "");
    } else if (name.toLowerCase(Locale.US).contains("light")) {
      attributes.add("font-weight: lighter;");
      family = family.replaceFirst("(?i)-?Light", "");
    } else {
      attributes.add("font-weight: normal;");
    }
    if (tf.isItalic() || name.toLowerCase(Locale.US).contains("italic")) {
      attributes.add("font-style: italic;");
      family = family.replaceFirst("(?i)-?Italic", "");
    } else if (name.toLowerCase(Locale.US).contains("oblique")) {
      attributes.add("font-style: oblique;");
      family = family.replaceFirst("(?i)-?Oblique", "");
    } else {
      attributes.add("font-style: normal;");
    }
    if (name.toLowerCase(Locale.US).contains("condensed")
        || name.toLowerCase(Locale.US).contains("narrow")) {
      attributes.add("font-stretch: condensed;");
      family = family.replaceFirst("(?i)-?Condensed", "");
      family = family.replaceFirst("(?i)-?Narrow(er)?", "");
    } else if (name.toLowerCase(Locale.US).contains("expanded")
        || name.toLowerCase(Locale.US).contains("wide")) {
      attributes.add("font-stretch: expanded;");
      family = family.replaceFirst("(?i)-?Expanded", "");
      family = family.replaceFirst("(?i)-?Wide(r)?", "");
    }

    AnkiFont createdFont = new AnkiFont(name, family, attributes, path);

    // determine if override font or default font
    SharedPreferences preferences = AnkiDroidApp.getSharedPrefs(ctx);
    String defaultFont = preferences.getString("defaultFont", "");
    boolean overrideFont = preferences.getString("overrideFontBehavior", "0").equals("1");
    if (defaultFont.equalsIgnoreCase(name)) {
      if (overrideFont) {
        createdFont.setAsOverride();
      } else {
        createdFont.setAsDefault();
      }
    }
    return createdFont;
  }
Beispiel #8
0
 @Override
 protected SharedPreferences restorePreferences() {
   super.restorePreferences();
   SharedPreferences preferences = AnkiDroidApp.getSharedPrefs(getBaseContext());
   mBlackWhiteboard = preferences.getBoolean("blackWhiteboard", true);
   return preferences;
 }
Beispiel #9
0
  @Override
  protected void onCreate(Bundle icicle) {
    // Workaround for bug 4611: http://code.google.com/p/android/issues/detail?id=4611
    if (AnkiDroidApp.SDK_VERSION >= 7 && AnkiDroidApp.SDK_VERSION <= 10) {
      Themes.applyTheme(this, Themes.THEME_ANDROID_DARK);
    }
    super.onCreate(icicle);

    mCol = AnkiDroidApp.getCol();
    if (mCol == null) {
      finish();
      return;
    }
    mDeck = mCol.getDecks().current();

    registerExternalStorageListener();

    if (mCol == null) {
      Log.i(AnkiDroidApp.TAG, "DeckOptions - No Collection loaded");
      finish();
      return;
    } else {
      mPref = new DeckPreferenceHack();
      mPref.registerOnSharedPreferenceChangeListener(this);

      this.addPreferencesFromResource(R.xml.deck_options);
      this.buildLists();
      this.updateSummaries();
    }
  }
Beispiel #10
0
 // Method for loading the collection which is inherited by all AnkiActivitys
 public void startLoadingCollection() {
   // Initialize the open collection loader
   Timber.d("AnkiActivity.startLoadingCollection()");
   if (!AnkiDroidApp.colIsOpen()) {
     showOpeningCollectionDialog();
   }
   getSupportLoaderManager().restartLoader(0, null, this);
 }
Beispiel #11
0
 @Override
 public void onLoadFinished(Loader<Collection> loader, Collection col) {
   if (col != null && AnkiDroidApp.colIsOpen()) {
     onCollectionLoaded(col);
   } else {
     onCollectionLoadError();
   }
 }
    public SizeControlledListAdapter(
        Context context,
        List<? extends Map<String, ?>> data,
        int resource,
        String[] from,
        int[] to,
        int fontSizeScalePcent) {
      super(context, data, resource, from, to);
      this.fontSizeScalePcent = fontSizeScalePcent;

      mTibetan = AnkiDroidApp.isTibetan();

      mTibTypeface = null;

      if (mTibetan) {
        mTibTypeface = AnkiDroidApp.getTibetanTypeface();
      }
    }
  private void recreateTagsDialog() {
    Resources res = getResources();
    if (allTags == null) {
      String[] oldTags = AnkiDroidApp.deck().allTags_();
      Log.i(AnkiDroidApp.TAG, "all tags: " + Arrays.toString(oldTags));
      allTags = new String[oldTags.length];
      for (int i = 0; i < oldTags.length; i++) {
        allTags[i] = oldTags[i];
      }
    }
    mSelectedTags.clear();

    StyledDialog.Builder builder = new StyledDialog.Builder(this);
    builder.setTitle(R.string.studyoptions_limit_select_tags);
    builder.setMultiChoiceItems(
        allTags,
        new boolean[0],
        new DialogInterface.OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
            String tag = allTags[which];
            if (mSelectedTags.contains(tag)) {
              Log.i(AnkiDroidApp.TAG, "unchecked tag: " + tag);
              mSelectedTags.remove(tag);
            } else {
              Log.i(AnkiDroidApp.TAG, "checked tag: " + tag);
              mSelectedTags.add(tag);
            }
          }
        });
    builder.setPositiveButton(
        res.getString(R.string.select),
        new OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
            updateCardsList();
          }
        });
    builder.setNegativeButton(
        res.getString(R.string.cancel),
        new OnClickListener() {
          @Override
          public void onClick(DialogInterface dialog, int which) {
            mSelectedTags.clear();
          }
        });
    builder.setOnCancelListener(
        new OnCancelListener() {

          @Override
          public void onCancel(DialogInterface dialog) {
            mSelectedTags.clear();
          }
        });
    mTagsDialog = builder.create();
  }
  private String unzipSharedDeckFile(String zipFilename, String title) {
    ZipInputStream zipInputStream = null;
    Log.i(AnkiDroidApp.TAG, "unzipSharedDeckFile");
    if (zipFilename.endsWith(".zip")) {
      Log.i(AnkiDroidApp.TAG, "zipFilename ends with .zip");
      try {
        zipInputStream = new ZipInputStream(new FileInputStream(new File(zipFilename)));

        title = title.replace("^", "");
        title = title.substring(0, java.lang.Math.min(title.length(), 40));

        if (new File(mDestination + "/" + title + ".anki").exists()) {
          title += System.currentTimeMillis();
        }

        String partialDeckPath = mDestination + "/tmp/" + title;
        String deckFilename = partialDeckPath + ".anki.updating";

        ZipEntry zipEntry = null;
        while ((zipEntry = zipInputStream.getNextEntry()) != null) {
          Log.i(AnkiDroidApp.TAG, "zipEntry = " + zipEntry.getName());

          if ("shared.anki".equalsIgnoreCase(zipEntry.getName())) {
            Utils.writeToFile(zipInputStream, deckFilename);
          } else if (zipEntry.getName().startsWith("shared.media/", 0)) {
            Log.i(
                AnkiDroidApp.TAG,
                "Folder created = " + new File(partialDeckPath + ".media/").mkdir());
            Log.i(
                AnkiDroidApp.TAG,
                "Destination = "
                    + AnkiDroidApp.getStorageDirectory()
                    + "/"
                    + title
                    + ".media/"
                    + zipEntry.getName().replace("shared.media/", ""));
            Utils.writeToFile(
                zipInputStream,
                partialDeckPath + ".media/" + zipEntry.getName().replace("shared.media/", ""));
          }
        }
        zipInputStream.close();

        // Delete zip file
        new File(zipFilename).delete();
      } catch (FileNotFoundException e) {
        Log.e(AnkiDroidApp.TAG, "FileNotFoundException = " + e.getMessage());
        e.printStackTrace();
      } catch (IOException e) {
        Log.e(AnkiDroidApp.TAG, "IOException = " + e.getMessage());
        e.printStackTrace();
      }
    }

    return title;
  }
 @Override
 public void onDestroy() {
   // // TODO: this does not seem to be reliably called
   // String path = "";
   long cardId = 0l;
   if (mCol != null) {
     // path = mLoadedDeck.getDeckPath();
     // DeckManager.closeDeck(path, DeckManager.REQUESTING_ACTIVITY_BIGWIDGET);
     if (mCurrentCard != null) {
       cardId = mCurrentCard.getId();
     }
   }
   // PrefSettings.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext()).edit().putString("lastWidgetDeck",
   // path).commit();
   AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext())
       .edit()
       .putLong("lastWidgetCard", cardId)
       .commit();
 }
Beispiel #16
0
 /**
  * Global method to show a dialog fragment including adding it to back stack and handling the case
  * where the dialog is shown from an async task, by showing the message in the notification bar if
  * the activity was stopped before the AsyncTask completed
  *
  * @param newFragment the AsyncDialogFragment you want to show
  */
 public void showAsyncDialogFragment(AsyncDialogFragment newFragment) {
   try {
     showDialogFragment(newFragment);
   } catch (IllegalStateException e) {
     String title = newFragment.getNotificationTitle();
     String message = newFragment.getNotificationMessage();
     AnkiDroidApp.setStoredDialogHandlerMessage(newFragment.getDialogHandlerMessage());
     showSimpleNotification(title, message);
   }
 }
Beispiel #17
0
 public static boolean initialize(Context context) {
   mContext = context;
   SharedPreferences preferences =
       AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext());
   mDictionary =
       Integer.parseInt(preferences.getString("dictionary", Integer.toString(DICTIONARY_NONE)));
   switch (mDictionary) {
     case DICTIONARY_NONE:
       mIsDictionaryAvailable = false;
       break;
     case DICTIONARY_AEDICT:
       mDictionaryAction = "sk.baka.aedict.action.ACTION_SEARCH_EDICT";
       mIsDictionaryAvailable = Utils.isIntentAvailable(mContext, mDictionaryAction);
       break;
     case DICTIONARY_LEO_WEB:
     case DICTIONARY_NCIKU_WEB:
     case DICTIONARY_EIJIRO_WEB:
       mDictionaryAction = "android.intent.action.VIEW";
       mIsDictionaryAvailable = Utils.isIntentAvailable(mContext, mDictionaryAction);
       break;
     case DICTIONARY_LEO_APP:
       mDictionaryAction = "android.intent.action.SEND";
       mIsDictionaryAvailable =
           Utils.isIntentAvailable(
               mContext,
               mDictionaryAction,
               new ComponentName("org.leo.android.dict", "org.leo.android.dict.LeoDict"));
       break;
     case DICTIONARY_COLORDICT:
       mDictionaryAction = "colordict.intent.action.SEARCH";
       mIsDictionaryAvailable = Utils.isIntentAvailable(mContext, mDictionaryAction);
       break;
     case DICTIONARY_FORA:
       mDictionaryAction = "com.ngc.fora.action.LOOKUP";
       mIsDictionaryAvailable = Utils.isIntentAvailable(mContext, mDictionaryAction);
       break;
     default:
       mIsDictionaryAvailable = false;
       break;
   }
   Log.i(AnkiDroidApp.TAG, "Is intent available = " + mIsDictionaryAvailable);
   return mIsDictionaryAvailable;
 }
Beispiel #18
0
 @Override
 public void onCorruption(SQLiteDatabase db) {
   Timber.e("The database has been corrupted...");
   AnkiDroidApp.sendExceptionReport(
       new RuntimeException("Database corrupted"),
       "AnkiDb.MyDbErrorHandler.onCorruption",
       "Db has been corrupted ");
   CollectionHelper.getInstance().closeCollection(false);
   DatabaseErrorDialog.databaseCorruptFlag = true;
 }
Beispiel #19
0
  @Override
  protected void onStop() {
    super.onStop();

    if (!isFinishing()) {
      if (AnkiDroidApp.colIsOpen()) {
        WidgetStatus.update(this, mSched.progressToday(null, mCurrentCard, true));
      }
    }
    UIUtils.saveCollectionInBackground();
  }
  /**
   * If collection has not been opened for a long time, we perform a backup here because Android
   * deleted sometimes corrupted decks
   */
  public static boolean safetyBackupNeeded(String path, int days) {
    if (!AnkiDroidApp.getSharedPrefs(AnkiDroidApp.getInstance().getBaseContext())
        .getBoolean("useBackup", true)) {
      return false;
    }

    File collectionFile = new File(path);
    File[] deckBackups = getBackups(collectionFile);
    int len = deckBackups.length;
    if (len == 0) {
      // no backup available
      return true;
    } else if (deckBackups[len - 1].lastModified() == collectionFile.lastModified()) {
      return false;
    }

    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd-HH-mm");
    Calendar cal = new GregorianCalendar();
    cal.setTimeInMillis(System.currentTimeMillis());

    Date lastBackupDate = null;
    while (lastBackupDate == null && len > 0) {
      try {
        len--;
        lastBackupDate =
            df.parse(
                deckBackups[len]
                    .getName()
                    .replaceAll("^.*-(\\d{4}-\\d{2}-\\d{2}-\\d{2}-\\d{2}).anki2$", "$1"));
      } catch (ParseException e) {
        lastBackupDate = null;
      }
    }
    if (lastBackupDate == null) {
      return true;
    } else if (lastBackupDate.getTime() + days * 24 * 3600000 < Utils.intNow(1000)) {
      return true;
    } else {
      return false;
    }
  }
Beispiel #21
0
  /**
   * Get the package version as defined in the manifest.
   *
   * @return the package version.
   */
  public static String getPkgVersion() {
    String pkgVersion = "?";
    Context context = sInstance.getApplicationContext();

    try {
      PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
      pkgVersion = pInfo.versionName;
    } catch (PackageManager.NameNotFoundException e) {
      Log.e(TAG, "Couldn't find package named " + context.getPackageName(), e);
    }

    return pkgVersion;
  }
Beispiel #22
0
  /**
   * Get package name as defined in the manifest.
   *
   * @return the package name.
   */
  public static String getPkgName() {
    String pkgName = TAG;
    Context context = sInstance.getApplicationContext();

    try {
      PackageInfo pInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
      pkgName = context.getString(pInfo.applicationInfo.labelRes);
    } catch (PackageManager.NameNotFoundException e) {
      Log.e(TAG, "Couldn't find package named " + context.getPackageName(), e);
    }

    return pkgName;
  }
  private void reloadCollection(final Bundle savedInstanceState) {
    DeckTask.launchDeckTask(
        DeckTask.TASK_TYPE_OPEN_COLLECTION,
        new DeckTask.TaskListener() {

          @Override
          public void onPostExecute(DeckTask.TaskData result) {
            mCol = result.getCollection();
            Collection.putCurrentCollection(mCol);
            if (mCol == null) {
              finish();
            } else {
              onCreate(savedInstanceState);
            }
          }

          @Override
          public void onPreExecute() {
            mOpenCollectionDialog =
                StyledOpenCollectionDialog.show(
                    CardBrowser.this,
                    getResources().getString(R.string.open_collection),
                    new OnCancelListener() {
                      @Override
                      public void onCancel(DialogInterface arg0) {
                        finish();
                      }
                    });
          }

          @Override
          public void onProgressUpdate(DeckTask.TaskData... values) {}
        },
        new DeckTask.TaskData(
            AnkiDroidApp.getSharedPrefs(getBaseContext())
                    .getString("deckPath", AnkiDroidApp.getDefaultAnkiDroidDirectory())
                + AnkiDroidApp.COLLECTION_PATH));
  }
Beispiel #24
0
  @Override
  protected void onResume() {
    super.onResume();
    getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);

    // syncAccount's summary can change while preferences are still open (user logs
    // in from preferences screen), so we need to update it here.
    SharedPreferences preferences = AnkiDroidApp.getSharedPrefs(getBaseContext());
    String username = preferences.getString("username", "");
    if (TextUtils.isEmpty(username)) {
      syncAccount.setSummary(R.string.sync_account_summ_logged_out);
    } else {
      syncAccount.setSummary(getString(R.string.sync_account_summ_logged_in, username));
    }
  }
Beispiel #25
0
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    initAllContentViews();
    initAllAlertDialogs();

    if (AnkiDroidApp.isUserLoggedIn()) {
      SharedPreferences preferences = PrefSettings.getSharedPrefs(getBaseContext());
      String username = preferences.getString("username", "");
      mUsernameLoggedIn.setText(username);
      setContentView(mLoggedIntoMyAccountView);
    } else {
      setContentView(mLoginToMyAccountView);
    }
  }
Beispiel #26
0
  /** On application creation. */
  @Override
  public void onCreate() {
    super.onCreate();
    sInstance = this;

    Connection.setContext(getApplicationContext());

    // Error Reporter
    CustomExceptionHandler customExceptionHandler = CustomExceptionHandler.getInstance();
    customExceptionHandler.Init(sInstance.getApplicationContext());
    Thread.setDefaultUncaughtExceptionHandler(customExceptionHandler);

    SharedPreferences preferences = PrefSettings.getSharedPrefs(this);
    // Assign some default settings if necessary
    if (preferences.getString(PrefSettings.KEY_CHECK_URI, null) == null) {
      Editor editor = preferences.edit();
      // Test Update Notifications
      // Some ridiculously fast polling, just to demonstrate it working...
      /*
       * editor.putBoolean(PrefSettings.KEY_ENABLED, true); editor.putLong(PrefSettings.KEY_PERIOD, 30 * 1000L);
       * editor.putLong(PrefSettings.KEY_CHECK_INTERVAL, 60 * 1000L); editor.putString(PrefSettings.KEY_CHECK_URI,
       * "http://ankidroid.googlecode.com/files/test_notifications.xml");
       */
      editor.putString(
          PrefSettings.KEY_CHECK_URI, "http://ankidroid.googlecode.com/files/last_release.xml");

      // Create the folder "AnkiDroid", if not exists, where the decks
      // will be stored by default
      new File(getStorageDirectory() + "/AnkiDroid").mkdir();

      // Put the base path in preferences pointing to the default
      // "AnkiDroid" folder
      editor.putString("deckPath", getStorageDirectory() + "/AnkiDroid");

      // Using commit instead of apply even though we don't need a return value.
      // Reason: apply() not available on Android 1.5
      editor.commit();
    }

    // Reschedule the checks - we need to do this if the settings have
    // changed (as above)
    // It may also necessary in the case where an application has been
    // updated
    // Here for simplicity, we do it every time the application is launched
    Intent intent = new Intent(Veecheck.getRescheduleAction(this));
    sendBroadcast(intent);
  }
Beispiel #27
0
 protected void showSimpleNotification(String title, String message) {
   SharedPreferences prefs = AnkiDroidApp.getSharedPrefs(this);
   // Don't show notification if disabled in preferences
   if (Integer.parseInt(prefs.getString("minimumCardsDueForNotification", "0")) <= 1000000) {
     // Use the title as the ticker unless the title is simply "AnkiDroid"
     String ticker = title;
     if (title.equals(getResources().getString(R.string.app_name))) {
       ticker = message;
     }
     // Build basic notification
     NotificationCompat.Builder builder =
         new NotificationCompat.Builder(this)
             .setSmallIcon(R.drawable.ic_stat_notify)
             .setContentTitle(title)
             .setContentText(message)
             .setStyle(new NotificationCompat.BigTextStyle().bigText(message))
             .setTicker(ticker);
     // Enable vibrate and blink if set in preferences
     if (prefs.getBoolean("widgetVibrate", false)) {
       builder.setVibrate(new long[] {1000, 1000, 1000});
     }
     if (prefs.getBoolean("widgetBlink", false)) {
       builder.setLights(Color.BLUE, 1000, 1000);
     }
     // Creates an explicit intent for an Activity in your app
     Intent resultIntent = new Intent(this, DeckPicker.class);
     resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK);
     PendingIntent resultPendingIntent =
         PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
     if (resultPendingIntent == null) {
       // PendingIntent could not be created... probably something wrong with the extras
       // try again without the extras, though the original dialog will not be shown when app
       // started
       Timber.e("AnkiActivity.showSimpleNotification() failed due to null PendingIntent");
       resultIntent = new Intent(this, DeckPicker.class);
       resultPendingIntent =
           PendingIntent.getActivity(this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
     }
     builder.setContentIntent(resultPendingIntent);
     NotificationManager notificationManager =
         (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
     // mId allows you to update the notification later on.
     notificationManager.notify(SIMPLE_NOTIFICATION_ID, builder.build());
   }
 }
  // It could be part of the AIDL Interface but at the moment no Activity uses it directly
  public void resumeDownload(Download download) {
    // Create tmp folder where the temporal decks are going to be stored
    new File(mDestination + "/tmp/").mkdirs();
    AnkiDroidApp.createNoMediaFileIfMissing(new File(mDestination));

    if (download instanceof SharedDeckDownload) {
      SharedDeckDownload sharedDeckDownload = (SharedDeckDownload) download;
      // We need to go through UpdateDeckTask even when the download is paused, in order for
      // numUpdatedCards and numTotalCards to get updated, so that progress is displayed correctly
      if (sharedDeckDownload.getStatus() == SharedDeckDownload.STATUS_PAUSED
          || sharedDeckDownload.getStatus() == SharedDeckDownload.STATUS_UPDATING) {
        new UpdateDeckTask().execute(new Payload(new Object[] {sharedDeckDownload}));
      } else {
        new DownloadSharedDeckTask().execute(sharedDeckDownload);
      }
    } else {
      // TODO: Check if there is already a deck with the same name, and if that's so
      // add the current milliseconds to the end of the name or notify the user
      new DownloadPersonalDeckTask().execute(download);
    }
  }
Beispiel #29
0
 public static Typeface getTypeface(Context ctx, String path) {
   try {
     if (path.startsWith(fAssetPathPrefix)) {
       return Typeface.createFromAsset(ctx.getAssets(), path.replaceFirst("/android_asset/", ""));
     } else {
       return Typeface.createFromFile(path);
     }
   } catch (RuntimeException e) {
     Timber.w(e, "Runtime error in getTypeface for File: %s", path);
     if (!corruptFonts.contains(path)) {
       // Show warning toast
       String name = new File(path).getName();
       Resources res = AnkiDroidApp.getAppResources();
       Toast toast =
           Toast.makeText(ctx, res.getString(R.string.corrupt_font, name), Toast.LENGTH_LONG);
       toast.show();
       // Don't warn again in this session
       corruptFonts.add(path);
     }
     return null;
   }
 }
  public static boolean repairDeck(String deckPath) {
    File deckFile = new File(deckPath);
    Collection col = AnkiDroidApp.getCol();
    if (col != null) {
      col.close();
    }
    AnkiDatabaseManager.closeDatabase(deckPath);

    // repair file
    String execString = "sqlite3 " + deckPath + " .dump | sqlite3 " + deckPath + ".tmp";
    Log.i(AnkiDroidApp.TAG, "repairDeck - Execute: " + execString);
    try {
      String[] cmd = {"/system/bin/sh", "-c", execString};
      Process process = Runtime.getRuntime().exec(cmd);
      process.waitFor();

      if (!new File(deckPath + ".tmp").exists()) {
        return false;
      }

      if (!moveDatabaseToBrokenFolder(deckPath, false)) {
        return false;
      }
      Log.i(AnkiDroidApp.TAG, "repairDeck - moved corrupt file to broken folder");
      File repairedFile = new File(deckPath + ".tmp");
      if (!repairedFile.renameTo(deckFile)) {
        return false;
      }
      return true;
    } catch (IOException e) {
      Log.e("AnkiDroidApp.TAG", "repairCollection - error: " + e);
    } catch (InterruptedException e) {
      Log.e("AnkiDroidApp.TAG", "repairCollection - error: " + e);
    }
    return false;
  }