Android Open Source - LyricHere Lyric Player Fragment






From Project

Back to project page LyricHere.

License

The source code is released under:

Apache License

If you think the Android project LyricHere listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package cn.zhaiyifan.lyrichere.ui;
//w ww .jav  a  2s  .c o m
import android.app.Activity;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.NotificationCompat;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;

import cn.zhaiyifan.lyrichere.Constants;
import cn.zhaiyifan.lyrichere.R;
import cn.zhaiyifan.lyrichere.utils.LyricProvider;
import cn.zhaiyifan.lyrichere.utils.Util;
import cn.zhaiyifan.lyrichere.workers.LyricEncodingUpdater;
import cn.zhaiyifan.lyrichere.workers.LyricLastVisitUpdater;

public class LyricPlayerFragment extends Fragment {
    private static final String TAG = LyricPlayerFragment.class.getSimpleName();
    private static final String ARG_PARAM_PATH = "path";
    private static final String ARG_PARAM_ENCODING = "encoding";
    private String mFilePath;
    private String mEncoding;

    private OnFragmentInteractionListener mListener;

    private LyricView mLyricView;
    private Handler mHandler = new Handler();
    private Runnable mUpdateResultsRunnable = new Runnable() {
        public void run() {
            mLyricView.invalidate();
        }
    };
    private Runnable mClearScreenOnFlagRunnable = new Runnable() {
        public void run() {
            getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
        }
    };
    private UIUpdateRunnable mUiUpdateRunnable = null;
    private Thread mUiUpdateThread = null;
    private NotificationManager mNotificationManager;

    private LyricProvider mLyricProvider;
    private boolean mIsForeground;

    private SharedPreferences mSharedPreferences;

    public LyricPlayerFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of this fragment using the provided parameters.
     *
     * @param path Lyric full path.
     * @return A new instance of fragment LyricPlayerFragment.
     */
    public static LyricPlayerFragment newInstance(String path, String encoding) {
        Util.log(TAG, String.format("newInstance(%s, %s)", path, encoding));
        LyricPlayerFragment fragment = new LyricPlayerFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM_PATH, path);
        args.putString(ARG_PARAM_ENCODING, encoding);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mFilePath = getArguments().getString(ARG_PARAM_PATH);
            mEncoding = getArguments().getString(ARG_PARAM_ENCODING);
        }

        mLyricProvider = LyricProvider.getInstance(getActivity());
        mNotificationManager = (NotificationManager) getActivity().getSystemService(Context.NOTIFICATION_SERVICE);

        mSharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
        setHasOptionsMenu(true);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        Util.log(TAG, "onCreateView");
        View view = inflater.inflate(R.layout.fragment_lyric_player, container, false);
        mLyricView = (LyricView) view.findViewById(R.id.textLyric);
        return view;
    }

    @Override
    public void onResume() {
        super.onResume();
        Util.log(TAG, "onResume");

        getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        mIsForeground = true;
        // Not first time createView
        String path = getActivity().getIntent().getStringExtra(Constants.Column.PATH);
        String encoding = getActivity().getIntent().getStringExtra(Constants.Column.ENCODING);
        if (path != null && !mFilePath.equals(path)) {
            mFilePath = path;
            mEncoding = encoding;

            mUiUpdateRunnable.stop();
            while (mUiUpdateThread.isAlive()) {
                // wait till dead
            }
            mUiUpdateRunnable.reset();
            mUiUpdateThread = new Thread(mUiUpdateRunnable);
            mLyricView.setLyric(mLyricProvider.get(mFilePath, mEncoding));
            mLyricView.setLyricIndex(0);
            mUiUpdateThread.start();

            new LyricLastVisitUpdater(this.getActivity()).execute(mFilePath);
        }
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        Util.log(TAG, "onCreateOptionsMenu");
        super.onCreateOptionsMenu(menu, inflater);
        inflater.inflate(R.menu.menu_encoding, menu);
    }

    @Override
    public void onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        if (mEncoding.equals(Constants.ENCODE_UTF_8)) {
            menu.findItem(R.id.action_encoding_utf_8).setChecked(true);
        } else if (mEncoding.equals(Constants.ENCODE_BIG5)) {
            menu.findItem(R.id.action_encoding_big5).setChecked(true);
        } else if (mEncoding.equals(Constants.ENCODE_GBK)) {
            menu.findItem(R.id.action_encoding_gbk).setChecked(true);
        } else if (mEncoding.equals(Constants.ENCODE_SJIS)) {
            menu.findItem(R.id.action_encoding_sjis).setChecked(true);
        }
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();
        String encoding = null;
        switch (id) {
            case R.id.action_encoding_utf_8:
                item.setChecked(true);
                encoding = Constants.ENCODE_UTF_8;
                break;
            case R.id.action_encoding_big5:
                item.setChecked(true);
                encoding = Constants.ENCODE_BIG5;
                break;
            case R.id.action_encoding_sjis:
                item.setChecked(true);
                encoding = Constants.ENCODE_SJIS;
                break;
            case R.id.action_encoding_gbk:
                item.setChecked(true);
                encoding = Constants.ENCODE_GBK;
                break;
            default:
                return false;
        }
        if (encoding != null && !mEncoding.equals(encoding)) {
            Util.log(TAG, "Changed encoding: " + encoding);
            mEncoding = encoding;
            mLyricView.setLyric(mLyricProvider.get(mFilePath, mEncoding));
            mLyricView.invalidate();
            new LyricEncodingUpdater(getActivity()).execute(mFilePath, mEncoding);
        }
        return true;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        Util.log(TAG, "onDestroy");
        mUiUpdateRunnable.stop();
    }

    public void onButtonPressed(Uri uri) {
        if (mListener != null) {
            mListener.onFragmentInteraction(uri);
        }
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        try {
            mListener = (OnFragmentInteractionListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString() + " must implement OnFragmentInteractionListener");
        }
    }

    @Override
    public void onDetach() {
        super.onDetach();
        mListener = null;
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    }

    @Override
    public void onStop() {
        super.onStop();
        Util.log(TAG, "onStop");
        mIsForeground = false;
    }

    @Override
    public void onStart() {
        super.onStart();
        Util.log(TAG, "onStart");
        if (mUiUpdateRunnable == null && mUiUpdateThread == null) {
            mUiUpdateRunnable = new UIUpdateRunnable();
            mUiUpdateThread = new Thread(mUiUpdateRunnable);
            mLyricView.setLyric(mLyricProvider.get(mFilePath, mEncoding));
            new LyricLastVisitUpdater(this.getActivity()).execute(mFilePath);
        }
        if (!mUiUpdateThread.isAlive() && !mUiUpdateRunnable.isStopped() && !mUiUpdateRunnable.mStopped) {
            mUiUpdateThread.start();
        }
    }

    @Override
    public void onPause() {
        super.onPause();
        Util.log(TAG, "onPause");
    }

    public boolean isForeground() {
        return mIsForeground;
    }

    /**
     * See <a href="http://developer.android.com/training/basics/fragments/communicating.html"
     * >Communicating with Other Fragments</a> for more information.
     */
    public interface OnFragmentInteractionListener {
        public void onFragmentInteraction(Uri uri);
    }

    private class UIUpdateRunnable implements Runnable {
        private long mStartTime = -1;
        private long mNextSentenceTime = -1;
        private boolean mStopping = false;
        private boolean mStopped = false;
        private NotificationCompat.Builder mNotifyBuilder;

        public void reset() {
            mStartTime = -1;
            mNextSentenceTime = -1;
            mStopping = false;
        }

        public void stop() {
            mStopping = true;
        }

        public boolean isStopped() {
            return mStopped;
        }

        // TODO: Improve user touch response
        public void run() {
            if (mStartTime == -1) {
                mStartTime = System.currentTimeMillis();
            }

            boolean isNotificationOn = mSharedPreferences.getBoolean(getString(R.string.pref_key_notification), true);

            NotificationCompat.BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle().bigText("...");

            if (isNotificationOn) {
                bigTextStyle.setSummaryText(getString(R.string.notification_expand_summary));
                mNotifyBuilder = new NotificationCompat.Builder(getActivity())
                        .setContentTitle(mLyricView.getLyric().getArtist() + " - " + mLyricView.getLyric().getTitle())
                        .setContentText("...")
                        .setTicker(mLyricView.getLyric().getTitle())
                        .setContentIntent(PendingIntent.getActivity(getActivity(), 0, new Intent(getActivity(), LyricPlayerActivity.class), 0))
                        .setSmallIcon(R.drawable.kid)
                        .setStyle(bigTextStyle);
                //mNotificationManager.notify(Constants.NOTIFY_ID, mNotifyBuilder.build());
            }

            while (mLyricView.getLyricIndex() != -2) {
                if (mStopping) {
                    mStopped = true;
                    return;
                }
                long ts = System.currentTimeMillis() - mStartTime;
                if (ts >= mNextSentenceTime || mLyricView.checkUpdate()) {
                    mNextSentenceTime = mLyricView.updateIndex(ts);
                    // Util.log(TAG, String.format("mNextSentenceTime: %d, ts %d, mLyricIndex: %d", mNextSentenceTime, ts, mLyricView.getLyricIndex()));

                    // Redraw only when fragment is visible
                    if (mIsForeground) {
                        mHandler.post(mUpdateResultsRunnable);
                    } else if (isNotificationOn) {
                        String sentence = mLyricView.getCurrentSentence();

                        //.setSmallIcon(R.drawable.ic_notify_status)
                        if (sentence != null) {
                            mNotifyBuilder.setContentText(sentence);
                            bigTextStyle.bigText(sentence);
                        }
                        // Because the ID remains unchanged, the existing notification is updated.
                        mNotificationManager.notify(Constants.NOTIFY_ID, mNotifyBuilder.build());
                    }
                }
                if (mNextSentenceTime == -1) {
                    mStopped = true;
                    if (isNotificationOn) {
                        mNotificationManager.cancel(Constants.NOTIFY_ID);
                    }
                    // Clear KEEP_SCREEN_ON flag when finish playing
                    mHandler.post(mClearScreenOnFlagRunnable);
                    return;
                }
            }
        }
    }
}




Java Source Code List

cn.zhaiyifan.lyrichere.ApplicationTest.java
cn.zhaiyifan.lyrichere.Constants.java
cn.zhaiyifan.lyrichere.MusicBroadcastReceiver.java
cn.zhaiyifan.lyrichere.adapters.LyricCursorAdapter.java
cn.zhaiyifan.lyrichere.db.DbHelper.java
cn.zhaiyifan.lyrichere.db.LyricContentProvider.java
cn.zhaiyifan.lyrichere.model.Lyric.java
cn.zhaiyifan.lyrichere.prefs.SettingsActivity.java
cn.zhaiyifan.lyrichere.prefs.SettingsFragment.java
cn.zhaiyifan.lyrichere.prefs.colorpicker.AlphaPatternDrawable.java
cn.zhaiyifan.lyrichere.prefs.colorpicker.ColorPickerDialog.java
cn.zhaiyifan.lyrichere.prefs.colorpicker.ColorPickerPanelView.java
cn.zhaiyifan.lyrichere.prefs.colorpicker.ColorPickerPreference.java
cn.zhaiyifan.lyrichere.prefs.colorpicker.ColorPickerView.java
cn.zhaiyifan.lyrichere.prefs.colorpicker.Test.java
cn.zhaiyifan.lyrichere.ui.AboutActivity.java
cn.zhaiyifan.lyrichere.ui.DownloadFragment.java
cn.zhaiyifan.lyrichere.ui.ListScrollTextView.java
cn.zhaiyifan.lyrichere.ui.LyricExplorerActivity.java
cn.zhaiyifan.lyrichere.ui.LyricExplorerFragment.java
cn.zhaiyifan.lyrichere.ui.LyricPlayerActivity.java
cn.zhaiyifan.lyrichere.ui.LyricPlayerFragment.java
cn.zhaiyifan.lyrichere.ui.LyricSearchView.java
cn.zhaiyifan.lyrichere.ui.LyricView.java
cn.zhaiyifan.lyrichere.utils.DbUtils.java
cn.zhaiyifan.lyrichere.utils.FileUtils.java
cn.zhaiyifan.lyrichere.utils.LyricCache.java
cn.zhaiyifan.lyrichere.utils.LyricProvider.java
cn.zhaiyifan.lyrichere.utils.LyricUtils.java
cn.zhaiyifan.lyrichere.utils.Util.java
cn.zhaiyifan.lyrichere.workers.Finder.java
cn.zhaiyifan.lyrichere.workers.LyricEncodingUpdater.java
cn.zhaiyifan.lyrichere.workers.LyricLastVisitUpdater.java
cn.zhaiyifan.lyrichere.workers.LyricOpener.java