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.aengbee.android.leanback.ui; import android.app.Activity; import android.app.LoaderManager; import android.content.ContentResolver; import android.content.Context; import android.content.CursorLoader; import android.content.Intent; import android.content.Loader; import android.content.SharedPreferences; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.preference.PreferenceManager; import android.support.v17.leanback.app.BackgroundManager; import android.support.v17.leanback.app.BrowseFragment; import android.support.v17.leanback.widget.ArrayObjectAdapter; import android.support.v17.leanback.widget.CursorObjectAdapter; import android.support.v17.leanback.widget.HeaderItem; import android.support.v17.leanback.widget.ImageCardView; import android.support.v17.leanback.widget.ListRow; import android.support.v17.leanback.widget.ListRowPresenter; import android.support.v17.leanback.widget.OnItemViewClickedListener; import android.support.v17.leanback.widget.OnItemViewSelectedListener; import android.support.v17.leanback.widget.Presenter; import android.support.v17.leanback.widget.PresenterSelector; import android.support.v17.leanback.widget.Row; import android.support.v17.leanback.widget.RowPresenter; import android.support.v4.app.ActivityOptionsCompat; import android.support.v4.content.ContextCompat; import android.util.DisplayMetrics; import android.util.Log; import android.view.View; import android.widget.Toast; import com.aengbee.android.leanback.showcase.ShowcaseActivity; import com.bumptech.glide.Glide; import com.bumptech.glide.request.animation.GlideAnimation; import com.bumptech.glide.request.target.SimpleTarget; import com.aengbee.android.leanback.R; import com.aengbee.android.leanback.data.FetchVideoService; import com.aengbee.android.leanback.data.VideoContract; import com.aengbee.android.leanback.model.Video; import com.aengbee.android.leanback.model.VideoCursorMapper; import com.aengbee.android.leanback.presenter.CardPresenter; import com.aengbee.android.leanback.presenter.GridItemPresenter; import com.aengbee.android.leanback.presenter.IconHeaderItemPresenter; import com.aengbee.android.leanback.recommendation.UpdateRecommendationsService; import org.json.JSONException; import org.json.JSONObject; import java.util.HashMap; import java.util.Map; import java.util.Timer; import java.util.TimerTask; /* * Main class to show BrowseFragment with header and rows of videos */ public class MainFragment extends BrowseFragment implements LoaderManager.LoaderCallbacks<Cursor> { private static final int BACKGROUND_UPDATE_DELAY = 300; private final Handler mHandler = new Handler(); private ArrayObjectAdapter mCategoryRowAdapter; private Drawable mDefaultBackground; private DisplayMetrics mMetrics; private Timer mBackgroundTimer; private Uri mBackgroundURI; private BackgroundManager mBackgroundManager; private static final int CATEGORY_LOADER = 123; // Unique ID for Category Loader. // Maps a Loader Id to its CursorObjectAdapter. private Map<Integer, CursorObjectAdapter> mVideoCursorAdapters; @Override public void onAttach(Context context) { super.onAttach(context); // Create a list to contain all the CursorObjectAdapters. // Each adapter is used to render a specific row of videos in the MainFragment. mVideoCursorAdapters = new HashMap<>(); // Start loading the categories from the database. getLoaderManager().initLoader(CATEGORY_LOADER, null, this); } @SuppressWarnings("deprecation") @Override public void onAttach(Activity activity) { super.onAttach(activity); if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { // Create a list to contain all the CursorObjectAdapters. // Each adapter is used to render a specific row of videos in the MainFragment. mVideoCursorAdapters = new HashMap<>(); // Start loading the categories from the database. getLoaderManager().initLoader(CATEGORY_LOADER, null, this); } } @Override public void onActivityCreated(Bundle savedInstanceState) { // Final initialization, modifying UI elements. super.onActivityCreated(savedInstanceState); // Prepare the manager that maintains the same background image between activities. prepareBackgroundManager(); setupUIElements(); setupEventListeners(); prepareEntranceTransition(); // Map category results from the database to ListRow objects. // This Adapter is used to render the MainFragment sidebar labels. mCategoryRowAdapter = new ArrayObjectAdapter(new ListRowPresenter()); setAdapter(mCategoryRowAdapter); updateRecommendations(); } @Override public void onDestroy() { if (null != mBackgroundTimer) { mBackgroundTimer.cancel(); mBackgroundTimer = null; } mBackgroundManager = null; super.onDestroy(); } @Override public void onStop() { mBackgroundManager.release(); super.onStop(); } private void prepareBackgroundManager() { mBackgroundManager = BackgroundManager.getInstance(getActivity()); mBackgroundManager.attach(getActivity().getWindow()); mDefaultBackground = getResources().getDrawable(R.drawable.default_background, null); mMetrics = new DisplayMetrics(); getActivity().getWindowManager().getDefaultDisplay().getMetrics(mMetrics); } private void setupUIElements() { setBadgeDrawable(getActivity().getResources().getDrawable(R.drawable.ui_badge, null)); setTitle(getString(R.string.browse_title)); // Badge, when set, takes precedent over title setHeadersState(HEADERS_ENABLED); setHeadersTransitionOnBackEnabled(true); // Set fastLane (or headers) background color setBrandColor(ContextCompat.getColor(getActivity(), R.color.fastlane_background)); // Set search icon color. setSearchAffordanceColor(ContextCompat.getColor(getActivity(), R.color.search_opaque)); setHeaderPresenterSelector(new PresenterSelector() { @Override public Presenter getPresenter(Object o) { return new IconHeaderItemPresenter(); } }); } private void setupEventListeners() { setOnSearchClickedListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(getActivity(), SearchActivity.class); startActivity(intent); } }); setOnItemViewClickedListener(new ItemViewClickedListener()); setOnItemViewSelectedListener(new ItemViewSelectedListener()); } private void updateBackground(String uri) { int width = mMetrics.widthPixels; int height = mMetrics.heightPixels; Glide.with(this).load(uri).asBitmap().centerCrop().error(mDefaultBackground) .into(new SimpleTarget<Bitmap>(width, height) { @Override public void onResourceReady(Bitmap resource, GlideAnimation<? super Bitmap> glideAnimation) { mBackgroundManager.setBitmap(resource); } }); mBackgroundTimer.cancel(); } private void startBackgroundTimer() { if (null != mBackgroundTimer) { mBackgroundTimer.cancel(); } mBackgroundTimer = new Timer(); mBackgroundTimer.schedule(new UpdateBackgroundTask(), BACKGROUND_UPDATE_DELAY); } private void updateRecommendations() { Intent recommendationIntent = new Intent(getActivity(), UpdateRecommendationsService.class); getActivity().startService(recommendationIntent); } @Override public Loader<Cursor> onCreateLoader(int id, Bundle args) { if (id == CATEGORY_LOADER) { return new CursorLoader(getActivity(), // Parent activity context VideoContract.VideoEntry.CONTENT_URI, // Table to query new String[] { "DISTINCT " + VideoContract.VideoEntry.COLUMN_CATEGORY }, // Only categories null, // No selection clause null, // No selection arguments VideoContract.VideoEntry.COLUMN_NAME // Default sort order ); } else { // Assume it is for a video. String category = args.getString(VideoContract.VideoEntry.COLUMN_CATEGORY); // This just creates a CursorLoader that gets all videos. return new CursorLoader(getActivity(), // Parent activity context VideoContract.VideoEntry.CONTENT_URI, // Table to query null, // Projection to return - null means return all fields VideoContract.VideoEntry.COLUMN_CATEGORY + " = ?", // Selection clause new String[] { category }, // Select based on the category id. VideoContract.VideoEntry.COLUMN_NAME// Default sort order ); } } @Override public void onLoadFinished(Loader<Cursor> loader, Cursor data) { if (data != null && data.moveToFirst()) { final int loaderId = loader.getId(); if (loaderId == CATEGORY_LOADER) { // Every time we have to re-get the category loader, we must re-create the sidebar. mCategoryRowAdapter.clear(); // Iterate through each category entry and add it to the ArrayAdapter. while (!data.isAfterLast()) { int categoryIndex = data.getColumnIndex(VideoContract.VideoEntry.COLUMN_CATEGORY); String category = data.getString(categoryIndex); // Create header for this category. HeaderItem header = new HeaderItem(category); int videoLoaderId = category.hashCode(); // Create unique int from category. CursorObjectAdapter existingAdapter = mVideoCursorAdapters.get(videoLoaderId); if (existingAdapter == null) { // Map video results from the database to Video objects. CursorObjectAdapter videoCursorAdapter = new CursorObjectAdapter(new CardPresenter()); videoCursorAdapter.setMapper(new VideoCursorMapper()); mVideoCursorAdapters.put(videoLoaderId, videoCursorAdapter); ListRow row = new ListRow(header, videoCursorAdapter); mCategoryRowAdapter.add(row); // Start loading the videos from the database for a particular category. Bundle args = new Bundle(); args.putString(VideoContract.VideoEntry.COLUMN_CATEGORY, category); getLoaderManager().initLoader(videoLoaderId, args, this); } else { ListRow row = new ListRow(header, existingAdapter); mCategoryRowAdapter.add(row); } data.moveToNext(); } // Create a row for this special case with more samples. HeaderItem gridHeader = new HeaderItem(getString(R.string.more_samples)); GridItemPresenter gridPresenter = new GridItemPresenter(this); ArrayObjectAdapter gridRowAdapter = new ArrayObjectAdapter(gridPresenter); gridRowAdapter.add(getString(R.string.personal_settings)); /* SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(getActivity()); try { JSONObject serverJson = new JSONObject(sharedPreferences.getString("serverList", "NULL")); if(serverJson!=null && !serverJson.equals("{}")) { if( serverJson.getString(serverJson.names().getString(0)).contains("http://fytoz.asuscomm.com/android-tv/ky.json")||serverJson.getString(serverJson.names().getString(0)).contains("http://fytoz.asuscomm.com/android-tv/tj.json")) { gridRowAdapter.add("Showcase"); gridRowAdapter.add(getString(R.string.grid_view)); gridRowAdapter.add(getString(R.string.guidedstep_first_title)); gridRowAdapter.add(getString(R.string.error_fragment)); } } } catch (JSONException ex) { ex.printStackTrace(); } gridRowAdapter.add("Showcase"); gridRowAdapter.add(getString(R.string.grid_view)); gridRowAdapter.add(getString(R.string.guidedstep_first_title)); gridRowAdapter.add(getString(R.string.error_fragment)); */ ListRow row = new ListRow(gridHeader, gridRowAdapter); mCategoryRowAdapter.add(row); startEntranceTransition(); // TODO: Move startEntranceTransition to after all // cursors have loaded. } else { // The CursorAdapter contains a Cursor pointing to all videos. mVideoCursorAdapters.get(loaderId).changeCursor(data); } } else { if (isOnline()) { Intent serviceIntent = new Intent(getActivity(), FetchVideoService.class); //serviceIntent.putExtra("data_url", getResources().getString(R.string.catalog_url) ); serviceIntent.putExtra("data_url", "http://fytoz.asuscomm.com/android-tv/tjweb.json"); getActivity().startService(serviceIntent); } else { Intent serviceIntent = new Intent(getActivity(), FetchVideoService.class); //serviceIntent.putExtra("data_url", getResources().getString(R.string.catalog_url) ); serviceIntent.putExtra("data_url", resourceToUri(getActivity(), R.raw.sample).toString()); getActivity().startService(serviceIntent); } } } public static Uri resourceToUri(Context context, int resID) { return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getResources().getResourcePackageName(resID) + '/' + context.getResources().getResourceTypeName(resID) + '/' + context.getResources().getResourceEntryName(resID)); } public Boolean isOnline() { try { Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com"); int returnVal = p1.waitFor(); boolean reachable = (returnVal == 0); return reachable; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return false; } @Override public void onLoaderReset(Loader<Cursor> loader) { int loaderId = loader.getId(); if (loaderId != CATEGORY_LOADER) { mVideoCursorAdapters.get(loaderId).changeCursor(null); } else { mCategoryRowAdapter.clear(); } } private class UpdateBackgroundTask extends TimerTask { @Override public void run() { mHandler.post(new Runnable() { @Override public void run() { if (mBackgroundURI != null) { updateBackground(mBackgroundURI.toString()); } } }); } } private final class ItemViewClickedListener implements OnItemViewClickedListener { @Override public void onItemClicked(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) { if (item instanceof Video) { Video video = (Video) item; Intent intent = new Intent(getActivity(), VideoDetailsActivity.class); intent.putExtra(VideoDetailsActivity.VIDEO, video); Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), ((ImageCardView) itemViewHolder.view).getMainImageView(), VideoDetailsActivity.SHARED_ELEMENT_NAME).toBundle(); getActivity().startActivity(intent, bundle); } else if (item instanceof String) { if (((String) item).contains("Showcase")) { startActivity(new Intent(getActivity(), ShowcaseActivity.class)); } else if (((String) item).contains(getString(R.string.grid_view))) { Intent intent = new Intent(getActivity(), VerticalGridActivity.class); Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity()).toBundle(); startActivity(intent, bundle); } else if (((String) item).contains(getString(R.string.guidedstep_first_title))) { Intent intent = new Intent(getActivity(), GuidedStepActivity.class); Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity()).toBundle(); startActivity(intent, bundle); } else if (((String) item).contains(getString(R.string.error_fragment))) { BrowseErrorFragment errorFragment = new BrowseErrorFragment(); getFragmentManager().beginTransaction().replace(R.id.main_frame, errorFragment) .addToBackStack(null).commit(); } else if (((String) item).contains(getString(R.string.personal_settings))) { Intent intent = new Intent(getActivity(), SettingsActivity.class); Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity()).toBundle(); startActivity(intent, bundle); } else { Toast.makeText(getActivity(), ((String) item), Toast.LENGTH_SHORT).show(); } } else { Video video = (Video) item; Intent intent = new Intent(getActivity(), VideoDetailsActivity.class); intent.putExtra(VideoDetailsActivity.VIDEO, video); Bundle bundle = ActivityOptionsCompat.makeSceneTransitionAnimation(getActivity(), ((ImageCardView) itemViewHolder.view).getMainImageView(), VideoDetailsActivity.SHARED_ELEMENT_NAME).toBundle(); getActivity().startActivity(intent, bundle); } } } private final class ItemViewSelectedListener implements OnItemViewSelectedListener { @Override public void onItemSelected(Presenter.ViewHolder itemViewHolder, Object item, RowPresenter.ViewHolder rowViewHolder, Row row) { if (item instanceof Video) { mBackgroundURI = Uri.parse(((Video) item).bgImageUrl); startBackgroundTimer(); } } } }