package com.gracecode.android.gojuon.service; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.AssetFileDescriptor; import android.media.AudioAttributes; import android.media.AudioManager; import android.media.SoundPool; import android.os.Build; import android.os.IBinder; import android.support.v4.util.LruCache; import com.gracecode.android.gojuon.Characters; import java.io.IOException; import java.util.Arrays; public class PronounceService extends Service { public static final String PLAY_PRONOUNCE_NAME = PronounceService.class.getName(); public static final String EXTRA_CHARSET = "extra_charset"; private static final int MAX_STREAMS = 5; private SoundPool mSoundPool; private AudioManager mAudioManager; private LruCache<String, String[]> mLruCache; BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String charset = intent.getStringExtra(EXTRA_CHARSET); if (charset != null && charset.length() > 0) { try { AssetFileDescriptor pronounceFile = getPronounceAssetFile(charset); if (pronounceFile.getLength() > 0) { final int playId = mSoundPool.load(pronounceFile, 1); mSoundPool.setOnLoadCompleteListener(new SoundPool.OnLoadCompleteListener() { @Override public void onLoadComplete(SoundPool soundPool, int i, int i2) { int volume = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); mSoundPool.play(playId, volume, volume, 1, 0, 1f); mSoundPool.unload(playId); } }); } } catch (IOException e) { e.printStackTrace(); } } } private String getRoumajiFromCharset(String needle) { String[] cached = mLruCache.get(needle); if (cached != null && cached.length > 0) { return cached[Characters.INDEX_ROUMAJI]; } String[][][] all = new String[][][]{ Characters.MONOGRAPHS, Characters.DIGRAPHS, Characters.MONOGRAPHS_WITH_DIACRITICS, Characters.DIGRAPHS_WITH_DIACRITICS }; for (String[][] characters : all) { for (String[] item : characters) { if (Arrays.asList(item).contains(needle)) { mLruCache.put(needle, item); return item[Characters.INDEX_ROUMAJI]; } } } return ""; } private AssetFileDescriptor getPronounceAssetFile(String charset) throws IOException { String roumaji = getRoumajiFromCharset(charset); roumaji = roumaji.replaceAll("(\\*+)$", ""); switch (roumaji) { case "o/wo": roumaji = "wo"; break; } return getAssets().openFd("pronounce/" + roumaji + ".ogg"); } }; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { SoundPool.Builder builder = new SoundPool.Builder(); AudioAttributes.Builder attributes = new AudioAttributes.Builder(); attributes.setContentType(AudioAttributes.CONTENT_TYPE_MUSIC) .setLegacyStreamType(AudioManager.STREAM_MUSIC) .setUsage(AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY); builder.setAudioAttributes(attributes.build()) .setMaxStreams(MAX_STREAMS); mSoundPool = builder.build(); } else { mSoundPool = new SoundPool(5, AudioManager.STREAM_MUSIC, 0); } mAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE); mLruCache = new LruCache<String, String[]>(Characters.MONOGRAPHS.length); registerReceiver(mBroadcastReceiver, new IntentFilter(PronounceService.PLAY_PRONOUNCE_NAME)); } @Override public void onDestroy() { super.onDestroy(); mSoundPool.release(); unregisterReceiver(mBroadcastReceiver); } }