package cn.qylk; import java.util.ArrayList; import java.util.List; import java.util.Locale; import android.app.Activity; import android.app.AlertDialog; import android.app.FragmentManager.OnBackStackChangedListener; import android.app.FragmentTransaction; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.DialogInterface.OnClickListener; import android.content.Intent; import android.content.IntentFilter; import android.graphics.Bitmap; import android.graphics.Paint; import android.media.audiofx.Visualizer; import android.media.audiofx.Visualizer.OnDataCaptureListener; import android.os.Bundle; import android.os.Handler; import android.os.Handler.Callback; import android.os.Message; import android.speech.RecognizerIntent; import android.view.Menu; import android.view.View; import android.view.WindowManager; import android.view.animation.Animation; import android.view.animation.Animation.AnimationListener; import android.view.animation.AnimationUtils; import android.widget.AutoCompleteTextView; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; import android.widget.Toast; import cn.qylk.adapter.trainAdptertest; import cn.qylk.app.APP; import cn.qylk.app.IPlayList.ListType; import cn.qylk.app.ListTypeInfo; import cn.qylk.app.MyAction; import cn.qylk.app.PlayList; import cn.qylk.app.SensorTest; import cn.qylk.app.Tasks; import cn.qylk.app.Tasks.onPostInfo; import cn.qylk.app.Tasks.onPostLrc; import cn.qylk.app.Tasks.onPostPic; import cn.qylk.app.TrackInfo; import cn.qylk.database.MediaDatabase; import cn.qylk.fragment.FragmentInfoInputDialog; import cn.qylk.fragment.Fragment_Menus; import cn.qylk.fragment.Fragment_MusicControls; import cn.qylk.lrc.LRCbean; import cn.qylk.lrc.MediaLyric; import cn.qylk.lrc.ModifyLyric; import cn.qylk.myview.LrcPackage; import cn.qylk.myview.LrcView; import cn.qylk.myview.VisualizerView; import cn.qylk.service.LocalService; import cn.qylk.service.LocalService.TimerOut; import cn.qylk.utils.SendAction; import cn.qylk.utils.SendAction.ServiceControl; /** * Main UI * * @author qylk2012 <br> * all rights resolved */ public class MainActivity extends Activity implements View.OnClickListener, onPostPic, onPostLrc, onPostInfo, Callback { private class Receiver extends BroadcastReceiver {// 当后台播放下一首歌后,通知UI @Override public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(MyAction.INTENT_UI_UPDATE)) { DealNew();// 开始更新界面 } else if (intent.getAction().equals(MyAction.INTENT_EXIT)) { finish(); } } } private static final int PREFERENCE_CODE = 1008; private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234; private Animation animationdown; private Fragment_MusicControls controls; private TextView ctitle, artist, nexttitle, nolrctip; private Handler handler; private boolean haslrc; private PlayList list; private LinearLayout lrcadj; private LrcView lrcview; private Visualizer mVisualizer; private boolean panelopened, menuopend; private ImageView picshow; private Receiver receiver;// 消息接收器 public LocalService Service; private TrackInfo trackentity; private VisualizerView visualizerview; /** * 处理设置 */ private void Date_Service() { list = APP.list; trackentity = list.getTrackEntity(); Service = ListUI.Service; Service.setTimeOutListener(new TimerOut() { @Override public void ontimeout(int pos) { if (haslrc) lrcview.updateView(pos); } }); LoadConfig(); handler.sendEmptyMessageDelayed(0, 300);// 计划初始化界面 } /** * UI更新从这开始的 */ private void DealNew() { haslrc = false; updateUI(); StartLoad(-1); Tasks.startPicTask(this, false); lrcview.clearView(); } /** * 删除歌词,这回停止歌词显示 */ public void delLyric() { if (!haslrc) return; haslrc = false; lrcview.clearView(); MediaLyric.DelLrc(trackentity.title); nolrctip.setVisibility(View.VISIBLE); } private void FindView() { setContentView(R.layout.main); ctitle = (TextView) findViewById(R.id.titledisplay); artist = (TextView) findViewById(R.id.artistdis); nexttitle = (TextView) findViewById(R.id.nextmusic); nolrctip = (TextView) findViewById(R.id.lrclink); nolrctip.getPaint().setFlags(Paint.UNDERLINE_TEXT_FLAG); lrcadj = (LinearLayout) findViewById(R.id.lrcadj); visualizerview = (VisualizerView) findViewById(R.id.visualizer); lrcadj.setOnClickListener(this); findViewById(R.id.delay).setOnClickListener(this); findViewById(R.id.ok).setOnClickListener(this); findViewById(R.id.advance).setOnClickListener(this); nolrctip.setOnClickListener(this); picshow = (ImageView) findViewById(R.id.albumpic); lrcview = (LrcView) findViewById(R.id.lrcshow); FragmentTransaction transcation = getFragmentManager() .beginTransaction(); controls = new Fragment_MusicControls(); transcation.replace(R.id.content, controls); transcation.commit(); handler = new Handler(this); } @Override public boolean handleMessage(Message msg) { DealNew(); return true; } /** * 加载设置 */ private void LoadConfig() { SetSensor(APP.Config.shake); SetLight(APP.Config.light); SetVisualizer(APP.Config.visualwave); lrcview.setFirstColor(APP.Config.lrccolor); lrcview.setShadow(APP.Config.lrcshadow); } /** * 获取歌词失败 */ private void LrcFail(boolean showtips) { nolrctip.setVisibility(View.VISIBLE);// 无歌词提示 } /** * 获取歌词成功 */ private void LrcSuc() { nolrctip.setVisibility(View.INVISIBLE); haslrc = true; } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) { ArrayList<String> matches = data// 获取结果 .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); for (String s : matches) { if (MediaDatabase.GetCursor( new ListTypeInfo(ListType.SEARCH, 0, s)).moveToFirst()) { Toast.makeText(this, s, Toast.LENGTH_LONG).show(); list.setListType(new ListTypeInfo(ListType.SEARCH, 0, s)); SendAction.SendControlMsg(ServiceControl.PLAYNEW);// 通知改变列表播放 return; } } Toast.makeText(this, "no result", Toast.LENGTH_LONG).show(); } else if (requestCode == PREFERENCE_CODE && resultCode == 1) { APP.Config.LoadConfig(); LoadConfig(); } super.onActivityResult(requestCode, resultCode, data); } @Override public void onBackPressed() { if (panelopened) showInfo2(); else super.onBackPressed(); } @Override public void onClick(View v) { switch (v.getId()) {// 通过传过来的BUTTON ID可以判断Button的类型 case R.id.lrclink:// 点击"歌词下载" OpenInfoDialog();// 出现对话框 break; case R.id.delay:// 歌词延迟0.5秒 lrcview.setOffset(500); break; case R.id.advance:// 歌词提前0.5秒 lrcview.setOffset(-500); break; case R.id.ok:// 确认修改并保存歌词 lrcadj.setVisibility(View.INVISIBLE); if (lrcview.GetOffset() == 0 || !haslrc) // 没有做出修改 break; new ModifyLyric().SetOffset(lrcview.GetOffset()).ModifyandSave( lrcview.GetLrcPackage());// 开始保存 break; } } @Override public void onCreate(Bundle savedInstanceState) { RegBc();// 注册广播 FindView(); // UI控件初始化 Date_Service(); // 处理设置 super.onCreate(savedInstanceState); } public boolean onCreateOptionsMenu(Menu menu) { menu.add("menu");// 必须创建一项,但不会让它显示出来 animationdown = AnimationUtils.loadAnimation(this, R.anim.down); getFragmentManager().addOnBackStackChangedListener( new OnBackStackChangedListener() { @Override public void onBackStackChanged() { menuopend = !menuopend; } }); return super.onCreateOptionsMenu(menu); } @Override protected void onDestroy() {// 主进程结束,退出程序,该函数由系统自动调用 unregisterReceiver(receiver); if (APP.Config.light) SetLight(false); if (APP.Config.visualwave) mVisualizer.release(); super.onDestroy(); } @Override public void onInfoGot(String info) { showInfo3(info); } @Override public void onLrcGot(List<LRCbean> lrc, boolean usedweb) { if (lrc != null) { lrcview.setLyric(new LrcPackage(lrc, list.getTrackEntity())); lrcview.initLrcIndex(Service.GetMediaPos()); LrcSuc(); } else LrcFail(false); } @Override public boolean onMenuOpened(int featureId, Menu menu) { if (menuopend) { animationdown.setAnimationListener(new AnimationListener() { @Override public void onAnimationEnd(Animation animation) { getFragmentManager().popBackStack(); } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationStart(Animation animation) { } }); View menuview = getFragmentManager().findFragmentByTag("menu") .getView(); menuview.startAnimation(animationdown); } else { if (panelopened) showInfo2(); FragmentTransaction ft = getFragmentManager().beginTransaction(); Fragment_Menus me = new Fragment_Menus(); ft.setCustomAnimations(R.anim.intest, R.anim.outtest); ft.add(R.id.content, me, "menu"); ft.addToBackStack(null); ft.commit(); } return false; } @Override public void onPicGot(Bitmap pic) { if (pic != null) picshow.setImageBitmap(pic); else picshow.setImageResource(R.drawable.audio_player_default_album); } /** * 歌词信息填写界面 */ private void OpenInfoDialog() { FragmentTransaction ft = getFragmentManager().beginTransaction(); FragmentInfoInputDialog dialog = new FragmentInfoInputDialog( trackentity, "搜索歌词"); dialog.show(getFragmentManager(), "lrc"); ft.addToBackStack(null); } /** * 打开设置 */ public void openPreference() { Intent intent = new Intent(this, Preference.class); startActivityForResult(intent, PREFERENCE_CODE); } /** * 快速找歌 */ public void QuickPlay() { final AutoCompleteTextView autv = new AutoCompleteTextView(this); autv.setThreshold(1); autv.setHint(R.string.searchtip); autv.setCompletionHint("qylk2012 supported"); autv.setAdapter(new trainAdptertest(this, null)); new AlertDialog.Builder(this).setTitle("search").setView(autv) .setPositiveButton(R.string.play, new OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { String text = autv.getText().toString(); if (MediaDatabase.GetCursor( new ListTypeInfo(ListType.SEARCH, 0, text)) .moveToFirst()) { list.setListType(new ListTypeInfo(ListType.SEARCH, 0, text)); SendAction.SendControlMsg(ServiceControl.PLAYNEW); } else Toast.makeText(MainActivity.this, "Nothing Found!", Toast.LENGTH_LONG).show(); } }).setNegativeButton(R.string.operation_cancel, null).show(); } /** * 广播接受器注册 */ private void RegBc() {// 注册broadcast的接收器 receiver = new Receiver();// 新建接收器实例 IntentFilter filter = new IntentFilter();// 过滤器 filter.addAction(MyAction.INTENT_UI_UPDATE); filter.addAction(MyAction.INTENT_EXIT); registerReceiver(receiver, filter); } /** * 屏幕常亮 */ private void SetLight(boolean light) { if (light) getWindow() .addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); else getWindow().clearFlags( WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } /** * 甩歌 */ private void SetSensor(boolean shake) { if (shake) SensorTest.getInstance().StartService();// 服务实例化 else SensorTest.getInstance().StopService();// 暂停服务 } /** * 设置标题 */ private void SetTitle() { ctitle.setText(list.getIndex() + 1 + "/" + list.getSum() + "\t" + trackentity.title); artist.setText(trackentity.artist); } /** * 初始化频谱显示 */ public void setupVisualizerFxAndUi() { mVisualizer = new Visualizer(Service.getAudioSessionId()); mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]); mVisualizer.setDataCaptureListener(new OnDataCaptureListener() { @Override public void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate) { visualizerview.updateVisualizer(fft); } @Override public void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate) { } }, Visualizer.getMaxCaptureRate() / 2, false, true); mVisualizer.setEnabled(true); } private void SetVisualizer(boolean visual) { if (visual && mVisualizer == null) { setupVisualizerFxAndUi(); visualizerview.setUpView(); } else if (mVisualizer != null && !visual) { mVisualizer.setEnabled(false); mVisualizer.release(); mVisualizer = null; visualizerview.ClearView(); } } /** * 打开\关闭歌曲信息显示窗口 */ public void showInfo2() { final View v = findViewById(R.id.infoarea); panelopened = !panelopened; if (!panelopened) { Animation animation = AnimationUtils.loadAnimation(this, R.anim.hide); animation.setAnimationListener(new AnimationListener() { @Override public void onAnimationEnd(Animation animation) { v.setVisibility(View.INVISIBLE); TextView infoText = (TextView) findViewById(R.id.trackinfo); infoText.setText(""); TextView artistinfo = (TextView) findViewById(R.id.artistinfo); artistinfo.setText(""); } @Override public void onAnimationRepeat(Animation animation) { } @Override public void onAnimationStart(Animation animation) { } }); v.startAnimation(animation); return; } else { Animation animation = AnimationUtils.loadAnimation(this, R.anim.show); v.setVisibility(View.VISIBLE); v.startAnimation(animation); } TextView infoText = (TextView) findViewById(R.id.trackinfo); StringBuilder sb = new StringBuilder(); String trackinfo = String.format(Locale.CHINESE, "曲名:%s\n艺术家:%s\n专辑:%s\n类型:%s\n大小:%.1f MB\n发行期:%s\n路径:%s\n", trackentity.title, trackentity.artist, trackentity.album, trackentity.mimetype, 1.0f * trackentity.size / 1024 / 1024, trackentity.year, trackentity.path); sb.append(trackinfo); sb.append("\r\n\r\n【"); sb.append(trackentity.artist); sb.append("信息】\r\n"); infoText.setText(sb.toString()); findViewById(R.id.waitposbar).setVisibility(View.VISIBLE); Tasks.startInfoTask2(this); } /** * 加载艺术家信息 * * @param info */ private void showInfo3(String info) { findViewById(R.id.waitposbar).setVisibility(View.GONE); TextView artistinfo = (TextView) findViewById(R.id.artistinfo); artistinfo.setText(info); } /** * 显示调整歌词的三个按钮 */ public void showLrcAdjustbtns() { if (haslrc) lrcadj.setVisibility(View.VISIBLE); } /** * 开始加载歌词,鉴于手动下载歌词可能会修改TAG信息,仍需要更新title显示,因而在这里 更新title显示, * * @param id * 千千歌词id,若还没有,置-1来计划下载 */ public void StartLoad(int id) { SetTitle(); Tasks.startLrcTask(this, id); } /** * 语音识别 */ public void startVoiceRecognition() { if (getPackageManager().queryIntentActivities( new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0).size() == 0) { Toast.makeText(this, "No Client", Toast.LENGTH_LONG).show(); return; } if (Service.IsPlaying()) Service.PauseOrContinue(true); startVoiceRecognitionActivity(); } /** * 启动语音识别界面 */ private void startVoiceRecognitionActivity() { Intent intent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH); intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM); intent.putExtra(RecognizerIntent.EXTRA_PROMPT, "title or artist"); intent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5); startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE); } /** * 刷新歌词显示 * * @param pos */ public void updateLrcPos(int pos) { if (haslrc) lrcview.initLrcIndex(pos); // 歌词进度调整 } /** * 换歌都要做的事:更新界面 */ private void updateUI() { int duration = trackentity.duration;// 获取曲长 controls.updateViewElements(duration); nexttitle.setText(list.getNextTitle());// 下一曲: picshow.setImageResource(R.drawable.loading);// 显示加载图标 } }