How to add Progress Dialog Box - java

I'm using Fragment to Display the Movies name, poster and reviews and Trailer using API key. I am trying to add progressbar such that when the RecyclerView is loading it will display the progress bar and when loading is complete..it will become invisible.
I tried to put various method but it always gives me error or app compiles and run but crashes.
Below is my MoviesUtil class file
public class MoviesUtil {
private static final Webb WEBB = Webb.create();
private static final String TMDB_API_MOVIES_URL = "http://api.themoviedb.org/3/movie/%s?api_key=%s&page=%s";
private static final String TMDB_API_VIDEOS_URL = "http://api.themoviedb.org/3/movie/%s/videos?api_key=%s";
private static final String TMDB_API_REVIEWS_URL = "http://api.themoviedb.org/3/movie/%s/reviews?api_key=%s";
private static final String TMDB_POSTER_URL = "https://image.tmdb.org/t/p/w185%s";
private static final String TMDB_BACKDROP_URL = "https://image.tmdb.org/t/p/w300%s";
private static final String TYPE_POPULAR = "popular";
private static final String TYPE_TOP_RATED = "top_rated";
private static final String TYPE_FAVORITES = "favorites";
public static boolean isFavorite(Context context, Movie movie) {
Cursor cursor = context.getContentResolver()
.query(MovieContract.CONTENT_URI,
null,
String.format("%s = ? and %s = ?", MovieContract.MOVIE_ID, MovieContract.TYPE),
new String[]{movie.getId() + "", TYPE_FAVORITES},
null
);
boolean isFavorite = cursor.getCount() > 0;
cursor.close();
return isFavorite;
}
public static boolean toggleFavorite(Context context, Movie movie) {
if (isFavorite(context, movie)) {
deleteMovie(context, TYPE_FAVORITES, movie);
return false;
} else {
saveMovie(context, TYPE_FAVORITES, movie);
return true;
}
}
public static void getPopularMovies(Activity activity, MoviesCallback callback) {
getMovies(activity, TYPE_POPULAR, callback);
}
public static void getTopRatedMovies(Activity activity, MoviesCallback callback) {
getMovies(activity, TYPE_TOP_RATED, callback);
}
public static void getFavoritesMovies(Activity activity, MoviesCallback callback) {
getMovies(activity, TYPE_FAVORITES, callback);
}
private static void getMovies(final Activity activity, final String type, final MoviesCallback callback) {
AsyncTask.execute(new Runnable() {
#Override
public void run() {
if (Util.isConnected(activity, false) && !type.equals(TYPE_FAVORITES)) {
getMoviesFromApi(activity, type);
}
getMoviesFromDb(activity, type, callback);
}
});
}
private static void getMoviesFromApi(Activity activity, String type) {
String apiUrl = String.format(TMDB_API_MOVIES_URL, type, activity.getString(R.string.tmdb_api_key), 1);
try {
JSONArray moviesJson = WEBB.get(apiUrl)
.asJsonObject()
.getBody()
.getJSONArray("results");
List<Movie> movies = toMovies(activity, moviesJson);
deleteMovies(activity, type);
saveMovies(activity, type, movies);
} catch (JSONException e) {
e.printStackTrace();
}
}
private static void getMoviesFromDb(Activity activity, String type, final MoviesCallback callback) {
try {
Cursor cursor = activity.getContentResolver()
.query(MovieContract.CONTENT_URI,
null,
MovieContract.TYPE + " = ?",
new String[]{type},
null
);
final List<Movie> movies = toMovies(cursor);
cursor.close();
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
callback.success(movies);
}
});
} catch (final Exception e) {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
callback.error(e);
}
});
}
}
public static void getReviewsFromApi(final Activity activity, final Movie movie, final ReviewsCallback callback) {
if (Util.isConnected(activity, false)) {
AsyncTask.execute(new Runnable() {
#Override
public void run() {
String apiUrl = String.format(TMDB_API_REVIEWS_URL, movie.getId(), activity.getString(R.string.tmdb_api_key));
final List<Review> reviews = new ArrayList<>();
try {
JSONArray reviewsJson = WEBB.get(apiUrl)
.asJsonObject()
.getBody()
.getJSONArray("results");
reviews.addAll(toReviews(reviewsJson));
} catch (final Exception e) {
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
callback.error(e);
}
});
}
if (reviews.isEmpty()) {
Review review = new Review();
review.setContent(activity.getString(R.string.no_review_found));
reviews.add(review);
}
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
callback.success(reviews);
}
});
}
});
} else {
Review review = new Review();
review.setContent(activity.getString(R.string.conn_internet));
final List<Review> reviews = new ArrayList<>();
reviews.add(review);
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
callback.success(reviews);
}
});
}
}
private static void saveMovie(final Context context, final String type, final Movie movie) {
AsyncTask.execute(new Runnable() {
#Override
public void run() {
List<Movie> movies = new ArrayList<>();
movies.add(movie);
saveMovies(context, type, movies);
}
});
}
private static void saveMovies(Context context, String type, List<Movie> movies) {
if (movies != null) {
ContentValues[] moviesValues = new ContentValues[movies.size()];
for (int i = 0; i < movies.size(); i++) {
try {
Movie movie = movies.get(i);
ContentValues movieValues = new ContentValues();
movieValues.put(MovieContract.MOVIE_ID, movie.getId());
movieValues.put(MovieContract.TYPE, type);
movieValues.put(MovieContract.TITLE, movie.getTitle());
movieValues.put(MovieContract.OVERVIEW, movie.getOverview());
movieValues.put(MovieContract.POSTER_URL, movie.getPosterUrl());
movieValues.put(MovieContract.BACKDROP_URL, movie.getBackdropUrl());
movieValues.put(MovieContract.TRAILER_URL, movie.getTrailerUrl());
movieValues.put(MovieContract.RELEASE_DATE, Util.toDbDate(movie.getReleaseDate()));
movieValues.put(MovieContract.RATING, movie.getRating());
movieValues.put(MovieContract.ADULT, movie.isAdult() ? 1 : 0);
moviesValues[i] = movieValues;
} catch (Exception ignore) {
}
}
context.getContentResolver()
.bulkInsert(MovieContract.CONTENT_URI, moviesValues);
}
}
private static void deleteMovie(final Context context, final String type, final Movie movie) {
AsyncTask.execute(new Runnable() {
#Override
public void run() {
context.getContentResolver()
.delete(MovieContract.CONTENT_URI,
MovieContract.MOVIE_ID + " = ? and " + MovieContract.TYPE + " = ?",
new String[]{movie.getId() + "", type});
}
});
}
private static void deleteMovies(final Context context, final String type) {
AsyncTask.execute(new Runnable() {
#Override
public void run() {
context.getContentResolver()
.delete(MovieContract.CONTENT_URI,
MovieContract.TYPE + " = ?",
new String[]{type});
}
});
}
private static List<Movie> toMovies(Cursor cursor) {
List<Movie> movies = new ArrayList<>();
while (cursor.moveToNext()) {
Movie movie = new Movie();
movie.setId(cursor.getInt(
cursor.getColumnIndex(MovieContract.MOVIE_ID)));
movie.setTitle(cursor.getString(
cursor.getColumnIndex(MovieContract.TITLE)));
movie.setOverview(cursor.getString(
cursor.getColumnIndex(MovieContract.OVERVIEW)));
movie.setPosterUrl(cursor.getString(
cursor.getColumnIndex(MovieContract.POSTER_URL)));
movie.setBackdropUrl(cursor.getString(
cursor.getColumnIndex(MovieContract.BACKDROP_URL)));
movie.setTrailerUrl(cursor.getString(
cursor.getColumnIndex(MovieContract.TRAILER_URL)));
movie.setReleaseDate(Util.toDate(cursor.getString(
cursor.getColumnIndex(MovieContract.RELEASE_DATE))));
movie.setRating(cursor.getFloat(
cursor.getColumnIndex(MovieContract.RATING)));
movie.setAdult(cursor.getInt(
cursor.getColumnIndex(MovieContract.ADULT)) == 1);
movies.add(movie);
}
return movies;
}
private static List<Movie> toMovies(Context context, JSONArray jsonMovies) {
List<Movie> movies = new ArrayList<>();
if (jsonMovies != null) {
for (int i = 0; i < jsonMovies.length(); i++) {
try {
JSONObject jsonMovie = jsonMovies.getJSONObject(i);
int movieId = jsonMovie.getInt("id");
Movie movie = new Movie();
movie.setId(movieId);
movie.setTitle(jsonMovie.getString("title"));
movie.setOverview(jsonMovie.getString("overview"));
movie.setPosterUrl(String.format(TMDB_POSTER_URL, jsonMovie.getString("poster_path")));
movie.setBackdropUrl(String.format(TMDB_BACKDROP_URL, jsonMovie.getString("backdrop_path")));
movie.setTrailerUrl(getTrailerUrl(context, movieId));
movie.setReleaseDate(Util.toDate(jsonMovie.getString("release_date")));
movie.setRating((float) jsonMovie.getDouble("vote_average"));
movie.setAdult(jsonMovie.getBoolean("adult"));
movies.add(movie);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return movies;
}
private static List<Review> toReviews(JSONArray jsonReviews) {
List<Review> reviews = new ArrayList<>();
if (jsonReviews != null) {
for (int i = 0; i < jsonReviews.length(); i++) {
try {
JSONObject jsonReview = jsonReviews.getJSONObject(i);
Review review = new Review();
review.setAuthor(jsonReview.getString("author"));
review.setContent(jsonReview.getString("content"));
reviews.add(review);
} catch (Exception e) {
e.printStackTrace();
}
}
}
return reviews;
}
private static String getTrailerUrl(Context context, int movieId) {
String apiUrl = String.format(TMDB_API_VIDEOS_URL, movieId, context.getString(R.string.tmdb_api_key));
try {
JSONArray trailersJson = WEBB.get(apiUrl)
.asJsonObject()
.getBody()
.getJSONArray("results");
for (int i = 0; i < trailersJson.length(); i++) {
JSONObject trailerJson = trailersJson.getJSONObject(i);
if (trailerJson.getString("site").toLowerCase().equals("youtube")) {
return "https://youtube.com/watch?v=" + trailerJson.getString("key");
}
}
return "";
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
}
and my Fragment class is
public class MoviesFragment extends BaseFragment implements SwipeRefreshLayout.OnRefreshListener,
RecyclerItemClickSupport.OnItemClickListener {
private static final String ARG_FRAG_TYPE = "fragType";
private static final String ARG_FRAG_TWO_PANE = "twoPane";
public enum Type {
POPULAR,
TOP_RATED,
FAVORITES
}
#State
ArrayList<Movie> movies;
#State
Type fragType;
#State
boolean twoPane;
#BindView(R.id.refresh)
SwipeRefreshLayout refreshView;
#BindView(R.id.movies)
RecyclerView moviesView;
public static MoviesFragment newInstance(Type fragType, boolean twoPane) {
MoviesFragment fragment = new MoviesFragment();
Bundle args = new Bundle();
args.putSerializable(ARG_FRAG_TYPE, fragType);
args.putBoolean(ARG_FRAG_TWO_PANE, twoPane);
fragment.setArguments(args);
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Icepick.restoreInstanceState(this, savedInstanceState);
if (getArguments() != null) {
fragType = (Type) getArguments().getSerializable(ARG_FRAG_TYPE);
twoPane = getArguments().getBoolean(ARG_FRAG_TWO_PANE);
}
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_movies_list, container, false);
unbinder = ButterKnife.bind(this, rootView);
init();
return rootView;
}
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
#Override
public void onRefresh() {
movies = null;
updateMovies();
}
#Override
public void onItemClicked(RecyclerView recyclerView, int position, View v) {
showMovieAtPosition(position);
}
#Subscribe(sticky = true)
public void onEvent(UpdateFavoritesEvent event) {
if (fragType == Type.FAVORITES) {
EventBus.getDefault().removeStickyEvent(UpdateFavoritesEvent.class);
onRefresh();
}
}
#Subscribe(sticky = true)
public void onEvent(TwoPaneEvent event) {
twoPane = event.twoPane;
}
#Override
protected void init() {
RecyclerItemClickSupport.addTo(moviesView)
.setOnItemClickListener(this);
moviesView.setLayoutManager(new GridLayoutManager(getContext(), 2));
moviesView.setHasFixedSize(true);
refreshView.setOnRefreshListener(this);
updateMovies();
}
private void updateMovies() {
if (movies == null) {
MoviesCallback callback = new MoviesCallback() {
#Override
public void success(List<Movie> result) {
movies = new ArrayList<>(result);
if (moviesView != null) {
moviesView.setAdapter(new MoviesAdapter(getContext(), movies));
}
refreshView.setRefreshing(false);
}
#Override
public void error(Exception error) {
Toast.makeText(getContext(), error.getMessage(), Toast.LENGTH_SHORT).show();
error.printStackTrace();
refreshView.setRefreshing(false);
}
};
switch (fragType) {
case POPULAR:
MoviesUtil.getPopularMovies(getActivity(), callback);
break;
case TOP_RATED:
MoviesUtil.getTopRatedMovies(getActivity(), callback);
break;
case FAVORITES:
MoviesUtil.getFavoritesMovies(getActivity(), callback);
break;
}
} else if (moviesView != null) {
moviesView.setAdapter(new MoviesAdapter(getContext(), movies));
refreshView.setRefreshing(false);
}
}
private void showMovieAtPosition(int position) {
if (movies != null && position <= movies.size() - 1) {
Movie movie = movies.get(position);
EventBus.getDefault().postSticky(new ShowMovieEvent(movie));
if (twoPane) {
getFragmentManager().beginTransaction()
.replace(R.id.movie_detail, new MovieFragment())
.commit();
} else {
startActivity(new Intent(getContext(), MovieActivity.class));
}
}
}
}

Related

LiveData isn't being observed properly (gets null) when using Android Pagination Library

I am trying to update the UI depending on whether the data is being loaded or has loaded but it is not working properly. I am using enum class for different states.
Initially the error was
Attempt to invoke virtual method 'void androidx.lifecycle.LiveData.observe(androidx.lifecycle.LifecycleOwner, androidx.lifecycle.Observer)' on a null object reference
Then I passed an empty new MutableLiveData()<>. Now, it doesn't crashes the application, however, the getDataStatus() observer isn't working correctly. Kindly look at my implementations and see if they are right.
DataSource
public class ArticlesDataSource extends PageKeyedDataSource<Integer, NewsItem> {
private static final int FIRST_PAGE = 1;
private static final String TAG = "ArticlesDataSource";
public static final String SORT_ORDER = "publishedAt";
public static final String LANGUAGE = "en";
public static final String API_KEY = Utils.API_KEY;
public static final int PAGE_SIZE = 10;
private String mKeyword;
private MutableLiveData<DataStatus> dataStatusMutableLiveData = new MutableLiveData<>();
public ArticlesDataSource(String keyword) {
mKeyword = keyword;
dataStatusMutableLiveData = new MutableLiveData<>();
}
public MutableLiveData<DataStatus> getDataStatusMutableLiveData() {
return dataStatusMutableLiveData;
}
#Override
public void loadInitial(#NonNull LoadInitialParams<Integer> params, #NonNull LoadInitialCallback<Integer, NewsItem> callback) {
dataStatusMutableLiveData.postValue(DataStatus.LOADING);
NewsAPI newsAPI = ServiceGenerator.createService(NewsAPI.class);
Call<RootJsonData> call = newsAPI.searchArticlesByKeyWord(mKeyword, SORT_ORDER, LANGUAGE, API_KEY, FIRST_PAGE, PAGE_SIZE);
call.enqueue(new Callback<RootJsonData>() {
#Override
public void onResponse(Call<RootJsonData> call, Response<RootJsonData> response) {
if (response.body() != null) {
callback.onResult(response.body().getNewsItems(), null, FIRST_PAGE + 1);
dataStatusMutableLiveData.postValue(DataStatus.LOADED);
}
}
#Override
public void onFailure(Call<RootJsonData> call, Throwable t) {
Log.d(TAG, "onFailure: " + t.getMessage());
dataStatusMutableLiveData.postValue(DataStatus.ERROR);
}
});
}
#Override
public void loadBefore(#NonNull LoadParams<Integer> params, #NonNull LoadCallback<Integer, NewsItem> callback) {
NewsAPI newsAPI = ServiceGenerator.createService(NewsAPI.class);
Call<RootJsonData> call = newsAPI.searchArticlesByKeyWord(mKeyword, SORT_ORDER, LANGUAGE, API_KEY, FIRST_PAGE, PAGE_SIZE);
call.enqueue(new Callback<RootJsonData>() {
#Override
public void onResponse(Call<RootJsonData> call, Response<RootJsonData> response) {
// if the current page is greater than one
// we are decrementing the page number
// else there is no previous page
Integer adjacentKey = (params.key > 1) ? params.key - 1 : null;
if (response.body() != null) {
// passing the loaded data
// and the previous page key
callback.onResult(response.body().getNewsItems(), adjacentKey);
}
}
#Override
public void onFailure(Call<RootJsonData> call, Throwable t) {
Log.d(TAG, "onFailure: " + t.getMessage());
}
});
}
#Override
public void loadAfter(#NonNull LoadParams<Integer> params, #NonNull LoadCallback<Integer, NewsItem> callback) {
NewsAPI newsAPI = ServiceGenerator.createService(NewsAPI.class);
Call<RootJsonData> call = newsAPI.searchArticlesByKeyWord(mKeyword, SORT_ORDER, LANGUAGE, API_KEY, params.key, PAGE_SIZE);
call.enqueue(new Callback<RootJsonData>() {
#Override
public void onResponse(Call<RootJsonData> call, Response<RootJsonData> response) {
dataStatusMutableLiveData.postValue(DataStatus.LOADED);
if (response.code() == 429) {
// no more results
List<NewsItem> emptyList = new ArrayList<>();
callback.onResult(emptyList, null);
}
if (response.body() != null) {
// if the response has next page
// incrementing the next page number
Integer key = params.key + 1;
// passing the loaded data and next page value
if (!response.body().getNewsItems().isEmpty()) {
callback.onResult(response.body().getNewsItems(), key);
}
}
}
#Override
public void onFailure(Call<RootJsonData> call, Throwable t) {
Log.d(TAG, "onFailure: " + t.getMessage());
dataStatusMutableLiveData.postValue(DataStatus.ERROR);
}
});
}
}
DataSourceFactory
public class ArticlesDataSourceFactory extends DataSource.Factory {
private final MutableLiveData<ArticlesDataSource> itemLiveDataSource;
private String mQuery;
private final LiveData<DataStatus> dataStatusLiveData = Transformations.switchMap(itemLiveDataSource, (itemDataSource) -> {
return itemDataSource.getDataStatusMutableLiveData();
});
public ArticlesDataSourceFactory() {
mQuery = "news";
itemLiveDataSource = new MutableLiveData<>();
}
#Override
public DataSource<Integer, NewsItem> create() {
ArticlesDataSource itemDataSource = new ArticlesDataSource(mQuery);
itemLiveDataSource.postValue(itemDataSource);
// dataStatusMutableLiveData = itemDataSource.getDataStatusMutableLiveData();
return itemDataSource;
}
public MutableLiveData<ArticlesDataSource> getArticlesLiveDataSource() {
return itemLiveDataSource;
}
public void setQuery(String query) {
mQuery = query;
}
public MutableLiveData<DataStatus> getDataStatusMutableLiveData() {
return dataStatusMutableLiveData;
}
public void setDataStatusMutableLiveData(DataStatus dataStatus){
dataStatusMutableLiveData.postValue(dataStatus);
}
public LiveData<DataStatus> getDataStatusLiveData() {
return dataStatusLiveData;
}
}
ViewModel
public class ArticlesViewModel extends ViewModel {
public LiveData<PagedList<NewsItem>> itemPagedList;
private MutableLiveData<ArticlesDataSource> liveDataSource;
private ArticlesDataSourceFactory articlesDataSourceFactory;
private LiveData dataStatus = new MutableLiveData<>();
public ArticlesViewModel() {
articlesDataSourceFactory = new ArticlesDataSourceFactory();
liveDataSource = articlesDataSourceFactory.getArticlesLiveDataSource();
dataStatus = articlesDataSourceFactory.getDataStatusMutableLiveData();
PagedList.Config pagedListConfig =
(new PagedList.Config.Builder())
.setEnablePlaceholders(false)
.setPageSize(10).build();
itemPagedList = (new LivePagedListBuilder(articlesDataSourceFactory, pagedListConfig)).build();
}
public void setKeyword(String query) {
if (query.equals("") || query.length() == 0)
articlesDataSourceFactory.setDataStatusMutableLiveData(DataStatus.EMPTY);
else {
articlesDataSourceFactory.setQuery(query);
refreshData();
}
}
void refreshData() {
if (itemPagedList.getValue() != null) {
itemPagedList.getValue().getDataSource().invalidate();
}
}
public LiveData<DataStatus> getDataStatus() {
return dataStatus;
}
}
Fragment
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View rootView = inflater.inflate(R.layout.fragment_articles, container, false);
mContext = getActivity();
progressBar = rootView.findViewById(R.id.progress_circular);
emptyStateTextView = rootView.findViewById(R.id.empty_view);
swipeRefreshLayout = rootView.findViewById(R.id.swipe_refresh);
textViewTitle = rootView.findViewById(R.id.text_view_top_headlines);
recyclerView = rootView.findViewById(R.id.recycler_view);
if (savedInstanceState != null) {
keyword = savedInstanceState.getString("keyword");
}
initEmptyRecyclerView();
articlesViewModel = ViewModelProviders.of(this).get(ArticlesViewModel.class);
articlesViewModel.itemPagedList.observe(getViewLifecycleOwner(), new Observer<PagedList<NewsItem>>() {
#Override
public void onChanged(PagedList<NewsItem> newsItems) {
adapter.submitList(newsItems);
// TODO: Handle UI changes
// handleUIChanges(newsItems);
}
});
articlesViewModel.getDataStatus().observe(getViewLifecycleOwner(), new Observer<DataStatus>() {
#Override
public void onChanged(DataStatus dataStatus) {
switch (dataStatus) {
case LOADED:
progressBar.setVisibility(View.GONE);
emptyStateTextView.setVisibility(View.INVISIBLE);
swipeRefreshLayout.setRefreshing(false);
textViewTitle.setVisibility(View.VISIBLE);
break;
case LOADING:
progressBar.setVisibility(View.VISIBLE);
swipeRefreshLayout.setRefreshing(true);
textViewTitle.setVisibility(View.INVISIBLE);
emptyStateTextView.setVisibility(View.INVISIBLE);
break;
case EMPTY:
progressBar.setVisibility(View.GONE);
swipeRefreshLayout.setRefreshing(false);
textViewTitle.setVisibility(View.INVISIBLE);
emptyStateTextView.setVisibility(View.VISIBLE);
emptyStateTextView.setText(R.string.no_news_found);
break;
case ERROR:
progressBar.setVisibility(View.GONE);
swipeRefreshLayout.setRefreshing(false);
textViewTitle.setVisibility(View.INVISIBLE);
emptyStateTextView.setVisibility(View.VISIBLE);
emptyStateTextView.setText(R.string.no_internet_connection);
break;
}
}
});
swipeRefreshLayout.setOnRefreshListener(() -> {
articlesViewModel.setKeyword(keyword);
});
setHasOptionsMenu(true);
return rootView;
}
DataStatus
public enum DataStatus {
ERROR,
LOADING,
LOADED,
EMPTY
}
When you call invalidate(), a new datasource will be created by the factory. However, you are directly exposing the data status liveData of the "current" created datasource, without taking into consideration that more will be created in the future.
The solution is to store the current data source in the factory in a MutableLiveData, and expose the "most recent current data status" using switchMap.
public class ArticlesDataSourceFactory extends DataSource.Factory {
private final MutableLiveData<ArticlesDataSource> itemLiveDataSource = new MutableLiveData<>();
private String mQuery = "news";
private final LiveData<DataStatus> dataStatusLiveData = Transformations.switchMap(itemLiveDataSource, (itemDataSource) -> {
return itemDataSource.getDataStatusMutableLiveData();
});
public ArticlesDataSourceFactory() {
}
#Override
public DataSource<Integer, NewsItem> create() {
ArticlesDataSource itemDataSource = new ArticlesDataSource(mQuery);
itemLiveDataSource.postValue(itemDataSource);
...
public LiveData<DataStatus> getDataStatusLiveData() {
return dataStatusLiveData;
}

How to show multiple data source data in single recycle view or adapter using LazyLoading?

The above image is a simple design that I want to develop.
I have four type of different data with different view type like the below image enter image description here. but that is not a problem. problem is the data will come from different API with lazy loading like when user scroll the list from recycle view it will grab the data from the server. My question is how to combine them in a single adapter because I need to use lazy loading .so I can't load whole data at a time so I need to call the different type of API like goal-list API, appraisal API, post API etc. When user scroll. anyone can give me an idea with example. How can I handle that? Also when user will scroll it will call another api likeCount and comment count also. Currently, In my, I am calling single API and show that in the single recycle view. Currently, I am using android architecture component LiveData
Fragment :
public class NewsFeedFragment extends FcaFragment {
private View view;
private RecyclerView postRecyclerView;
private PostsAdapter postsAdapter;
private List<Post> posts;
private TimelineViewModel timelineViewModel;
private ImageView addPostView;
private View addPostPanel;
private long lastApiCallTime;
private SwipyRefreshLayout swipeRefresh;
private long lastScroolItemInPost= 0;
public NewsFeedFragment() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
if(lastScroolItemInPost < 1) {
initViewModel(1 , 0 , true);
lastScroolItemInPost = 1;
}else {
initViewModel(((int) lastScroolItemInPost + 5), lastScroolItemInPost , true);
lastScroolItemInPost += 5;
}
final LinearLayoutManager linearLayoutManager = new LinearLayoutManager(ownerActivity);
view = inflater.inflate(R.layout.fragment_news_feed, container, false);
postRecyclerView = (RecyclerView) view.findViewById(R.id.postRecyclerView);
postRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
#Override
public void onScrolled(RecyclerView postRecyclerView, int dx, int dy) {
super.onScrolled(postRecyclerView, dx, dy);
int lastVisiableItemInPostList = linearLayoutManager.findLastVisibleItemPosition();
if(lastScroolItemInPost < lastVisiableItemInPostList)
{
if(lastScroolItemInPost == 1)
{
initViewModel((int) (lastScroolItemInPost + 2), ( lastScroolItemInPost - 2 ) , false);
lastScroolItemInPost += 2;
}else{
initViewModel((int) (lastScroolItemInPost + 2), ( lastScroolItemInPost - 2 ) , false );
lastScroolItemInPost += 2;
}
}
}
});
posts = new ArrayList<>();
postRecyclerView.setLayoutManager(linearLayoutManager);
postsAdapter = new PostsAdapter(ownerActivity,posts,timelineViewModel);
postRecyclerView.setAdapter(postsAdapter);
swipeRefresh = (SwipyRefreshLayout) view.findViewById(R.id.swipeRefresh);
swipeRefresh.setOnRefreshListener(new SwipyRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh(SwipyRefreshLayoutDirection direction) {
if(direction == SwipyRefreshLayoutDirection.TOP){
timelineViewModel.fetchPosts2();
}
if(direction == SwipyRefreshLayoutDirection.BOTTOM){
timelineViewModel.fetchPosts();
}
}
});
return view;
}
private void initViewModel(int lastVisiableItemInPostList , long lastScroolItemInPost , boolean isFirstTimeOpenFeedFragment) {
TimelineViewModel.Factory factory = new TimelineViewModel.Factory(UserPreferences.getToken(ownerActivity), TaskUtils.getMySelfContact(ownerActivity));
timelineViewModel = ViewModelProviders.of(this,factory).get(TimelineViewModel.class);
timelineViewModel.getPostList().observe(this, new Observer<List<Post>>() {
#Override
public void onChanged(#Nullable List<Post> posts) {
postsAdapter.setPostList(posts);
swipeRefresh.setRefreshing(false);
}
});
timelineViewModel.getPostDeleted().observe(this, new Observer<Boolean>() {
#Override
public void onChanged(#Nullable Boolean aBoolean) {
if(aBoolean){
postsAdapter.setPostList(Post.getAll());
}
}
});
timelineViewModel.init( lastVisiableItemInPostList , lastScroolItemInPost ,isFirstTimeOpenFeedFragment);
}
}
ViewModel :
public class TimelineViewModel extends FCViewModel implements PostDetailsDownloadManager.PostDetailDownloadedListener,OnContactReceivedListner{
public TimelineViewModel(String token,Contact user){
super(token);
this.user = user;
post = new MutableLiveData<>();
postDeleted = new MutableLiveData<>();
}
public void init(int lastVisiableItemInPostList , long lastScroolItemInPost , boolean isFirstTimeOpenFeedFragment){
repository =
//postDetailsDownloadManager = ServiceLocator.getServiceLocator().postDetailsDownloadManager;
likePostDownloadManager = ServiceLocator.getServiceLocator().likePostDownloadManager;
likePostDownloadManager.setPostDetailDownloadedListener(new DataDownloadManager.DataDownloadedListener<LikePostTouple>() {
#Override
public void onDataDownloaded(List<LikePostTouple> dataTouple) {
TimelineViewModel.this.post.setValue(Post.getAll());
}
#Override
public void onSingleDataDownloaded(LikePostTouple dataTouple) {
}
});
postDetailDownloadManager = ServiceLocator.getServiceLocator().postDetailDownloadManager;
postDetailDownloadManager.setPostDetailDownloadedListener(new DataDownloadManager.DataDownloadedListener<PostTouple>() {
#Override
public void onDataDownloaded(List<PostTouple> dataTouple) {
TimelineViewModel.this.post.setValue(Post.getAll());
}
#Override
public void onSingleDataDownloaded(PostTouple dataTouple) {
}
});
post.setValue(Post.getAll());
if(isFirstTimeOpenFeedFragment)
{
fetchPosts2();
}
try {
if(Post.getAll().size() > 0)
{
List<Post> tempPosts = Post.getAll();
List<Post> passList = tempPosts.subList( (int) lastScroolItemInPost ,lastVisiableItemInPostList);
fetchLikesOfPosts(passList);
}else{
fetchLikesOfPosts(Post.getAll());
}
} catch (Exception e) {
e.printStackTrace();
}
Log.d("Testing Injecting", repository.toString());
}
public LiveData<List<Post>> getPostList() {
return post;
}
public MutableLiveData<Boolean> getPostDeleted() {
return postDeleted;
}
boolean isContactFetched = false;
public void fetchPosts(){
if(Contact.getAll().size() < 1){
fetchContacts();
return;
}
Map<String,Object> requestData = new HashMap<>();
requestData.put("type",1);
requestData.put("cpid",Post.getLastPid());
isDataLoading = true;
repository.getData(new Repository.DataFetchedListener<List<Post>>() {
#Override
public void onDataFetched(List<Post> posts) {
isDataLoading = false;
Log.d("fetched posts",""+posts.size());
post.setValue(Post.getAll());
fetchPostDetails(posts);
if(posts.size() > 0){
fetchLikesOfPosts(posts);
}
}
},requestData);
}
private boolean isDataLoading = false;
public void fetchPosts2(){
if(Contact.getAll().size() < 1){
fetchContacts();
return;
}
Map<String,Object> requestData = new HashMap<>();
requestData.put("type",2);
requestData.put("cpid", Post.getFirstPid()); // cpid means cursor pid
isDataLoading = true;
repository.getData(new Repository.DataFetchedListener<List<Post>>() {
#Override
public void onDataFetched(List<Post> posts) {
isDataLoading = false;
Log.d("fetched posts",""+posts.size());
post.setValue(Post.getAll());
fetchPostDetails(posts);
if(posts.size() > 0){
fetchLikesOfPosts(posts);
}
}
},requestData);
}
public boolean isDataLoading() {
return isDataLoading;
}
private void fetchContacts() {
contactRepository.getData(new Repository.DataFetchedListener<List<Contact>>() {
#Override
public void onDataFetched(List<Contact> data) {
if(data.size()>0 && !isContactFetched) {
fetchPosts2();
isContactFetched = true;
}
}
},null);
}
#NonNull
private PostTouple getPostToubleFromPost(Post post) throws JSONException {
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String json = gson.toJson(post);
JSONObject postJson = new JSONObject(json);
return new PostTouple(postJson,post.getPid());
}
#NonNull
private LikePostTouple getLkePostToupleFromPost(Post post) throws JSONException {
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String json = gson.toJson(post);
JSONObject postJson = new JSONObject(json);
return new LikePostTouple(postJson,post.getPid());
}
public void giveLike(String token, final long pid){
Map<String,Object> requestData = new HashMap<>();
requestData.put("token",token);
requestData.put("pid",Long.toString(pid));
likeRepository.postData(new Repository.DataFetchedListener<Post>() {
#Override
public void onDataFetched(Post data) {
Log.d("Like post", data.toString());
Post post = getPostById(pid);
post.setLikes(data.getLikes());
post.setComments(data.getComments());
TimelineViewModel.this.post.setValue(TimelineViewModel.this.post.getValue());
fetchLikesOfLikedPost(data);
}
},requestData);
}
private void fetchLikesOfLikedPost(Post data) {
try {
likePostDownloadManager.addItemInQueue(getLkePostToupleFromPost(data));
likePostDownloadManager.startDownload();
} catch (JSONException e) {
e.printStackTrace();
}
}
private Post getPostById(long pid){
List<Post> posts = post.getValue();
for(Post post : posts){
if(post.getPid()==pid){
return post;
}
}
return null;
}
public Contact getSenderContactFromComment(Post post) {
if(post.getPqrc().equals(user.getUserId())){
return user;
}
Contact contact = Contact.getByUserId(post.getPqrc());
return contact;
}
public String getDescriptionForType5(Post post,String message){
try {
PostDetail postDetail = PostDetail.getByPostId(post.getPid());
if(postDetail!=null) {
String qrc = JSonUtils.qrcFromCntOfPostDetails(postDetail.getContent());
int sid = JSonUtils.skillidFromCntOfPostDetails(postDetail.getContent());
if (qrc == null || sid == 0) {
return "";
}
SkillDb skill = SkillDb.getBySId(Integer.toString(sid));
Contact contact = getPosterContact(post.getPqrc());
return contact.getName() + " " + message + " " + skill.getSkillName() + ".";
}
return "";
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public String getDescriptionForPost(Post post, String message){
if(post.getCtype()==1){
return post.getDescr();
}
if(post.getCtype() == 2){
String postDetail = getContent(post);
if (postDetail != null) return Html.fromHtml(""+postDetail+"").toString();
}
if(post.getCtype()==5){
return getDescriptionForType5(post, message);
}
return "";
}
#Nullable
public String getContent(Post post) {
PostDetail postDetail = PostDetail.getByPostId(post.getPid());
if(postDetail!=null){
return postDetail.getContent();
}
return null;
}
public Contact getPosterContact(String qrc){
try {
String userqrc = user.getUserId();
if (userqrc.equals(qrc)) {
return user;
}
}catch (Exception e){
e.printStackTrace();
}
try {
return Contact.getByUserId(qrc);
}catch (Exception e){
e.printStackTrace();
}
return null;
}
public void fetchUrlPreview(String url, final UrlMetaDataFetchListener metaDataFetchListener){
String modifiedUrl = !url.contains("http://")&&!url.contains("https://")? "http://"+url : url;
TextCrawler textCrawler = new TextCrawler();
LinkPreviewCallback linkPreviewCallback = new LinkPreviewCallback() {
#Override
public void onPre() {
}
#Override
public void onPos(SourceContent sourceContent, boolean b) {
String imageUrl = sourceContent.getImages().isEmpty()? "" : sourceContent.getImages().get(0);
metaDataFetchListener.onMetaDataFetched(sourceContent.getTitle(),sourceContent.getDescription(), imageUrl);
}
};
textCrawler.makePreview(linkPreviewCallback, modifiedUrl,1);
}
public interface UrlMetaDataFetchListener{
void onMetaDataFetched(String title, String description, String imageUrl);
}
#Override
public void onPostDownloaded(PostTouple postTouple) {
this.post.setValue(Post.getAll());
}
#Override
public void onContactsReceived() {
fetchPosts();
}
public void deletePost(long pid) {
Map<String, Object> requestData = new HashMap<>();
requestData.put("token",token);
requestData.put("pid",pid);
repository.postData(new Repository.DataFetchedListener<Post>() {
#Override
public void onDataFetched(Post data) {
postDeleted.setValue(data!=null);
}
},requestData);
}
public boolean isMyPost(Post post){
return user.getUserId().equals(post.getPqrc());
}
public static class Factory extends ViewModelProvider.NewInstanceFactory {
private String token;
private Contact user;
public Factory(String token,Contact user) {
this.token = token;
this.user = user;
}
#Override
public <T extends ViewModel> T create(Class<T> modelClass) {
return (T) new TimelineViewModel(token,user);
}
}
}
Adapter :
public class PostsAdapter extends RecyclerView.Adapter {
private Context context;
private List<Post> postList;
private int[] badges = {R.drawable.badge1, R.drawable.badge2, R.drawable.badge3};
private List<Integer> randomNumbers = Utils.getRandomNumberList(2,true);
private ArrayDeque<Integer> randomQueue = new ArrayDeque<>(randomNumbers);
private static Map<Long,URLPreview> urlPreviewMap = new HashMap<>();
private TimelineViewModel timelineViewModel;
public PostsAdapter(Context context, List<Post> postList, TimelineViewModel timelineViewModel){
super();
this.context = context;
this.postList = postList;
this.timelineViewModel = timelineViewModel;
}
#Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.post_item_layout, null);
PostViewHolder postViewHolder = new PostViewHolder(view);
postViewHolder.setIsRecyclable(false);
return postViewHolder;
}
#Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, final int position) {
final Post post = postList.get(position);
final PostViewHolder postViewHolder = (PostViewHolder) holder;
final String postDetail = timelineViewModel.getDescriptionForPost(post,context.getResources().getString(R.string.postType5message));
setPostDescription(post, postViewHolder, postDetail);
handlePreviewVisibility(post, postViewHolder);
postViewHolder.setLikes(""+post.getLikes()+" Likes");
postViewHolder.setCommentCount("" + post.getComments() + " Comments");
postViewHolder.setSupDescription("Posted By System");
int randomNumber = getRandomNumber();
postViewHolder.setBadgeIcon(badges[randomNumber]);
setPostLikedIndicator(post, postViewHolder);
postViewHolder.getLikeButtonWrapper().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
giveLikeToPost(post);
if(post.getIsLiked() == 0) {
post.setLikes(post.getLikes() + 1);
postViewHolder.setLikes("" + post.getLikes() + " Likes");
post.setIsLiked(1);
setPostLikedIndicator(post, postViewHolder);
}
}
});
postViewHolder.getCommentPanel().setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CommentPostFragment fragment = CommentPostFragment.GetInstance(post.getPid());
ViewUtils.launchFragmentKeepingInBackStack(context,fragment);
}
});
Contact contact = timelineViewModel.getPosterContact(post.getPqrc());
if(contact!=null && TaskUtils.isNotEmpty(contact.getImageToken())){
Utils.setImageToImageView(postViewHolder.getPosterImage(),timelineViewModel.getToken(),contact.getImageToken());
postViewHolder.getPosterNameTextView().setText(contact.getName());
}
postViewHolder.getPostingDate().setText(Utils.getDateFromMilliseconds(post.getdC()));
if(post.getCtype() != 3)
{
postViewHolder.contentImage.setVisibility(View.GONE);
postViewHolder.fullScreenIndicatorIcon.setVisibility(View.GONE);
}
if(post.getCtype() == 3){
setContentOfType3(post, postViewHolder);
}
}
#Override
public void onViewRecycled(RecyclerView.ViewHolder holder) {
super.onViewRecycled(holder);
PostViewHolder viewHolder = (PostViewHolder) holder;
viewHolder.pTitle.setText("");
viewHolder.pDescription.setText("");
viewHolder.pImage.setImageDrawable(null);
}
private void handlePreviewVisibility(Post post, PostViewHolder postViewHolder) {
if(post.getCtype()==2){
postViewHolder.preview.setVisibility(View.VISIBLE);
}else{
postViewHolder.preview.setVisibility(View.GONE);
}
}
private void handleShowingOptionsIcon(Post post, PostViewHolder postViewHolder) {
if(post.getCtype()!=5 && timelineViewModel.isMyPost(post)){
postViewHolder.options.setVisibility(View.VISIBLE);
}else{
postViewHolder.options.setVisibility(View.GONE);
}
}
private void giveLikeToPost(Post post) {
post.setLikes(post.getLikes()+1);
post.setIsLiked(1);
//notifyDataSetChanged();
timelineViewModel.giveLike(UserPreferences.getToken(context),post.getPid());
}
private void setPostLikedIndicator(Post post, PostViewHolder postViewHolder) {
if(post.getIsLiked()==1) {
postViewHolder.getLikeButton().setImageDrawable(ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_like_red, null));
}else{
postViewHolder.getLikeButton().setImageDrawable(ResourcesCompat.getDrawable(context.getResources(), R.drawable.ic_like_filled, null));
}
}
private void setPostDescription(final Post post, final PostViewHolder postViewHolder, final String postDetail) {
if(post.getCtype()==2){
String postDescription = "<p>"+ post.getDescr()+"</p>";
postViewHolder.description.setText( Html.fromHtml(postDescription +""+postDetail+"") );
postViewHolder.descriptionContainer.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String url = !postDetail.contains("http://")&&!postDetail.contains("https://")? "http://"+postDetail : postDetail;
Uri uri = Uri.parse(url);
context.startActivity(new Intent(Intent.ACTION_VIEW,uri));
}
});
URLPreview urlPreview = null;
if((urlPreview=urlPreviewMap.get(post.getPid()))==null) {
timelineViewModel.fetchUrlPreview(postDetail, new TimelineViewModel.UrlMetaDataFetchListener() {
#Override
public void onMetaDataFetched(String title, String description, String imageUrl) {
showURLPreview(title, description, imageUrl, postViewHolder);
urlPreviewMap.put(post.getPid(),new URLPreview(title,description,imageUrl));
}
});
}else {
showURLPreview(urlPreview.getTitle(),urlPreview.getDescription(),urlPreview.getImageUrl(),postViewHolder);
}
}else if(post.getCtype() == 3)
{
String postDescription = post.getDescr();
postViewHolder.description.setText(postDescription);
}
else {
postViewHolder.setDescription(postDetail);
}
}
private void initImageClickListener(final ImageView imageView, final String pictureLink) {
imageView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
List<String> pictureLinks = new ArrayList<String>();
pictureLinks.add(pictureLink);
int[] screenLocation = new int[2];
imageView.getLocationOnScreen(screenLocation);
ImagePagerFragment imagePagerFragment = ImagePagerFragment.newInstance(pictureLinks, 0, screenLocation, imageView.getWidth(), imageView.getHeight());
ViewUtils.launchPopUpFragmentUpdated(context, imagePagerFragment);
}
});
}
private void showURLPreview(String title, String description, String imageUrl, PostViewHolder postViewHolder) {
context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(!TaskUtils.isEmpty(imageUrl)) {
Picasso.with(context)
.load(imageUrl)
.into(postViewHolder.pImage);
}
view.findViewById(R.id.description);
postViewHolder.pTitle.setText(title);
postViewHolder.pDescription.setText(description);
}
#Override
public int getItemCount() {
return postList.size();
}
private int getRandomNumber(){
if(!randomQueue.isEmpty()){
return randomQueue.poll();
}
randomQueue = new ArrayDeque<>(randomNumbers);
return randomQueue.poll();
}
public void setPostList(List<Post> postList) {
this.postList = postList;
notifyDataSetChanged();
Log.d("Data rec", postList.size()+"");
}
class PostViewHolder extends RecyclerView.ViewHolder implements PopupMenu.OnMenuItemClickListener {
}
public void setLikes(String likes) {
this.likes.setText(likes);
}
public void setCommentCount(String commentCount)
{
this.commentCount.setText(commentCount);
}
public void setDescription(String description){
this.description.setText(description);
}
public void setSupDescription(String subDescription){
this.supDescription.setText(subDescription);
}
public void setBadgeIcon(int resID){
Utils.setImageViewFromResource(badgeIcon,resID);
}
public ImageView getLikeButton() {
return likeButton;
}
public RelativeLayout getLikeButtonWrapper()
{
return likeButtonWrapper;
}
public ImageView getCommentButton() {
return commentButton;
}
public ImageView getPosterImage() {
return posterImage;
}
public TextView getPosterNameTextView() {
return posterNameTextView;
}
public TextView getPostingDate() {
return postingDate;
}
public RelativeLayout getCommentPanel() {
return commentPanel;
}
#Override
public boolean onMenuItemClick(MenuItem item) {
timelineViewModel.deletePost(postList.get(getAdapterPosition()).getPid());
return false;
}
}
}

NullPointerException while evaluating toString() for anonymous class

Trying to convert JSON array to list of objects using Gson library.
Code:
TypeToken<List<Comment>> token = new TypeToken<List<Comment>>() {}; //this line throws the following exception
public class Comment implements Serializable{
#SerializedName("id")
private int mID;
#SerializedName("content")
private String mContent;
#SerializedName("author")
private String mAuthor;
#SerializedName("author_id")
private int mAuthorID;
#SerializedName("author_email")
private String mAuthorEmail;
#SerializedName("date")
private String mDate;
#SerializedName("name")
private String mName;
#SerializedName("image")
private String mImage;
public int getmID() {
return mID;
}
public void setmID(int mID) {
this.mID = mID;
}
public String getmContent() {
return mContent;
}
public void setmContent(String mContent) {
this.mContent = mContent;
}
public String getmAuthor() {
return mAuthor;
}
public void setmAuthor(String mAuthor) {
this.mAuthor = mAuthor;
}
public int getmAuthorID() {
return mAuthorID;
}
public void setmAuthorID(int mAuthorID) {
this.mAuthorID = mAuthorID;
}
public String getmAuthorEmail() {
return mAuthorEmail;
}
public void setmAuthorEmail(String mAuthorEmail) {
this.mAuthorEmail = mAuthorEmail;
}
public String getmDate() {
return mDate;
}
public void setmDate(String mDate) {
this.mDate = mDate;
}
public String getmName() {
return mName;
}
public void setmName(String mName) {
this.mName = mName;
}
public String getmImage() {
return mImage;
}
public void setmImage(String mImage) {
this.mImage = mImage;
}
}
public class CommentListingActivity extends BaseActivity implements View.OnClickListener {
private static final String TAG = "CommentListingActivity";
private ListView mListViewComments;
private CommentAdapter mCommentAdapter;
private ArrayList<Comment> mCommentList = new ArrayList<Comment>();
private ProgressBar mProgressBar;
private TextView mTextViewErrorMessage;
private Button mButtonRefresh;
private LinearLayout mLinearLayoutError;
private int mPostID;
private boolean isCommentListLoading = true;
private EditText mEditTextComment;
private ImageView mImageViewSend;
private InputMethodManager mInputMethodManager;
private SwipeRefreshLayout mSwipeRefreshLayout;
private boolean mIsRefreshing = false;
private int mOffset = 0;
private View mProgressBarView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_comment_listing);
mPostID = getIntent().getIntExtra("postID",0);
setToolbar();
setToolBarTitle(getString(R.string.commentsLabel));
setToolbarHomeAsUpEnabled(true);
mSwipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipeRefreshLayout);
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
mSwipeRefreshLayout.setRefreshing(false);
mIsRefreshing = true;
mOffset = 0;
fetchComments();
}
});
mListViewComments = (ListView) findViewById(R.id.listViewComments);
mCommentAdapter = new CommentAdapter(this, mCommentList,mImageLoader);
mListViewComments.setAdapter(mCommentAdapter);
mProgressBarView = getLayoutInflater().inflate(R.layout.recyclerview_loading_item,null);
mListViewComments.addFooterView(mProgressBarView);
// set the custom dialog components - text, image and button
mEditTextComment = (EditText) findViewById(R.id.editTextComment);
mImageViewSend = (ImageView) findViewById(R.id.imageViewSend);
mImageViewSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
postComment();
}
});
mEditTextComment.requestFocus();
mInputMethodManager = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
mInputMethodManager.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0);
initProgressBar();
initErrorView();
mListViewComments.setOnScrollListener(new EndlessScrollListener() {
#Override
public boolean onLoadMore(int page, int totalItemsCount) {
mOffset = mOffset + LIST_LIMIT;
mListViewComments.addFooterView(mProgressBarView);
fetchComments();
return true;
}
});
fetchComments();
}
private void fetchComments(){
if (!mIsRefreshing && mCommentAdapter.getCount()==0)
showProgressBar();
HashMap<String,String> parameters = new HashMap<String, String>();
parameters.put("post",String.valueOf(mPostID));
parameters.put("offset",String.valueOf(mOffset));
NetworkUtility.getJSONRquest(this, APIURLs.LIST_COMMENTS, parameters, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//Remove loading item
if(mCommentList.size()>0) {
mListViewComments.removeFooterView(mProgressBarView);
}
try {
if(response.getString(API_KEY_STATUS).equalsIgnoreCase(API_RESPONSE_SUCCESS)){
JSONArray jsonArrayComments = response.getJSONArray(API_KEY_DATA);
if(jsonArrayComments.length()>0) {
if (mIsRefreshing) {
mCommentList.clear();
mCommentAdapter.notifyDataSetChanged();
}
TypeToken<List<Comment>> token = new TypeToken<List<Comment>>() {};
mCommentList.addAll((Collection<? extends Comment>) GsonUtility.convertJSONStringToObject(jsonArrayComments.toString(), token));
mCommentAdapter.notifyDataSetChanged();
}
mIsRefreshing = false;
if(mCommentAdapter.getCount()>0) {
showContent();
} else {
if (mOffset == 0)
showError("No comments found.");
}
} else {
mProgressBarView.setVisibility(View.GONE);
if(mCommentAdapter.getCount()>0){
AlertDialogUtility.showErrorMessage(CommentListingActivity.this,getString(R.string.errorLabel),response.getString(API_KEY_MESSAGE),getString(R.string.okLabel),null,null,null);
} else
showError(response.getString(API_KEY_MESSAGE));
}
} catch (JSONException e) {
e.printStackTrace();
mProgressBarView.setVisibility(View.GONE);
if(mCommentAdapter.getCount()>0){
AlertDialogUtility.showErrorMessage(CommentListingActivity.this,getString(R.string.errorLabel),getString(R.string.volleyErrorMessage),getString(R.string.okLabel),null,null,null);
} else {
showError(getString(R.string.volleyErrorMessage));
}
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
mProgressBarView.setVisibility(View.GONE);
if(mCommentAdapter.getCount()>0){
AlertDialogUtility.showErrorMessage(CommentListingActivity.this,getString(R.string.errorLabel),getString(R.string.volleyErrorMessage),getString(R.string.okLabel),null,null,null);
} else {
showError(error.getCause().getMessage());
}
error.printStackTrace();
}
},null,TAG);
}
private void postComment() {
final AppProgressDialog appProgressDialog = new AppProgressDialog(this);
appProgressDialog.setProgressDialogTitle("Posting Comment");
appProgressDialog.setProgressDialogMessage("Please Wait...");
appProgressDialog.showProgressDialog();
try {
final String comment = mEditTextComment.getText().toString();
if (!ValidatorUtility.isBlank(comment) && mPostID!=0) {
JSONObject jsonData = new JSONObject();
jsonData.put("content",comment);
jsonData.put("post",mPostID);
NetworkUtility.postRquestWithBasicAuth(this, APIURLs.POST_COMMENT, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
if(response.has("id") && response.getInt("id")>0){
AppToast.toastLong(mContext,"Comment Added");
Comment objComment = new Comment();
if (response.has("author_name"))
objComment.setmAuthor(response.getString("author_name"));
if (response.has("author_email"))
objComment.setmAuthorEmail(response.getString("author_email"));
if (response.has("author"))
objComment.setmAuthorID(response.getInt("author"));
objComment.setmContent(comment);
if (response.has("date"))
objComment.setmDate(response.getString("date"));
if (response.has("id"))
objComment.setmID(response.getInt("id"));
objComment.setmImage(mUser.getImage());
objComment.setmName(mUser.getName());
mCommentList.add(0,objComment);
mCommentAdapter.notifyDataSetChanged();
mEditTextComment.setText(null);
mEditTextComment.clearFocus();
mInputMethodManager.hideSoftInputFromWindow(mEditTextComment.getWindowToken(),0);
showContent();
} else {
AlertDialogUtility.showErrorMessage(CommentListingActivity.this,getString(R.string.errorLabel),"Failed to add comment. Please try again later.",getString(R.string.okLabel),null,null,null);
}
} catch (JSONException e) {
e.printStackTrace();
} finally {
appProgressDialog.dismissProgressDialog();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
appProgressDialog.dismissProgressDialog();
AlertDialogUtility.showErrorMessage(CommentListingActivity.this,getString(R.string.errorLabel),error.getCause().getMessage(),getString(R.string.okLabel),null,null,null);
}
}, jsonData, TAG);
} else {
appProgressDialog.dismissProgressDialog();
}
} catch (Exception e){
e.printStackTrace();
appProgressDialog.dismissProgressDialog();
}
}
private void initProgressBar(){
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
}
private void initErrorView(){
mLinearLayoutError = (LinearLayout) findViewById(R.id.linearLayoutError);
mTextViewErrorMessage = (TextView) findViewById(R.id.textViewErrorMessage);
mButtonRefresh = (Button) findViewById(R.id.buttonRefresh);
mButtonRefresh.setOnClickListener(this);
}
private void showProgressBar(){
mProgressBar.setVisibility(View.VISIBLE);
mLinearLayoutError.setVisibility(View.GONE);
mSwipeRefreshLayout.setVisibility(View.GONE);
}
private void showContent(){
mProgressBar.setVisibility(View.GONE);
mLinearLayoutError.setVisibility(View.GONE);
mSwipeRefreshLayout.setVisibility(View.VISIBLE);
}
private void showError(String message){
mProgressBar.setVisibility(View.GONE);
mLinearLayoutError.setVisibility(View.VISIBLE);
mSwipeRefreshLayout.setVisibility(View.GONE);
mTextViewErrorMessage.setText(message);
}
#Override
public void onClick(View view) {
if(view == mButtonRefresh){
fetchComments();
}
}
#Override
protected void onDestroy() {
super.onDestroy();
KeyboardUtility.closeKeyboard(this,mEditTextComment);
}
}
Exception:
Method threw 'java.lang.NullPointerException' exception. Cannot evaluate app.govindaconnect.mangaltaraproductions.com.views.CommentListingActivity$4$1.toString()
Only 1 JSON objects get converted and added to the list.
What might be causing the exception? Because this is not happening with other classes.
You can try this
replace this line
TypeToken<List<Comment>> token = new TypeToken<List<Comment>>() {};
with this and try
Type token = new TypeToken<List<Comment>>() {}.getType();
List<Comment> commentsList = gson.fromJson(String.valueOf(resultArray), type);
I took JSON array in a string variable and then it started working.
why don't you try Jackson parser for conversion, it's much simpler and easier
example for you :
List<Comment> list=null;
String json="your json array";
ObjectMapper mapper = new ObjectMapper();
try {
list= mapper.readValue(json, new TypeReference<List<Comment>>(){});
} catch (IOException e) {
throw new Exception(e);
}

Trying to develop an in Android, MediaPlayer plays two songs ath the same time

I'm new to Android app developing, and I've tried to program a very simple app: each time the headphone cable is inserted it will play a random song from the collection, and stop whenever the headphone cable is disconnected.
However, I now face a very strange problem: no matter what I do, the app plays always two songs at the same time.
It's very strange because I tried to synchronize everything but it didn't solve the issue...
Here follows my code. Thanks in advance for any help!
public class MainActivity extends AppCompatActivity {
private int countMusic;
private boolean headphones= false;
private HeadphonePlugReceiver receiver;
private HashMap<Integer, String> playing_title;
private RandomPlayer player;
Object lock = new Object();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
playing_title = new HashMap<>();
scanAgain();
Button scanButton = (Button)findViewById(R.id.scan_again);
scanButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
scanAgain();
}
});
updateStatus();
receiver = new HeadphonePlugReceiver();
registerReceiver(receiver, new IntentFilter(Intent.ACTION_HEADSET_PLUG));
}
private void updateStatus() {
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView statusTextView = (TextView)findViewById(R.id.status);
TextView titleTextView = (TextView)findViewById(R.id.title);
if (headphones) {
statusTextView.setText("Headphones connected!");
String txt = "";
for (Integer cd: playing_title.keySet()) {
txt += String.format("%d: %s ### ", cd, playing_title.get(cd).replace("_", " "));
}
titleTextView.setText(txt);
} else {
statusTextView.setText("Headphones not connected.");
titleTextView.setText("Music not playing");
}
}
});
}
private void addDebug(final String code) {
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView debugTextView = (TextView)findViewById(R.id.debug);
String dbg = String.format("%s \n %s", debugTextView.getText(), code);
debugTextView.setText(dbg);
}
});
}
private void addError(final String msg) {
runOnUiThread(new Runnable() {
#Override
public void run() {
TextView errorTextView = (TextView)findViewById(R.id.error);
errorTextView.setText(msg);
}
});
}
private void startPlayer() {
if (player == null) {
player = new RandomPlayer(this);
player.start();
}
}
private void stopPlayer() {
if (player != null) {
player.interr();
player = null;
}
}
private void scanAgain() {
try {
TextView countTextView = (TextView)findViewById(R.id.count);
countTextView.setText("Scanning... ");
countMusic = scanMusic().getCount();
countTextView.setText(String.format("Music file found: %d", countMusic));
}
catch(Exception e) {
Log.e("problem", e.getMessage());
}
}
public Cursor scanMusic() {
ContentResolver cr = this.getContentResolver();
Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
String selection = MediaStore.Audio.Media.IS_MUSIC + "!= 0";
String sortOrder = MediaStore.Audio.Media.TITLE + " ASC";
String[] projection = {
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.DURATION,
MediaStore.Audio.Media.TITLE_KEY
};
Cursor cur = cr.query(uri, projection, selection, null, sortOrder);
return cur;
}
private class HeadphonePlugReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
synchronized (lock) {
int state = intent.getIntExtra("state", 0);
managePlayer(state);
// Log.e("state", String.format("state: %d", state));
}
}
private void managePlayer(int state) {
boolean n_headphones = (state != 0);
if (n_headphones == headphones)
return;
headphones = n_headphones;
if (headphones)
startPlayer();
else
stopPlayer();
}
}
private class RandomPlayer extends Thread implements MediaPlayer.OnCompletionListener {
private final MainActivity act;
private final Random r;
private final int code;
private MediaPlayer mp;
private boolean keep_going = true;
Object lock2 = new Object();
public RandomPlayer(MainActivity mainActivity) {
r = new Random(System.currentTimeMillis());
act = mainActivity;
code = r.nextInt(10000);
}
public void onCompletion(MediaPlayer arg0) {
playNext();
}
#Override
public void run() {
playNext();
while (keep_going) {
try {
sleep(100);
} catch (InterruptedException e) {
keep_going = false;
}
}
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
playing_title.remove(code);
updateStatus();
}
public void interr() {
keep_going = false;
}
private void playNext() {
synchronized (lock2) {
if (mp != null) {
mp.stop();
mp.release();
mp = null;
}
mp = new MediaPlayer();
mp.setAudioStreamType(AudioManager.STREAM_MUSIC);
//mp.setVolume(0.9f , 0.9f);
mp.setOnCompletionListener(this);
int chosen = r.nextInt(countMusic);
Cursor cur = scanMusic();
for (int i = 0; i < chosen; i++)
cur.moveToNext();
playing_title.put(code, cur.getString(cur.getColumnIndex(MediaStore.Audio.Media.TITLE)));
try {
int a1 = cur.getColumnIndex(MediaStore.Audio.Media.DATA);
String a2 = cur.getString(a1);
mp.setDataSource(a2);
mp.prepare();
mp.start();
addDebug(a2);
} catch (Exception e) {
Log.e("Randomplayer", "exception", e);
addError(e.getMessage());
}
updateStatus();
}
}
}
}

how to implement media player without blocking ui when implementing the media source from server?

the problem is simple, the media player is blocking the UI when implementing the source from remote server. i used a sync prepare for the initialize the media-player, but its block the UI when reset the media player.
here i written a code using thread, it helps a lot but need a clean solution.
public class QuranPlayerAct extends Activity implements DownloadMusicLstn,SeekBar.OnSeekBarChangeListener, OnClickListener,
MediaPlayer.OnPreparedListener, OnCompletionListener,
PlayerBtnClickedLstn, Runnable {
private static final int PLAY_FROM_LOCAL = 234;
private static final int PLAY_FROM_SERVER = 321;
private static final String TAG = "SongsListAct";
private static final int PAUSED = 756;
private static final int STARTED = 554;
private static final int STOPED = 386;
private static final int CLOSED = 453;
private TextView downloadEsplasedTV;
private RelativeLayout playerRetLay;
private ListView musicLst;
private ProgressBar dwnPrgV;
private ImageView playImgV;
private SeekBar songProgressBar;
private TextView songTitleLabel;
private TextView songCurrentDurationLabel;
private TextView songTotalDurationLabel;
private MediaPlayer mp;
private Utilities utils;
private Handler handler;
private boolean stopDownload;
private RelativeLayout downloadRetLay;
private ArrayList<String> musicFiles;
private ImageButton closeImgV;
private TextView downloadTitle;
private long currentDuration;
private Runnable mUpdateTimeTask = new Runnable() {
public void run() {
if (mPrepared) {
long totalDuration = mp.getDuration();
currentDuration = mp.getCurrentPosition();
songTotalDurationLabel.setText(""
+ utils.milliSecondsToTimer(totalDuration));
songCurrentDurationLabel.setText(""
+ utils.milliSecondsToTimer(currentDuration));
int progress = (int) (utils.getProgressPercentage(
currentDuration, totalDuration));
songProgressBar.setProgress(progress);
}
handler.postDelayed(this, 100);
}
};
private TextView downloadTotalTV;
private TextView downloadPercentageTV;
private ImageView stopImgV;
private ImageButton closeDownloadImgV;
private int fileSize;
private boolean mPrepared;
private ProgressBar songsLoadingPB;
private String url;
private String fName;
private boolean stopped;
private int plLoc;
private int track_no;
private int state;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.act_quran_player);
// setActionBar();
setActionBar2();
getRefs();
handler = new Handler();
initMediaPlayer();
playerRetLay.setVisibility(View.GONE);
// updateList();
createAppDirectory();
Thread t = new Thread(this);
t.start();
}
private void setActionBar2() {
final ActionBar bar = getActionBar();
bar.setDisplayShowHomeEnabled(false);
bar.setDisplayShowCustomEnabled(true);
bar.setDisplayShowTitleEnabled(false);
bar.setCustomView(R.layout.player_actionbar_lay);
}
/*
* private void setActionBar() { final ActionBar bar = getActionBar();
*
* bar.setDisplayShowHomeEnabled(false);
* bar.setDisplayShowCustomEnabled(true);
* bar.setDisplayShowTitleEnabled(false);
* bar.setCustomView(R.layout.player_actionbar_lay);
*
* TextView tv = (TextView) bar.getCustomView().findViewById(
* R.id.action_bar_title);
*
* try { tv.setTypeface(Typeface .createFromAsset(getAssets(),
* "DANUBE__.TTF")); } catch (Exception e) { e.printStackTrace(); } }
*/
#Override
public void onResume() {
super.onResume();
setVisiblilityToPlayerAndUI(false);
updateProgressBar();
if(state==CLOSED)playerRetLay.setVisibility(View.GONE);
}
#Override
public void onPause() {
super.onPause();
l("Activity paused");
stopDownload = true;
setVisiblilityToPlayerAndUI(false);
handler.removeCallbacks(mUpdateTimeTask);
if (mp != null)
switch (state) {
case STARTED:
mp.pause();
playImgV.setImageResource(R.drawable.play_img);
break;
}
}
private void getRefs() {
musicLst = (ListView) findViewById(R.id.musLst_lstV);
playerRetLay = (RelativeLayout) findViewById(R.id.musLst_player_retLay);
dwnPrgV = (ProgressBar) findViewById(R.id.musLst_down_progbarV);
downloadRetLay = (RelativeLayout) findViewById(R.id.musLst_dwn_retLay);
playImgV = (ImageView) findViewById(R.id.musLst_ply_btn);
songProgressBar = (SeekBar) findViewById(R.id.musLst_seek_bar);
songTitleLabel = (TextView) findViewById(R.id.musLst_mus_det_txt);
songCurrentDurationLabel = (TextView) findViewById(R.id.time_esplased_TV);
songTotalDurationLabel = (TextView) findViewById(R.id.total_time_TV);
closeImgV = (ImageButton) findViewById(R.id.musLst_close_btn);
downloadTitle = (TextView) findViewById(R.id.musLst_down_title_TV);
downloadEsplasedTV = (TextView) findViewById(R.id.time_esplased_TV22);
downloadTotalTV = (TextView) findViewById(R.id.total_time_TV2);
downloadPercentageTV = (TextView) findViewById(R.id.total_percentage);
stopImgV = (ImageView) findViewById(R.id.musLst_stop_btn);
closeDownloadImgV = (ImageButton) findViewById(R.id.close_down_btn);
songsLoadingPB = (ProgressBar) findViewById(R.id.songs_load_progressbar);
}
#Override
public void run() {
if (!isNetworkAvailable()) {
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(QuranPlayerAct.this,
"No Internet Connection Available",
Toast.LENGTH_LONG).show();
}
});
return;
}
MusicAppUtils appUtils = new MusicAppUtils();
String jsn = appUtils
.getDataFromUrl(MusicAppCommons.HTTP_AIMANSANGAM_COM_LISTFILES_PHP);
if (jsn == null)
return;
jsn = jsn.replace(",]", "]");
musicFiles = appUtils.parseMusicFilesJson(jsn);
updateList();
}
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager
.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
private void createAppDirectory() {
if (MusicAppCommons
.checkFileExist(MusicAppCommons.AIMANSANGAM_MUSIC_DIR)) {
Log.i(TAG, "app directory already exist");
return;
}
File dir = new File(MusicAppCommons.AIMANSANGAM_MUSIC_DIR);
if (dir.mkdirs())
Log.i(TAG, "app directory created");
}
private void setVisiblilityToPlayerAndUI(boolean b) {
if (b) {
songsLoadingPB.setVisibility(View.VISIBLE);
downloadRetLay.setVisibility(View.VISIBLE);
// playerRetLay.setVisibility(View.VISIBLE);
} else {
songsLoadingPB.setVisibility(View.GONE);
downloadRetLay.setVisibility(View.GONE);
// playerRetLay.setVisibility(View.GONE);
}
}
private void initMediaPlayer() {
utils = new Utilities();
mp = new MediaPlayer();
mp.setOnCompletionListener(this);
songProgressBar.setOnSeekBarChangeListener(this);
playImgV.setOnClickListener(this);
closeDownloadImgV.setOnClickListener(this);
closeImgV.setOnClickListener(this);
stopImgV.setOnClickListener(this);
}
private void resetTimeLabel() {
runOnUiThread(new Runnable() {
#Override
public void run() {
songTotalDurationLabel.setText("..");
songCurrentDurationLabel.setText("..");
}
});
}
public void updateProgressBar() {
handler.removeCallbacks(mUpdateTimeTask);
handler.postDelayed(mUpdateTimeTask, 100);
}
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(mUpdateTimeTask);
if (mp != null)
mp.release();
}
public void updateList() {
l("called update list");
if (musicFiles == null)
return;
updateMusicListView(MusicLstAdapter.MUSIC_NOT_DOWNLOADING);
}
private void updateMusicListView(int state) {
final MusicLstAdapter lstAdapter = new MusicLstAdapter(this,
musicFiles, this, state, this);
runOnUiThread(new Runnable() {
#Override
public void run() {
musicLst.setAdapter(lstAdapter);
lstAdapter.notifyDataSetChanged();
}
});
}
#Override
public void onClick(View v) {
if (v == closeDownloadImgV) {
downloadRetLay.setVisibility(View.GONE);
stopDownload = true;
Toast.makeText(this, "Download canceled", Toast.LENGTH_SHORT)
.show();
} else if (v == playImgV) {
if (stopped)
new PlayerThread();
if (mp.isPlaying()) {
if (mp != null) {
state = PAUSED;
mp.pause();
l("pause");
playImgV.setImageResource(R.drawable.play_img);
}
} else {
if (mp != null) {
state = STARTED;
mp.start();
l("start");
playImgV.setImageResource(R.drawable.pause_img);
}
}
} else if (v == closeImgV) {
l("close clicked");
state = CLOSED;
playerRetLay.setVisibility(View.GONE);
handler.removeCallbacks(mUpdateTimeTask);
mp.stop();
mPrepared = false;
new Thread(new Runnable() {
#Override
public void run() {
mp.reset();
}
}).start();
} else if (v == stopImgV) {
l("stop clicked");
state = STOPED;
handler.removeCallbacks(mUpdateTimeTask);
mp.stop();
resetTimeLabel();
playImgV.setImageResource(R.drawable.play_img);
stopped = true;
mPrepared = false;
}
}
// --------************************************************************************
#Override
public void setSize(final int fileSize) {
handler.post(new Runnable() {
#Override
public void run() {
dwnPrgV.setMax(fileSize);
QuranPlayerAct.this.fileSize = fileSize;
float size = (float) fileSize / 1048576;
DecimalFormat format = new DecimalFormat("#.##");
downloadTotalTV.setText(format.format(size) + " MB");
downloadPercentageTV.setText("0 %");
}
});
}
#Override
public void onProgressUpdate(final long total) {
handler.post(new Runnable() {
#Override
public void run() {
dwnPrgV.setProgress((int) total);
float size = (float) total / 1048576;
DecimalFormat format = new DecimalFormat("#.##");
downloadEsplasedTV.setText(format.format(size) + " MB");
float l = total / (float) fileSize * 100;
int round = Math.round(l);
downloadPercentageTV.setText(round + " %");
}
});
}
#Override
public void finished() {
handler.post(new Runnable() {
#Override
public void run() {
downloadRetLay.setVisibility(View.GONE);
}
});
updateMusicListView(MusicLstAdapter.MUSIC_NOT_DOWNLOADING);
}
#Override
public void onDownloadSuccess(boolean success) {
if (success) {
} else {
}
}
#Override
public boolean isStopDownload() {
return stopDownload;
}
#Override
public void downloadStarted(final String fName) {
stopDownload = false;
handler.post(new Runnable() {
#Override
public void run() {
downloadTitle.setText(fName);
downloadRetLay.setVisibility(View.VISIBLE);
}
});
updateMusicListView(MusicLstAdapter.MUSIC_DOWNLOADING);
}
// ----------------*****************************************************************************
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromTouch) {
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(mUpdateTimeTask);
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
handler.removeCallbacks(mUpdateTimeTask);
int totalDuration = mp.getDuration();
int currentPosition = utils.progressToTimer(seekBar.getProgress(),
totalDuration);
mp.seekTo(currentPosition);
updateProgressBar();
}
#Override
public void onPrepared(MediaPlayer mp) {
l("onprepared");
mPrepared = true;
mp.start();
state = STARTED;
playImgV.setImageResource(R.drawable.pause_img);
}
private void l(String str) {
Log.i(TAG, str);
}
// ---------------------***************************************************************************
private class PlayerThread extends Thread {
public PlayerThread() {
start();
}
#Override
public void run() {
try {
stopped = false;
mPrepared = false;
resetTimeLabel();
mp.reset();
mp.setDataSource(url);
if (plLoc == PLAY_FROM_SERVER) {
mp.prepareAsync();
mp.setOnPreparedListener(QuranPlayerAct.this);
updatePlayerImg(R.drawable.play_img);
} else {
mp.prepare();
mp.start();
mPrepared = true;
state = STARTED;
updatePlayerImg(R.drawable.pause_img);
}
updatePlayerUI();
updateProgressBar();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
private void updatePlayerUI() {
runOnUiThread(new Runnable() {
#Override
public void run() {
songTitleLabel.setText(fName);
songProgressBar.setProgress(0);
songProgressBar.setMax(100);
}
});
}
}
private void updatePlayerImg(final int playImg) {
runOnUiThread(new Runnable() {
#Override
public void run() {
playImgV.setImageResource(playImg);
}
});
}
// ------------------------------
#Override
public void onCompletion(MediaPlayer mp) {
track_no++;
if (track_no > musicFiles.size() - 1) {
track_no = 0;
}
playerRetLay.setVisibility(View.VISIBLE);
fName = musicFiles.get(track_no);
String filePath = MusicAppCommons.AIMANSANGAM_MUSIC_DIR + "/" + fName;
if (MusicAppCommons.checkFileExist(filePath)) {
url = filePath;
plLoc = PLAY_FROM_LOCAL;
} else {
url = MusicAppCommons.HTTP_AIMANSANGAM_COM_QURAN_FILES + fName;
url = url.replace(" ", "%20");
plLoc = PLAY_FROM_SERVER;
}
new PlayerThread();
}
#Override
public void clickedOnPlayBtn(int val) {
this.track_no = val;
l("song clicked");
playerRetLay.setVisibility(View.VISIBLE);
fName = musicFiles.get(val);
String filePath = MusicAppCommons.AIMANSANGAM_MUSIC_DIR + "/" + fName;
if (MusicAppCommons.checkFileExist(filePath)) {
url = filePath;
plLoc = PLAY_FROM_LOCAL;
} else {
url = MusicAppCommons.HTTP_AIMANSANGAM_COM_QURAN_FILES + fName;
url = url.replace(" ", "%20");
plLoc = PLAY_FROM_SERVER;
}
new PlayerThread();
}
}

Categories