mirror of
https://github.com/ankidroid/Anki-Android.git
synced 2024-09-20 20:03:05 +02:00
Remove v7 compat classes
Additionally, removed some methods that are not required to be in the compat classes, including: - Methods that are now available on all supported platforms after the recent minsdkversion bump - Methods that are supported on all platform through the support library and don't gain any benefits from being in our compat classes
This commit is contained in:
parent
5098ae502c
commit
ac9d3c3da4
@ -29,6 +29,7 @@ import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
@ -37,6 +38,7 @@ import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.os.SystemClock;
|
||||
import android.os.Vibrator;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.text.ClipboardManager;
|
||||
import android.text.SpannableString;
|
||||
import android.text.Spanned;
|
||||
@ -1490,7 +1492,7 @@ public abstract class AbstractFlashcardViewer extends NavigationDrawerActivity {
|
||||
webView.getSettings().setJavaScriptEnabled(true);
|
||||
webView.setWebChromeClient(new AnkiDroidWebChromeClient());
|
||||
webView.setFocusableInTouchMode(false);
|
||||
CompatHelper.getCompat().setScrollbarFadingEnabled(webView, false);
|
||||
webView.setScrollbarFadingEnabled(false);
|
||||
Timber.d("Focusable = %s, Focusable in touch mode = %s",webView.isFocusable(),webView.isFocusableInTouchMode());
|
||||
|
||||
webView.setWebViewClient(new WebViewClient() {
|
||||
@ -1556,8 +1558,12 @@ public abstract class AbstractFlashcardViewer extends NavigationDrawerActivity {
|
||||
if (mCard != null) {
|
||||
mCard.setBackgroundColor(mCurrentBackgroundColor);
|
||||
}
|
||||
CompatHelper.getCompat().setActionBarBackground(this,
|
||||
invert ? R.color.white_background_night : R.color.theme_primary);
|
||||
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setBackgroundDrawable(new ColorDrawable(res.getColor(
|
||||
invert ? R.color.white_background_night : R.color.theme_primary)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1794,7 +1800,7 @@ public abstract class AbstractFlashcardViewer extends NavigationDrawerActivity {
|
||||
|
||||
try {
|
||||
String[] title = getCol().getDecks().get(mCurrentCard.getDid()).getString("name").split("::");
|
||||
CompatHelper.getCompat().setTitle(this, title[title.length - 1], mInvertedColors);
|
||||
UIUtils.setTitle(this, title[title.length - 1]);
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
@ -1802,7 +1808,7 @@ public abstract class AbstractFlashcardViewer extends NavigationDrawerActivity {
|
||||
int[] counts = mSched.counts(mCurrentCard);
|
||||
|
||||
int eta = mSched.eta(counts, false);
|
||||
CompatHelper.getCompat().setSubtitle(this,
|
||||
UIUtils.setSubtitle(this,
|
||||
getResources().getQuantityString(R.plurals.reviewer_window_title, eta, eta), mInvertedColors);
|
||||
|
||||
SpannableString newCount = new SpannableString(String.valueOf(counts[0]));
|
||||
@ -2630,7 +2636,7 @@ public abstract class AbstractFlashcardViewer extends NavigationDrawerActivity {
|
||||
|
||||
|
||||
protected void refreshActionBar() {
|
||||
CompatHelper.getCompat().invalidateOptionsMenu(AbstractFlashcardViewer.this);
|
||||
supportInvalidateOptionsMenu();
|
||||
}
|
||||
|
||||
/** Fixing bug 720: <input> focus, thanks to pablomouzo on android issue 7189 */
|
||||
|
@ -178,7 +178,7 @@ public class AnkiDroidApp extends Application {
|
||||
|
||||
// Set good default values for swipe detection
|
||||
final ViewConfiguration vc = ViewConfiguration.get(this);
|
||||
DEFAULT_SWIPE_MIN_DISTANCE = CompatHelper.getCompat().getScaledPagingTouchSlop(vc);
|
||||
DEFAULT_SWIPE_MIN_DISTANCE = vc.getScaledPagingTouchSlop();
|
||||
DEFAULT_SWIPE_THRESHOLD_VELOCITY = vc.getScaledMinimumFlingVelocity();
|
||||
|
||||
// Create the AnkiDroid directory if missing. Send exception report if inaccessible.
|
||||
|
@ -1735,7 +1735,7 @@ public class DeckPicker extends NavigationDrawerActivity implements OnShowcaseEv
|
||||
if (eta != -1) {
|
||||
time = res.getQuantityString(R.plurals.deckpicker_title_minutes, eta, eta);
|
||||
}
|
||||
CompatHelper.getCompat().setSubtitle(DeckPicker.this,
|
||||
UIUtils.setSubtitle(DeckPicker.this,
|
||||
res.getQuantityString(R.plurals.deckpicker_title, due, due, time));
|
||||
}
|
||||
|
||||
@ -1751,7 +1751,7 @@ public class DeckPicker extends NavigationDrawerActivity implements OnShowcaseEv
|
||||
// update widget
|
||||
WidgetStatus.update(DeckPicker.this, nodes);
|
||||
// update options menu and clear welcome screen
|
||||
CompatHelper.getCompat().invalidateOptionsMenu(DeckPicker.this);
|
||||
supportInvalidateOptionsMenu();
|
||||
// Update the mini statistics bar as well
|
||||
AnkiStatsTaskHandler.createSmallTodayOverview(getCol(), mTodayTextView);
|
||||
}
|
||||
|
@ -19,12 +19,10 @@
|
||||
package com.ichi2.anki;
|
||||
|
||||
import android.os.Bundle;
|
||||
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
|
||||
import com.ichi2.compat.CompatHelper;
|
||||
import com.ichi2.libanki.Collection;
|
||||
|
||||
import timber.log.Timber;
|
||||
@ -50,7 +48,7 @@ public class Previewer extends AbstractFlashcardViewer {
|
||||
|
||||
@Override
|
||||
protected void setTitle() {
|
||||
CompatHelper.getCompat().setTitle(this, getResources().getString(R.string.preview_title), mInvertedColors);
|
||||
UIUtils.setTitle(this, getResources().getString(R.string.preview_title));
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,12 +59,12 @@ public class Reviewer extends AbstractFlashcardViewer {
|
||||
} else {
|
||||
Timber.e("Could not set title in reviewer because collection closed");
|
||||
}
|
||||
CompatHelper.getCompat().setTitle(this, title[title.length - 1], mNightMode);
|
||||
UIUtils.setTitle(this, title[title.length - 1]);
|
||||
super.setTitle(title[title.length - 1]);
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
CompatHelper.getCompat().setSubtitle(this, "", mNightMode);
|
||||
UIUtils.setSubtitle(this, "", mNightMode);
|
||||
}
|
||||
|
||||
|
||||
|
@ -39,7 +39,6 @@ import com.ichi2.anim.ActivityTransitionAnimation;
|
||||
import com.ichi2.anki.stats.AnkiStatsTaskHandler;
|
||||
import com.ichi2.anki.stats.ChartView;
|
||||
import com.ichi2.anki.widgets.DeckDropDownAdapter;
|
||||
import com.ichi2.compat.CompatHelper;
|
||||
import com.ichi2.libanki.Collection;
|
||||
import com.ichi2.libanki.Stats;
|
||||
|
||||
@ -473,7 +472,7 @@ public class Statistics extends NavigationDrawerActivity implements ActionBar.On
|
||||
Collection col = CollectionHelper.getInstance().getCol(getActivity());
|
||||
List<String> parts = Arrays.asList(col.getDecks().current().getString("name").split("::"));
|
||||
if(sIsSubtitle)
|
||||
CompatHelper.getCompat().setSubtitle(getActivity(), parts.get(parts.size() - 1));
|
||||
UIUtils.setSubtitle(getActivity(), parts.get(parts.size() - 1));
|
||||
else
|
||||
getActivity().setTitle(parts.get(parts.size() - 1));
|
||||
} catch (JSONException e) {
|
||||
@ -481,7 +480,7 @@ public class Statistics extends NavigationDrawerActivity implements ActionBar.On
|
||||
}
|
||||
} else {
|
||||
if(sIsSubtitle)
|
||||
CompatHelper.getCompat().setSubtitle(getActivity(), getResources().getString(R.string.stats_deck_collection));
|
||||
UIUtils.setSubtitle(getActivity(), getResources().getString(R.string.stats_deck_collection));
|
||||
else
|
||||
getActivity().setTitle(getResources().getString(R.string.stats_deck_collection));
|
||||
}
|
||||
@ -628,7 +627,7 @@ public class Statistics extends NavigationDrawerActivity implements ActionBar.On
|
||||
try {
|
||||
List<String> parts = Arrays.asList(col.getDecks().current().getString("name").split("::"));
|
||||
if(sIsSubtitle)
|
||||
CompatHelper.getCompat().setSubtitle(getActivity(), parts.get(parts.size() - 1));
|
||||
UIUtils.setSubtitle(getActivity(), parts.get(parts.size() - 1));
|
||||
else
|
||||
getActivity().setTitle(parts.get(parts.size() - 1));
|
||||
} catch (JSONException e) {
|
||||
@ -636,7 +635,7 @@ public class Statistics extends NavigationDrawerActivity implements ActionBar.On
|
||||
}
|
||||
} else {
|
||||
if(sIsSubtitle)
|
||||
CompatHelper.getCompat().setSubtitle(getActivity(), getResources().getString(R.string.stats_deck_collection));
|
||||
UIUtils.setSubtitle(getActivity(), getResources().getString(R.string.stats_deck_collection));
|
||||
else
|
||||
getActivity().setTitle(getResources().getString(R.string.stats_deck_collection));
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ import android.content.DialogInterface.OnCancelListener;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.os.Bundle;
|
||||
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
@ -32,7 +31,6 @@ import android.view.View;
|
||||
import com.ichi2.anim.ActivityTransitionAnimation;
|
||||
import com.ichi2.anki.StudyOptionsFragment.StudyOptionsListener;
|
||||
import com.ichi2.anki.receiver.SdCardReceiver;
|
||||
import com.ichi2.compat.CompatHelper;
|
||||
import com.ichi2.themes.StyledOpenCollectionDialog;
|
||||
import com.ichi2.themes.Themes;
|
||||
import com.ichi2.widget.WidgetStatus;
|
||||
@ -119,7 +117,7 @@ public class StudyOptionsActivity extends NavigationDrawerActivity implements St
|
||||
|
||||
String newLanguage = AnkiDroidApp.getSharedPrefs(this).getString(Preferences.LANGUAGE, "");
|
||||
if (AnkiDroidApp.setLanguage(newLanguage)) {
|
||||
CompatHelper.getCompat().invalidateOptionsMenu(this);
|
||||
supportInvalidateOptionsMenu();
|
||||
}
|
||||
getCurrentFragment().restorePreferences();
|
||||
}
|
||||
|
@ -51,7 +51,6 @@ import com.ichi2.anki.stats.AnkiStatsTaskHandler;
|
||||
import com.ichi2.anki.stats.ChartView;
|
||||
import com.ichi2.async.CollectionLoader;
|
||||
import com.ichi2.async.DeckTask;
|
||||
import com.ichi2.compat.CompatHelper;
|
||||
import com.ichi2.libanki.Collection;
|
||||
import com.ichi2.libanki.Consts;
|
||||
import com.ichi2.libanki.Utils;
|
||||
@ -767,7 +766,7 @@ public class StudyOptionsFragment extends Fragment implements LoaderManager.Load
|
||||
if (!mFragmented) {
|
||||
getActivity().setTitle(getResources().getString(R.string.studyoptions_title));
|
||||
List<String> parts = Arrays.asList(fullName.split("::"));
|
||||
CompatHelper.getCompat().setSubtitle(getActivity(), parts.get(parts.size() - 1));
|
||||
UIUtils.setSubtitle(getActivity(), parts.get(parts.size() - 1));
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
throw new RuntimeException(e);
|
||||
|
@ -4,10 +4,16 @@ package com.ichi2.anki;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.style.CharacterStyle;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.ichi2.async.DeckTask;
|
||||
import com.ichi2.async.DeckTask.TaskData;
|
||||
import com.ichi2.themes.Themes;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
@ -67,4 +73,38 @@ public class UIUtils {
|
||||
WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
}
|
||||
|
||||
|
||||
public static void setTitle(Activity activity, String title) {
|
||||
ActionBarActivity actionBarActivity = (ActionBarActivity) activity;
|
||||
ActionBar actionBar = actionBarActivity.getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
CharacterStyle span = new ForegroundColorSpan(activity.getResources().getColor(
|
||||
Themes.getResourceIdFromAttributeId(R.attr.actionBarTextColor)));
|
||||
SpannableStringBuilder ssb = new SpannableStringBuilder(title);// Is it even necessary to use spannables anymore?
|
||||
ssb.setSpan(span, 0, ssb.length(), 0);
|
||||
actionBar.setTitle(ssb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public static void setSubtitle(Activity activity, String title) {
|
||||
setSubtitle(activity, title, false);
|
||||
}
|
||||
|
||||
|
||||
public static void setSubtitle(Activity activity, String title, boolean inverted) {
|
||||
ActionBarActivity actionBarActivity = (ActionBarActivity) activity;
|
||||
ActionBar actionBar = actionBarActivity.getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
if (inverted) {
|
||||
CharacterStyle span = new ForegroundColorSpan(activity.getResources().getColor(
|
||||
Themes.getResourceIdFromAttributeId(R.attr.actionBarTextColor)));
|
||||
SpannableStringBuilder ssb = new SpannableStringBuilder(title);
|
||||
ssb.setSpan(span, 0, ssb.length(), 0);
|
||||
actionBar.setSubtitle(ssb);
|
||||
} else {
|
||||
actionBar.setSubtitle(title);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -16,14 +16,10 @@
|
||||
|
||||
package com.ichi2.compat;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.media.AudioManager;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import com.ichi2.anki.exception.APIVersionException;
|
||||
@ -40,30 +36,21 @@ import com.ichi2.anki.exception.APIVersionException;
|
||||
* <p>
|
||||
* Each implementation should only override the methods that first become available in its own version, use @Override.
|
||||
* <p>
|
||||
* Methods not supported by its API will default to the empty implementations of CompatV7. Methods first supported
|
||||
* Methods not supported by its API will default to the empty implementations of CompatV8. Methods first supported
|
||||
* by lower APIs will default to those implementations since we extended them.
|
||||
* <p>
|
||||
* Example: CompatV9 extends CompatV8. This means that the nfdNormalized function that uses classes only available
|
||||
* Example: CompatV9 extends CompatV8. This means that the nfcNormalized function that uses classes only available
|
||||
* in API 9, should be implemented properly in CompatV9 with @Override annotation. On the other hand a method
|
||||
* like requestAudioFocus that first becomes available in API 8 need not be implemented again in CompatV9, unless the
|
||||
* behaviour is supposed to be different there.
|
||||
* like setOverScrollModeNever that first becomes available in API 9 need not be implemented again in CompatV10,
|
||||
* unless the behaviour is supposed to be different there.
|
||||
*/
|
||||
public interface Compat {
|
||||
public abstract String nfcNormalized(String txt) throws APIVersionException;
|
||||
public abstract String detagged(String txt);
|
||||
public abstract void setScrollbarFadingEnabled(WebView webview, boolean enable);
|
||||
public abstract void setOverScrollModeNever(View v);
|
||||
public abstract void invalidateOptionsMenu(Activity activity);
|
||||
public abstract void setActionBarBackground(Activity activity, int color);
|
||||
public abstract void setTitle(Activity activity, String title, boolean inverted);
|
||||
public abstract void setSubtitle(Activity activity, String title);
|
||||
public abstract void setSubtitle(Activity activity, String title, boolean inverted);
|
||||
public abstract void setTtsOnUtteranceProgressListener(TextToSpeech tts);
|
||||
public abstract void disableDatabaseWriteAheadLogging(SQLiteDatabase db);
|
||||
public abstract void requestAudioFocus(AudioManager audioManager);
|
||||
public abstract void abandonAudioFocus(AudioManager audioManager);
|
||||
public abstract void enableCookiesForFileSchemePages();
|
||||
public abstract int getScaledPagingTouchSlop(ViewConfiguration vc);
|
||||
public abstract void updateWidgetDimensions(Context context, RemoteViews updateViews, Class<?> cls);
|
||||
}
|
||||
|
||||
|
@ -38,12 +38,8 @@ public class CompatHelper {
|
||||
mCompat = new CompatV12();
|
||||
} else if (getSdkVersion() >= 9) {
|
||||
mCompat = new CompatV9();
|
||||
} else if (getSdkVersion() >= 8) {
|
||||
mCompat = new CompatV8();
|
||||
} else if (isNook() && getSdkVersion() == 7) {
|
||||
mCompat = new CompatV7Nook();
|
||||
} else {
|
||||
mCompat = new CompatV7();
|
||||
mCompat = new CompatV8();
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,10 +48,6 @@ public class CompatHelper {
|
||||
return Build.VERSION.SDK_INT;
|
||||
}
|
||||
|
||||
/** Determine if the device is running API level 8 or higher. */
|
||||
public static boolean isFroyo() {
|
||||
return getSdkVersion() >= Build.VERSION_CODES.FROYO;
|
||||
}
|
||||
|
||||
/** Determine if the device is running API level 11 or higher. */
|
||||
public static boolean isHoneycomb() {
|
||||
|
@ -8,7 +8,7 @@ import android.webkit.CookieManager;
|
||||
public class CompatV12 extends CompatV9 implements Compat {
|
||||
|
||||
// On API level 12 and higher, WebKit prevents file scheme pages from accessing cookies.
|
||||
// This function removes this restriction.
|
||||
// This function removes this restriction.
|
||||
@Override
|
||||
public void enableCookiesForFileSchemePages() {
|
||||
CookieManager.setAcceptFileSchemeCookies(true);
|
||||
|
@ -1,174 +0,0 @@
|
||||
|
||||
package com.ichi2.compat;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.media.AudioManager;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.style.CharacterStyle;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.view.View;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.webkit.WebView;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import com.ichi2.anki.R;
|
||||
import com.ichi2.anki.ReadText;
|
||||
import com.ichi2.anki.exception.APIVersionException;
|
||||
import com.ichi2.themes.Themes;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** Implementation of {@link Compat} for SDK level 7 */
|
||||
@TargetApi(7)
|
||||
public class CompatV7 implements Compat {
|
||||
|
||||
|
||||
// Only match text that is entirely ASCII.
|
||||
private static final Pattern fASCII = Pattern.compile("^\\p{ASCII}*$");
|
||||
|
||||
|
||||
/*
|
||||
* Return the input string. Not doing the NFC normalization may cause a typed answer to be displayed as
|
||||
* incorrect when it was correct, but stored in a differnt but equivalent form in the card. (E.g. umlauts
|
||||
* stored decomposed but typed as single characters.)
|
||||
*
|
||||
* @param txt Text to be normalized
|
||||
* @return The input text not NFC normalized.
|
||||
*/
|
||||
@Override
|
||||
public String nfcNormalized(String txt) throws APIVersionException {
|
||||
// We will at least try to check if the string can be represented entirely in ASCII.
|
||||
// If it can be, we can be sure it's normalized. If not, we throw since we can't
|
||||
// make a guarantee about the actual normalized state of the string.
|
||||
if (fASCII.matcher(txt).find()) {
|
||||
return txt;
|
||||
} else {
|
||||
throw new APIVersionException("NFC normalization is not available in this API version");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Return the input string in a form suitable for display on a HTML page. Replace “<”, “>”, “&”, “"” and “'” with
|
||||
* HTML entities.
|
||||
*
|
||||
* @param txt Text to be cleaned.
|
||||
* @return The input text, with HTML tags and entities escaped.
|
||||
*/
|
||||
public String detagged(String txt) {
|
||||
if (txt == null)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
return txt.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """).replace(
|
||||
"'", "'");
|
||||
}
|
||||
|
||||
|
||||
public void setScrollbarFadingEnabled(WebView webview, boolean enable) {
|
||||
webview.setScrollbarFadingEnabled(enable);
|
||||
}
|
||||
|
||||
|
||||
public void setOverScrollModeNever(View v) {
|
||||
}
|
||||
|
||||
|
||||
public void invalidateOptionsMenu(Activity activity) {
|
||||
ActionBarActivity actionBarActivity = (ActionBarActivity) activity;
|
||||
actionBarActivity.supportInvalidateOptionsMenu();
|
||||
}
|
||||
|
||||
|
||||
public void setActionBarBackground(Activity activity, int color) {
|
||||
ActionBarActivity actionBarActivity = (ActionBarActivity) activity;
|
||||
ActionBar actionBar = actionBarActivity.getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setBackgroundDrawable(new ColorDrawable(activity.getResources().getColor(color)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setTitle(Activity activity, String title, boolean inverted) {
|
||||
ActionBarActivity actionBarActivity = (ActionBarActivity) activity;
|
||||
ActionBar actionBar = actionBarActivity.getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
CharacterStyle span = new ForegroundColorSpan(activity.getResources().getColor(
|
||||
Themes.getResourceIdFromAttributeId(R.attr.actionBarTextColor)));
|
||||
SpannableStringBuilder ssb = new SpannableStringBuilder(title);// Is it even necessary to use spannables anymore?
|
||||
ssb.setSpan(span, 0, ssb.length(), 0);
|
||||
actionBar.setTitle(ssb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setSubtitle(Activity activity, String title) {
|
||||
setSubtitle(activity, title, false);
|
||||
}
|
||||
|
||||
|
||||
public void setSubtitle(Activity activity, String title, boolean inverted) {
|
||||
ActionBarActivity actionBarActivity = (ActionBarActivity) activity;
|
||||
ActionBar actionBar = actionBarActivity.getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
if (inverted) {
|
||||
CharacterStyle span = new ForegroundColorSpan(activity.getResources().getColor(
|
||||
Themes.getResourceIdFromAttributeId(R.attr.actionBarTextColor)));
|
||||
SpannableStringBuilder ssb = new SpannableStringBuilder(title);
|
||||
ssb.setSpan(span, 0, ssb.length(), 0);
|
||||
actionBar.setSubtitle(ssb);
|
||||
} else {
|
||||
actionBar.setSubtitle(title);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setTtsOnUtteranceProgressListener(TextToSpeech tts) {
|
||||
tts.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {
|
||||
@Override
|
||||
public void onUtteranceCompleted(String utteranceId) {
|
||||
if (ReadText.sTextQueue.size() > 0) {
|
||||
String[] text = ReadText.sTextQueue.remove(0);
|
||||
ReadText.speak(text[0], text[1]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void disableDatabaseWriteAheadLogging(SQLiteDatabase db) {
|
||||
}
|
||||
|
||||
|
||||
public void requestAudioFocus(AudioManager audioManager) {
|
||||
}
|
||||
|
||||
|
||||
public void abandonAudioFocus(AudioManager audioManager) {
|
||||
}
|
||||
|
||||
|
||||
// Below API level 12, file scheme pages are not restricted, so no adjustment is needed.
|
||||
public void enableCookiesForFileSchemePages() { }
|
||||
|
||||
// Below API 9 this method doesn't exist, so use reasonable value
|
||||
@Override
|
||||
public int getScaledPagingTouchSlop(ViewConfiguration vc) {
|
||||
return vc.getScaledTouchSlop()*2;
|
||||
}
|
||||
|
||||
// Below API level 16, widget dimensions cannot be adjusted
|
||||
@Override
|
||||
public void updateWidgetDimensions(Context context, RemoteViews updateViews, Class<?> cls) {
|
||||
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
|
||||
package com.ichi2.compat;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.webkit.WebView;
|
||||
|
||||
/**
|
||||
* Implementation of {@link Compat} for SDK level 7 for Nooks, e.g. Simple Touch.
|
||||
* <p>
|
||||
* This device does not support scrollbar fading.
|
||||
**/
|
||||
@TargetApi(7)
|
||||
public class CompatV7Nook extends CompatV7 implements Compat {
|
||||
|
||||
@Override
|
||||
public void setScrollbarFadingEnabled(WebView webview, boolean enable) {
|
||||
}
|
||||
|
||||
}
|
@ -2,38 +2,90 @@
|
||||
package com.ichi2.compat;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.media.AudioManager;
|
||||
import android.media.AudioManager.OnAudioFocusChangeListener;
|
||||
import android.view.ViewConfiguration;
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.speech.tts.TextToSpeech.OnUtteranceCompletedListener;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
/** Implementation of {@link Compat} for SDK level 8 */
|
||||
import com.ichi2.anki.ReadText;
|
||||
import com.ichi2.anki.exception.APIVersionException;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/** Implementation of {@link Compat} for SDK level 7 */
|
||||
@TargetApi(8)
|
||||
public class CompatV8 extends CompatV7 implements Compat {
|
||||
public class CompatV8 implements Compat {
|
||||
|
||||
/**
|
||||
* Listener to handle audio focus. Currently blank because we're not respecting losing focus from other apps.
|
||||
*/
|
||||
private static OnAudioFocusChangeListener afChangeListener = new OnAudioFocusChangeListener() {
|
||||
public void onAudioFocusChange(int focusChange) {
|
||||
// Only match text that is entirely ASCII.
|
||||
private static final Pattern fASCII = Pattern.compile("^\\p{ASCII}*$");
|
||||
|
||||
/*
|
||||
* Return the input string. Not doing the NFC normalization may cause a typed answer to be displayed as
|
||||
* incorrect when it was correct, but stored in a different but equivalent form in the card. (E.g. umlauts
|
||||
* stored decomposed but typed as single characters.)
|
||||
*
|
||||
* @param txt Text to be normalized
|
||||
* @return The input text not NFC normalized.
|
||||
*/
|
||||
@Override
|
||||
public String nfcNormalized(String txt) throws APIVersionException {
|
||||
// We will at least try to check if the string can be represented entirely in ASCII.
|
||||
// If it can be, we can be sure it's normalized. If not, we throw since we can't
|
||||
// make a guarantee about the actual normalized state of the string.
|
||||
if (fASCII.matcher(txt).find()) {
|
||||
return txt;
|
||||
} else {
|
||||
throw new APIVersionException("NFC normalization is not available in this API version");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@Override
|
||||
public void requestAudioFocus(AudioManager audioManager) {
|
||||
audioManager.requestAudioFocus(afChangeListener, AudioManager.STREAM_MUSIC,
|
||||
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void abandonAudioFocus(AudioManager audioManager) {
|
||||
audioManager.abandonAudioFocus(afChangeListener);
|
||||
/*
|
||||
* Return the input string in a form suitable for display on a HTML page. Replace “<”, “>”, “&”, “"” and “'” with
|
||||
* HTML entities.
|
||||
*
|
||||
* @param txt Text to be cleaned.
|
||||
* @return The input text, with HTML tags and entities escaped.
|
||||
*/
|
||||
public String detagged(String txt) {
|
||||
if (txt == null) {
|
||||
return "";
|
||||
}
|
||||
return txt.replace("&", "&").replace("<", "<").replace(">", ">").replace("\"", """).replace(
|
||||
"'", "'");
|
||||
}
|
||||
|
||||
|
||||
public void setOverScrollModeNever(View v) {
|
||||
}
|
||||
|
||||
|
||||
public void setTtsOnUtteranceProgressListener(TextToSpeech tts) {
|
||||
tts.setOnUtteranceCompletedListener(new OnUtteranceCompletedListener() {
|
||||
@Override
|
||||
public void onUtteranceCompleted(String utteranceId) {
|
||||
if (ReadText.sTextQueue.size() > 0) {
|
||||
String[] text = ReadText.sTextQueue.remove(0);
|
||||
ReadText.speak(text[0], text[1]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
public void disableDatabaseWriteAheadLogging(SQLiteDatabase db) {
|
||||
}
|
||||
|
||||
|
||||
// Below API level 12, file scheme pages are not restricted, so no adjustment is needed.
|
||||
public void enableCookiesForFileSchemePages() { }
|
||||
|
||||
|
||||
// Below API level 16, widget dimensions cannot be adjusted
|
||||
@Override
|
||||
public int getScaledPagingTouchSlop(ViewConfiguration vc) {
|
||||
return vc.getScaledPagingTouchSlop();
|
||||
public void updateWidgetDimensions(Context context, RemoteViews updateViews, Class<?> cls) {
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -92,6 +92,13 @@ public class Sound {
|
||||
*/
|
||||
private static HashMap<Integer, ArrayList<String>> sSoundPaths = new HashMap<Integer, ArrayList<String>>();
|
||||
|
||||
/**
|
||||
* Listener to handle audio focus. Currently blank because we're not respecting losing focus from other apps.
|
||||
*/
|
||||
private static AudioManager.OnAudioFocusChangeListener afChangeListener = new AudioManager.OnAudioFocusChangeListener() {
|
||||
public void onAudioFocusChange(int focusChange) {
|
||||
}
|
||||
};
|
||||
|
||||
/* Prevent class from being instantiated */
|
||||
private Sound() {
|
||||
@ -307,7 +314,8 @@ public class Sound {
|
||||
sMediaPlayer.setOnCompletionListener(playAllListener);
|
||||
}
|
||||
sMediaPlayer.prepareAsync();
|
||||
CompatHelper.getCompat().requestAudioFocus(sAudioManager);
|
||||
sAudioManager.requestAudioFocus(afChangeListener, AudioManager.STREAM_MUSIC,
|
||||
AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK);
|
||||
} catch (Exception e) {
|
||||
Timber.e(e, "playSounds - Error reproducing sound %s", soundPath);
|
||||
releaseSound();
|
||||
@ -384,7 +392,7 @@ public class Sound {
|
||||
sMediaPlayer = null;
|
||||
}
|
||||
if (sAudioManager != null) {
|
||||
CompatHelper.getCompat().abandonAudioFocus(sAudioManager);
|
||||
sAudioManager.abandonAudioFocus(afChangeListener);
|
||||
sAudioManager = null;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user