Пример #1
0
 @Override
 public void onClick(View v) {
   final SharedPreferences settings = MyApplication.getInstance().getSettings();
   final String securityQuestion = MyApplication.PrefKey.SECURITY_QUESTION.getString("");
   EditText input = (EditText) dialog.findViewById(R.id.password);
   TextView error = (TextView) dialog.findViewById(R.id.passwordInvalid);
   if (v == dialog.getButton(AlertDialog.BUTTON_NEGATIVE)) {
     if ((Boolean) input.getTag()) {
       input.setTag(Boolean.valueOf(false));
       ((Button) v).setText(R.string.password_lost);
       dialog.setTitle(R.string.password_prompt);
     } else {
       input.setTag(Boolean.valueOf(true));
       dialog.setTitle(securityQuestion);
       ((Button) v).setText(android.R.string.cancel);
     }
   } else {
     String value = input.getText().toString();
     boolean isInSecurityQuestion = (Boolean) input.getTag();
     if (Utils.md5(value)
         .equals(
             (isInSecurityQuestion
                     ? MyApplication.PrefKey.SECURITY_ANSWER
                     : MyApplication.PrefKey.SET_PASSWORD)
                 .getString(""))) {
       input.setText("");
       error.setText("");
       MyApplication.getInstance().setLocked(false);
       ctx.findViewById(android.R.id.content).setVisibility(View.VISIBLE);
       if (ctx instanceof ActionBarActivity) {
         ((ActionBarActivity) ctx).getSupportActionBar().show();
       }
       if (isInSecurityQuestion) {
         MyApplication.PrefKey.PERFORM_PROTECTION.putBoolean(false);
         Toast.makeText(
                 ctx.getBaseContext(), R.string.password_disabled_reenable, Toast.LENGTH_LONG)
             .show();
         dialog.getButton(AlertDialog.BUTTON_NEGATIVE).setText(R.string.password_lost);
         dialog.setTitle(R.string.password_prompt);
         input.setTag(Boolean.valueOf(false));
       }
       dialog.dismiss();
     } else {
       input.setText("");
       error.setText(
           isInSecurityQuestion
               ? R.string.password_security_answer_not_valid
               : R.string.password_not_valid);
     }
   }
 }
Пример #2
0
 @Override
 public boolean onPreferenceChange(Preference pref, Object value) {
   String key = pref.getKey();
   if (key.equals(MyApplication.PrefKey.SHARE_TARGET.getKey())) {
     String target = (String) value;
     URI uri;
     if (!target.equals("")) {
       uri = Utils.validateUri(target);
       if (uri == null) {
         Toast.makeText(
                 getBaseContext(),
                 getString(R.string.ftp_uri_malformed, target),
                 Toast.LENGTH_LONG)
             .show();
         return false;
       }
       String scheme = uri.getScheme();
       if (!(scheme.equals("ftp") || scheme.equals("mailto"))) {
         Toast.makeText(
                 getBaseContext(),
                 getString(R.string.share_scheme_not_supported, scheme),
                 Toast.LENGTH_LONG)
             .show();
         return false;
       }
       Intent intent;
       if (scheme.equals("ftp")) {
         intent = new Intent(android.content.Intent.ACTION_SENDTO);
         intent.setData(android.net.Uri.parse(target));
         if (!Utils.isIntentAvailable(this, intent)) {
           showDialog(R.id.FTP_DIALOG);
         }
       }
     }
   } else if (key.equals(MyApplication.PrefKey.ENTER_LICENCE.getKey())) {
     if (Utils.verifyLicenceKey((String) value)) {
       Toast.makeText(getBaseContext(), R.string.licence_validation_success, Toast.LENGTH_LONG)
           .show();
       MyApplication.getInstance().setContribEnabled(true);
       setProtectionDependentsState();
     } else {
       Toast.makeText(getBaseContext(), R.string.licence_validation_failure, Toast.LENGTH_LONG)
           .show();
       MyApplication.getInstance().setContribEnabled(false);
     }
     configureContribPrefs();
   }
   return true;
 }
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    if (MyApplication.debug) {
      StrictMode.setThreadPolicy(
          new StrictMode.ThreadPolicy.Builder()
              .detectDiskReads()
              .detectDiskWrites()
              .detectNetwork() // or .detectAll() for all detectable problems
              .penaltyLog()
              .build());
      StrictMode.setVmPolicy(
          new StrictMode.VmPolicy.Builder()
              .detectLeakedSqlLiteObjects()
              // .detectLeakedClosableObjects()
              .penaltyLog()
              .penaltyDeath()
              .build());
    }

    super.onCreate(savedInstanceState);
    MyApplication.getInstance().getSettings().registerOnSharedPreferenceChangeListener(this);
    setLanguage();
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
    getSupportActionBar().setDisplayShowHomeEnabled(true);
  }
 @Override
 public void onClick(DialogInterface dialog, int which) {
   ConfirmationDialogBaseListener ctx = (ConfirmationDialogBaseListener) getActivity();
   if (ctx == null) {
     return;
   }
   Bundle bundle = getArguments();
   String prefKey = bundle.getString(KEY_PREFKEY);
   if (prefKey != null && checkBox.isChecked()) {
     SharedPreferencesCompat.apply(
         MyApplication.getInstance().getSettings().edit().putBoolean(prefKey, true));
   }
   if (which == AlertDialog.BUTTON_POSITIVE) {
     if (bundle.getInt(KEY_CHECKBOX_LABEL, 0) == 0) {
       ((ConfirmationDialogListener) ctx).onPositive(bundle);
     } else {
       ((ConfirmationDialogCheckedListener) ctx).onPositive(bundle, checkBox.isChecked());
     }
   } else {
     int negativeCommand = getArguments().getInt(KEY_COMMAND_NEGATIVE);
     if (negativeCommand != 0) {
       ctx.onNegative(bundle);
     } else {
       onCancel(dialog);
     }
   }
 }
Пример #5
0
 public static Spinner configureEncoding(View view, Context context, String prefName) {
   Spinner spinner = (Spinner) view.findViewById(R.id.Encoding);
   spinner.setSelection(
       Arrays.asList(context.getResources().getStringArray(R.array.pref_qif_export_file_encoding))
           .indexOf(MyApplication.getInstance().getSettings().getString(prefName, "UTF-8")));
   return spinner;
 }
Пример #6
0
 public static Spinner configureDelimiter(View view, Context context, String prefName) {
   Spinner spinner = (Spinner) view.findViewById(R.id.Delimiter);
   spinner.setSelection(
       Arrays.asList(
               context.getResources().getStringArray(R.array.pref_csv_import_delimiter_values))
           .indexOf(MyApplication.getInstance().getSettings().getString(prefName, ",")));
   return spinner;
 }
Пример #7
0
 private void setProtectionDependentsState() {
   boolean isProtected = MyApplication.PrefKey.PERFORM_PROTECTION.getBoolean(false);
   findPreference(MyApplication.PrefKey.SECURITY_QUESTION.getKey())
       .setEnabled(MyApplication.getInstance().isContribEnabled() && isProtected);
   findPreference(MyApplication.PrefKey.PROTECTION_DELAY_SECONDS.getKey()).setEnabled(isProtected);
   findPreference(MyApplication.PrefKey.PROTECTION_ENABLE_ACCOUNT_WIDGET.getKey())
       .setEnabled(isProtected);
   findPreference(MyApplication.PrefKey.PROTECTION_ENABLE_TEMPLATE_WIDGET.getKey())
       .setEnabled(isProtected);
   findPreference(MyApplication.PrefKey.PROTECTION_ENABLE_DATA_ENTRY_FROM_WIDGET.getKey())
       .setEnabled(isProtected);
 }
Пример #8
0
 private void configureContribPrefs() {
   Preference pref1 = findPreference(MyApplication.PrefKey.REQUEST_LICENCE.getKey()),
       pref2 = findPreference(MyApplication.PrefKey.CONTRIB_DONATE.getKey());
   if (MyApplication.getInstance().isContribEnabled()) {
     ((PreferenceCategory) findPreference(MyApplication.PrefKey.CATEGORY_CONTRIB.getKey()))
         .removePreference(pref1);
     pref2.setSummary(
         Utils.concatResStrings(
             this, R.string.thank_you, R.string.pref_contrib_donate_summary_already_contrib));
   } else {
     pref1.setOnPreferenceClickListener(this);
     pref1.setSummary(
         getString(
             R.string.pref_request_licence_summary,
             Secure.getString(getContentResolver(), Secure.ANDROID_ID)));
     pref2.setSummary(R.string.pref_contrib_donate_summary);
   }
   pref2.setOnPreferenceClickListener(this);
   findPreference(MyApplication.PrefKey.SHORTCUT_CREATE_SPLIT.getKey())
       .setEnabled(MyApplication.getInstance().isContribEnabled());
 }
Пример #9
0
  /**
   * @return display name for document stored at mUri. Returns null if accessing mUri raises {@link
   *     SecurityException}
   */
  @SuppressLint("NewApi")
  public static String getDisplayName(Uri uri) {

    if (!"file".equalsIgnoreCase(uri.getScheme())
        && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
      // The query, since it only applies to a single document, will only return
      // one row. There's no need to filter, sort, or select fields, since we want
      // all fields for one document.
      try {
        Cursor cursor =
            MyApplication.getInstance()
                .getContentResolver()
                .query(uri, null, null, null, null, null);

        if (cursor != null) {
          try {
            if (cursor.moveToFirst()) {
              // Note it's called "Display Name".  This is
              // provider-specific, and might not necessarily be the file name.
              int columnIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
              if (columnIndex != -1) {
                String displayName = cursor.getString(columnIndex);
                if (displayName != null) {
                  return displayName;
                }
              }
            }
          } catch (Exception e) {
          } finally {
            cursor.close();
          }
        }
      } catch (SecurityException e) {
        // this can happen if the user has restored a backup and
        // we do not have a persistable permision
        // return null;
      }
    }
    List<String> filePathSegments = uri.getPathSegments();
    if (filePathSegments.size() > 0) {
      return filePathSegments.get(filePathSegments.size() - 1);
    } else {
      return "UNKNOWN";
    }
  }
Пример #10
0
 @Override
 public void onHeaderClick(
     StickyListHeadersListView l,
     View header,
     int itemPosition,
     long headerId,
     boolean currentlySticky) {
   MyExpenses ctx = (MyExpenses) getActivity();
   if (mappedCategoriesPerGroup.get(itemPosition)) {
     if (MyApplication.getInstance().isContribEnabled()) {
       ctx.contribFeatureCalled(Feature.DISTRIBUTION, headerId);
     } else {
       CommonCommands.showContribDialog(ctx, Feature.DISTRIBUTION, headerId);
     }
   } else {
     Toast.makeText(ctx, getString(R.string.no_mapped_transactions), Toast.LENGTH_LONG).show();
   }
 }
Пример #11
0
 public static Spinner configureDateFormat(View view, Context context, String prefName) {
   Spinner spinner = (Spinner) view.findViewById(R.id.DateFormat);
   ArrayAdapter<QifDateFormat> dateFormatAdapter =
       new ArrayAdapter<QifDateFormat>(
           context, android.R.layout.simple_spinner_item, QifDateFormat.values());
   dateFormatAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
   spinner.setAdapter(dateFormatAdapter);
   QifDateFormat qdf;
   try {
     qdf =
         QifDateFormat.valueOf(
             MyApplication.getInstance().getSettings().getString(prefName, "EU"));
   } catch (IllegalArgumentException e) {
     qdf = QifDateFormat.EU;
   }
   spinner.setSelection(qdf.ordinal());
   return spinner;
 }
Пример #12
0
 public static Uri handleFilenameRequestResult(
     Intent data, EditText mFilename, String typeName, UriTypePartChecker checker) {
   Uri mUri = data.getData();
   String errorMsg;
   if (mUri != null) {
     Context context = MyApplication.getInstance();
     mFilename.setError(null);
     String displayName = getDisplayName(mUri);
     mFilename.setText(displayName);
     if (displayName == null) {
       mUri = null;
       // SecurityException raised during getDisplayName
       errorMsg = "Error while retrieving document";
       mFilename.setError(errorMsg);
       Toast.makeText(context, errorMsg, Toast.LENGTH_LONG).show();
     } else {
       String type = context.getContentResolver().getType(mUri);
       if (type != null) {
         String[] typeParts = type.split("/");
         if (typeParts.length == 0 || !checker.checkTypeParts(typeParts)) {
           mUri = null;
           errorMsg = context.getString(R.string.import_source_select_error, typeName);
           mFilename.setError(errorMsg);
           Toast.makeText(context, errorMsg, Toast.LENGTH_LONG).show();
         }
       }
     }
     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && mUri != null) {
       final int takeFlags = data.getFlags() & Intent.FLAG_GRANT_READ_URI_PERMISSION;
       try {
         // this probably will not succeed as long as we stick to ACTION_GET_CONTENT
         context.getContentResolver().takePersistableUriPermission(mUri, takeFlags);
       } catch (SecurityException e) {
         // Utils.reportToAcra(e);
       }
     }
   }
   return mUri;
 }
 protected void setLanguage() {
   MyApplication.getInstance().setLanguage();
 }
 @Override
 protected void onDestroy() {
   super.onDestroy();
   MyApplication.getInstance().getSettings().unregisterOnSharedPreferenceChangeListener(this);
 }
  @TargetApi(Build.VERSION_CODES.HONEYCOMB)
  @Override
  public Dialog onCreateDialog(Bundle savedInstanceState) {
    MyExpenses ctx = (MyExpenses) getActivity();
    Bundle args = getArguments();
    Long accountId = args != null ? args.getLong(KEY_ACCOUNTID) : null;
    boolean allP = false, hasExported;
    String warningText;
    final String fileName;
    String now = new SimpleDateFormat("yyyMMdd-HHmmss", Locale.US).format(new Date());

    if (accountId == null) {
      allP = true;
      warningText = getString(R.string.warning_reset_account_all);
      // potential Strict mode violation (currently exporting all accounts with different currencies
      // is not active in the UI)
      hasExported = Account.getHasExported(null);
      fileName = "export" + "-" + now;
    } else {
      Account a = Account.getInstanceFromDb(accountId);
      hasExported = ctx.hasExported();
      if (accountId < 0L) {
        allP = true;
        currency = a.currency.getCurrencyCode();
        fileName = "export" + "-" + currency + "-" + now;
        warningText = getString(R.string.warning_reset_account_all, " (" + currency + ")");
      } else {
        fileName = Utils.escapeForFileName(a.label) + "-" + now;
        warningText = getString(R.string.warning_reset_account);
      }
    }

    LayoutInflater li = LayoutInflater.from(ctx);
    View view = li.inflate(R.layout.export_dialog, null);

    if (args.getBoolean(KEY_IS_FILTERED)) {
      view.findViewById(R.id.with_filter).setVisibility(View.VISIBLE);
      warningText = getString(R.string.warning_reset_account_matched);
    }

    dateFormatET = (EditText) view.findViewById(R.id.date_format);
    String dateFormatDefault =
        ((SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT)).toPattern();
    String dateFormat =
        MyApplication.getInstance().getSettings().getString(PREFKEY_EXPORT_DATE_FORMAT, "");
    if (dateFormat.equals("")) dateFormat = dateFormatDefault;
    else {
      try {
        new SimpleDateFormat(dateFormat, Locale.US);
      } catch (IllegalArgumentException e) {
        dateFormat = dateFormatDefault;
      }
    }
    dateFormatET.setText(dateFormat);
    dateFormatET.addTextChangedListener(
        new TextWatcher() {
          public void afterTextChanged(Editable s) {
            try {
              new SimpleDateFormat(s.toString(), Locale.US);
              mDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(true);
            } catch (IllegalArgumentException e) {
              dateFormatET.setError(getString(R.string.date_format_illegal));
              mDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(false);
            }
          }

          public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

          public void onTextChanged(CharSequence s, int start, int before, int count) {}
        });

    fileNameET = (EditText) view.findViewById(R.id.file_name);
    fileNameET.setText(fileName);
    fileNameET.addTextChangedListener(
        new TextWatcher() {
          public void afterTextChanged(Editable s) {
            int error = 0;
            if (s.toString().length() > 0) {
              if (s.toString().indexOf('/') > -1) {
                error = R.string.slash_forbidden_in_filename;
              }
            } else {
              error = R.string.no_title_given;
            }
            mDialog.getButton(AlertDialog.BUTTON_POSITIVE).setEnabled(error == 0);
            if (error != 0) {
              fileNameET.setError(getString(error));
            }
          }

          public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

          public void onTextChanged(CharSequence s, int start, int before, int count) {}
        });

    notYetExportedCB = (CheckBox) view.findViewById(R.id.export_not_yet_exported);
    deleteCB = (CheckBox) view.findViewById(R.id.export_delete);
    warningTV = (TextView) view.findViewById(R.id.warning_reset);

    String encoding =
        MyApplication.getInstance().getSettings().getString(PREFKEY_EXPORT_ENCODING, "UTF-8");

    ((Spinner) view.findViewById(R.id.Encoding))
        .setSelection(
            Arrays.asList(getResources().getStringArray(R.array.pref_qif_export_file_encoding))
                .indexOf(encoding));

    formatRBCSV = (RadioButton) view.findViewById(R.id.csv);
    String format = MyApplication.PrefKey.EXPORT_FORMAT.getString("QIF");
    if (format.equals("CSV")) {
      formatRBCSV.setChecked(true);
    }

    separatorRBComma = (RadioButton) view.findViewById(R.id.comma);
    char separator =
        (char)
            MyApplication.getInstance()
                .getSettings()
                .getInt(ExportTask.KEY_DECIMAL_SEPARATOR, Utils.getDefaultDecimalSeparator());
    if (separator == ',') {
      separatorRBComma.setChecked(true);
    }

    handleDeletedGroup = (RadioGroup) view.findViewById(R.id.handle_deleted);
    View.OnClickListener radioClickListener =
        new View.OnClickListener() {
          public void onClick(View v) {
            int mappedAction =
                v.getId() == R.id.create_helper
                    ? Account.EXPORT_HANDLE_DELETED_CREATE_HELPER
                    : Account.EXPORT_HANDLE_DELETED_UPDATE_BALANCE;
            if (handleDeletedAction == mappedAction) {
              handleDeletedAction = Account.EXPORT_HANDLE_DELETED_DO_NOTHING;
              handleDeletedGroup.clearCheck();
            } else {
              handleDeletedAction = mappedAction;
            }
          }
        };

    final RadioButton updateBalanceRadioButton =
        (RadioButton) view.findViewById(R.id.update_balance);
    final RadioButton createHelperRadioButton = (RadioButton) view.findViewById(R.id.create_helper);
    updateBalanceRadioButton.setOnClickListener(radioClickListener);
    createHelperRadioButton.setOnClickListener(radioClickListener);

    if (savedInstanceState == null) {
      handleDeletedAction =
          MyApplication.getInstance()
              .getSettings()
              .getInt(
                  ExportTask.KEY_EXPORT_HANDLE_DELETED, Account.EXPORT_HANDLE_DELETED_DO_NOTHING);
      if (handleDeletedAction == Account.EXPORT_HANDLE_DELETED_UPDATE_BALANCE) {
        updateBalanceRadioButton.setChecked(true);
      } else if (handleDeletedAction == Account.EXPORT_HANDLE_DELETED_CREATE_HELPER) {
        createHelperRadioButton.setChecked(true);
      }
    }

    deleteCB.setOnCheckedChangeListener(this);
    if (hasExported) {
      notYetExportedCB.setChecked(true);
      notYetExportedCB.setVisibility(View.VISIBLE);
    }

    warningTV.setText(warningText);
    if (allP) {
      ((TextView) view.findViewById(R.id.file_name_label)).setText(R.string.folder_name);
    }
    AlertDialog.Builder builder =
        new AlertDialog.Builder(ctx)
            .setTitle(allP ? R.string.menu_reset_all : R.string.menu_reset)
            .setView(view)
            .setPositiveButton(android.R.string.ok, this)
            .setNegativeButton(android.R.string.cancel, null);
    if (Build.VERSION.SDK_INT < 11) builder.setIcon(android.R.drawable.ic_dialog_alert);
    else builder.setIconAttribute(android.R.attr.alertDialogIcon);
    mDialog = builder.create();
    return mDialog;
  }
  @Override
  public void onClick(DialogInterface dialog, int which) {
    Activity ctx = getActivity();
    if (ctx == null) {
      return;
    }
    Bundle args = getArguments();
    Long accountId = args != null ? args.getLong(KEY_ACCOUNTID) : null;
    AlertDialog dlg = (AlertDialog) dialog;
    String format =
        ((RadioGroup) dlg.findViewById(R.id.format)).getCheckedRadioButtonId() == R.id.csv
            ? "CSV"
            : "QIF";
    String dateFormat = dateFormatET.getText().toString();
    char decimalSeparator =
        ((RadioGroup) dlg.findViewById(R.id.separator)).getCheckedRadioButtonId() == R.id.dot
            ? '.'
            : ',';

    int handleDeleted;
    switch (handleDeletedGroup.getCheckedRadioButtonId()) {
      case R.id.update_balance:
        handleDeleted = Account.EXPORT_HANDLE_DELETED_UPDATE_BALANCE;
        break;
      case R.id.create_helper:
        handleDeleted = Account.EXPORT_HANDLE_DELETED_CREATE_HELPER;
        break;
      default: // -1
        handleDeleted = Account.EXPORT_HANDLE_DELETED_DO_NOTHING;
    }

    String encoding = (String) ((Spinner) dlg.findViewById(R.id.Encoding)).getSelectedItem();
    SharedPreferencesCompat.apply(
        MyApplication.getInstance()
            .getSettings()
            .edit()
            .putString(MyApplication.PrefKey.EXPORT_FORMAT.getKey(), format)
            .putString(PREFKEY_EXPORT_DATE_FORMAT, dateFormat)
            .putString(PREFKEY_EXPORT_ENCODING, encoding)
            .putInt(ExportTask.KEY_DECIMAL_SEPARATOR, decimalSeparator)
            .putInt(ExportTask.KEY_EXPORT_HANDLE_DELETED, handleDeleted));
    boolean deleteP = deleteCB.isChecked();
    boolean notYetExportedP = notYetExportedCB.isChecked();
    String fileName = fileNameET.getText().toString();
    Result appDirStatus = Utils.checkAppDir();
    if (appDirStatus.success) {
      Bundle b = new Bundle();
      b.putInt(ConfirmationDialogFragment.KEY_COMMAND_POSITIVE, R.id.START_EXPORT_COMMAND);
      if (accountId == null) {
      } else if (accountId > 0) {
        b.putLong(KEY_ROWID, accountId);
      } else {
        b.putString(KEY_CURRENCY, currency);
      }
      b.putString(TaskExecutionFragment.KEY_FORMAT, format);
      b.putBoolean(ExportTask.KEY_DELETE_P, deleteP);
      b.putBoolean(ExportTask.KEY_NOT_YET_EXPORTED_P, notYetExportedP);
      b.putString(TaskExecutionFragment.KEY_DATE_FORMAT, dateFormat);
      b.putChar(ExportTask.KEY_DECIMAL_SEPARATOR, decimalSeparator);
      b.putString(TaskExecutionFragment.KEY_ENCODING, encoding);
      b.putInt(ExportTask.KEY_EXPORT_HANDLE_DELETED, handleDeleted);
      b.putString(ExportTask.KEY_FILE_NAME, fileName);
      if (Utils.checkAppFolderWarning()) {
        ((ConfirmationDialogListener) getActivity()).onPositive(b);
      } else {
        b.putInt(ConfirmationDialogFragment.KEY_TITLE, R.string.dialog_title_attention);
        b.putString(
            ConfirmationDialogFragment.KEY_MESSAGE,
            getString(R.string.warning_app_folder_will_be_deleted_upon_uninstall));
        b.putString(
            ConfirmationDialogFragment.KEY_PREFKEY,
            MyApplication.PrefKey.APP_FOLDER_WARNING_SHOWN.getKey());
        ConfirmationDialogFragment.newInstance(b).show(getFragmentManager(), "APP_FOLDER_WARNING");
      }
    } else {
      Toast.makeText(ctx, appDirStatus.print(ctx), Toast.LENGTH_LONG).show();
    }
  }