Java tutorial
/* * Copyright (C) 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.murati.oszk.audiobook.ui; import android.app.ActivityManager; import android.app.SearchManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.graphics.BitmapFactory; import android.os.Build; import android.os.Bundle; import android.os.RemoteException; import android.support.annotation.NonNull; import android.support.v4.media.MediaBrowserCompat; import android.support.v4.media.MediaMetadataCompat; import android.support.v4.media.session.MediaControllerCompat; import android.support.v4.media.session.MediaSessionCompat; import android.support.v4.media.session.PlaybackStateCompat; import android.support.v7.view.menu.ActionMenuItemView; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.SearchView; import com.murati.oszk.audiobook.MusicService; import com.murati.oszk.audiobook.R; import com.murati.oszk.audiobook.utils.LanguageHelper; import com.murati.oszk.audiobook.utils.LogHelper; import com.murati.oszk.audiobook.utils.NetworkHelper; import com.murati.oszk.audiobook.utils.ResourceHelper; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * Base activity for activities that need to show a playback control fragment when media is playing. */ public abstract class BaseActivity extends ActionBarCastActivity implements MediaBrowserProvider { private static final String TAG = LogHelper.makeLogTag(BaseActivity.class); protected Menu mMenu; private MediaBrowserCompat mMediaBrowser; private PlaybackControlsFragment mControlsFragment; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LogHelper.d(TAG, "Activity onCreate"); //LanguageHelper.setDefaultAppLocale(this); if (Build.VERSION.SDK_INT >= 21) { // Since our app icon has the same color as colorPrimary, our entry in the Recent Apps // list gets weird. We need to change either the icon or the color // of the TaskDescription. ActivityManager.TaskDescription taskDesc = new ActivityManager.TaskDescription(getTitle().toString(), //TODO: remove white BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher_white), ResourceHelper.getThemeColor(this, R.attr.colorPrimary, android.R.color.darker_gray)); setTaskDescription(taskDesc); } // Connect a media browser just to get the media session token. There are other ways // this can be done, for example by sharing the session token directly. mMediaBrowser = new MediaBrowserCompat(this, new ComponentName(this, MusicService.class), mConnectionCallback, null); if (getIntent() != null) { handleIntent(getIntent()); } } @Override protected void onStart() { super.onStart(); LogHelper.d(TAG, "Activity onStart"); mControlsFragment = (PlaybackControlsFragment) getFragmentManager() .findFragmentById(R.id.fragment_playback_controls); if (mControlsFragment == null) { throw new IllegalStateException("Mising fragment with id 'controls'. Cannot continue."); } hidePlaybackControls(); mMediaBrowser.connect(); } @Override protected void onStop() { super.onStop(); LogHelper.d(TAG, "Activity onStop"); MediaControllerCompat controllerCompat = MediaControllerCompat.getMediaController(this); if (controllerCompat != null) { controllerCompat.unregisterCallback(mMediaControllerCallback); } mMediaBrowser.disconnect(); } @Override protected void onNewIntent(Intent intent) { handleIntent(intent); } /** * Assuming this activity was started with a new intent, process the incoming information and * react accordingly. * @param intent */ private void handleIntent(Intent intent) { // Special processing of the incoming intent only occurs if the if the action specified // by the intent is ACTION_SEARCH. if (Intent.ACTION_SEARCH.equals(intent.getAction())) { // SearchManager.QUERY is the key that a dsfdsSearchManager will use to send a query string // to an Activity. String query = intent.getStringExtra(SearchManager.QUERY); //SearchQuery = query; // We need to create a bundle containing the query string to send along to the // LoaderManager, which will be handling querying the database and returning results. Bundle bundle = new Bundle(); //bundle.putString(QUERY_KEY, query); //ContactablesLoaderCallbacks loaderCallbacks = new ContactablesLoaderCallbacks(this); // Start the loader with the new query, and an object that will handle all callbacks. //getLoaderManager().restartLoader(CONTACT_QUERY_LOADER, bundle, loaderCallbacks); } } @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); // Associate searchable configuration with the SearchView SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE); SearchView searchView = (SearchView) menu.findItem(R.id.search).getActionView(); searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName())); mMenu = menu; return true; } @Override public MediaBrowserCompat getMediaBrowser() { return mMediaBrowser; } protected void onMediaControllerConnected() { // empty implementation, can be overridden by clients. } protected void showPlaybackControls() { LogHelper.d(TAG, "showPlaybackControls"); getFragmentManager().beginTransaction() .setCustomAnimations(R.animator.slide_in_from_bottom, R.animator.slide_out_to_bottom, R.animator.slide_in_from_bottom, R.animator.slide_out_to_bottom) .show(mControlsFragment).commit(); } protected void hidePlaybackControls() { LogHelper.d(TAG, "hidePlaybackControls"); getFragmentManager().beginTransaction().hide(mControlsFragment).commit(); } /** * Check if the MediaSession is active and in a "playback-able" state * (not NONE and not STOPPED). * * @return true if the MediaSession's state requires playback controls to be visible. */ protected boolean shouldShowControls() { MediaControllerCompat mediaController = MediaControllerCompat.getMediaController(this); if (mediaController == null || mediaController.getMetadata() == null || mediaController.getPlaybackState() == null) { return false; } switch (mediaController.getPlaybackState().getState()) { case PlaybackStateCompat.STATE_ERROR: case PlaybackStateCompat.STATE_NONE: case PlaybackStateCompat.STATE_STOPPED: return false; default: return true; } } private void connectToSession(MediaSessionCompat.Token token) throws RemoteException { MediaControllerCompat mediaController = new MediaControllerCompat(this, token); MediaControllerCompat.setMediaController(this, mediaController); mediaController.registerCallback(mMediaControllerCallback); if (shouldShowControls()) { showPlaybackControls(); } else { LogHelper.d(TAG, "connectionCallback.onConnected: " + "hiding controls because metadata is null"); hidePlaybackControls(); } if (mControlsFragment != null) { mControlsFragment.onConnected(); } onMediaControllerConnected(); } // Callback that ensures that we are showing the controls private final MediaControllerCompat.Callback mMediaControllerCallback = new MediaControllerCompat.Callback() { @Override public void onPlaybackStateChanged(@NonNull PlaybackStateCompat state) { if (shouldShowControls()) { showPlaybackControls(); } else { LogHelper.d(TAG, "mediaControllerCallback.onPlaybackStateChanged: " + "hiding controls because state is ", state.getState()); hidePlaybackControls(); } } @Override public void onMetadataChanged(MediaMetadataCompat metadata) { if (shouldShowControls()) { showPlaybackControls(); } else { LogHelper.d(TAG, "mediaControllerCallback.onMetadataChanged: " + "hiding controls because metadata is null"); hidePlaybackControls(); } } }; private final MediaBrowserCompat.ConnectionCallback mConnectionCallback = new MediaBrowserCompat.ConnectionCallback() { @Override public void onConnected() { LogHelper.d(TAG, "onConnected"); try { connectToSession(mMediaBrowser.getSessionToken()); } catch (RemoteException e) { LogHelper.e(TAG, e, "could not connect media controller"); hidePlaybackControls(); } } }; }