use of com.ichi2.anki.CardBrowser.Column.ANSWER in project AnkiChinaAndroid by ankichinateam.
the class AbstractFlashcardViewer method readCardText.
private void readCardText(final Card card, final SoundSide cardSide) {
final String cardSideContent;
if (!cardContentIsEmpty() && ((sDisplayAnswer && mFinalLoadAnswer.isEmpty()) || (!sDisplayAnswer && mFinalLoadQuestion.isEmpty()))) {
mainHandler.postDelayed(() -> {
showProgressBar();
Toast.makeText(AbstractFlashcardViewer.this, "卡牌加载中,网络不佳", Toast.LENGTH_SHORT).show();
}, 3000);
nNeedSpeakFinalRenderContent = true;
if (!fetchingRenderContent) {
fetchWebViewRenderContent(mCardWebView);
}
return;
}
mainHandler.removeCallbacksAndMessages(null);
hideProgressBar();
// 在这里获取最后的内容
cardSideContent = cardSide == SoundSide.QUESTION ? mFinalLoadQuestion : mFinalLoadAnswer;
Timber.i("finally i wanna say:%s,showing answer:%s", cardSideContent, sDisplayAnswer);
// 如果不是设置了离线模式且当前没网时,且非强制离线模式,则默认使用在线模式
if (AnkiDroidApp.getSharedPrefs(this).getBoolean(KEY_SELECT_ONLINE_SPEAK_ENGINE, false) && !mOfflineSpeakingForOnce) {
// 使用在线语音引擎
File target = new File(FileUtil.createTmpDir(this), card.getId() + "-" + cardSide + ".wav");
Timber.i("target audio :%s", target.getAbsolutePath());
if (target.exists()) {
Timber.i("target audio is exists,play it now");
mSoundPlayer.playSound(target.getAbsolutePath(), mp -> mOnlineSpeaking = false);
mOnlineSpeaking = true;
speakingHandler.postDelayed(speakingRunnable, 300);
return;
}
if (!isNetworkAvailable(AbstractFlashcardViewer.this)) {
CustomStyleDialog customStyleDialog = new CustomStyleDialog.Builder(AbstractFlashcardViewer.this).setCustomLayout(R.layout.dialog_common_custom_next).setTitle("在线朗读需联网!").centerTitle().setMessage("没有网络时可以点下方按钮切换成本地引擎").setPositiveButton("切换本地引擎", (dialog, which) -> {
dialog.dismiss();
AnkiDroidApp.getSharedPrefs(this).edit().putBoolean(KEY_SELECT_ONLINE_SPEAK_ENGINE, false).apply();
}).create();
customStyleDialog.show();
return;
}
getAccount().getToken(this, new MyAccount.TokenCallback() {
@Override
public void onSuccess(String token) {
mCacheToken = token;
// if (mFreeOnlineEngineCount != -10086) {
// if (mFreeOnlineEngineCount > 0) {
// String voice=ReadText.getAzureLanguage(card.getDid(), card.getOrd(), cardSide);
// if (voice.isEmpty()) {
// //选择语言
// CustomStyleDialog d = new CustomStyleDialog.Builder(AbstractFlashcardViewer.this)
// .setCustomLayout(R.layout.dialog_common_custom_next)
// .setTitle("首次朗读,请设置语言")
// .centerTitle()
// .setMessage("设置语言后,朗读效果更优,还可以选择是否自动朗读。")
// .setPositiveButton("前往设置", (dialog, which) -> {
// dialog.dismiss();
// SpeakSettingActivity.OpenSpeakSetting(card.getId(), card.getDid(), AbstractFlashcardViewer.this);
// }) .create();
// d.show();
// return;
// }
List<Pair<String, String>> texts = splitAry(cardSideContent, 59, String.valueOf(card.getId()), cardSide);
Map<String, String> params = new HashMap<>();
params.put(SpeechSynthesizer.PARAM_SPEED, String.valueOf(ReadText.getSpeechRate(mCurrentCard.getDid(), mCurrentCard.getOrd()) * 5));
synthesizer.setParams(params);
int result = synthesizer.batchSpeak(texts);
checkResult(result, "speak");
//
// } else {
// CustomStyleDialog customStyleDialog = new CustomStyleDialog.Builder(AbstractFlashcardViewer.this)
// .setCustomLayout(R.layout.dialog_common_custom_next)
// .setTitle("在线朗读次数已用完")
// .centerTitle()
// .setMessage("请前往充值在线朗读次数,学霸用户可以切换离线引擎,不限朗读次数")
// .setPositiveButton("前往充值", (dialog, which) -> {
// dialog.dismiss();
// WebViewActivity.openUrlInApp(AbstractFlashcardViewer.this, String.format(mBuyOnlineEngineUrl, token, BuildConfig.VERSION_NAME), token, REFRESH_VOICE_INFO);
// }).setNegativeButton("使用离线引擎", (dialog, which) -> {
// dialog.dismiss();
// AnkiDroidApp.getSharedPrefs(AbstractFlashcardViewer.this).edit().putBoolean(KEY_SELECT_ONLINE_SPEAK_ENGINE, false).apply();
// })
//
// .create();
//
// customStyleDialog.show();
// }
// } else {
// updateOnlineVoiceInfo(token);
// }
}
@Override
public void onFail(String message) {
Timber.e("need login while using online speak engine ");
Toast.makeText(AbstractFlashcardViewer.this, "当前未使用Anki记忆卡账号登录,无法使用在线语音引擎", Toast.LENGTH_SHORT).show();
Intent myAccount = new Intent(AbstractFlashcardViewer.this, MyAccount.class);
myAccount.putExtra("notLoggedIn", true);
startActivityForResultWithAnimation(myAccount, REFRESH_VOICE_INFO, ActivityTransitionAnimation.FADE);
}
});
speakingHandler.postDelayed(speakingRunnable, 300);
return;
}
mOfflineSpeakingForOnce = false;
String clozeReplacement = this.getString(R.string.reviewer_tts_cloze_spoken_replacement);
ReadText.readCardSide(cardSide, cardSideContent, card.getId(), getDeckIdForCard(card), card.getOrd(), clozeReplacement, true);
speakingHandler.postDelayed(speakingRunnable, 300);
}
use of com.ichi2.anki.CardBrowser.Column.ANSWER in project AnkiChinaAndroid by ankichinateam.
the class AbstractFlashcardViewer method getAnswerFormat.
/**
* getAnswerFormat returns the answer part of this card's template as entered by user, without any parsing
*/
public String getAnswerFormat() {
JSONObject model = mCurrentCard.model();
JSONObject template;
if (model.getInt("type") == Consts.MODEL_STD) {
template = model.getJSONArray("tmpls").getJSONObject(mCurrentCard.getOrd());
} else {
template = model.getJSONArray("tmpls").getJSONObject(0);
}
return template.getString("afmt");
}
use of com.ichi2.anki.CardBrowser.Column.ANSWER in project AnkiChinaAndroid by ankichinateam.
the class AbstractFlashcardViewer method initLayout.
// Set the content view to the one provided and initialize accessors.
// Tracked separately as #5023 on github for clipboard
@SuppressWarnings("deprecation")
protected void initLayout() {
FrameLayout mCardContainer = (FrameLayout) findViewById(R.id.flashcard_frame);
mTopBarLayout = (RelativeLayout) findViewById(R.id.top_bar);
ImageView mark = mTopBarLayout.findViewById(R.id.mark_icon);
ImageView flag = mTopBarLayout.findViewById(R.id.flag_icon);
mCardMarker = new CardMarker(mark, flag);
mCardFrame = (FrameLayout) findViewById(R.id.flashcard);
mCardFrameParent = (ViewGroup) mCardFrame.getParent();
mTouchLayer = (FrameLayout) findViewById(R.id.touch_layer);
mTouchLayer.setOnTouchListener(mGestureListener);
if (!mDisableClipboard) {
mClipboard = (android.text.ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
}
mCardFrame.removeAllViews();
// Initialize swipe
mGestureDetectorImpl = mLinkOverridesTouchGesture ? new LinkDetectingGestureDetector() : new MyGestureDetector();
gestureDetector = new GestureDetectorCompat(this, mGestureDetectorImpl);
mEaseButtonsLayout = findViewById(R.id.ease_buttons);
mEase1 = findViewById(R.id.ease1);
mEase1Layout = findViewById(R.id.flashcard_layout_ease1);
mEase1Layout.setOnClickListener(mSelectEaseHandler);
mEase2 = findViewById(R.id.ease2);
mEase2Layout = findViewById(R.id.flashcard_layout_ease2);
mEase2Layout.setOnClickListener(mSelectEaseHandler);
mEase3 = findViewById(R.id.ease3);
mEase3Layout = findViewById(R.id.flashcard_layout_ease3);
mEase3Layout.setOnClickListener(mSelectEaseHandler);
mEase4 = findViewById(R.id.ease4);
mEase4Layout = findViewById(R.id.flashcard_layout_ease4);
mEase4Layout.setOnClickListener(mSelectEaseHandler);
mNext1 = findViewById(R.id.nextTime1);
mNext2 = findViewById(R.id.nextTime2);
mNext3 = findViewById(R.id.nextTime3);
mNext4 = findViewById(R.id.nextTime4);
if (!mShowNextReviewTime) {
mNext1.setVisibility(View.GONE);
mNext2.setVisibility(View.GONE);
mNext3.setVisibility(View.GONE);
mNext4.setVisibility(View.GONE);
}
Button mFlipCard = (Button) findViewById(R.id.flip_card);
mFlipCardLayout = (LinearLayout) findViewById(R.id.flashcard_layout_flip);
mFlipCardLayout.setOnClickListener(mFlipCardListener);
if (!mButtonHeightSet && mRelativeButtonSize != 100) {
ViewGroup.LayoutParams params = mFlipCardLayout.getLayoutParams();
params.height = params.height * mRelativeButtonSize / 100;
params = mEase1Layout.getLayoutParams();
params.height = params.height * mRelativeButtonSize / 100;
params = mEase2Layout.getLayoutParams();
params.height = params.height * mRelativeButtonSize / 100;
params = mEase3Layout.getLayoutParams();
params.height = params.height * mRelativeButtonSize / 100;
params = mEase4Layout.getLayoutParams();
params.height = params.height * mRelativeButtonSize / 100;
mButtonHeightSet = true;
}
mPreviewButtonsLayout = findViewById(R.id.preview_buttons_layout);
mPreviewPrevCard = findViewById(R.id.preview_previous_flashcard);
mPreviewNextCard = findViewById(R.id.preview_next_flashcard);
mPreviewToggleAnswerText = findViewById(R.id.preview_flip_flashcard);
mCardTimer = (Chronometer) findViewById(R.id.card_time);
mChosenAnswer = (TextView) findViewById(R.id.choosen_answer);
mAnswerField = (EditText) findViewById(R.id.answer_field);
mLookUpIcon = findViewById(R.id.lookup_button);
mLookUpIcon.setVisibility(View.GONE);
mLookUpIcon.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View arg0) {
Timber.i("AbstractFlashcardViewer:: Lookup button pressed");
if (clipboardHasText()) {
lookUp();
}
}
});
initControls();
// Position answer buttons
String answerButtonsPosition = AnkiDroidApp.getSharedPrefs(this).getString(getString(R.string.answer_buttons_position_preference), "bottom");
LinearLayout answerArea = (LinearLayout) findViewById(R.id.bottom_area_layout);
RelativeLayout.LayoutParams answerAreaParams = (RelativeLayout.LayoutParams) answerArea.getLayoutParams();
RelativeLayout.LayoutParams cardContainerParams = (RelativeLayout.LayoutParams) mCardContainer.getLayoutParams();
switch(answerButtonsPosition) {
case "top":
cardContainerParams.addRule(RelativeLayout.BELOW, R.id.bottom_area_layout);
answerAreaParams.addRule(RelativeLayout.BELOW, R.id.mic_tool_bar_layer);
answerArea.removeView(mAnswerField);
answerArea.addView(mAnswerField, 1);
break;
case "bottom":
cardContainerParams.addRule(RelativeLayout.ABOVE, R.id.bottom_area_layout);
cardContainerParams.addRule(RelativeLayout.BELOW, R.id.mic_tool_bar_layer);
answerAreaParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
break;
default:
Timber.w("Unknown answerButtonsPosition: %s", answerButtonsPosition);
break;
}
answerArea.setLayoutParams(answerAreaParams);
mCardContainer.setLayoutParams(cardContainerParams);
}
use of com.ichi2.anki.CardBrowser.Column.ANSWER in project AnkiChinaAndroid by ankichinateam.
the class AbstractFlashcardViewer method answerCard.
protected void answerCard(@Consts.BUTTON_TYPE int ease) {
if (mInAnswer) {
return;
}
mIsSelecting = false;
hideLookupButton();
int buttonNumber = getCol().getSched().answerButtons(mCurrentCard);
// Detect invalid ease for current card (e.g. by using keyboard shortcut or gesture).
if (buttonNumber < ease) {
return;
}
// Set the dots appearing below the toolbar
switch(ease) {
case EASE_1:
mChosenAnswer.setText("\u2022");
mChosenAnswer.setTextColor(ContextCompat.getColor(this, R.color.material_red_500));
break;
case EASE_2:
mChosenAnswer.setText("\u2022\u2022");
mChosenAnswer.setTextColor(ContextCompat.getColor(this, buttonNumber == Consts.BUTTON_FOUR ? R.color.material_blue_grey_600 : R.color.material_green_500));
break;
case EASE_3:
mChosenAnswer.setText("\u2022\u2022\u2022");
mChosenAnswer.setTextColor(ContextCompat.getColor(this, buttonNumber == Consts.BUTTON_FOUR ? R.color.material_green_500 : R.color.material_light_blue_500));
break;
case EASE_4:
mChosenAnswer.setText("\u2022\u2022\u2022\u2022");
mChosenAnswer.setTextColor(ContextCompat.getColor(this, R.color.material_light_blue_500));
break;
default:
Timber.w("Unknown easy type %s", ease);
break;
}
// remove chosen answer hint after a while
mTimerHandler.removeCallbacks(removeChosenAnswerText);
mTimerHandler.postDelayed(removeChosenAnswerText, mShowChosenAnswerLength);
mSoundPlayer.stopSounds();
stopOnlineSpeaking();
mCurrentEase = ease;
CollectionTask.launchCollectionTask(ANSWER_CARD, mAnswerCardHandler(true), new TaskData(mCurrentCard, mCurrentEase));
}
use of com.ichi2.anki.CardBrowser.Column.ANSWER in project AnkiChinaAndroid by ankichinateam.
the class ContentProviderTest method testAnswerCard.
/**
* Test giving the answer for a reviewed card
*/
@Test
public void testAnswerCard() {
Collection col = getCol();
Card card = getFirstCardFromScheduler(col);
long cardId = card.getId();
// the card starts out being new
assertEquals("card is initial new", Consts.CARD_TYPE_NEW, card.getQueue());
ContentResolver cr = InstrumentationRegistry.getInstrumentation().getTargetContext().getContentResolver();
Uri reviewInfoUri = FlashCardsContract.ReviewInfo.CONTENT_URI;
ContentValues values = new ContentValues();
long noteId = card.note().getId();
int cardOrd = card.getOrd();
int earlyGraduatingEase = (schedVersion == 1) ? AbstractFlashcardViewer.EASE_3 : AbstractFlashcardViewer.EASE_4;
// 5 seconds
long timeTaken = 5000;
values.put(FlashCardsContract.ReviewInfo.NOTE_ID, noteId);
values.put(FlashCardsContract.ReviewInfo.CARD_ORD, cardOrd);
values.put(FlashCardsContract.ReviewInfo.EASE, earlyGraduatingEase);
values.put(FlashCardsContract.ReviewInfo.TIME_TAKEN, timeTaken);
int updateCount = cr.update(reviewInfoUri, values, null, null);
assertEquals("Check if update returns 1", 1, updateCount);
try {
Thread.currentThread().wait(500);
} catch (Exception e) {
/* do nothing */
}
col.reset();
Card newCard = col.getSched().getCard();
if (newCard != null) {
if (newCard.note().getId() == card.note().getId() && newCard.getOrd() == card.getOrd()) {
fail("Next scheduled card has not changed");
}
}
// lookup the card after update, ensure it's not new anymore
Card cardAfterReview = col.getCard(cardId);
assertEquals("card is now type rev", Card.TYPE_REV, cardAfterReview.getQueue());
}
Aggregations