Kore/app/src/main/java/org/xbmc/kore/ui/AbstractDetailsFragment.java

322 lines
10 KiB
Java
Raw Normal View History

/*
* Copyright 2015 Martijn Brekhof. All rights reserved.
*
* 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 org.xbmc.kore.ui;
import android.Manifest;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v13.app.FragmentCompat;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;
import org.xbmc.kore.R;
import org.xbmc.kore.Settings;
import org.xbmc.kore.host.HostInfo;
import org.xbmc.kore.host.HostManager;
import org.xbmc.kore.jsonrpc.ApiException;
import org.xbmc.kore.jsonrpc.event.MediaSyncEvent;
import org.xbmc.kore.service.library.LibrarySyncService;
import org.xbmc.kore.service.library.SyncUtils;
import org.xbmc.kore.utils.LogUtils;
import org.xbmc.kore.utils.UIUtils;
import org.xbmc.kore.utils.Utils;
import butterknife.OnClick;
import butterknife.Optional;
import de.greenrobot.event.EventBus;
abstract public class AbstractDetailsFragment extends Fragment
implements SwipeRefreshLayout.OnRefreshListener,
SyncUtils.OnServiceListener {
private static final String TAG = LogUtils.makeLogTag(AbstractDetailsFragment.class);
private HostManager hostManager;
private HostInfo hostInfo;
private EventBus bus;
private String syncType;
private SwipeRefreshLayout swipeRefreshLayout;
private ServiceConnection serviceConnection;
// Used to hide the refresh animation when a silent refresh is issued
private boolean silentRefresh = false;
abstract protected View createView(LayoutInflater inflater, ViewGroup container);
/**
* Should return {@link LibrarySyncService} SyncType that
* this fragment initiates
* @return {@link LibrarySyncService} SyncType
*/
abstract protected String getSyncType();
/**
* Should return the {@link LibrarySyncService} syncID if this fragment
* synchronizes a single item. The itemId that should be synced must returned by {@link #getSyncItemID()}
* @return {@link LibrarySyncService} SyncID
*/
abstract protected String getSyncID();
/**
* Should return the item ID for SyncID returned by {@link #getSyncID()}
* @return -1 if not used.
*/
abstract protected int getSyncItemID();
/**
* Should return the SwipeRefreshLayout if the fragment's view uses one.
* Used to notify the user if a sync for synctype returned by {@link #getSyncType()}
* is currently in progress
* @return
*/
abstract protected SwipeRefreshLayout getSwipeRefreshLayout();
/**
* When the view created in {@link #createView(LayoutInflater, ViewGroup)} contains a button
* with resource identifier R.id.download this will be called to initiate the download
*/
abstract protected void onDownload();
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
bus = EventBus.getDefault();
hostManager = HostManager.getInstance(getActivity());
hostInfo = hostManager.getHostInfo();
syncType = getSyncType();
}
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (container == null) {
// We're not being shown or there's nothing to show
return null;
}
View view = createView(inflater, container);
if( view != null ) {
swipeRefreshLayout = getSwipeRefreshLayout();
if( swipeRefreshLayout != null ) {
swipeRefreshLayout.setOnRefreshListener(this);
}
}
return view;
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setHasOptionsMenu(true);
}
2015-11-13 11:33:58 +01:00
@Override
public void onStart() {
super.onStart();
serviceConnection = SyncUtils.connectToLibrarySyncService(getActivity(), this);
}
@Override
public void onResume() {
bus.register(this);
super.onResume();
}
@Override
public void onPause() {
bus.unregister(this);
super.onPause();
}
2015-11-13 11:33:58 +01:00
@Override
public void onStop() {
super.onStop();
SyncUtils.disconnectFromLibrarySyncService(getActivity(), serviceConnection);
}
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.refresh_item, menu);
super.onCreateOptionsMenu(menu, inflater);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_refresh:
onRefresh();
}
return super.onOptionsItemSelected(item);
}
@Optional
@OnClick(R.id.download)
public void onDownloadClicked(View v) {
boolean hasStoragePermission =
ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
if (!hasStoragePermission) {
requestPermissions(new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE},
Utils.PERMISSION_REQUEST_WRITE_STORAGE);
return;
}
if (Settings.allowedDownloadNetworkTypes(getActivity()) != 0) {
onDownload();
} else {
Toast.makeText(getActivity(), R.string.no_connection_type_selected, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
switch (requestCode) {
case Utils.PERMISSION_REQUEST_WRITE_STORAGE:
// If request is cancelled, the result arrays are empty.
if ((grantResults.length > 0) &&
(grantResults[0] == PackageManager.PERMISSION_GRANTED)) {
onDownloadClicked(null);
} else {
Toast.makeText(getActivity(), R.string.write_storage_permission_denied, Toast.LENGTH_SHORT)
.show();
}
break;
}
}
protected void startSync(boolean silentRefresh) {
this.silentRefresh = silentRefresh;
LogUtils.LOGD(TAG, "Starting syc. Silent? " + silentRefresh);
if (getHostInfo() != null) {
if ((swipeRefreshLayout != null) && (!silentRefresh)) {
UIUtils.showRefreshAnimation(swipeRefreshLayout);
}
// Start the syncing process
Intent syncIntent = new Intent(this.getActivity(), LibrarySyncService.class);
if (syncType != null) {
syncIntent.putExtra(syncType, true);
}
String syncID = getSyncID();
int itemId = getSyncItemID();
if ((syncID != null) && (itemId != -1)) {
syncIntent.putExtra(syncID, itemId);
}
Bundle syncExtras = new Bundle();
syncExtras.putBoolean(LibrarySyncService.SILENT_SYNC, silentRefresh);
syncIntent.putExtra(LibrarySyncService.SYNC_EXTRAS, syncExtras);
getActivity().startService(syncIntent);
} else {
if (swipeRefreshLayout != null) {
swipeRefreshLayout.setRefreshing(false);
}
Toast.makeText(getActivity(), R.string.no_xbmc_configured, Toast.LENGTH_SHORT)
.show();
}
}
/**
* Swipe refresh layout callback
*/
/** {@inheritDoc} */
@Override
public void onRefresh () {
startSync(false);
}
/**
* Event bus post. Called when the syncing process ended
*
* @param event Refreshes data
*/
public void onEventMainThread(MediaSyncEvent event) {
if ((syncType == null) || (! event.syncType.equals(syncType)))
return;
boolean silentSync = false;
if (event.syncExtras != null) {
silentSync = event.syncExtras.getBoolean(LibrarySyncService.SILENT_SYNC, false);
}
if( swipeRefreshLayout != null ) {
swipeRefreshLayout.setRefreshing(false);
}
onSyncProcessEnded(event);
if (event.status == MediaSyncEvent.STATUS_SUCCESS) {
if (!silentSync) {
Toast.makeText(getActivity(),
R.string.sync_successful, Toast.LENGTH_SHORT)
.show();
}
} else if (!silentSync) {
String msg = (event.errorCode == ApiException.API_ERROR) ?
String.format(getString(R.string.error_while_syncing), event.errorMessage) :
getString(R.string.unable_to_connect_to_xbmc);
Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show();
}
}
@Override
public void onServiceConnected(LibrarySyncService librarySyncService) {
if (syncType == null)
return;
if (!silentRefresh &&
(swipeRefreshLayout != null) &&
SyncUtils.isLibrarySyncing(librarySyncService,
HostManager.getInstance(getActivity()).getHostInfo(),
syncType)) {
LogUtils.LOGD(TAG, "Showing refresh animation");
UIUtils.showRefreshAnimation(swipeRefreshLayout);
}
}
/**
* Called when sync process for type set through {@link #getSyncType()} ends
* @param event
*/
abstract protected void onSyncProcessEnded(MediaSyncEvent event);
protected HostManager getHostManager() {
return hostManager;
}
protected HostInfo getHostInfo() {
return hostInfo;
}
}