/*
This file is part of Subsonic.
Subsonic is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Subsonic is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Subsonic. If not, see .
Copyright 2009 (C) Sindre Mehus
*/
package github.daneren2005.dsub.activity;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.AlertDialog;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import github.daneren2005.dsub.R;
import github.daneren2005.dsub.domain.MusicDirectory;
import github.daneren2005.dsub.domain.PlayerState;
import github.daneren2005.dsub.fragments.ChatFragment;
import github.daneren2005.dsub.fragments.MainFragment;
import github.daneren2005.dsub.fragments.SearchFragment;
import github.daneren2005.dsub.fragments.SelectArtistFragment;
import github.daneren2005.dsub.fragments.SelectBookmarkFragment;
import github.daneren2005.dsub.fragments.SelectDirectoryFragment;
import github.daneren2005.dsub.fragments.SelectPlaylistFragment;
import github.daneren2005.dsub.fragments.SelectPodcastsFragment;
import github.daneren2005.dsub.fragments.SelectShareFragment;
import github.daneren2005.dsub.fragments.SubsonicFragment;
import github.daneren2005.dsub.service.DownloadFile;
import github.daneren2005.dsub.service.DownloadService;
import github.daneren2005.dsub.service.DownloadServiceImpl;
import github.daneren2005.dsub.updates.Updater;
import github.daneren2005.dsub.util.Constants;
import github.daneren2005.dsub.util.FileUtil;
import github.daneren2005.dsub.util.SilentBackgroundTask;
import github.daneren2005.dsub.util.Util;
import github.daneren2005.dsub.view.ChangeLog;
/**
* Created by Scott on 10/14/13.
*/
public class SubsonicFragmentActivity extends SubsonicActivity {
private static String TAG = SubsonicFragmentActivity.class.getSimpleName();
private static boolean infoDialogDisplayed;
private ScheduledExecutorService executorService;
private View bottomBar;
private View coverArtView;
private TextView trackView;
private TextView artistView;
private ImageButton startButton;
private long lastBackPressTime = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_EXIT)) {
stopService(new Intent(this, DownloadServiceImpl.class));
finish();
} else if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD)) {
DownloadService service = getDownloadService();
boolean downloadView = getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD_VIEW);
if((service != null && service.getCurrentPlaying() != null) || downloadView) {
getIntent().removeExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD);
Intent intent = new Intent();
intent.setClass(this, DownloadActivity.class);
if(downloadView) {
intent.putExtra(Constants.INTENT_EXTRA_NAME_DOWNLOAD_VIEW, true);
}
startActivity(intent);
}
}
setContentView(R.layout.abstract_fragment_activity);
if (findViewById(R.id.fragment_container) != null && savedInstanceState == null) {
String fragmentType = getIntent().getStringExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE);
currentFragment = getNewFragment(fragmentType);
if("".equals(fragmentType) || fragmentType == null) {
// Initial startup stuff
loadSettings();
}
currentFragment.setPrimaryFragment(true);
getSupportFragmentManager().beginTransaction().add(R.id.fragment_container, currentFragment, currentFragment.getSupportTag() + "").commit();
if(getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_QUERY) != null) {
SearchFragment fragment = new SearchFragment();
replaceFragment(fragment, R.id.home_layout, fragment.getSupportTag());
}
}
bottomBar = findViewById(R.id.bottom_bar);
bottomBar.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(v.getContext(), DownloadActivity.class);
startActivity(intent);
}
});
coverArtView = bottomBar.findViewById(R.id.album_art);
trackView = (TextView) bottomBar.findViewById(R.id.track_name);
artistView = (TextView) bottomBar.findViewById(R.id.artist_name);
ImageButton previousButton = (ImageButton) findViewById(R.id.download_previous);
previousButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new SilentBackgroundTask(SubsonicFragmentActivity.this) {
@Override
protected Void doInBackground() throws Throwable {
if(getDownloadService() == null) {
return null;
}
getDownloadService().previous();
return null;
}
@Override
protected void done(Void result) {
update();
}
}.execute();
}
});
startButton = (ImageButton) findViewById(R.id.download_start);
startButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new SilentBackgroundTask(SubsonicFragmentActivity.this) {
@Override
protected Void doInBackground() throws Throwable {
PlayerState state = getDownloadService().getPlayerState();
if(state == PlayerState.STARTED) {
getDownloadService().pause();
} else {
getDownloadService().start();
}
return null;
}
@Override
protected void done(Void result) {
update();
}
}.execute();
}
});
ImageButton nextButton = (ImageButton) findViewById(R.id.download_next);
nextButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
new SilentBackgroundTask(SubsonicFragmentActivity.this) {
@Override
protected Void doInBackground() throws Throwable {
if(getDownloadService() == null) {
return null;
}
if (getDownloadService().getCurrentPlayingIndex() < getDownloadService().size() - 1) {
getDownloadService().next();
}
return null;
}
@Override
protected void done(Void result) {
update();
}
}.execute();
}
});
}
@Override
protected void onPostCreate(Bundle bundle) {
super.onPostCreate(bundle);
showInfoDialog();
checkUpdates();
ChangeLog changeLog = new ChangeLog(this, Util.getPreferences(this));
if(changeLog.isFirstRun()) {
changeLog.getLogDialog().show();
}
}
@Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if(currentFragment != null && intent.getStringExtra(Constants.INTENT_EXTRA_NAME_QUERY) != null) {
if(currentFragment instanceof SearchFragment) {
String query = intent.getStringExtra(Constants.INTENT_EXTRA_NAME_QUERY);
boolean autoplay = intent.getBooleanExtra(Constants.INTENT_EXTRA_NAME_AUTOPLAY, false);
boolean requestsearch = intent.getBooleanExtra(Constants.INTENT_EXTRA_REQUEST_SEARCH, false);
if (query != null) {
((SearchFragment)currentFragment).search(query, autoplay);
} else {
((SearchFragment)currentFragment).populateList();
if (requestsearch) {
onSearchRequested();
}
}
getIntent().removeExtra(Constants.INTENT_EXTRA_NAME_QUERY);
} else {
setIntent(intent);
SearchFragment fragment = new SearchFragment();
replaceFragment(fragment, currentFragment.getRootId(), fragment.getSupportTag());
}
} else {
setIntent(intent);
}
}
@Override
public void onResume() {
super.onResume();
final Handler handler = new Handler();
Runnable runnable = new Runnable() {
@Override
public void run() {
handler.post(new Runnable() {
@Override
public void run() {
update();
}
});
}
};
if(getIntent().hasExtra(Constants.INTENT_EXTRA_VIEW_ALBUM)) {
int fragmentID = currentFragment != null ? currentFragment.getRootId() : R.id.fragment_list_layout;
if(getIntent().hasExtra(Constants.INTENT_EXTRA_NAME_PARENT_ID)) {
SubsonicFragment fragment = new SelectDirectoryFragment();
Bundle args = new Bundle();
args.putString(Constants.INTENT_EXTRA_NAME_ID, getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_PARENT_ID));
args.putString(Constants.INTENT_EXTRA_NAME_NAME, getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_PARENT_NAME));
fragment.setArguments(args);
replaceFragment(fragment, R.id.fragment_list_layout, currentFragment.getSupportTag());
fragmentID = fragment.getRootId();
}
SubsonicFragment fragment = new SelectDirectoryFragment();
Bundle args = new Bundle();
args.putString(Constants.INTENT_EXTRA_NAME_ID, getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_ID));
args.putString(Constants.INTENT_EXTRA_NAME_NAME, getIntent().getStringExtra(Constants.INTENT_EXTRA_NAME_NAME));
fragment.setArguments(args);
replaceFragment(fragment, fragmentID, currentFragment.getSupportTag());
getIntent().removeExtra(Constants.INTENT_EXTRA_VIEW_ALBUM);
if("Artist".equals(getIntent().getStringExtra(Constants.INTENT_EXTRA_FRAGMENT_TYPE))) {
lastSelectedPosition = 1;
}
}
createAccount();
executorService = Executors.newSingleThreadScheduledExecutor();
executorService.scheduleWithFixedDelay(runnable, 0L, 1000L, TimeUnit.MILLISECONDS);
}
@Override
public void onPause() {
super.onPause();
executorService.shutdown();
}
@Override
public void setContentView(int viewId) {
super.setContentView(viewId);
drawerToggle.setDrawerIndicatorEnabled(true);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if(super.onOptionsItemSelected(item)) {
return true;
} else {
return false;
}
}
@Override
public void onBackPressed() {
if(onBackPressedSupport()) {
if(lastBackPressTime < (System.currentTimeMillis() - 4000)) {
lastBackPressTime = System.currentTimeMillis();
Util.toast(this, R.string.main_back_confirm);
} else {
finish();
}
}
}
@Override
public void replaceFragment(SubsonicFragment fragment, int id, int tag, boolean replaceCurrent) {
super.replaceFragment(fragment, id, tag, replaceCurrent);
drawerToggle.setDrawerIndicatorEnabled(false);
}
@Override
public void removeCurrent() {
super.removeCurrent();
if(backStack.isEmpty()) {
drawerToggle.setDrawerIndicatorEnabled(true);
}
}
@Override
public void startFragmentActivity(String fragmentType) {
// Create a transaction that does all of this
FragmentTransaction trans = getSupportFragmentManager().beginTransaction();
// Clear existing stack
for(int i = backStack.size() - 1; i >= 0; i--) {
trans.remove(backStack.get(i));
}
trans.remove(currentFragment);
backStack.clear();
// Create new stack
currentFragment = getNewFragment(fragmentType);
currentFragment.setPrimaryFragment(true);
trans.add(R.id.fragment_container, currentFragment, currentFragment.getSupportTag() + "");
// Done, cleanup
trans.commit();
supportInvalidateOptionsMenu();
recreateSpinner();
drawer.closeDrawers();
if(secondaryContainer != null) {
secondaryContainer.setVisibility(View.GONE);
}
drawerToggle.setDrawerIndicatorEnabled(true);
}
private SubsonicFragment getNewFragment(String fragmentType) {
if("Artist".equals(fragmentType)) {
return new SelectArtistFragment();
} else if("Playlist".equals(fragmentType)) {
return new SelectPlaylistFragment();
} else if("Chat".equals(fragmentType)) {
return new ChatFragment();
} else if("Podcast".equals(fragmentType)) {
return new SelectPodcastsFragment();
} else if("Bookmark".equals(fragmentType)) {
return new SelectBookmarkFragment();
} else if("Share".equals(fragmentType)) {
return new SelectShareFragment();
} else {
return new MainFragment();
}
}
private void update() {
if (getDownloadService() == null) {
return;
}
DownloadFile current = getDownloadService().getCurrentPlaying();
if(current == null) {
trackView.setText("Title");
artistView.setText("Artist");
getImageLoader().loadImage(coverArtView, null, false, false);
return;
}
MusicDirectory.Entry song = current.getSong();
trackView.setText(song.getTitle());
artistView.setText(song.getArtist());
getImageLoader().loadImage(coverArtView, song, false, false);
int[] attrs = new int[] {(getDownloadService().getPlayerState() == PlayerState.STARTED) ? R.attr.media_button_pause : R.attr.media_button_start};
TypedArray typedArray = this.obtainStyledAttributes(attrs);
startButton.setImageResource(typedArray.getResourceId(0, 0));
typedArray.recycle();
}
public void checkUpdates() {
try {
String version = getPackageManager().getPackageInfo(getPackageName(), 0).versionName;
int ver = Integer.parseInt(version.replace(".", ""));
Updater updater = new Updater(ver);
updater.checkUpdates(this);
}
catch(Exception e) {
}
}
private void loadSettings() {
PreferenceManager.setDefaultValues(this, R.xml.settings, false);
SharedPreferences prefs = Util.getPreferences(this);
if (!prefs.contains(Constants.PREFERENCES_KEY_CACHE_LOCATION)) {
SharedPreferences.Editor editor = prefs.edit();
editor.putString(Constants.PREFERENCES_KEY_CACHE_LOCATION, FileUtil.getDefaultMusicDirectory().getPath());
editor.commit();
}
if (!prefs.contains(Constants.PREFERENCES_KEY_OFFLINE)) {
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean(Constants.PREFERENCES_KEY_OFFLINE, false);
editor.putString(Constants.PREFERENCES_KEY_SERVER_NAME + 1, "Demo Server");
editor.putString(Constants.PREFERENCES_KEY_SERVER_URL + 1, "http://demo.subsonic.org");
editor.putString(Constants.PREFERENCES_KEY_USERNAME + 1, "android-guest");
editor.putString(Constants.PREFERENCES_KEY_PASSWORD + 1, "guest");
editor.putInt(Constants.PREFERENCES_KEY_SERVER_INSTANCE, 1);
editor.commit();
}
if(!prefs.contains(Constants.PREFERENCES_KEY_SERVER_COUNT)) {
SharedPreferences.Editor editor = prefs.edit();
editor.putInt(Constants.PREFERENCES_KEY_SERVER_COUNT, 3);
editor.commit();
}
}
private void createAccount() {
final Context context = this;
new SilentBackgroundTask(this) {
@Override
protected Void doInBackground() throws Throwable {
AccountManager accountManager = (AccountManager) context.getSystemService(ACCOUNT_SERVICE);
Account account = new Account(Constants.SYNC_ACCOUNT_NAME, Constants.SYNC_ACCOUNT_TYPE);
accountManager.addAccountExplicitly(account, null, null);
SharedPreferences prefs = Util.getPreferences(context);
boolean syncEnabled = prefs.getBoolean(Constants.PREFERENCES_KEY_SYNC_ENABLED, true);
int syncInterval = Integer.parseInt(prefs.getString(Constants.PREFERENCES_KEY_SYNC_INTERVAL, "60"));
// Add enabled/frequency to playlist/podcasts syncing
ContentResolver.setSyncAutomatically(account, Constants.SYNC_ACCOUNT_PLAYLIST_AUTHORITY, syncEnabled);
ContentResolver.addPeriodicSync(account, Constants.SYNC_ACCOUNT_PLAYLIST_AUTHORITY, new Bundle(), 60L * syncInterval);
ContentResolver.setSyncAutomatically(account, Constants.SYNC_ACCOUNT_PODCAST_AUTHORITY, syncEnabled);
ContentResolver.addPeriodicSync(account, Constants.SYNC_ACCOUNT_PODCAST_AUTHORITY, new Bundle(), 60L * syncInterval);
// Add for starred/recently added
ContentResolver.setSyncAutomatically(account, Constants.SYNC_ACCOUNT_STARRED_AUTHORITY, (syncEnabled && prefs.getBoolean(Constants.PREFERENCES_KEY_SYNC_STARRED, false)));
ContentResolver.addPeriodicSync(account, Constants.SYNC_ACCOUNT_STARRED_AUTHORITY, new Bundle(), 60L * syncInterval);
ContentResolver.setSyncAutomatically(account, Constants.SYNC_ACCOUNT_MOST_RECENT_AUTHORITY, (syncEnabled && prefs.getBoolean(Constants.PREFERENCES_KEY_SYNC_MOST_RECENT, false)));
ContentResolver.addPeriodicSync(account, Constants.SYNC_ACCOUNT_MOST_RECENT_AUTHORITY, new Bundle(), 60L * syncInterval);
return null;
}
@Override
protected void done(Void result) {
}
}.execute();
}
private void showInfoDialog() {
if (!infoDialogDisplayed) {
infoDialogDisplayed = true;
Log.i(TAG, Util.getRestUrl(this, null));
if (Util.getRestUrl(this, null).contains("demo.subsonic.org")) {
Util.info(this, R.string.main_welcome_title, R.string.main_welcome_text);
}
}
}
}