0
0
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:
Houssam Salem 2015-04-03 14:28:07 +11:00
parent 5098ae502c
commit ac9d3c3da4
16 changed files with 154 additions and 268 deletions

View File

@ -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 */

View File

@ -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.

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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();
}

View File

@ -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);

View File

@ -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);
}
}
}
}

View File

@ -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);
}

View File

@ -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() {

View File

@ -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);

View File

@ -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("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace("\"", "&quot;").replace(
"'", "&#39;");
}
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) {
}
}

View File

@ -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) {
}
}

View File

@ -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("&", "&amp;").replace("<", "&lt;").replace(">", "&gt;").replace("\"", "&quot;").replace(
"'", "&#39;");
}
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) {
}
}

View File

@ -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;
}
}