Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/nextcloud/news-android.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Development <david-dev@live.de>2014-07-04 13:34:27 +0400
committerDavid Development <david-dev@live.de>2014-07-04 13:34:27 +0400
commitc706b6c42e5966c96a29e753b852f01c7395017b (patch)
tree19f6176ce5d29a788acdfd5a44941ced59b9c851 /News-Android-App
parent99a5b5dd417f03b749a5dedb5ad3f52403491a13 (diff)
parentaa786bc5e68b53cbc0a57c75dcb3a61a4e5e390a (diff)
update podcast support
Diffstat (limited to 'News-Android-App')
-rw-r--r--News-Android-App/News-Android-App-News-Android-App.iml17
-rw-r--r--News-Android-App/build.gradle11
-rw-r--r--News-Android-App/src/main/AndroidManifest.xml12
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ListView/PodcastArrayAdapter.java92
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/MenuUtilsSherlockFragmentActivity.java220
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailActivity.java36
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailFragment.java5
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java7
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java49
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PodcastFragment.java159
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PodcastSherlockFragmentActivity.java467
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SettingsActivity.java3
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/AsyncTask_DownloadImages.java9
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/IKeyValuePair.java65
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/KeyValuePair.java154
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/MapUtils.java145
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/URLParams.java198
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnection.java18
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/NewPodcastPlaybackListener.java7
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/RegisterVideoOutput.java18
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/StartDownloadPodcast.java10
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/UpdatePodcastStatusEvent.java12
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/VideoDoubleClicked.java7
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/AlphaAnimator.java53
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/DatabaseUtils.java2
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java6
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FileUtils.java46
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageHandler.java33
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/JavaYoutubeDownloader.java381
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/SizeAnimator.java40
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/PodcastItem.java19
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/DownloadItemsToCache.java4
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/owncloud/InsertItemIntoDatabase.java19
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java7
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastDownloadService.java240
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastPlaybackService.java171
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/OnPinchListener.java44
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java11
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastSlidingUpPanelLayout.java4
-rw-r--r--News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/ZoomableRelativeLayout.java242
-rw-r--r--News-Android-App/src/main/res/drawable-hdpi/av_download.pngbin0 -> 1328 bytes
-rw-r--r--News-Android-App/src/main/res/drawable-xhdpi/av_download.pngbin0 -> 1473 bytes
-rw-r--r--News-Android-App/src/main/res/layout/activity_news_detail.xml15
-rw-r--r--News-Android-App/src/main/res/layout/activity_newsreader.xml80
-rw-r--r--News-Android-App/src/main/res/layout/activity_newsreader_twopane.xml93
-rw-r--r--News-Android-App/src/main/res/layout/fragment_news_detail.xml6
-rw-r--r--News-Android-App/src/main/res/layout/fragment_podcast.xml23
-rw-r--r--News-Android-App/src/main/res/layout/podcast_audio_row.xml30
-rw-r--r--News-Android-App/src/main/res/layout/podcast_row.xml105
-rw-r--r--News-Android-App/src/main/res/values-el/strings.xml3
-rw-r--r--News-Android-App/src/main/res/values-en-rGB/strings.xml3
-rw-r--r--News-Android-App/src/main/res/values-et-rEE/strings.xml1
-rw-r--r--News-Android-App/src/main/res/values-eu/strings.xml39
-rw-r--r--News-Android-App/src/main/res/values-fr/strings.xml2
-rw-r--r--News-Android-App/src/main/res/values-gl/strings.xml1
-rw-r--r--News-Android-App/src/main/res/values-nb-rNO/strings.xml3
-rw-r--r--News-Android-App/src/main/res/values-nl/strings.xml3
-rw-r--r--News-Android-App/src/main/res/values-pl/strings.xml3
-rw-r--r--News-Android-App/src/main/res/values-pt-rBR/strings.xml3
-rw-r--r--News-Android-App/src/main/res/values-ro/strings.xml8
-rw-r--r--News-Android-App/src/main/res/values-sl/strings.xml3
-rw-r--r--News-Android-App/src/main/res/values-sv/strings.xml2
-rw-r--r--News-Android-App/src/main/res/values-tr/strings.xml3
-rw-r--r--News-Android-App/src/main/res/values/dimens.xml15
-rw-r--r--News-Android-App/src/main/res/values/strings.xml2
-rw-r--r--News-Android-App/src/main/res/values/styles.xml1
66 files changed, 3142 insertions, 348 deletions
diff --git a/News-Android-App/News-Android-App-News-Android-App.iml b/News-Android-App/News-Android-App-News-Android-App.iml
index e1e9fa87..d1f37a0f 100644
--- a/News-Android-App/News-Android-App-News-Android-App.iml
+++ b/News-Android-App/News-Android-App-News-Android-App.iml
@@ -58,20 +58,21 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
</content>
- <orderEntry type="jdk" jdkName="Android API 19 Platform" jdkType="Android SDK" />
+ <orderEntry type="jdk" jdkName="Android API 20 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
- <orderEntry type="library" exported="" name="eventbus-2.2.1" level="project" />
- <orderEntry type="library" exported="" name="library-1.0.3" level="project" />
+ <orderEntry type="library" exported="" name="library-2.0.0" level="project" />
<orderEntry type="library" exported="" name="gson-2.2.4" level="project" />
+ <orderEntry type="library" exported="" name="jsoup-1.7.2" level="project" />
+ <orderEntry type="library" exported="" name="support-v4-20.0.0" level="project" />
+ <orderEntry type="library" exported="" name="actionbarsherlock-4.4.0" level="project" />
+ <orderEntry type="library" exported="" name="picasso-2.3.1" level="project" />
+ <orderEntry type="library" exported="" name="eventbus-2.2.1" level="project" />
<orderEntry type="library" exported="" name="extra-abs-0.9.9" level="project" />
- <orderEntry type="library" exported="" name="support-v4-19.1.0" level="project" />
- <orderEntry type="library" exported="" name="library-0.9.9" level="project" />
<orderEntry type="library" exported="" name="butterknife-5.1.1" level="project" />
- <orderEntry type="library" exported="" name="jsoup-1.7.2" level="project" />
+ <orderEntry type="library" exported="" name="library-0.9.9" level="project" />
+ <orderEntry type="library" exported="" name="support-annotations-20.0.0" level="project" />
<orderEntry type="library" exported="" name="library-0.4.0" level="project" />
<orderEntry type="library" exported="" name="library-2.4.0" level="project" />
- <orderEntry type="library" exported="" name="actionbarsherlock-4.4.0" level="project" />
- <orderEntry type="library" exported="" name="picasso-2.3.1" level="project" />
<orderEntry type="module" module-name="ownCloud-Account-Importer" exported="" />
<orderEntry type="module" module-name="MessageBar" exported="" />
<orderEntry type="module" module-name="ChangeLogLibrary" exported="" />
diff --git a/News-Android-App/build.gradle b/News-Android-App/build.gradle
index 8620b2f6..296700da 100644
--- a/News-Android-App/build.gradle
+++ b/News-Android-App/build.gradle
@@ -1,4 +1,4 @@
-apply plugin: 'android'
+apply plugin: 'com.android.application'
android {
@@ -25,6 +25,13 @@ android {
}
}
+configurations.all {
+ resolutionStrategy {
+ force 'com.android.support:support-v4:20.+'
+ }
+}
+
+
dependencies {
// You must install or update the Google Repository through the SDK manager to use this dependency.
// The Google Repository (separate from the corresponding library) can be found in the Extras category.
@@ -34,7 +41,7 @@ dependencies {
compile project(':Changeloglib:ChangeLogLibrary')
compile project(':MessageBar')
compile project(':ownCloud-Account-Importer')
- compile 'com.android.support:support-v4:19.0.+'
+ compile 'com.android.support:support-v4:20.+'
compile 'com.jakewharton:butterknife:5.1.+'
compile 'com.squareup.picasso:picasso:2.3.1@jar'
compile 'com.actionbarsherlock:actionbarsherlock:4.4.0@aar'
diff --git a/News-Android-App/src/main/AndroidManifest.xml b/News-Android-App/src/main/AndroidManifest.xml
index 938c7844..cbc4b811 100644
--- a/News-Android-App/src/main/AndroidManifest.xml
+++ b/News-Android-App/src/main/AndroidManifest.xml
@@ -19,10 +19,12 @@
android:debuggable="false"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
- android:theme="@style/AppTheme" >
+ android:theme="@style/AppTheme">
<activity
android:name=".NewsReaderListActivity"
- android:label="@string/app_name" >
+ android:label="@string/app_name"
+ android:configChanges="orientation|keyboardHidden"
+ android:launchMode="singleTop">
<!-- android:configChanges="keyboardHidden|orientation|screenSize" -->
<intent-filter>
@@ -124,10 +126,14 @@
</activity>
<service
- android:name=".services.AudioPodcastService"
+ android:name=".services.PodcastPlaybackService"
android:enabled="true"
android:exported="true" >
</service>
+ <service
+ android:name=".services.PodcastDownloadService"
+ android:exported="false" >
+ </service>
</application>
</manifest> \ No newline at end of file
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ListView/PodcastArrayAdapter.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ListView/PodcastArrayAdapter.java
index 0e0c2fea..5c073094 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ListView/PodcastArrayAdapter.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ListView/PodcastArrayAdapter.java
@@ -5,40 +5,46 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
+import android.widget.FrameLayout;
+import android.widget.ProgressBar;
import android.widget.TextView;
+import android.widget.Toast;
import butterknife.ButterKnife;
import butterknife.InjectView;
import de.greenrobot.event.EventBus;
import de.luhmer.owncloudnewsreader.R;
import de.luhmer.owncloudnewsreader.events.podcast.AudioPodcastClicked;
-import de.luhmer.owncloudnewsreader.model.AudioPodcastItem;
+import de.luhmer.owncloudnewsreader.events.podcast.StartDownloadPodcast;
+import de.luhmer.owncloudnewsreader.helper.JavaYoutubeDownloader;
+import de.luhmer.owncloudnewsreader.model.PodcastItem;
/**
* Created by David on 21.06.2014.
*/
-public class PodcastArrayAdapter extends ArrayAdapter<AudioPodcastItem> {
+public class PodcastArrayAdapter extends ArrayAdapter<PodcastItem> {
LayoutInflater inflater;
EventBus eventBus;
- public PodcastArrayAdapter(Context context, AudioPodcastItem[] values) {
- super(context, R.layout.podcast_audio_row, values);
+ public PodcastArrayAdapter(Context context, PodcastItem[] values) {
+ super(context, R.layout.podcast_row, values);
inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
eventBus = EventBus.getDefault();
+ //eventBus.register(this);
}
@Override
public View getView(final int position, View view, ViewGroup parent) {
- ViewHolder holder;
+ final ViewHolder holder;
if (view != null) {
holder = (ViewHolder) view.getTag();
} else {
- view = inflater.inflate(R.layout.podcast_audio_row, parent, false);
+ view = inflater.inflate(R.layout.podcast_row, parent, false);
holder = new ViewHolder(view);
view.setTag(holder);
}
- AudioPodcastItem podcastItem = getItem(position);
+ final PodcastItem podcastItem = getItem(position);
holder.tvTitle.setText(podcastItem.title);
holder.tvBody.setText(podcastItem.mimeType);
@@ -46,19 +52,85 @@ public class PodcastArrayAdapter extends ArrayAdapter<AudioPodcastItem> {
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
- AudioPodcastClicked audioPodcastClicked = new AudioPodcastClicked();
- audioPodcastClicked.position = position;
- eventBus.post(audioPodcastClicked);
+ playPodcast(position);
}
});
+
+ holder.flDownloadPodcast.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ holder.flDownloadPodcast.setVisibility(View.GONE);
+
+ Toast.makeText(getContext(), "Starting download.. Please wait", Toast.LENGTH_SHORT).show();
+
+ eventBus.post(new StartDownloadPodcast() {{ podcast = podcastItem; }});
+ }
+ });
+
+ holder.flPlayPodcast.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View view) {
+ playPodcast(position);
+ }
+ });
+
+
+ holder.pbDownloadPodcast.setProgress(podcastItem.downloadProgress);
+ if(podcastItem.downloadProgress >= 0)
+ holder.tvDownloadPodcastProgress.setText(podcastItem.downloadProgress + "%");
+ else
+ holder.tvDownloadPodcastProgress.setText(null);
+
+
+ if(podcastItem.link.contains(JavaYoutubeDownloader.host)) {
+ if(podcastItem.downloadProgress == PodcastItem.DOWNLOAD_NOT_STARTED) {
+ holder.flPlayPodcast.setVisibility(View.GONE);//Youtube Videos can't be streamed
+ holder.flDownloadPodcast.setVisibility(View.VISIBLE);
+ } else {
+ holder.flPlayPodcast.setVisibility(View.VISIBLE);
+ holder.flDownloadPodcast.setVisibility(View.GONE);
+ }
+ } else if(podcastItem.downloadProgress == PodcastItem.DOWNLOAD_NOT_STARTED) {
+ holder.flDownloadPodcast.setVisibility(View.VISIBLE);
+ } else {
+ holder.flDownloadPodcast.setVisibility(View.GONE);
+ }
+
+ /*
+ File podcastFile = new File(PodcastDownloadService.getUrlToPodcastFile(getContext(), podcastItem.link, true));
+ File podcastFileCache = new File(PodcastDownloadService.getUrlToPodcastFile(getContext(), podcastItem.link, true) + ".download");
+ if(podcastFile.exists()) {
+ holder.flDownloadPodcast.setVisibility(View.GONE);
+ }
+ else if(podcastFileCache.exists()) {
+ holder.flDownloadPodcast.setVisibility(View.GONE);
+ }
+ else
+ holder.flDownloadPodcast.setVisibility(View.VISIBLE);
+ */
+
return view;
}
+ private void playPodcast(int position) {
+ AudioPodcastClicked audioPodcastClicked = new AudioPodcastClicked();
+ audioPodcastClicked.position = position;
+ eventBus.post(audioPodcastClicked);
+ }
+
+
+
static class ViewHolder {
@InjectView(R.id.tv_title) TextView tvTitle;
@InjectView(R.id.tv_body) TextView tvBody;
+ @InjectView(R.id.fl_downloadPodcastWrapper) FrameLayout flDownloadPodcast;
+ @InjectView(R.id.fl_PlayPodcastWrapper) FrameLayout flPlayPodcast;
+ @InjectView(R.id.pbDownloadPodcast) ProgressBar pbDownloadPodcast;
+ @InjectView(R.id.tvDownloadPodcastProgress) TextView tvDownloadPodcastProgress;
+
+
public ViewHolder(View view) {
ButterKnife.inject(this, view);
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/MenuUtilsSherlockFragmentActivity.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/MenuUtilsSherlockFragmentActivity.java
new file mode 100644
index 00000000..cafc0807
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/MenuUtilsSherlockFragmentActivity.java
@@ -0,0 +1,220 @@
+/**
+ * Android ownCloud News
+ *
+ * @author David Luhmer
+ * @copyright 2013 David Luhmer david-dev@live.de
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+package de.luhmer.owncloudnewsreader;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+import android.preference.PreferenceManager;
+import android.support.v4.app.FragmentActivity;
+import android.util.Log;
+import android.widget.Toast;
+
+import com.actionbarsherlock.app.SherlockDialogFragment;
+import com.actionbarsherlock.view.Menu;
+import com.actionbarsherlock.view.MenuInflater;
+import com.actionbarsherlock.view.MenuItem;
+
+import de.luhmer.owncloudnewsreader.database.DatabaseConnection;
+import de.luhmer.owncloudnewsreader.reader.IReader;
+import de.luhmer.owncloudnewsreader.reader.OnAsyncTaskCompletedListener;
+import de.luhmer.owncloudnewsreader.reader.owncloud.API;
+import de.luhmer.owncloudnewsreader.reader.owncloud.OwnCloud_Reader;
+
+public class MenuUtilsSherlockFragmentActivity extends PodcastSherlockFragmentActivity {
+
+ protected static final String TAG = "MenuUtils";
+
+ static FragmentActivity activity;
+
+ static MenuItem menuItemSettings;
+ static MenuItem menuItemLogin;
+ static MenuItem menuItemStartImageCaching;
+
+
+ private static MenuItem menuItemUpdater;
+ private static MenuItem menuItemDownloadMoreItems;
+
+ static IReader _Reader;
+
+ /**
+ * @return the menuItemUpdater
+ */
+ public static MenuItem getMenuItemUpdater() {
+ return menuItemUpdater;
+ }
+
+
+ /**
+ * @return the menuItemDownloadMoreItems
+ */
+ public static MenuItem getMenuItemDownloadMoreItems() {
+ return menuItemDownloadMoreItems;
+ }
+
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB)
+ @Override
+ protected void onResume() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ invalidateOptionsMenu();
+ }
+ super.onResume();
+ }
+
+
+ public static void onCreateOptionsMenu(Menu menu, MenuInflater inflater, FragmentActivity act) {
+ inflater.inflate(R.menu.news_reader, menu);
+ activity = act;
+
+ menuItemSettings = menu.findItem(R.id.action_settings);
+ menuItemLogin = menu.findItem(R.id.action_login);
+ menuItemStartImageCaching = menu.findItem(R.id.menu_StartImageCaching);
+
+ menuItemUpdater = menu.findItem(R.id.menu_update);
+ //menuItemMarkAllAsRead = menu.findItem(R.id.menu_markAllAsRead);
+ menuItemDownloadMoreItems = menu.findItem(R.id.menu_downloadMoreItems);
+
+
+ //menuItemMarkAllAsRead.setEnabled(false);
+ menuItemDownloadMoreItems.setEnabled(false);
+
+ NewsReaderDetailFragment ndf = ((NewsReaderDetailFragment) activity.getSupportFragmentManager().findFragmentById(R.id.content_frame));
+ if(ndf != null)
+ ndf.UpdateMenuItemsState();
+ }
+
+ public static boolean onOptionsItemSelected(MenuItem item, FragmentActivity activity) {
+ switch (item.getItemId()) {
+ case R.id.menu_About_Changelog:
+ SherlockDialogFragment dialog = new VersionInfoDialogFragment();
+ dialog.show(activity.getSupportFragmentManager(), "VersionChangelogDialogFragment");
+ return true;
+
+ case R.id.menu_markAllAsRead:
+ NewsReaderDetailFragment ndf = ((NewsReaderDetailFragment) activity.getSupportFragmentManager().findFragmentById(R.id.content_frame));
+ if(ndf != null)
+ {
+ /*
+ for(int i = 0; i < ndf.getListView().getChildCount(); i++)
+ {
+ View view = ndf.getListView().getChildAt(i);
+ CheckBox cb = (CheckBox) view.findViewById(R.id.cb_lv_item_read);
+ if(!cb.isChecked())
+ cb.setChecked(true);
+ }
+ */
+
+ DatabaseConnection dbConn = new DatabaseConnection(activity);
+ try {
+ /*
+ //dbConn.markAllItemsAsRead(ndf.getDatabaseIdsOfItems());
+ List<Integer> items = new ArrayList<Integer>();
+
+
+ Cursor cursor = ncla.getLvAdapter().getCursor();
+ cursor.moveToFirst();
+ do {
+ items.add(Integer.parseInt(cursor.getString(0)));
+ } while (cursor.moveToNext());
+ dbConn.markAllItemsAsRead(items);
+ */
+ dbConn.markAllItemsAsReadForCurrentView();
+ } finally {
+ dbConn.closeDatabase();
+ }
+ ndf.UpdateCursor();
+
+ //If tablet view is enabled update the listview as well
+ if(activity instanceof NewsReaderListActivity)
+ ((NewsReaderListActivity) activity).updateAdapter();
+
+ }
+ return true;
+
+ case R.id.menu_downloadMoreItems:
+ DownloadMoreItems();
+ return true;
+ }
+ return false;
+ }
+
+ private static void DownloadMoreItems()
+ {
+ /*
+ DatabaseConnection dbConn = new DatabaseConnection(activity);
+ int count = dbConn.getCountFeedsForFolder(SubscriptionExpandableListAdapter.ALL_ITEMS, false);
+ if(count >= Constants.maxItemsCount)
+ {
+ String text = activity.getString(R.string.max_items_count_reached);
+ text = text.replace("XX", "" + Constants.maxItemsCount);
+ new AlertDialog.Builder(activity)
+ .setTitle(activity.getString(R.string.empty_view_header))
+ .setMessage(text)
+ .setPositiveButton(activity.getString(android.R.string.ok), new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog,int id) {
+
+ }
+ })
+ .create()
+ .show();
+ //Toast.makeText(activity, text, Toast.LENGTH_LONG).show();
+ }
+ else
+ {*/
+ String username = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext()).getString("edt_username", "");
+ String password = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext()).getString("edt_password", "");
+
+ if(username != null) {
+ _Reader = new OwnCloud_Reader();
+ ((OwnCloud_Reader)_Reader).Start_AsyncTask_GetVersion(Constants.TaskID_GetVersion, activity, onAsyncTaskGetVersionFinished, username, password);
+
+ Toast.makeText(activity, activity.getString(R.string.toast_GettingMoreItems), Toast.LENGTH_SHORT).show();
+ }
+ //}
+ }
+
+ static OnAsyncTaskCompletedListener onAsyncTaskGetVersionFinished = new OnAsyncTaskCompletedListener() {
+
+ @Override
+ public void onAsyncTaskCompleted(int task_id, Object task_result) {
+ if(_Reader != null) {
+ String appVersion = task_result.toString();
+ API api = API.GetRightApiForVersion(appVersion, activity);
+ ((OwnCloud_Reader) _Reader).setApi(api);
+
+ NewsReaderDetailFragment ndf = ((NewsReaderDetailFragment) activity.getSupportFragmentManager().findFragmentById(R.id.content_frame));
+ _Reader.Start_AsyncTask_GetOldItems(Constants.TaskID_GetItems, activity, onAsyncTaskComplete, ndf.getIdFeed(), ndf.getIdFolder());
+ }
+ }
+ };
+
+ static OnAsyncTaskCompletedListener onAsyncTaskComplete = new OnAsyncTaskCompletedListener() {
+ @Override
+ public void onAsyncTaskCompleted(int task_id, Object task_result) {
+ NewsReaderDetailFragment ndf = ((NewsReaderDetailFragment) activity.getSupportFragmentManager().findFragmentById(R.id.content_frame));
+ if(ndf != null)
+ ndf.UpdateCursor();
+
+ Log.d(TAG, "Finished Download extra items..");
+ }
+ };
+} \ No newline at end of file
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailActivity.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailActivity.java
index 33b8083a..0c00036f 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailActivity.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailActivity.java
@@ -38,9 +38,7 @@ import android.support.v4.view.ViewPager.OnPageChangeListener;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.KeyEvent;
-import android.view.View;
-import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
@@ -53,10 +51,9 @@ import de.luhmer.owncloudnewsreader.helper.PostDelayHandler;
import de.luhmer.owncloudnewsreader.helper.ThemeChooser;
import de.luhmer.owncloudnewsreader.reader.IReader;
import de.luhmer.owncloudnewsreader.reader.owncloud.OwnCloud_Reader;
-import de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout;
import de.luhmer.owncloudnewsreader.widget.WidgetProvider;
-public class NewsDetailActivity extends SherlockFragmentActivity {
+public class NewsDetailActivity extends PodcastSherlockFragmentActivity {
/**
* The {@link android.support.v4.view.PagerAdapter} that will provide
@@ -67,7 +64,6 @@ public class NewsDetailActivity extends SherlockFragmentActivity {
* {@link android.support.v4.app.FragmentStatePagerAdapter}.
*/
SectionsPagerAdapter mSectionsPagerAdapter;
- public PodcastSlidingUpPanelLayout sliding_layout;
/**
* The {@link ViewPager} that will host the section contents.
@@ -75,8 +71,6 @@ public class NewsDetailActivity extends SherlockFragmentActivity {
public ViewPager mViewPager;
private int currentPosition;
- PodcastFragment podcastFragment;
-
PostDelayHandler pDelayHandler;
MenuItem menuItem_Starred;
@@ -100,9 +94,6 @@ public class NewsDetailActivity extends SherlockFragmentActivity {
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
- sliding_layout = (PodcastSlidingUpPanelLayout) findViewById(R.id.sliding_layout);
- UpdatePodcastView();
-
pDelayHandler = new PostDelayHandler(this);
_Reader = new OwnCloud_Reader();
@@ -184,20 +175,9 @@ public class NewsDetailActivity extends SherlockFragmentActivity {
public void onPageScrollStateChanged(int arg0) {
}
});
- }
-
- public void UpdatePodcastView() {
- SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
- if(mPrefs.getBoolean(SettingsActivity.CB_ENABLE_PODCASTS_STRING, false)) {
- podcastFragment = PodcastFragment.newInstance(null, null);
- getSupportFragmentManager().beginTransaction()
- .replace(R.id.podcast_frame, podcastFragment)
- .commit();
- } else {
- sliding_layout.getChildAt(1).setVisibility(View.GONE);
- }
}
+
@Override
protected void onDestroy() {
if(dbConn != null)
@@ -349,10 +329,8 @@ public class NewsDetailActivity extends SherlockFragmentActivity {
@Override
public void onBackPressed() {
- if(podcastFragment != null && sliding_layout.isPanelExpanded()) {
- if (!podcastFragment.onBackPressed())
- sliding_layout.collapsePanel();
- } else
+ if(handlePodcastBackPressed());
+ else
super.onBackPressed();
}
@@ -383,10 +361,8 @@ public class NewsDetailActivity extends SherlockFragmentActivity {
switch (item.getItemId()) {
case android.R.id.home:
- if(podcastFragment != null && sliding_layout.isPanelExpanded()) {
- if (!podcastFragment.onBackPressed())
- sliding_layout.collapsePanel();
- } else {
+ if(handlePodcastBackPressed());
+ else {
super.onBackPressed();
}
break;
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailFragment.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailFragment.java
index 89085df6..1fabb950 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailFragment.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailFragment.java
@@ -46,6 +46,7 @@ import java.util.Date;
import java.util.List;
import de.luhmer.owncloudnewsreader.database.DatabaseConnection;
+import de.luhmer.owncloudnewsreader.helper.FileUtils;
import de.luhmer.owncloudnewsreader.helper.FontHelper;
import de.luhmer.owncloudnewsreader.helper.ImageHandler;
import de.luhmer.owncloudnewsreader.helper.ThemeChooser;
@@ -264,7 +265,7 @@ public class NewsDetailFragment extends SherlockFragment {
favIconUrl = favIconCursor.getString(favIconCursor.getColumnIndex(DatabaseConnection.SUBSCRIPTION_FAVICON_URL));
if(favIconUrl != null)
{
- File file = ImageHandler.getFullPathOfCacheFile(favIconUrl, ImageHandler.getPathFavIcons(context));
+ File file = ImageHandler.getFullPathOfCacheFile(favIconUrl, FileUtils.getPathFavIcons(context));
if(file.isFile())
favIconUrl = "file://" + file.getAbsolutePath().toString();
}
@@ -356,7 +357,7 @@ public class NewsDetailFragment extends SherlockFragment {
link = link.trim();
try
{
- File file = ImageHandler.getFullPathOfCacheFile(link, ImageHandler.getPathImageCache(context));
+ File file = ImageHandler.getFullPathOfCacheFile(link, FileUtils.getPathImageCache(context));
if(file.isFile())
text = text.replace(link, "file://" + file.getAbsolutePath().toString());
}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java
index 8fda9002..361abab7 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java
@@ -52,7 +52,6 @@ import de.luhmer.owncloudnewsreader.cursor.NewsListCursorAdapter;
import de.luhmer.owncloudnewsreader.cursor.SimpleCursorLoader;
import de.luhmer.owncloudnewsreader.database.DatabaseConnection;
import de.luhmer.owncloudnewsreader.database.DatabaseConnection.SORT_DIRECTION;
-import de.luhmer.owncloudnewsreader.helper.MenuUtilsSherlockFragmentActivity;
/**
* A fragment representing a single NewsReader detail screen. This fragment is
@@ -140,7 +139,7 @@ public class NewsReaderDetailFragment extends SherlockListFragment implements IO
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- //setRetainInstance(true);
+ setRetainInstance(true);
//dbConn = new DatabaseConnection(getActivity());
@@ -173,7 +172,7 @@ public class NewsReaderDetailFragment extends SherlockListFragment implements IO
}
- public void UpdateMenuItemsState()
+ public void UpdateMenuItemsState()
{
if(MenuUtilsSherlockFragmentActivity.getMenuItemDownloadMoreItems() != null)
{
@@ -225,6 +224,8 @@ public class NewsReaderDetailFragment extends SherlockListFragment implements IO
+
+
private RobotoCheckBox getCheckBoxAtPosition(int pos, AbsListView viewLV)
{
ListView lv = (ListView) viewLV;
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java
index 5d539889..e006a116 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java
@@ -49,11 +49,9 @@ import de.luhmer.owncloudnewsreader.cursor.NewsListCursorAdapter;
import de.luhmer.owncloudnewsreader.database.DatabaseConnection;
import de.luhmer.owncloudnewsreader.helper.DatabaseUtils;
import de.luhmer.owncloudnewsreader.helper.ImageHandler;
-import de.luhmer.owncloudnewsreader.helper.MenuUtilsSherlockFragmentActivity;
import de.luhmer.owncloudnewsreader.helper.ThemeChooser;
import de.luhmer.owncloudnewsreader.services.DownloadImagesService;
import de.luhmer.owncloudnewsreader.services.IOwnCloudSyncService;
-import de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout;
import uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock.PullToRefreshLayout;
/**
@@ -70,8 +68,8 @@ import uk.co.senab.actionbarpulltorefresh.extras.actionbarsherlock.PullToRefresh
public class NewsReaderListActivity extends MenuUtilsSherlockFragmentActivity implements
NewsReaderListFragment.Callbacks {
- private SlidingPaneLayout mSlidingLayout;
- public PodcastSlidingUpPanelLayout sliding_layout;
+ SlidingPaneLayout mSlidingLayout;
+
//static final String TAG = "NewsReaderListActivity";
//ActionBarDrawerToggle drawerToggle;
@@ -82,7 +80,6 @@ public class NewsReaderListActivity extends MenuUtilsSherlockFragmentActivity im
public static final String ITEM_ID = "ITEM_ID";
public static final String TITEL = "TITEL";
- PodcastFragment podcastFragment;
//boolean isSlideUpPanelExpanded = false;
@TargetApi(Build.VERSION_CODES.HONEYCOMB)
@@ -131,14 +128,6 @@ public class NewsReaderListActivity extends MenuUtilsSherlockFragmentActivity im
-
-
-
- sliding_layout = (PodcastSlidingUpPanelLayout) findViewById(R.id.sliding_layout);
- UpdatePodcastView();
-
-
-
mSlidingLayout = (SlidingPaneLayout) findViewById(R.id.sliding_pane);
mSlidingLayout.setParallaxDistance(280);
@@ -152,6 +141,8 @@ public class NewsReaderListActivity extends MenuUtilsSherlockFragmentActivity im
@Override
public void onPanelOpened(View arg0) {
+ togglePodcastVideoViewAnimation();
+
updateAdapter();
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
@@ -162,6 +153,8 @@ public class NewsReaderListActivity extends MenuUtilsSherlockFragmentActivity im
@Override
public void onPanelClosed(View arg0) {
+ togglePodcastVideoViewAnimation();
+
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
@@ -222,25 +215,6 @@ public class NewsReaderListActivity extends MenuUtilsSherlockFragmentActivity im
private static final String OPTIONAL_FOLDER_ID ="OPTIONAL_FOLDER_ID";
- public void UpdatePodcastView() {
-
- if(podcastFragment != null) {
- getSupportFragmentManager().beginTransaction().remove(podcastFragment).commitAllowingStateLoss();
- }
-
-
- SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
- if(mPrefs.getBoolean(SettingsActivity.CB_ENABLE_PODCASTS_STRING, false)) {
- podcastFragment = PodcastFragment.newInstance(null, null);
- getSupportFragmentManager().beginTransaction()
- .replace(R.id.podcast_frame, podcastFragment)
- .commitAllowingStateLoss();
- } else {
- sliding_layout.getChildAt(1).setVisibility(View.GONE);
- podcastFragment = null;
- }
- }
-
/* (non-Javadoc)
* @see com.actionbarsherlock.app.SherlockFragmentActivity#onSaveInstanceState(android.os.Bundle)
*/
@@ -481,10 +455,8 @@ public class NewsReaderListActivity extends MenuUtilsSherlockFragmentActivity im
@Override
public void onBackPressed() {
- if(podcastFragment != null && sliding_layout.isPanelExpanded()) {
- if (!podcastFragment.onBackPressed())
- sliding_layout.collapsePanel();
- } else if(mSlidingLayout.isOpen())
+ if(handlePodcastBackPressed());
+ else if(mSlidingLayout.isOpen())
super.onBackPressed();
else
mSlidingLayout.openPane();
@@ -502,10 +474,7 @@ public class NewsReaderListActivity extends MenuUtilsSherlockFragmentActivity im
switch (item.getItemId()) {
case android.R.id.home:
- if(podcastFragment != null && sliding_layout.isPanelExpanded()) {
- if (!podcastFragment.onBackPressed())
- sliding_layout.collapsePanel();
- }
+ if(handlePodcastBackPressed());
else if(!mSlidingLayout.isOpen())
mSlidingLayout.openPane();
return true;
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PodcastFragment.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PodcastFragment.java
index dacf89f4..9d5d1c96 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PodcastFragment.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PodcastFragment.java
@@ -24,6 +24,8 @@ import android.widget.ViewSwitcher;
import com.actionbarsherlock.app.SherlockFragment;
import com.sothree.slidinguppanel.SlidingUpPanelLayout;
+import java.io.File;
+import java.util.Arrays;
import java.util.List;
import butterknife.ButterKnife;
@@ -34,14 +36,16 @@ import de.luhmer.owncloudnewsreader.ListView.PodcastArrayAdapter;
import de.luhmer.owncloudnewsreader.ListView.PodcastFeedArrayAdapter;
import de.luhmer.owncloudnewsreader.database.DatabaseConnection;
import de.luhmer.owncloudnewsreader.events.podcast.AudioPodcastClicked;
-import de.luhmer.owncloudnewsreader.events.podcast.OpenAudioPodcastEvent;
+import de.luhmer.owncloudnewsreader.events.podcast.OpenPodcastEvent;
import de.luhmer.owncloudnewsreader.events.podcast.PodcastFeedClicked;
+import de.luhmer.owncloudnewsreader.events.podcast.StartDownloadPodcast;
import de.luhmer.owncloudnewsreader.events.podcast.TogglePlayerStateEvent;
import de.luhmer.owncloudnewsreader.events.podcast.UpdatePodcastStatusEvent;
import de.luhmer.owncloudnewsreader.events.podcast.WindPodcast;
-import de.luhmer.owncloudnewsreader.model.AudioPodcastItem;
import de.luhmer.owncloudnewsreader.model.PodcastFeedItem;
-import de.luhmer.owncloudnewsreader.services.AudioPodcastService;
+import de.luhmer.owncloudnewsreader.model.PodcastItem;
+import de.luhmer.owncloudnewsreader.services.PodcastDownloadService;
+import de.luhmer.owncloudnewsreader.services.PodcastPlaybackService;
import de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout;
@@ -106,6 +110,9 @@ public class PodcastFragment extends SherlockFragment {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
+
+ setRetainInstance(true);
+
if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
@@ -114,7 +121,10 @@ public class PodcastFragment extends SherlockFragment {
eventBus = EventBus.getDefault();
- getActivity().startService(new Intent(getActivity(), AudioPodcastService.class));
+ // when initialize
+ //getActivity().registerReceiver(downloadCompleteReceiver, downloadCompleteIntentFilter);
+
+ getActivity().startService(new Intent(getActivity(), PodcastPlaybackService.class));
}
@@ -133,29 +143,135 @@ public class PodcastFragment extends SherlockFragment {
super.onPause();
}
+ public void onEventMainThread(StartDownloadPodcast podcast) {
+ PodcastDownloadService.startPodcastDownload(getActivity(), podcast.podcast);//, new DownloadReceiver(new Handler(), new WeakReference<ProgressBar>(holder.pbDownloadPodcast)));
+ }
+
+ /*
+ private class DownloadReceiver extends ResultReceiver {
+ WeakReference<ProgressBar> progressBar;
+
+ public DownloadReceiver(Handler handler, WeakReference<ProgressBar> progressBar) {
+ super(handler);
+
+ this.progressBar = progressBar;
+ }
+
+ @Override
+ protected void onReceiveResult(int resultCode, Bundle resultData) {
+ super.onReceiveResult(resultCode, resultData);
+ if (resultCode == PodcastDownloadService.UPDATE_PROGRESS) {
+
+ if(progressBar.get() != null) {
+ int progress = resultData.getInt("progress");
+ progressBar.get().setIndeterminate(false);
+ progressBar.get().setProgress(progress);
+ if (progress == 100) {
+ progressBar.get().setVisibility(View.GONE);
+ }
+ }
+ }
+ }
+ }
+ */
+
+ public static String[] VIDEO_FORMATS = { "youtube" };
+
public void onEventMainThread(AudioPodcastClicked podcast) {
- final AudioPodcastItem audioPodcast = audioPodcasts.get(podcast.position);
+ final PodcastItem audioPodcast = audioPodcasts.get(podcast.position);
tvTitle.setText(audioPodcast.title);
- eventBus.post(new OpenAudioPodcastEvent() {{ pathToFile = audioPodcast.link; mediaTitle = audioPodcast.title; }});
+ boolean isVideo = Arrays.asList(VIDEO_FORMATS).contains(audioPodcast.mimeType);
- Toast.makeText(getActivity(), "Starting podcast.. please wait", Toast.LENGTH_SHORT).show();
+ if(audioPodcast.mimeType.equals("youtube") && !audioPodcast.offlineCached)
+ Toast.makeText(getActivity(), "Cannot stream from youtube. Please download the video first.", Toast.LENGTH_SHORT).show();
+ else {
+ File file = new File(PodcastDownloadService.getUrlToPodcastFile(getActivity(), audioPodcast.link, true));
+ if(file.exists())
+ audioPodcast.link = file.getAbsolutePath();
+ else
+ Toast.makeText(getActivity(), "Starting podcast.. please wait", Toast.LENGTH_SHORT).show(); //Only show if we need to stream the file
+
+ eventBus.post(new OpenPodcastEvent(audioPodcast.link, audioPodcast.title, isVideo));
+ }
}
public void onEventMainThread(PodcastFeedClicked podcast) {
DatabaseConnection dbConn = new DatabaseConnection(getActivity());
- audioPodcasts = dbConn.getListOfAudioPodcastsForFeed(feedsWithAudioPodcasts.get(podcast.position).itemId);
+ audioPodcasts = dbConn.getListOfAudioPodcastsForFeed(getActivity(), feedsWithAudioPodcasts.get(podcast.position).itemId);
+
+
+ for(int i = 0; i < audioPodcasts.size(); i++) {
+ PodcastItem podcastItem = audioPodcasts.get(i);
+
+ File podcastFile = new File(PodcastDownloadService.getUrlToPodcastFile(getActivity(), podcastItem.link, false));
+ File podcastFileCache = new File(PodcastDownloadService.getUrlToPodcastFile(getActivity(), podcastItem.link, false) + ".download");
+ if(podcastFile.exists())
+ podcastItem.downloadProgress = PodcastItem.DOWNLOAD_COMPLETED;
+ else if(podcastFileCache.exists())
+ podcastItem.downloadProgress = 0;
+ else
+ podcastItem.downloadProgress = PodcastItem.DOWNLOAD_NOT_STARTED;
+ }
- PodcastArrayAdapter mArrayAdapter = new PodcastArrayAdapter(getActivity(), audioPodcasts.toArray(new AudioPodcastItem[audioPodcasts.size()]));
+ PodcastArrayAdapter mArrayAdapter = new PodcastArrayAdapter(getActivity(), audioPodcasts.toArray(new PodcastItem[audioPodcasts.size()]));
if (podcastTitleGrid != null) {
podcastTitleGrid.setAdapter(mArrayAdapter);
}
podcastTitleGrid.setVisibility(View.VISIBLE);
podcastFeedList.setVisibility(View.GONE);
+
+
+ //eventBus.post(new OpenAudioPodcastEvent(FileUtils.getPathPodcasts(getActivity()) + "/Foxes.mp4", "Test Video"));
+ //eventBus.post(new OpenPodcastEvent(FileUtils.getPathPodcasts(getActivity()) + "/Aneta.mp4", "Test Video", true));
+
+ //PodcastDownloadService.startPodcastDownload(getActivity(), new PodcastItem("5", "Blaa", "http://www.youtube.com/v/wtLJPvx7-ys?version=3&f=playlists&app=youtube_gdata", "youtube"));
+ }
+
+
+ public void onEventMainThread(PodcastDownloadService.DownloadProgressUpdate downloadProgress) {
+ PodcastArrayAdapter podcastArrayAdapter = (PodcastArrayAdapter) podcastTitleGrid.getAdapter();
+
+ for(int i = 0; i < podcastTitleGrid.getCount(); i++) {
+ if(podcastArrayAdapter.getItem(i).link.equals(downloadProgress.podcast.link)) {
+
+ if(podcastArrayAdapter.getItem(i).downloadProgress != downloadProgress.podcast.downloadProgress) { //If Progress changed
+ PodcastItem pItem = podcastArrayAdapter.getItem(i);
+
+ if (downloadProgress.podcast.downloadProgress == 100) {
+ pItem.downloadProgress = PodcastItem.DOWNLOAD_COMPLETED;
+ File file = new File(PodcastDownloadService.getUrlToPodcastFile(getActivity(), pItem.link, false));
+ pItem.offlineCached = file.exists();
+ } else
+ pItem.downloadProgress = downloadProgress.podcast.downloadProgress;
+ podcastTitleGrid.invalidateViews();
+ }
+
+ return;
+ /*
+ View v = podcastTitleGrid.getChildAt(i -
+ podcastTitleGrid.getFirstVisiblePosition());
+ ((ProgressBar)v.findViewById(R.id.pbDownloadPodcast)).setProgress(downloadProgress.podcast.downloadProgress);
+
+ //podcastArrayAdapter.notifyDataSetChanged();
+ return;
+ */
+ }
+ }
}
+ /*
+ private String downloadCompleteIntentName = DownloadManager.ACTION_DOWNLOAD_COMPLETE;
+ private IntentFilter downloadCompleteIntentFilter = new IntentFilter(downloadCompleteIntentName);
+ private BroadcastReceiver downloadCompleteReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ ((ArrayAdapter) podcastTitleGrid.getAdapter()).notifyDataSetChanged();
+ }
+ };
+ */
int lastDrawableId;
@@ -207,7 +323,7 @@ public class PodcastFragment extends SherlockFragment {
}
}
- List<AudioPodcastItem> audioPodcasts;
+ List<PodcastItem> audioPodcasts;
List<PodcastFeedItem> feedsWithAudioPodcasts;
@InjectView(R.id.btn_playPausePodcast) ImageButton btnPlayPausePodcast;
@@ -274,15 +390,14 @@ public class PodcastFragment extends SherlockFragment {
ButterKnife.inject(this, view);
- if(getActivity() instanceof NewsReaderListActivity) {
- sliding_layout = ((NewsReaderListActivity) getActivity()).sliding_layout;
- } else if(getActivity() instanceof NewsDetailActivity) {
- sliding_layout = ((NewsDetailActivity) getActivity()).sliding_layout;
+ if(getActivity() instanceof PodcastSherlockFragmentActivity) {
+ sliding_layout = ((PodcastSherlockFragmentActivity) getActivity()).getSlidingLayout();
}
if(sliding_layout != null) {
sliding_layout.setSlideableView(rlPodcast);
sliding_layout.setDragView(rlPodcastHeader);
+ //sliding_layout.setEnableDragViewTouchEvents(true);
sliding_layout.setPanelSlideListener(onPanelSlideListener);
}
@@ -365,6 +480,9 @@ public class PodcastFragment extends SherlockFragment {
if(sliding_layout != null)
sliding_layout.setDragView(rlPodcastHeader);
viewSwitcherProgress.setDisplayedChild(0);
+
+ if(getActivity() instanceof PodcastSherlockFragmentActivity)
+ ((PodcastSherlockFragmentActivity)getActivity()).togglePodcastVideoViewAnimation();
}
@Override
@@ -372,6 +490,9 @@ public class PodcastFragment extends SherlockFragment {
if(sliding_layout != null)
sliding_layout.setDragView(viewSwitcherProgress);
viewSwitcherProgress.setDisplayedChild(1);
+
+ if(getActivity() instanceof PodcastSherlockFragmentActivity)
+ ((PodcastSherlockFragmentActivity)getActivity()).togglePodcastVideoViewAnimation();
}
@Override
@@ -389,7 +510,7 @@ public class PodcastFragment extends SherlockFragment {
private SeekBar.OnSeekBarChangeListener onSeekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
@Override
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
- Log.d(TAG, "onProgressChanged");
+ //Log.d(TAG, "onProgressChanged");
}
@Override
@@ -400,8 +521,12 @@ public class PodcastFragment extends SherlockFragment {
@Override
public void onStopTrackingTouch(final SeekBar seekBar) {
- eventBus.post(new WindPodcast() {{ toPositionInPercent = seekBar.getProgress(); }});
- blockSeekbarUpdate = false;
+ if(hasTitleInCache) {
+ eventBus.post(new WindPodcast() {{
+ toPositionInPercent = seekBar.getProgress();
+ }});
+ blockSeekbarUpdate = false;
+ }
Log.d(TAG, "onStopTrackingTouch");
}
};
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PodcastSherlockFragmentActivity.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PodcastSherlockFragmentActivity.java
new file mode 100644
index 00000000..4a5c9dcd
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PodcastSherlockFragmentActivity.java
@@ -0,0 +1,467 @@
+package de.luhmer.owncloudnewsreader;
+
+import android.animation.Animator;
+import android.annotation.TargetApi;
+import android.content.SharedPreferences;
+import android.content.res.Resources;
+import android.os.Build;
+import android.os.Bundle;
+import android.preference.PreferenceManager;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.animation.Animation;
+import android.widget.LinearLayout;
+
+import com.actionbarsherlock.app.SherlockFragmentActivity;
+
+import butterknife.ButterKnife;
+import butterknife.InjectView;
+import de.greenrobot.event.EventBus;
+import de.luhmer.owncloudnewsreader.ListView.SubscriptionExpandableListAdapter;
+import de.luhmer.owncloudnewsreader.events.podcast.RegisterVideoOutput;
+import de.luhmer.owncloudnewsreader.events.podcast.UpdatePodcastStatusEvent;
+import de.luhmer.owncloudnewsreader.events.podcast.VideoDoubleClicked;
+import de.luhmer.owncloudnewsreader.helper.SizeAnimator;
+import de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout;
+import de.luhmer.owncloudnewsreader.view.ZoomableRelativeLayout;
+
+/**
+ * Created by David on 29.06.2014.
+ */
+public class PodcastSherlockFragmentActivity extends SherlockFragmentActivity {
+
+ private static final String TAG = "PodcastSherlockFragmentActivity";
+ private PodcastFragment podcastFragment;
+
+ private EventBus eventBus;
+
+ @InjectView(R.id.videoPodcastSurfaceWrapper) ZoomableRelativeLayout rlVideoPodcastSurfaceWrapper;
+ //@InjectView(R.id.videoPodcastSurface) SurfaceView surfaceView;
+ @InjectView(R.id.sliding_layout) PodcastSlidingUpPanelLayout sliding_layout;
+
+ int appHeight;
+ int appWidth;
+
+ @Override
+ protected void onPostCreate(Bundle savedInstanceState) {
+ eventBus = EventBus.getDefault();
+
+ ButterKnife.inject(this);
+
+ //surfaceView.getHolder().setFixedSize(surfaceView.getWidth(), 10);
+ //surfaceView.setVisibility(View.GONE);
+ //rlVideoPodcastSurfaceWrapper.setVisibility(View.GONE);
+
+ rlVideoPodcastSurfaceWrapper.setVisibility(View.INVISIBLE);
+
+ UpdatePodcastView();
+
+ /*
+ new OrientationEventListener(this, SensorManager.SENSOR_DELAY_UI) {
+ @Override
+ public void onOrientationChanged(int i) {
+ sliding_layout.collapsePanel();
+ }
+ };
+ */
+
+ super.onPostCreate(savedInstanceState);
+ }
+
+
+
+
+ @Override
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ if(hasWindowFocus) {
+ int currentOrientation = getResources().getConfiguration().orientation;
+ if (currentOrientation != lastOrientation) {
+ sliding_layout.collapsePanel();
+ lastOrientation = currentOrientation;
+ }
+ }
+
+ //rlVideoPodcastSurfaceWrapper.setVisibility(View.GONE);
+ //isVideoViewVisible = false;
+
+ super.onWindowFocusChanged(hasWindowFocus);
+ }
+
+
+
+ int lastOrientation = -1;
+ @Override
+ protected void onResume() {
+ eventBus.register(this);
+
+ //eventBus.post(new RegisterVideoOutput(surfaceView));
+ super.onResume();
+ }
+
+ @Override
+ protected void onPause() {
+ Log.d(TAG, "onPause");
+ eventBus.unregister(this);
+ eventBus.post(new RegisterVideoOutput(null, null));
+
+ super.onPause();
+ }
+
+
+ //TODO sliding_layout.collapsePanel();// --> on Orientation change!!!!
+
+ /*
+ @Override
+ public void onConfigurationChanged(Configuration newConfig) {
+ sliding_layout.collapsePanel();
+ super.onConfigurationChanged(newConfig);
+ }
+ */
+
+ public PodcastSlidingUpPanelLayout getSlidingLayout() {
+ return sliding_layout;
+ }
+
+ public boolean handlePodcastBackPressed() {
+ if(podcastFragment != null && sliding_layout.isPanelExpanded()) {
+ if (!podcastFragment.onBackPressed())
+ sliding_layout.collapsePanel();
+ return true;
+ }
+ return false;
+ }
+
+ public void UpdatePodcastView() {
+
+ if(podcastFragment != null) {
+ getSupportFragmentManager().beginTransaction().remove(podcastFragment).commitAllowingStateLoss();
+ }
+
+
+ SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
+ if(mPrefs.getBoolean(SettingsActivity.CB_ENABLE_PODCASTS_STRING, false)) {
+ podcastFragment = PodcastFragment.newInstance(null, null);
+ getSupportFragmentManager().beginTransaction()
+ .replace(R.id.podcast_frame, podcastFragment)
+ .commitAllowingStateLoss();
+ } else {
+ sliding_layout.getChildAt(1).setVisibility(View.GONE);
+ podcastFragment = null;
+ }
+ }
+
+
+ boolean surfaceInitalized = false;
+ boolean isVideoViewVisible = true;
+ public void onEventMainThread(UpdatePodcastStatusEvent podcast) {
+
+ if (podcast.isVideoFile()) {
+ if((!isVideoViewVisible || !surfaceInitalized) && rlVideoPodcastSurfaceWrapper.isPositionReady()) {
+ surfaceInitalized = true;
+ isVideoViewVisible = true;
+
+ rlVideoPodcastSurfaceWrapper.setVisibility(View.VISIBLE);
+ //AlphaAnimator.AnimateVisibilityChange(rlVideoPodcastSurfaceWrapper, View.VISIBLE);
+
+
+ SurfaceView surfaceView = new SurfaceView(this);
+ surfaceView.setLayoutParams(new LinearLayout.LayoutParams(
+ LinearLayout.LayoutParams.MATCH_PARENT,
+ LinearLayout.LayoutParams.MATCH_PARENT));
+ rlVideoPodcastSurfaceWrapper.addView(surfaceView);
+
+ eventBus.post(new RegisterVideoOutput(surfaceView, rlVideoPodcastSurfaceWrapper));
+ togglePodcastVideoViewAnimation();
+ }
+ } else if(isVideoViewVisible) {
+ isVideoViewVisible = false;
+
+ eventBus.post(new RegisterVideoOutput(null, null));
+
+ rlVideoPodcastSurfaceWrapper.setVisibility(View.GONE);
+ //AlphaAnimator.AnimateVisibilityChange(rlVideoPodcastSurfaceWrapper, View.GONE);
+
+ rlVideoPodcastSurfaceWrapper.removeAllViews();
+ }
+
+ }
+
+ private static final int animationTime = 300; //Milliseconds
+ float oldScaleFactor = 1;
+ boolean isFullScreen = false;
+ float scaleFactor = 1;
+ boolean useAnimation = false;
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
+ public void onEventMainThread(VideoDoubleClicked doubleClicked) {
+ appHeight = getWindow().getDecorView().findViewById(android.R.id.content).getHeight();
+ appWidth = getWindow().getDecorView().findViewById(android.R.id.content).getWidth();
+
+ if(isFullScreen) {
+ rlVideoPodcastSurfaceWrapper.setDisableScale(false);
+ togglePodcastVideoViewAnimation();
+ } else {
+ rlVideoPodcastSurfaceWrapper.setDisableScale(true);
+ oldScaleFactor = rlVideoPodcastSurfaceWrapper.getScaleFactor();
+
+ final View view = rlVideoPodcastSurfaceWrapper;
+
+ final float oldHeight = view.getLayoutParams().height;
+ final float oldWidth = view.getLayoutParams().width;
+
+
+ //view.setPivotX(oldWidth/2);
+ //view.setPivotY(oldHeight/2);
+
+ /*
+ Display display = getWindowManager().getDefaultDisplay();
+ float width = display.getWidth(); // deprecated
+ float height = display.getHeight(); // deprecated
+ */
+
+
+
+ scaleFactor = appWidth / (float) view.getWidth();
+ float newHeightTemp = oldHeight * scaleFactor;
+ float newWidthTemp = oldWidth * scaleFactor;
+
+ //view.animate().scaleX(scaleFactor).scaleY(scaleFactor).setDuration(100);
+ //scaleView(view, 1f, scaleFactor, 1f, scaleFactor);
+
+
+ if(newHeightTemp > appHeight) { //Could happen on Tablets or in Landscape Mode
+ scaleFactor = appHeight / (float) view.getHeight();
+ newHeightTemp = oldHeight * scaleFactor;
+ newWidthTemp = oldWidth * scaleFactor;
+ }
+
+
+ final float newHeight = newHeightTemp;
+ final float newWidth = newWidthTemp;
+ float newXPosition = rlVideoPodcastSurfaceWrapper.getVideoXPosition() + (int) getResources().getDimension(R.dimen.activity_vertical_margin);// (appWidth / 2) + dipToPx(10);
+ float newYPosition = (appHeight/2) + ((newHeight/2) - oldHeight);
+
+ useAnimation = true;
+
+ view.animate().x(newXPosition).y(newYPosition).setDuration(animationTime).setListener(new Animator.AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animator) {
+
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ if(useAnimation) {
+ view.startAnimation(new SizeAnimator(view, newWidth, newHeight, oldWidth, oldHeight, animationTime).sizeAnimator);
+ }
+ useAnimation = false;
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animator) {
+
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animator) {
+
+ }
+ });
+
+
+ //rlVideoPodcastSurfaceWrapper.animate().scaleX(scaleFactor).scaleY(scaleFactor).x(newXPosition).y(newYPosition).setDuration(500).setListener(onResizeListener);
+ //surfaceView.animate().scaleX(scaleFactor).scaleY(scaleFactor).setDuration(500);
+
+ //oldScaleFactor
+ //scaleFactor = dipToPx(oldWidth) / newWidth;
+ //scaleFactor = (1/oldScaleFactor) * dipToPx(oldWidth) / newWidth;
+ //scaleFactor = oldWidth / newWidth;
+
+ scaleFactor = 1/scaleFactor;
+ }
+
+ isFullScreen = !isFullScreen;
+ }
+
+
+
+ Animator.AnimatorListener onResizeListener = new Animator.AnimatorListener() {
+ @Override
+ public void onAnimationStart(Animator animator) {
+
+ }
+
+ @Override
+ public void onAnimationEnd(Animator animator) {
+ View view = rlVideoPodcastSurfaceWrapper;
+
+
+ int height = (int) (view.getHeight() * view.getScaleY());
+ int width = (int) (view.getWidth() * view.getScaleX());
+
+ //view.setPivotX(width/2);
+ //view.setPivotY(height/2);
+
+ view.setScaleX(1);
+ view.setScaleY(1);
+ view.getLayoutParams().height = height;
+ view.getLayoutParams().width = width;
+ view.setLayoutParams(view.getLayoutParams());
+
+ //view.setX(0);
+
+ /*
+ surfaceView.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT));
+ surfaceView.forceLayout();
+ surfaceView.requestLayout();
+ surfaceView.invalidate();
+ surfaceView.requestLayout();
+ surfaceView.forceLayout();
+ */
+ }
+
+ @Override
+ public void onAnimationCancel(Animator animator) {
+
+ }
+
+ @Override
+ public void onAnimationRepeat(Animator animator) {
+
+ }
+ };
+
+
+ /*
+ public void scaleView(View v, float startX, float startY, float endX, float endY) {
+ Animation anim = new ScaleAnimation(
+ startX, endX, // Start and end values for the X axis scaling
+ startY, endY, // Start and end values for the Y axis scaling
+ Animation.RELATIVE_TO_SELF, 0f, // Pivot point of X scaling
+ Animation.RELATIVE_TO_SELF, 0f); // Pivot point of Y scaling
+ anim.setFillAfter(true); // Needed to keep the result of the animation
+ anim.setDuration(500);
+ v.startAnimation(anim);
+ }
+ */
+
+ /*
+ public void onEvent(PodcastPlaybackService.PodcastPlaybackServiceStarted serviceStarted) {
+
+ }
+ */
+
+
+ public void togglePodcastVideoViewAnimation() {
+ boolean isLeftSliderOpen = false;
+
+ if(this instanceof NewsReaderListActivity) {
+ isLeftSliderOpen = ((NewsReaderListActivity) this).mSlidingLayout.isOpen();
+ }
+
+ boolean isTabletView = SubscriptionExpandableListAdapter.isTwoPane(this);
+
+ int podcastMediaControlHeightDp = pxToDp((int) getResources().getDimension(R.dimen.podcast_media_control_height));
+
+ if(isTabletView && sliding_layout.isPanelExpanded()) { //On Tablets
+ animateToPosition(podcastMediaControlHeightDp);
+ } else if(!isTabletView && isLeftSliderOpen)
+ animateToPosition(0);
+ else if(sliding_layout.isPanelExpanded()) {
+ animateToPosition(podcastMediaControlHeightDp);
+ } else {
+ animateToPosition(64);
+ }
+ }
+
+ public static int pxToDp(int px)
+ {
+ return (int) (px / Resources.getSystem().getDisplayMetrics().density);
+ }
+
+ @TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
+ public void animateToPosition(final int yPosition) {
+ appHeight = getWindow().getDecorView().findViewById(android.R.id.content).getHeight();
+ appWidth = getWindow().getDecorView().findViewById(android.R.id.content).getWidth();
+
+ final View view = rlVideoPodcastSurfaceWrapper; //surfaceView
+
+ /*
+ viewToMove.getLayoutParams().height *= scaleFactor;
+ viewToMove.getLayoutParams().width *= scaleFactor;
+ viewToMove.setLayoutParams(viewToMove.getLayoutParams());
+ */
+ //float newHeight = viewToMove.getLayoutParams().height * scaleFactor;
+ //float newWidth = viewToMove.getLayoutParams().width * scaleFactor;
+ //viewToMove.animate().scaleX(scaleFactor).scaleY(scaleFactor).setDuration(100);
+ //viewToMove.startAnimation(new SizeAnimator(viewToMove, newWidth, newHeight, 500).sizeAnimator);
+
+ //scaleView(viewToMove, scaleFactor, 1f, scaleFactor, 1f);
+
+
+
+
+
+
+
+
+
+
+ if(scaleFactor != 1) {
+ int oldHeight = view.getLayoutParams().height;
+ int oldWidth = view.getLayoutParams().width;
+ int newHeight = view.getLayoutParams().height *= scaleFactor;
+ int newWidth = view.getLayoutParams().width *= scaleFactor;
+ scaleFactor = 1;
+
+ Animation animator = new SizeAnimator(view, newWidth, newHeight, oldWidth, oldHeight, animationTime).sizeAnimator;
+ animator.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {
+
+ }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ animateToPosition(yPosition);
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+
+ }
+ });
+ view.startAnimation(animator);
+ } else {
+ int absoluteYPosition = appHeight - view.getHeight() - (int) getResources().getDimension(R.dimen.activity_vertical_margin) - (int) dipToPx(yPosition);
+
+ //int animationpos = 500;
+ float xPosition = rlVideoPodcastSurfaceWrapper.getVideoXPosition();
+ view.animate().x(xPosition).y(absoluteYPosition).setDuration(animationTime);
+ //scaleX(scaleFactor).scaleY(scaleFactor)
+ }
+
+
+
+
+ /*
+ int height = (int)(view.getHeight() * scaleFactor);
+ int width = (int)(view.getWidth() * scaleFactor);
+ view.setScaleX(oldScaleFactor);
+ view.setScaleY(oldScaleFactor);
+ view.getLayoutParams().height = height;
+ view.getLayoutParams().width = width;
+*/
+ oldScaleFactor = 1;
+
+
+ }
+
+
+ float dipToPx(float dip) {
+ Resources r = getResources();
+ float px = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dip, r.getDisplayMetrics());
+ return px;
+ }
+}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SettingsActivity.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SettingsActivity.java
index 13fd686e..d611fe66 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SettingsActivity.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SettingsActivity.java
@@ -51,6 +51,7 @@ import java.text.DecimalFormat;
import java.util.List;
import de.luhmer.owncloudnewsreader.database.DatabaseConnection;
+import de.luhmer.owncloudnewsreader.helper.FileUtils;
import de.luhmer.owncloudnewsreader.helper.ImageHandler;
import de.luhmer.owncloudnewsreader.helper.PostDelayHandler;
import de.luhmer.owncloudnewsreader.helper.ThemeChooser;
@@ -597,7 +598,7 @@ public class SettingsActivity extends SherlockPreferenceActivity {
protected Void doInBackground(Void... params) {
try
{
- getFolderSize(new File(ImageHandler.getPath(_mActivity)));
+ getFolderSize(new File(FileUtils.getPath(_mActivity)));
mSize = dcmFormat.format(size / 1024d / 1024d) + "MB";
mCount = String.valueOf(count) + " Files";
}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/AsyncTask_DownloadImages.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/AsyncTask_DownloadImages.java
index 9b373731..a4457b48 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/AsyncTask_DownloadImages.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/AsyncTask_DownloadImages.java
@@ -26,25 +26,26 @@ import android.os.AsyncTask;
import java.util.List;
+import de.luhmer.owncloudnewsreader.helper.FileUtils;
import de.luhmer.owncloudnewsreader.helper.ImageHandler;
public class AsyncTask_DownloadImages extends AsyncTask<Void, Void, Void>{
String text;
Context context;
-
+
public AsyncTask_DownloadImages(String text, Context context) {
this.text = text;
this.context = context;
}
-
+
@Override
protected Void doInBackground(Void... params) {
if(text != null)
{
List<String> links = ImageHandler.getImageLinksFromText(text);
-
+
for(String link : links)
- new GetImageAsyncTask(link, null, 999, ImageHandler.getPathImageCache(context), context, null).execute();
+ new GetImageAsyncTask(link, null, 999, FileUtils.getPathImageCache(context), context, null).execute();
}
return null;
}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/IKeyValuePair.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/IKeyValuePair.java
new file mode 100644
index 00000000..6c930681
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/IKeyValuePair.java
@@ -0,0 +1,65 @@
+package de.luhmer.owncloudnewsreader.collections;
+
+/*
+
+ * Copyright (c) 2008, 2009 by Xuggle Incorporated. All rights reserved.
+
+ *
+
+ * This file is part of Xuggler.
+
+ *
+
+ * You can redistribute Xuggler and/or modify it under the terms of the GNU
+
+ * Affero General Public License as published by the Free Software
+
+ * Foundation, either version 3 of the License, or (at your option) any
+
+ * later version.
+
+ *
+
+ * Xuggler 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 Affero General Public
+
+ * License for more details.
+
+ *
+
+ * You should have received a copy of the GNU Affero General Public License
+
+ * along with Xuggler. If not, see <http://www.gnu.org/licenses/>.
+
+ */
+
+
+/**
+ * A key-alue pair.
+ *
+ * @author aclarke
+ *
+ */
+public interface IKeyValuePair
+
+{
+
+ /**
+ * Get the key.
+ *
+ * @return the key.
+ */
+ public String getKey();
+
+
+ /**
+ * Get the value.
+ *
+ * @return the value.
+ */
+ public String getValue();
+
+}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/KeyValuePair.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/KeyValuePair.java
new file mode 100644
index 00000000..33397f26
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/KeyValuePair.java
@@ -0,0 +1,154 @@
+package de.luhmer.owncloudnewsreader.collections;
+
+/*
+
+ * Copyright (c) 2008, 2009 by Xuggle Incorporated. All rights reserved.
+
+ *
+
+ * This file is part of Xuggler.
+
+ *
+
+ * You can redistribute Xuggler and/or modify it under the terms of the GNU
+
+ * Affero General Public License as published by the Free Software
+
+ * Foundation, either version 3 of the License, or (at your option) any
+
+ * later version.
+
+ *
+
+ * Xuggler 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 Affero General Public
+
+ * License for more details.
+
+ *
+
+ * You should have received a copy of the GNU Affero General Public License
+
+ * along with Xuggler. If not, see <http://www.gnu.org/licenses/>.
+
+ */
+
+
+import java.util.Map.Entry;
+
+
+/**
+
+ * An implementation of {@link IKeyValuePair} with immutable keys
+
+ * but resettable values.
+
+ *
+
+ * @author aclarke
+
+ *
+
+ */
+
+public class KeyValuePair implements IKeyValuePair, Entry<String, String>
+
+{
+
+ private final String mKey;
+
+ private String mValue;
+
+
+
+ /**
+
+ * Creates a new key-value pair.
+
+ *
+
+ * @param key
+
+ * The key; may not be null.
+
+ * @param value
+
+ * The value; may be null.
+
+ * @throws IllegalArgumentException
+
+ * if <code>name==null</code>.
+
+ */
+
+ public KeyValuePair(final String key, final String value)
+
+ {
+
+ if (key == null)
+
+ throw new IllegalArgumentException("must have non null name");
+
+ mKey = key;
+
+ mValue = value;
+
+ }
+
+
+
+ /**
+
+ * {@inheritDoc}
+
+ */
+
+ public String getKey()
+
+ {
+
+ return mKey;
+
+ }
+
+
+
+ /**
+
+ * {@inheritDoc}
+
+ */
+
+ public String getValue()
+
+ {
+
+ return mValue;
+
+ }
+
+
+
+ /**
+
+ * {@inheritDoc}
+
+ */
+
+ public String setValue(String value)
+
+ {
+
+ final String retval = mValue;
+
+ mValue = value;
+
+ return retval;
+
+ }
+
+}
+
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/MapUtils.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/MapUtils.java
new file mode 100644
index 00000000..ef05d858
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/MapUtils.java
@@ -0,0 +1,145 @@
+package de.luhmer.owncloudnewsreader.collections;
+
+/*
+ * Copyright (c) 2008, 2009 by Xuggle Incorporated. All rights reserved.
+ *
+ * This file is part of Xuggler.
+ *
+ * You can redistribute Xuggler and/or modify it under the terms of the GNU
+ * Affero General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Xuggler 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 Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Xuggler. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * Some useful utilities for mapping lists to maps and back.
+ * @author aclarke
+ *
+ */
+public class MapUtils
+{
+ /**
+ * How {@link MapUtils#listToMap(List, Map, ListToMapMode)} treats
+ * duplicate values in the input list.
+ * @author aclarke
+ *
+ */
+ public enum ListToMapMode
+ {
+ /**
+ * Last item in list always wins.
+ */
+ LAST_WINS,
+ /**
+ * First item in list always wins.
+ */
+ FIRST_WINS,
+ }
+
+ /**
+ * Converts a list of key-value pairs into a {@link Map}, with either
+ * the first duplicate key always being inserted, or the last duplicate key
+ * always being inserted.
+ *
+ * @param list
+ * The list of name value pairs to convert.
+ * @param mapToFill
+ * The map to fill. This method will empty the list first.
+ * @param mode
+ * How duplicate values in <code>list</code> should be treated.
+ */
+ public static void listToMap(final List<? extends IKeyValuePair> list,
+ final Map<String, String> mapToFill, final ListToMapMode mode)
+ {
+ if (list == null)
+ throw new IllegalArgumentException();
+ if (mapToFill == null)
+ throw new IllegalArgumentException();
+ mapToFill.clear();
+ for (IKeyValuePair pair : list)
+ {
+ if (pair != null)
+ {
+ if (mode == ListToMapMode.FIRST_WINS)
+ {
+ if (mapToFill.containsKey(pair.getKey()))
+ continue;
+ }
+ mapToFill.put(pair.getKey(), pair.getValue());
+ }
+ }
+ }
+
+ /**
+ * Converts a list of key-value pairs into a {@link Map}, with either
+ * the first duplicate key always being inserted, or the last duplicate key
+ * always being inserted.
+ *
+ * @param list
+ * The list of name value pairs to convert.
+ * @param mode
+ * How duplicate values in <code>list</code> should be treated.
+ * @return a new {@link Map} of key-value pairs.
+ */
+ public static Map<String, String> listToMap(
+ final List<? extends IKeyValuePair> list, final ListToMapMode mode)
+ {
+ final Map<String, String> retval = new HashMap<String, String>();
+ listToMap(list, retval, mode);
+ return retval;
+ }
+
+ /**
+ * Converts a map into a {@link List} of {@link IKeyValuePair} objects.
+ * @param map Map to convert.
+ * @param listToFill List to fill. The list has {@link List#clear()} called
+ * before any items are added.
+ */
+ public static void mapToList(final Map<String, String> map, final List<IKeyValuePair> listToFill)
+ {
+ if (map == null || listToFill == null)
+ throw new IllegalArgumentException();
+ final Set<Entry<String, String>> entries = map.entrySet();
+ for(Entry<String, String> entry : entries)
+ {
+ final String name = entry.getKey();
+ final String value = entry.getValue();
+ if (name == null)
+ continue;
+ IKeyValuePair pair = new KeyValuePair(name, value);
+ listToFill.add(pair);
+ }
+ }
+ /**
+ * Converts a map into a {@link List} of {@link IKeyValuePair} objects, and
+ * returns the new list.
+ * @param map Map to convert.
+ * @return A new {@link List} containing all key-value pairs in <code>map</code>
+ * as {@link IKeyValuePair} objects.
+ */
+ public static List<IKeyValuePair> mapToList(final Map<String, String> map)
+ {
+ final List<IKeyValuePair> retval = new ArrayList<IKeyValuePair>();
+ mapToList(map, retval);
+ return retval;
+ }
+
+
+}
+
+
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/URLParams.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/URLParams.java
new file mode 100644
index 00000000..cb681f22
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/collections/URLParams.java
@@ -0,0 +1,198 @@
+package de.luhmer.owncloudnewsreader.collections;
+
+/*
+ * Copyright (c) 2008, 2009 by Xuggle Incorporated. All rights reserved.
+ *
+ * This file is part of Xuggler.
+ *
+ * You can redistribute Xuggler and/or modify it under the terms of the GNU
+ * Affero General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any
+ * later version.
+ *
+ * Xuggler 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 Affero General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with Xuggler. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Utilities for generating and parsing URL parameter strings
+ *
+ * @author aclarke
+ *
+ */
+public class URLParams
+{
+ /**
+ * Parse the query string, placing the results in <code>paramsToFill</code>,
+ * assuming UTF-8 encoding.
+ *
+ * @param queryString
+ * The query string (without leading "?").
+ * @param paramsToFill
+ * A list to add entries to; the list is not emptied first by this
+ * method. Entries are added in the order they are found.
+ * @see URLParams#parseQueryString(String, List, String)
+ */
+ public static void parseQueryString(final String queryString,
+ final List<KeyValuePair> paramsToFill)
+ {
+ try
+ {
+ parseQueryString(queryString, paramsToFill, "UTF-8");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new RuntimeException("What? UTF-8 isn't a valid encoding", e);
+ }
+ }
+
+ /**
+ * Parse the query string, and return as a new list, assuming UTF-8 encoding.
+ *
+ * @param queryString
+ * The query string (without leading "?").
+ * @return A new list with all entries included, in the order they were found.
+ * @see URLParams#parseQueryString(String, List, String)
+ */
+ public static List<KeyValuePair> parseQueryString(final String queryString)
+ {
+ final List<KeyValuePair> retval = new ArrayList<KeyValuePair>();
+ parseQueryString(queryString, retval);
+ return retval;
+ }
+
+ /**
+ * Parse the query string, and return as a new list, assuming UTF-8 encoding.
+ *
+ * @param queryString
+ * The query string (without leading "?").
+ * @param encoding
+ * An encoding (e.g. "UTF-8") to decode parameters as.
+ * @return A new list with all entries included, in the order they were found.
+ * @throws UnsupportedEncodingException
+ * If the <code>encode</code> specified is not supported.
+ * @see URLParams#parseQueryString(String, List, String)
+ */
+ public static List<KeyValuePair> parseQueryString(final String queryString,
+ final String encoding) throws UnsupportedEncodingException
+ {
+ final List<KeyValuePair> retval = new ArrayList<KeyValuePair>();
+ parseQueryString(queryString, retval, encoding);
+ return retval;
+ }
+
+ /**
+ * Parse the query string, placing the results in <code>paramsToFill</code>.
+ *
+ * @param queryString
+ * The query string (without leading "?").
+ * @param parametersToFill
+ * A list to add entries to; the list is not emptied first by this
+ * method. Entries are added in the order they are found.
+ * @param encoding
+ * An encoding (e.g. "UTF-8") to decode parameters as.
+ * @throws UnsupportedEncodingException
+ * If the <code>encode</code> specified is not supported.
+ * @see URLParams#parseQueryString(String, List, String)
+ */
+ public static void parseQueryString(final String queryString,
+ final List<KeyValuePair> parametersToFill, final String encoding)
+ throws UnsupportedEncodingException
+ {
+ final String params[] = queryString.split("&");
+ for (String param : params)
+ {
+ final String[] tuple = param.split("=");
+ final KeyValuePair retval = new KeyValuePair(URLDecoder.decode(
+ tuple[0], encoding), tuple.length > 1 ? URLDecoder.decode(tuple[1],
+ encoding) : null);
+ parametersToFill.add(retval);
+ }
+ }
+
+ /**
+ * Generates a query string suitable for appending to a URI that encodes the
+ * given parameters as UTF-8 encoding strings.
+ *
+ * @param params
+ * A list of name value pairs to encode.
+ * @return A string suitable for appending to URIs.
+ */
+ public static String generateQueryString(
+ final List<? extends IKeyValuePair> params)
+ {
+ try
+ {
+ return generateQueryString(params, "UTF-8");
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new RuntimeException("What? UTF-8 isn't a valid encoding", e);
+ }
+ }
+
+ /**
+ * Generates a query string suitable for appending to a URI that encodes the
+ * given parameters as specified by the encoding parameter.
+ *
+ * @param params
+ * A list of name value pairs to encode.
+ * @param encoding
+ * The text encoding to use
+ * @return A string suitable for appending to URIs.
+ * @throws UnsupportedEncodingException
+ * If the encoding is not supported.
+ */
+ public static String generateQueryString(
+ final List<? extends IKeyValuePair> params, final String encoding)
+ throws UnsupportedEncodingException
+ {
+ if (params == null)
+ throw new IllegalArgumentException("need params");
+ if (encoding == null)
+ throw new UnsupportedEncodingException();
+
+ final StringBuilder builder = new StringBuilder();
+ final Iterator<? extends IKeyValuePair> iterator = params.iterator();
+ boolean hasNext = iterator.hasNext();
+ while (hasNext)
+ {
+ IKeyValuePair pair = iterator.next();
+ if (pair != null)
+ {
+ final String key = pair.getKey();
+ final String value = pair.getValue();
+ builder.append(URLEncoder.encode(key, encoding));
+ if (value != null)
+ {
+ builder.append("=");
+ builder.append(URLEncoder.encode(value, encoding));
+ }
+ }
+ if (iterator.hasNext())
+ {
+ if (pair != null)
+ builder.append("&");
+ hasNext = true;
+ }
+ else
+ {
+ hasNext = false;
+ }
+ }
+ return builder.toString();
+ }
+}
+
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnection.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnection.java
index 49e8481b..5a0a13df 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnection.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnection.java
@@ -29,15 +29,17 @@ import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import android.util.SparseArray;
+import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import de.luhmer.owncloudnewsreader.Constants;
import de.luhmer.owncloudnewsreader.ListView.UnreadFolderCount;
-import de.luhmer.owncloudnewsreader.model.AudioPodcastItem;
import de.luhmer.owncloudnewsreader.model.PodcastFeedItem;
+import de.luhmer.owncloudnewsreader.model.PodcastItem;
import de.luhmer.owncloudnewsreader.model.RssFile;
+import de.luhmer.owncloudnewsreader.services.PodcastDownloadService;
import static de.luhmer.owncloudnewsreader.ListView.SubscriptionExpandableListAdapter.SPECIAL_FOLDERS.ALL_ITEMS;
import static de.luhmer.owncloudnewsreader.ListView.SubscriptionExpandableListAdapter.SPECIAL_FOLDERS.ALL_STARRED_ITEMS;
@@ -932,7 +934,7 @@ public class DatabaseConnection {
//Log.d("DatabaseConnection", "Inserted Rows: " + result);
}
- private static final String ALLOWED_PODCASTS_TYPES = "audio/mp3', 'audio/mpeg', 'audio/ogg', 'audio/opus', 'audio/ogg;codecs=opus";
+ private static final String ALLOWED_PODCASTS_TYPES = "audio/mp3', 'audio/mpeg', 'audio/ogg', 'audio/opus', 'audio/ogg;codecs=opus', 'youtube";
public List<PodcastFeedItem> getListOfFeedsWithAudioPodcasts() {
@@ -965,13 +967,13 @@ public class DatabaseConnection {
return result;
}
- public List<AudioPodcastItem> getListOfAudioPodcastsForFeed(String feedId) {
+ public List<PodcastItem> getListOfAudioPodcastsForFeed(Context context, String feedId) {
String buildSQL = "SELECT rowid, " + RSS_ITEM_TITLE + ", " + RSS_ITEM_ENC_LINK + ", " + RSS_ITEM_ENC_MIME + " FROM " + RSS_ITEM_TABLE +
" WHERE " + RSS_ITEM_ENC_MIME + " IN ('" + ALLOWED_PODCASTS_TYPES + "') AND " + RSS_ITEM_SUBSCRIPTION_ID + " = " + feedId;
- List<AudioPodcastItem> result = new ArrayList<AudioPodcastItem>();
+ List<PodcastItem> result = new ArrayList<PodcastItem>();
Cursor cursor = database.rawQuery(buildSQL, null);
try
{
@@ -981,11 +983,17 @@ public class DatabaseConnection {
{
cursor.moveToFirst();
do {
- AudioPodcastItem podcastItem = new AudioPodcastItem();
+ PodcastItem podcastItem = new PodcastItem();
podcastItem.itemId = cursor.getString(0);
podcastItem.title = cursor.getString(1);
podcastItem.link = cursor.getString(2);
podcastItem.mimeType = cursor.getString(3);
+
+ File file = new File(PodcastDownloadService.getUrlToPodcastFile(context, podcastItem.link, false));
+ podcastItem.offlineCached = file.exists();
+
+
+
result.add(podcastItem);
} while(cursor.moveToNext());
}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/NewPodcastPlaybackListener.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/NewPodcastPlaybackListener.java
new file mode 100644
index 00000000..f0fa6c19
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/NewPodcastPlaybackListener.java
@@ -0,0 +1,7 @@
+package de.luhmer.owncloudnewsreader.events.podcast;
+
+/**
+ * Created by David on 29.06.2014.
+ */
+public class NewPodcastPlaybackListener {
+}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/RegisterVideoOutput.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/RegisterVideoOutput.java
new file mode 100644
index 00000000..f2514a13
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/RegisterVideoOutput.java
@@ -0,0 +1,18 @@
+package de.luhmer.owncloudnewsreader.events.podcast;
+
+import android.view.SurfaceView;
+import android.view.View;
+
+/**
+ * Created by David on 28.06.2014.
+ */
+public class RegisterVideoOutput {
+
+ public RegisterVideoOutput(SurfaceView surfaceView, View parentResizableView) {
+ this.surfaceView = surfaceView;
+ this.parentResizableView = parentResizableView;
+ }
+
+ public SurfaceView surfaceView;
+ public View parentResizableView;
+}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/StartDownloadPodcast.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/StartDownloadPodcast.java
new file mode 100644
index 00000000..0c109ae0
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/StartDownloadPodcast.java
@@ -0,0 +1,10 @@
+package de.luhmer.owncloudnewsreader.events.podcast;
+
+import de.luhmer.owncloudnewsreader.model.PodcastItem;
+
+/**
+ * Created by David on 28.06.2014.
+ */
+public class StartDownloadPodcast {
+ public PodcastItem podcast;
+}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/UpdatePodcastStatusEvent.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/UpdatePodcastStatusEvent.java
index f26bbf44..4d41abc5 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/UpdatePodcastStatusEvent.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/UpdatePodcastStatusEvent.java
@@ -10,6 +10,8 @@ public class UpdatePodcastStatusEvent {
private String title;
private boolean playing;
private boolean preparingFile;
+ private boolean fileLoaded;
+ private boolean isVideoFile;
public String getTitle() {
return title;
@@ -31,12 +33,20 @@ public class UpdatePodcastStatusEvent {
return preparingFile;
}
- public UpdatePodcastStatusEvent(long current, long max, boolean playing, String title, boolean preparingFile) {
+ public boolean isFileLoaded() {
+ return fileLoaded;
+ }
+
+ public boolean isVideoFile() { return isVideoFile; }
+
+ public UpdatePodcastStatusEvent(long current, long max, boolean playing, String title, boolean preparingFile, boolean fileLoaded, boolean isVideoFile) {
this.current = current;
this.max = max;
this.playing = playing;
this.title = title;
this.preparingFile = preparingFile;
+ this.fileLoaded = fileLoaded;
+ this.isVideoFile = isVideoFile;
}
}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/VideoDoubleClicked.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/VideoDoubleClicked.java
new file mode 100644
index 00000000..4b3f76e0
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/VideoDoubleClicked.java
@@ -0,0 +1,7 @@
+package de.luhmer.owncloudnewsreader.events.podcast;
+
+/**
+ * Created by David on 30.06.2014.
+ */
+public class VideoDoubleClicked {
+}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/AlphaAnimator.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/AlphaAnimator.java
new file mode 100644
index 00000000..319fa564
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/AlphaAnimator.java
@@ -0,0 +1,53 @@
+package de.luhmer.owncloudnewsreader.helper;
+
+import android.view.View;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+
+/**
+ * Created by David on 02.07.2014.
+ */
+public class AlphaAnimator {
+
+ public static void AnimateVisibilityChange(final View view, final int visibilityTo) {
+
+
+ Animation animation;
+ if(visibilityTo == View.GONE) {
+ animation = new AlphaAnimation(1f, 0f);
+ } else {
+ view.setAlpha(0.1f);
+ view.setVisibility(View.VISIBLE);
+ animation = new AlphaAnimation(0f, 1f);
+ }
+
+
+ animation.setFillAfter(true);
+ animation.setDuration(1000);
+ animation.setStartOffset(1000);
+ //animation.setStartOffset(5000);
+
+ /*
+ animation.setAnimationListener(new Animation.AnimationListener() {
+ @Override
+ public void onAnimationStart(Animation animation) {
+
+ }
+
+ @Override
+ public void onAnimationEnd(Animation animation) {
+ view.setVisibility(visibilityTo);
+ }
+
+ @Override
+ public void onAnimationRepeat(Animation animation) {
+
+ }
+ });
+ */
+
+ animation.start();
+
+
+ }
+}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/DatabaseUtils.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/DatabaseUtils.java
index 51370fc5..8ef35a43 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/DatabaseUtils.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/DatabaseUtils.java
@@ -55,6 +55,6 @@ public class DatabaseUtils {
}
public static File GetPath(Context context) {
- return new File(ImageHandler.getPath(context) + "/dbBackup/" + DatabaseHelper.DATABASE_NAME);
+ return new File(FileUtils.getPath(context) + "/dbBackup/" + DatabaseHelper.DATABASE_NAME);
}
}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java
index 9f2ac621..0dbadfba 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java
@@ -46,7 +46,7 @@ public class FavIconHandler {
{
try
{
- File favIconFile = ImageHandler.getFullPathOfCacheFile(URL_TO_PAGE, ImageHandler.getPathFavIcons(context));
+ File favIconFile = ImageHandler.getFullPathOfCacheFile(URL_TO_PAGE, FileUtils.getPathFavIcons(context));
if(favIconFile.isFile() && favIconFile.length() > 0)
{
if(feedID != null) {
@@ -94,7 +94,7 @@ public class FavIconHandler {
int key = Integer.parseInt(feedID);
favIconToFeedId.put(key, favIconCache);
- GetImageAsyncTask giAsync = new GetImageAsyncTask(WEB_URL_TO_FILE, favIconDownloadFinished, key, ImageHandler.getPathFavIcons(context), context, null);
+ GetImageAsyncTask giAsync = new GetImageAsyncTask(WEB_URL_TO_FILE, favIconDownloadFinished, key, FileUtils.getPathFavIcons(context), context, null);
giAsync.scaleImage = true;
giAsync.dstHeight = 2*32;
giAsync.dstWidth = 2*32;
@@ -146,7 +146,7 @@ public class FavIconHandler {
imageView.setImageDrawable(null);
- GetImageAsyncTask giAsync = new GetImageAsyncTask(WEB_URL_TO_FILE, imgDownloadFinished, key, ImageHandler.getPathFavIcons(context), context/*, imageView*/, lruCache);
+ GetImageAsyncTask giAsync = new GetImageAsyncTask(WEB_URL_TO_FILE, imgDownloadFinished, key, FileUtils.getPathFavIcons(context), context/*, imageView*/, lruCache);
giAsync.scaleImage = true;
giAsync.dstHeight = 2*32;
giAsync.dstWidth = 2*32;
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FileUtils.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FileUtils.java
index d329987c..cb230b35 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FileUtils.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FileUtils.java
@@ -21,6 +21,9 @@
package de.luhmer.owncloudnewsreader.helper;
+import android.content.Context;
+import android.os.Environment;
+
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
@@ -35,7 +38,7 @@ public class FileUtils {
* <br/>
* <i> Note: <code>fromFile</code> and <code>toFile</code> will be closed by
* this function.</i>
- *
+ *
* @param fromFile
* - FileInputStream for the file to copy from.
* @param toFile
@@ -60,4 +63,45 @@ public class FileUtils {
}
}
}
+
+
+
+
+
+ public static String getPath(Context context) {
+ String url;
+ Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
+ if(isSDPresent)
+ {
+ url = Environment.getExternalStorageDirectory().getAbsolutePath();
+ if (android.os.Build.DEVICE.contains("Samsung") || android.os.Build.MANUFACTURER.contains("Samsung")) {
+ url = url + "/external_sd";
+ }
+ //url = url + "/" + context.getString(R.string.app_name);
+ url = url + "/ownCloud News Reader";
+ }
+ else
+ url = context.getCacheDir().getAbsolutePath();
+
+ return url;
+ }
+
+
+
+
+ public static String getPathPodcasts(Context context)
+ {
+ return getPath(context) + "/podcasts";
+ }
+
+ public static String getPathFavIcons(Context context)
+ {
+ return getPath(context) + "/favIcons";
+ }
+
+ public static String getPathImageCache(Context context)
+ {
+ return getPath(context) + "/imgCache";
+ }
+
}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageHandler.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageHandler.java
index 87a36ac8..90c2029f 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageHandler.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageHandler.java
@@ -23,7 +23,6 @@ package de.luhmer.owncloudnewsreader.helper;
import android.content.Context;
import android.graphics.drawable.Drawable;
-import android.os.Environment;
import java.io.File;
import java.io.FileOutputStream;
@@ -116,34 +115,6 @@ public class ImageHandler {
- public static String getPathFavIcons(Context context)
- {
- return getPath(context) + "/favIcons";
- }
-
- public static String getPathImageCache(Context context)
- {
- return getPath(context) + "/imgCache";
- }
-
- public static String getPath(Context context) {
- String url;
- Boolean isSDPresent = android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);
- if(isSDPresent)
- {
- url = Environment.getExternalStorageDirectory().getAbsolutePath();
- if (android.os.Build.DEVICE.contains("Samsung") || android.os.Build.MANUFACTURER.contains("Samsung")) {
- url = url + "/external_sd";
- }
- //url = url + "/" + context.getString(R.string.app_name);
- url = url + "/ownCloud News Reader";
- }
- else
- url = context.getCacheDir().getAbsolutePath();
-
- return url;
- }
-
public static List<String> getImageLinksFromText(String text)
{
@@ -168,14 +139,14 @@ public class ImageHandler {
public static boolean clearCache(Context context)
{
- String path = getPath(context);
+ String path = FileUtils.getPath(context);
boolean result = deleteDir(new File(path));
createNoMediaFile(context);
return result;
}
public static void createNoMediaFile(Context context) {
- String path = getPath(context);
+ String path = FileUtils.getPath(context);
createEmptyFile(path + "/.nomedia");
}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/JavaYoutubeDownloader.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/JavaYoutubeDownloader.java
new file mode 100644
index 00000000..260fabe7
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/JavaYoutubeDownloader.java
@@ -0,0 +1,381 @@
+package de.luhmer.owncloudnewsreader.helper;
+
+import android.content.Context;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpResponse;
+import org.apache.http.NameValuePair;
+import org.apache.http.client.CookieStore;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.protocol.ClientContext;
+import org.apache.http.client.utils.URIUtils;
+import org.apache.http.client.utils.URLEncodedUtils;
+import org.apache.http.impl.client.BasicCookieStore;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.apache.http.message.BasicNameValuePair;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.HttpContext;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.io.UnsupportedEncodingException;
+import java.io.Writer;
+import java.math.BigInteger;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.net.URLEncoder;
+import java.security.MessageDigest;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.regex.Pattern;
+
+import de.luhmer.owncloudnewsreader.collections.IKeyValuePair;
+import de.luhmer.owncloudnewsreader.collections.KeyValuePair;
+import de.luhmer.owncloudnewsreader.collections.MapUtils;
+import de.luhmer.owncloudnewsreader.collections.URLParams;
+
+public class JavaYoutubeDownloader {
+
+ public static String newline = System.getProperty("line.separator");
+ public static final String scheme = "http";
+ public static final String host = "www.youtube.com";
+ public static final Pattern commaPattern = Pattern.compile(",");
+ public static final char[] ILLEGAL_FILENAME_CHARACTERS = { '/', '\n', '\r', '\t', '\0', '\f', '`', '?', '*', '\\', '<', '>', '|', '\"', ':' };
+
+
+
+
+
+
+ public String getVideoID( String urlString ){
+ int start = urlString.indexOf("?v=") + 3;
+ int end = urlString.indexOf("&", start);
+ if ( end == -1 ){
+ end = urlString.length();
+ }
+
+ if(start == 2) { //Doesn't work
+ start = urlString.indexOf("/v/") + 3;
+ end = urlString.indexOf("?", start);
+ if (end == -1){
+ end = urlString.length();
+ }
+ }
+
+ return urlString.substring(start, end);
+ }
+
+ public String getExtension(int format) {
+ return "mp4";
+ }
+
+
+ public String getDownloadUrl(String url, Context context) throws Throwable {
+
+ //Map<String, String> videoInfo = getVideoInfo(getVideoID(url));// Html.fromHtml(getStringFromWebsite("http://youtube.com/get_video_info?video_id=" + getVideoID(url))).toString();
+ /*
+
+ byte[] b = videoInfo.getBytes();
+ String videoInfoAscii = new String(b, "ASCII");
+ */
+
+ //getFullPathOfPodcastYoutubeFile(url, context), ".mp4"
+
+ //String urlTemp = videoInfo.get("sig");
+
+ return getDownloadUrl(getVideoID(url), "UTF-8", "ownCloud News Reader");
+ }
+
+ public static File getFullPathOfPodcastYoutubeFile(String WEB_URL_TO_FILE, Context context) throws Exception
+ {
+ String rootPath = FileUtils.getPathPodcasts(context);
+ URL url = new URL(WEB_URL_TO_FILE.trim());
+
+ MessageDigest m = MessageDigest.getInstance("MD5");
+ m.reset();
+ m.update(url.toString().getBytes());
+ byte[] digest = m.digest();
+ BigInteger bigInt = new BigInteger(1,digest);
+ String hashtext = bigInt.toString(16);
+
+ return new File(rootPath + "/" + hashtext + ".mp4");
+ }
+
+
+ public String getDownloadUrl(String videoId, String encoding, String userAgent) throws Throwable {
+ //Utils.log.fine("Retrieving " + videoId);
+ List<NameValuePair> qparams = new ArrayList<NameValuePair>();
+ qparams.add(new BasicNameValuePair("video_id", videoId));
+ URI uri = getUri("get_video_info", qparams);
+
+ CookieStore cookieStore = new BasicCookieStore();
+ HttpContext localContext = new BasicHttpContext();
+ localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
+
+ HttpClient httpclient = new DefaultHttpClient();
+ HttpGet httpget = new HttpGet(uri);
+ httpget.setHeader("User-Agent", userAgent);
+
+ //Utils.log.finer("Executing " + uri);
+ HttpResponse response = httpclient.execute(httpget, localContext);
+ HttpEntity entity = response.getEntity();
+ if (entity != null && response.getStatusLine().getStatusCode() == 200) {
+ InputStream instream = entity.getContent();
+ String videoInfo = getStringFromInputStream(encoding, instream);
+ if (videoInfo != null && videoInfo.length() > 0) {
+ List<NameValuePair> infoMap = new ArrayList<NameValuePair>();
+ URLEncodedUtils.parse(infoMap, new Scanner(videoInfo), encoding);
+ String downloadUrl = null;
+ String filename = videoId;
+ int bestQuality = -1;
+ for (NameValuePair pair : infoMap) {
+ String key = pair.getName();
+ String val = pair.getValue();
+ //Utils.log.finest(key + "=" + val);
+ if (key.equals("title")) {
+ filename = val;
+ } else if (key.equals("url_encoded_fmt_stream_map")) {
+ String[] formats = commaPattern.split(val);
+
+ String fmtString = null;
+ //for (String fmt : formats) {
+ String fmt = formats[0]; {
+ int itagLocation = fmt.indexOf("itag=");
+ if ( itagLocation == -1 ) continue;
+ itagLocation += 5;
+ String subStr = null;
+ try {
+ subStr = fmt.substring(itagLocation, fmt.indexOf("&", itagLocation));
+ }
+ catch( IndexOutOfBoundsException ex){
+ return "Could not find the itag attribute to determine quality";
+ }
+ int tempQuality = Integer.parseInt(fmt.substring(itagLocation, fmt.indexOf("&", itagLocation)));
+ if ( bestQuality < tempQuality ){
+ bestQuality = tempQuality;
+ fmtString = fmt;
+ }
+
+ }
+ //we are going to automatically download the best quality youtube
+ int begin = fmtString.indexOf("url=");
+ int sig = fmtString.indexOf("sig=");
+ if (begin != -1) {
+ int end = fmtString.indexOf("&", begin + 4);
+ int end2 = fmtString.indexOf("&", sig + 4);
+ if (end == -1) {
+ end = fmtString.length();
+ }
+ if (end2 == -1 ){
+ end2 = fmtString.length();
+ }
+ String tempURL = fmtString.substring(begin+ 4, end );
+ String signatureURL = URLEncoder.encode("&signature="+fmtString.substring(sig + 4, end2), "UTF-8");
+ //downloadUrl = new String(URLCodec.decodeUrl((tempURL + signatureURL).getBytes()));
+ downloadUrl = URLDecoder.decode((tempURL + signatureURL), "UTF-8");
+
+ return downloadUrl;
+ //break;
+ }
+ }
+ }
+
+ /*
+ if ( downloadUrl == null ){
+ //Utils.log.fine("Content is protected");
+ }
+ filename = cleanFilename(filename);
+ if (filename.length() == 0) {
+ filename = videoId;
+ } else {
+ filename += "_" + videoId;
+ }
+ filename += "." + extension;
+ File outputfile = new File(outputdir, filename);
+ if (downloadUrl != null) {
+ downloadWithHttpClient(userAgent, downloadUrl, outputfile);
+ }
+ */
+ }
+ }
+ return "successful";
+ }
+
+ public void downloadWithHttpClient(String userAgent, String downloadUrl, File outputfile) throws Throwable {
+
+ HttpGet httpget2 = new HttpGet(downloadUrl);
+ //Utils.log.finer("Executing " + httpget2.getURI());
+ HttpClient httpclient2 = new DefaultHttpClient();
+
+ HttpResponse response2 = httpclient2.execute(httpget2);
+ HttpEntity entity2 = response2.getEntity();
+
+ if (entity2 != null && response2.getStatusLine().getStatusCode() == 200) {
+ long length = entity2.getContentLength();
+ InputStream instream2 = entity2.getContent();
+ //Utils.log.finer("Writing " + length + " bytes to " + outputfile);
+ if (outputfile.exists()) {
+ outputfile.delete();
+ }
+ FileOutputStream outstream = new FileOutputStream(outputfile);
+ try {
+ byte[] buffer = new byte[2048];
+ int count = -1;
+ while ((count = instream2.read(buffer)) != -1) {
+ outstream.write(buffer, 0, count);
+ }
+ outstream.flush();
+ } finally {
+ outstream.close();
+ }
+ }
+ }
+
+ private String cleanFilename(String filename) {
+ for (char c : ILLEGAL_FILENAME_CHARACTERS) {
+ filename = filename.replace(c, '_');
+ }
+ return filename;
+ }
+
+ private static URI getUri(String path, List<NameValuePair> qparams) throws URISyntaxException {
+ URI uri = URIUtils.createURI(scheme, host, -1, "/" + path, URLEncodedUtils.format(qparams, "UTF-8"), null);
+ return uri;
+ }
+
+ private String getStringFromInputStream(String encoding, InputStream instream) throws UnsupportedEncodingException, IOException {
+ Writer writer = new StringWriter();
+
+ char[] buffer = new char[1024];
+ try {
+ Reader reader = new BufferedReader(new InputStreamReader(instream, encoding));
+ int n;
+ while ((n = reader.read(buffer)) != -1) {
+ writer.write(buffer, 0, n);
+ }
+ } finally {
+ instream.close();
+ }
+ String result = writer.toString();
+ return result;
+ }
+
+
+ private String getStringFromWebsite(String url) {
+ String response = "";
+ DefaultHttpClient client = new DefaultHttpClient();
+ HttpGet httpGet = new HttpGet(url);
+ try {
+ HttpResponse execute = client.execute(httpGet);
+ InputStream content = execute.getEntity().getContent();
+
+ BufferedReader buffer = new BufferedReader(
+ new InputStreamReader(content));
+ String s = "";
+ //Charset cs = Charset.forName("ASCII"); // Or whatever encoding you want
+
+
+ while ((s = buffer.readLine()) != null) {
+ response += s;
+ }
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return response;
+ }
+
+
+
+
+
+ /**
+ * Gets all parameters we can figure out about this youTubeId by scraping YouTube.
+ * The URL for the underlying video will have the key "location".
+ * @param youTubeId A YouTube ID
+ * @return A map with all parameters as key-value pairs.
+ * @throws IOException if we have networking troubles
+ */
+ public static Map<String, String> getVideoInfo(String youTubeId) throws IOException
+ {
+ final Map<String, String> retval = new HashMap<String, String>();
+ getVideoInfo(youTubeId, retval);
+ return retval;
+ }
+ /**
+ * Gets all parameters we can figure out about this youTubeId by scraping YouTube.
+ * The URL for the underlying video will have the key "location".
+ * @param youTubeId A YouTube ID
+ * @param map A map to fill with data; it is not cleared first.
+ * @throws IOException if we have networking troubles
+ */
+ public static void getVideoInfo(String youTubeId, Map<String, String> map) throws IOException
+ {
+ final String host = "http://www.youtube.com";
+ final List<IKeyValuePair> params = new ArrayList<IKeyValuePair>();
+ params.add(new KeyValuePair("video_id", youTubeId));
+ final String urlString = host + "/get_video_info?&"+ URLParams.generateQueryString(params);
+
+ final URL url;
+ try
+ {
+ url = new URL(urlString);
+ }
+ catch (MalformedURLException e)
+ {
+ throw new RuntimeException("malformed url: " + urlString, e);
+ }
+ HttpURLConnection conn;
+ BufferedInputStream in;
+ byte[] data = new byte[4096]; // bad Art; fixed size
+
+ conn = (HttpURLConnection)url.openConnection();
+ if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
+ // badness.
+ conn.disconnect();
+ throw new RuntimeException("could not get video info: " + urlString);
+ }
+ in = new BufferedInputStream(conn.getInputStream());
+ int offset=0;
+ do {
+ offset = in.read(data, offset, data.length-offset);
+ } while(offset >= 0 && offset < data.length);
+ conn.disconnect();
+ // convert to string; ugh
+ String response = new String(data, "UTF-8");
+ System.out.println("Response: "+response);
+ // convert into parameter map
+ final Map<String, String> youTubeParams = MapUtils.listToMap(URLParams.parseQueryString(response), MapUtils.ListToMapMode.FIRST_WINS);
+
+
+ final String token = youTubeParams.get("token");
+ //if (token == null)
+ //throw new RuntimeException("Could not find youtube token: "+ urlString +"; response="+response);
+
+
+ params.clear();
+ params.add(new KeyValuePair("video_id", youTubeId));
+ params.add(new KeyValuePair("t", token));
+ final String location = host + "/get_video?"+URLParams.generateQueryString(params);
+ map.put("location", location);
+ map.putAll(youTubeParams);
+
+ }
+}
+
+
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/SizeAnimator.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/SizeAnimator.java
new file mode 100644
index 00000000..5db6f4b3
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/SizeAnimator.java
@@ -0,0 +1,40 @@
+package de.luhmer.owncloudnewsreader.helper;
+
+import android.view.View;
+import android.view.animation.Animation;
+import android.view.animation.Transformation;
+
+/**
+ * Created by David on 30.06.2014.
+ */
+public class SizeAnimator {
+
+ public SizeAnimator(View view, float mWidth, float mHeight, float oldWidth, float oldHeight, int duration) {
+ this.viewToSizeAnimate = view;
+ this.mWidth = mWidth;
+ this.mHeight = mHeight;
+ this.mOldHeight = oldHeight;
+ this.mOldWidth = oldWidth;
+
+ sizeAnimator.setDuration(duration);
+ }
+
+ View viewToSizeAnimate;
+ float mWidth;
+ float mHeight;
+ float mOldWidth;
+ float mOldHeight;
+
+
+
+ public Animation sizeAnimator = new Animation() {
+
+ @Override
+ protected void applyTransformation(float interpolatedTime, Transformation t) {
+ viewToSizeAnimate.getLayoutParams().width = (int)(mOldWidth + ((mWidth - mOldWidth) * interpolatedTime));
+ viewToSizeAnimate.getLayoutParams().height = (int) (mOldHeight + ((mHeight - mOldHeight) * interpolatedTime));
+ viewToSizeAnimate.setLayoutParams(viewToSizeAnimate.getLayoutParams());
+ }
+ };
+
+}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/PodcastItem.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/PodcastItem.java
index 7fb53e4e..544b91c2 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/PodcastItem.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/PodcastItem.java
@@ -7,13 +7,26 @@ import java.io.Serializable;
*/
public class PodcastItem implements Serializable {
+ public PodcastItem() {
+
+ }
+
+ public PodcastItem(String itemId, String title, String link, String mimeType, boolean offlineCached) {
+ this.itemId = itemId;
+ this.title = title;
+ this.link = link;
+ this.mimeType = mimeType;
+ this.offlineCached = offlineCached;
+ }
+
public String itemId;
public String title;
public String link;
public String mimeType;
+ public boolean offlineCached;
- public int downloadProgress;
+ public Integer downloadProgress;
- public static int DOWNLOAD_COMPLETED = -1;
- public static int DOWNLOAD_NOT_STARTED = -2;
+ public static Integer DOWNLOAD_COMPLETED = -1;
+ public static Integer DOWNLOAD_NOT_STARTED = -2;
}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/DownloadItemsToCache.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/DownloadItemsToCache.java
index 2540a887..eb3c2c32 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/DownloadItemsToCache.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/DownloadItemsToCache.java
@@ -28,8 +28,8 @@ import android.util.SparseArray;
import de.luhmer.owncloudnewsreader.async_tasks.GetImageAsyncTask;
import de.luhmer.owncloudnewsreader.helper.BitmapDrawableLruCache;
+import de.luhmer.owncloudnewsreader.helper.FileUtils;
import de.luhmer.owncloudnewsreader.helper.ImageDownloadFinished;
-import de.luhmer.owncloudnewsreader.helper.ImageHandler;
public class DownloadItemsToCache {
SparseArray<String> URLs;
@@ -47,7 +47,7 @@ public class DownloadItemsToCache {
key = URLs.keyAt(URLs.size() -1) + 1;
URLs.append(key, URL_TO_IMAGE);
- GetImageAsyncTask getImageAsync = new GetImageAsyncTask(URL_TO_IMAGE, imgDownloadFinished, key, ImageHandler.getPathImageCache(context), context, null);
+ GetImageAsyncTask getImageAsync = new GetImageAsyncTask(URL_TO_IMAGE, imgDownloadFinished, key, FileUtils.getPathImageCache(context), context, null);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB)
getImageAsync.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, ((Void) null));// Execute in parallel
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/owncloud/InsertItemIntoDatabase.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/owncloud/InsertItemIntoDatabase.java
index dbc7132b..2eb03b94 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/owncloud/InsertItemIntoDatabase.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/owncloud/InsertItemIntoDatabase.java
@@ -55,18 +55,29 @@ public class InsertItemIntoDatabase implements IHandleJsonObject {
content = content.replaceAll("<img[^>]*auslieferung.commindo-media-ressourcen.de.*>", "");
content = content.replaceAll("<img[^>]*rss.buysellads.com.*>", "");
+ String url = e.optString("url");
+ String guid = e.optString("guid");
+ String enclosureLink = e.optString("enclosureLink");
+ String enclosureMime = e.optString("enclosureMime");
+
+ if(enclosureLink.isEmpty() && guid.startsWith("http://gdata.youtube.com/feeds/api/")) {
+ enclosureLink = url;
+ enclosureMime = "youtube";
+ }
+
+
return new RssFile(0, e.optString("id"),
e.optString("title"),
- e.optString("url"), content,
+ url, content,
!e.optBoolean("unread"), null,
e.optString("feedId"), null,
date, e.optBoolean("starred"),
- e.optString("guid"),
+ guid,
e.optString("guidHash"),
e.optString("lastModified"),
e.optString("author"),
- e.optString("enclosureLink"),
- e.optString("enclosureMime"));
+ enclosureLink,
+ enclosureMime);
}
@Override
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java
index 492cef8d..79100813 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java
@@ -49,6 +49,7 @@ import de.luhmer.owncloudnewsreader.async_tasks.GetImageAsyncTask;
import de.luhmer.owncloudnewsreader.database.DatabaseConnection;
import de.luhmer.owncloudnewsreader.helper.BitmapDrawableLruCache;
import de.luhmer.owncloudnewsreader.helper.FavIconHandler;
+import de.luhmer.owncloudnewsreader.helper.FileUtils;
import de.luhmer.owncloudnewsreader.helper.ImageDownloadFinished;
import de.luhmer.owncloudnewsreader.helper.ImageHandler;
@@ -144,7 +145,7 @@ public class DownloadImagesService extends IntentService {
notificationManager.notify(NOTIFICATION_ID, notify);
for (String link : links)
- new GetImageAsyncTask(link, imgDownloadFinished, 999, ImageHandler.getPathImageCache(this), this, null).execute();
+ new GetImageAsyncTask(link, imgDownloadFinished, 999, FileUtils.getPathImageCache(this), this, null).execute();
}
}
@@ -169,7 +170,7 @@ public class DownloadImagesService extends IntentService {
private void RemoveOldImages(Context context) {
HashMap<File, Long> files;
- long size = ImageHandler.getFolderSize(new File(ImageHandler.getPath(context)));
+ long size = ImageHandler.getFolderSize(new File(FileUtils.getPath(context)));
size = (long) (size / 1024d / 1024d);
SharedPreferences mPrefs = PreferenceManager.getDefaultSharedPreferences(context);
@@ -177,7 +178,7 @@ public class DownloadImagesService extends IntentService {
if(size > max_allowed_size)
{
files = new HashMap<File, Long>();
- for(File file : ImageHandler.getFilesFromDir(new File(ImageHandler.getPathImageCache(context))))
+ for(File file : ImageHandler.getFilesFromDir(new File(FileUtils.getPathImageCache(context))))
{
files.put(file, file.lastModified());
}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastDownloadService.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastDownloadService.java
new file mode 100644
index 00000000..0a88c77c
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastDownloadService.java
@@ -0,0 +1,240 @@
+package de.luhmer.owncloudnewsreader.services;
+
+import android.annotation.TargetApi;
+import android.app.DownloadManager;
+import android.app.IntentService;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.ResultReceiver;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.math.BigInteger;
+import java.net.URL;
+import java.net.URLConnection;
+import java.security.MessageDigest;
+
+import de.greenrobot.event.EventBus;
+import de.luhmer.owncloudnewsreader.helper.FileUtils;
+import de.luhmer.owncloudnewsreader.helper.JavaYoutubeDownloader;
+import de.luhmer.owncloudnewsreader.model.PodcastItem;
+
+/**
+ * An {@link IntentService} subclass for handling asynchronous task requests in
+ * a service on a separate handler thread.
+ * <p>
+ * TODO: Customize class - update intent actions, extra parameters and static
+ * helper methods.
+ */
+public class PodcastDownloadService extends IntentService {
+ // TODO: Rename actions, choose action names that describe tasks that this
+ // IntentService can perform, e.g. ACTION_FETCH_NEW_ITEMS
+ private static final String ACTION_DOWNLOAD = "de.luhmer.owncloudnewsreader.services.action.DOWNLOAD";
+
+
+
+ // TODO: Rename parameters
+ private static final String EXTRA_RECEIVER = "de.luhmer.owncloudnewsreader.services.extra.RECEIVER";
+ private static final String EXTRA_URL = "de.luhmer.owncloudnewsreader.services.extra.URL";
+ private static final String EXTRA_PARAM2 = "de.luhmer.owncloudnewsreader.services.extra.PARAM2";
+ private static final String TAG = "PodcastDownloadService";
+
+ private EventBus eventBus;
+
+ /**
+ * Starts this service to perform action Foo with the given parameters. If
+ * the service is already performing a task this action will be queued.
+ *
+ * @see IntentService
+ */
+ // TODO: Customize helper method
+ public static void startPodcastDownload(Context context, PodcastItem podcastItem/*, ResultReceiver receiver*/) {
+ Intent intent = new Intent(context, PodcastDownloadService.class);
+ intent.setAction(ACTION_DOWNLOAD);
+ intent.putExtra(EXTRA_URL, podcastItem);
+ //intent.putExtra(EXTRA_RECEIVER, receiver);
+ //intent.putExtra(EXTRA_PARAM2, param2);
+ context.startService(intent);
+ }
+
+
+ public PodcastDownloadService() {
+ super("PodcastDownloadService");
+
+ eventBus = EventBus.getDefault();
+ }
+
+ @Override
+ protected void onHandleIntent(Intent intent) {
+
+ if (intent != null) {
+ final String action = intent.getAction();
+ if (ACTION_DOWNLOAD.equals(action)) {
+ ResultReceiver receiver = (ResultReceiver) intent.getParcelableExtra(EXTRA_RECEIVER);
+ PodcastItem podcast = (PodcastItem) intent.getSerializableExtra(EXTRA_URL);
+ //final String param2 = intent.getStringExtra(EXTRA_PARAM2);
+ //handleActionDownload(podcast);
+
+ downloadPodcast(podcast, this);
+
+
+ }/* else if (ACTION_BAZ.equals(action)) {
+ final String param1 = intent.getStringExtra(EXTRA_PARAM1);
+ final String param2 = intent.getStringExtra(EXTRA_PARAM2);
+ handleActionBaz(param1, param2);
+ }*/
+ }
+ }
+
+ /**
+ * Handle action Foo in the provided background thread with the provided
+ * parameters.
+ */
+ @TargetApi(Build.VERSION_CODES.GINGERBREAD)
+ private void handleActionDownload(PodcastItem podcast) {
+ Uri uri = Uri.parse(podcast.link);
+ DownloadManager.Request request = new DownloadManager.Request(uri);
+ request.setDescription(podcast.mimeType);
+ request.setTitle(podcast.title);
+
+ // in order for this if to run, you must use the android 3.2 to compile your app
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
+ request.allowScanningByMediaScanner();
+ request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
+ }
+
+ String path = "file://" + getUrlToPodcastFile(this, podcast.link, true);
+ request.setDestinationUri(Uri.parse(path));
+ //request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "bla.txt");
+
+ // get download service and enqueue file
+ DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
+ manager.enqueue(request);
+ }
+
+
+ public static String getUrlToPodcastFile(Context context, String WEB_URL_TO_FILE, boolean createDir) {
+ if(WEB_URL_TO_FILE.contains(JavaYoutubeDownloader.host))
+ return getUrlToYoutubePodcastFile(context, WEB_URL_TO_FILE, createDir);
+
+ File file = new File(WEB_URL_TO_FILE);
+
+ String path = FileUtils.getPathPodcasts(context) + "/" + getHashOfString(WEB_URL_TO_FILE) + "/";
+ if(createDir)
+ new File(path).mkdirs();
+
+ return path + file.getName();
+ }
+
+ private static String getUrlToYoutubePodcastFile(Context context, String WEB_URL_TO_FILE, boolean createDir) {
+ String path = FileUtils.getPathPodcasts(context) + "/" + getHashOfString(WEB_URL_TO_FILE) + "/";
+ if(createDir)
+ new File(path).mkdirs();
+
+ return path + "video.mp4";
+ }
+
+
+ public static String getHashOfString(String WEB_URL_TO_FILE)
+ {
+ try {
+ MessageDigest m = MessageDigest.getInstance("MD5");
+ m.reset();
+ m.update(WEB_URL_TO_FILE.trim().getBytes());
+ byte[] digest = m.digest();
+ BigInteger bigInt = new BigInteger(1,digest);
+ String hashtext = bigInt.toString(16);
+
+ return hashtext;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ return WEB_URL_TO_FILE;
+ }
+
+
+ private void downloadPodcast(PodcastItem podcast, Context context) {
+ try {
+ String urlTemp = podcast.link;
+ String path = getUrlToPodcastFile(this, urlTemp, true);
+
+ if(podcast.link.contains(JavaYoutubeDownloader.host)) {
+
+ path = getUrlToPodcastFile(context, urlTemp, true);
+
+ try {
+ urlTemp = new JavaYoutubeDownloader().getDownloadUrl(podcast.link, context);
+ } catch (Throwable throwable) {
+ throwable.printStackTrace();
+ }
+
+ }
+ URL url = new URL(urlTemp);
+ URLConnection connection = url.openConnection();
+ connection.connect();
+ connection.setConnectTimeout(10000);
+ connection.setReadTimeout(120000);//2min
+ // this will be useful so that you can show a typical 0-100% progress bar
+ int fileLength = connection.getContentLength();
+
+ // download the file
+ InputStream input = new BufferedInputStream(url.openStream());
+
+
+ String pathCache = path + ".download";
+ OutputStream output = new FileOutputStream(pathCache);
+
+
+ byte data[] = new byte[1024];
+ long total = 0;
+ int count;
+ while ((count = input.read(data)) != -1) {
+ total += count;
+
+ int progress = (int) (total * 100 / fileLength);
+ podcast.downloadProgress = progress;
+ eventBus.post(new DownloadProgressUpdate(podcast));
+
+ output.write(data, 0, count);
+ }
+
+ output.flush();
+ output.close();
+ input.close();
+
+
+ new File(pathCache).renameTo(new File(path));
+
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+
+
+ podcast.downloadProgress = 100;
+ eventBus.post(new DownloadProgressUpdate(podcast));
+
+ /*
+ Bundle resultData = new Bundle();
+ resultData.putInt("progress" ,100);
+ receiver.send(UPDATE_PROGRESS, resultData);
+ */
+ }
+
+ public static final int UPDATE_PROGRESS = 5555;
+
+
+ public class DownloadProgressUpdate {
+
+ public DownloadProgressUpdate(PodcastItem podcast) {
+ this.podcast = podcast;
+ }
+
+ public PodcastItem podcast;
+ }
+}
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastPlaybackService.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastPlaybackService.java
index 7a656ba2..61c935ff 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastPlaybackService.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastPlaybackService.java
@@ -5,12 +5,16 @@ import android.content.Intent;
import android.media.MediaPlayer;
import android.os.Handler;
import android.os.IBinder;
+import android.util.Log;
import android.view.SurfaceHolder;
+import android.view.View;
import java.io.IOException;
import de.greenrobot.event.EventBus;
-import de.luhmer.owncloudnewsreader.events.podcast.OpenAudioPodcastEvent;
+import de.luhmer.owncloudnewsreader.R;
+import de.luhmer.owncloudnewsreader.events.podcast.NewPodcastPlaybackListener;
+import de.luhmer.owncloudnewsreader.events.podcast.OpenPodcastEvent;
import de.luhmer.owncloudnewsreader.events.podcast.RegisterVideoOutput;
import de.luhmer.owncloudnewsreader.events.podcast.TogglePlayerStateEvent;
import de.luhmer.owncloudnewsreader.events.podcast.UpdatePodcastStatusEvent;
@@ -19,33 +23,35 @@ import de.luhmer.owncloudnewsreader.view.PodcastNotification;
public class PodcastPlaybackService extends Service {
+ private static final String TAG = "PodcastPlaybackService";
PodcastNotification podcastNotification;
@Override
public void onCreate() {
podcastNotification = new PodcastNotification(this);
+ mediaTitle = getString(R.string.no_podcast_selected);
+
super.onCreate();
}
public PodcastPlaybackService() {
- mediaPlayer = new MediaPlayer();
+ mMediaPlayer = new MediaPlayer();
mHandler = new Handler();
eventBus = EventBus.getDefault();
eventBus.register(this);
-
-
- mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
+ mMediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
play();
isPreparing = false;
+ canCallGetDuration = true;
}
});
- mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
+ mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
pause();//Send the over signal
@@ -53,39 +59,52 @@ public class PodcastPlaybackService extends Service {
});
+ eventBus.post(new PodcastPlaybackServiceStarted());
+
+ mHandler.postDelayed(mUpdateTimeTask, 0);
+
//openFile("/sdcard/Music/#Musik/Finest Tunes/Netsky - Running Low (Ft. Beth Ditto).mp3");
}
@Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ return Service.START_STICKY;
+ //return super.onStartCommand(intent, flags, startId);
+ }
+
+ @Override
public IBinder onBind(Intent intent) {
- // TODO: Return the communication channel to the service.
- throw new UnsupportedOperationException("Not yet implemented");
+ return null;
+ //throw new UnsupportedOperationException("Not yet implemented");
}
private EventBus eventBus;
private Handler mHandler;
- private MediaPlayer mediaPlayer;
+ private MediaPlayer mMediaPlayer;
private String mediaTitle;
+ View parentResizableView;
public static final int delay = 500; //In milliseconds
+ private boolean canCallGetDuration = false;//Otherwise the player would call getDuration all the time without loading a media file
private boolean isPreparing = false;
+ private boolean isVideoFile = false;
public void openFile(String pathToFile, String mediaTitle) {
try {
- this.mediaTitle = mediaTitle;
-
- if(mediaPlayer.isPlaying())
+ if(mMediaPlayer.isPlaying())
pause();
+ this.mediaTitle = mediaTitle;
+
isPreparing = true;
mHandler.postDelayed(mUpdateTimeTask, 0);
- mediaPlayer.reset();
- mediaPlayer.setDataSource(pathToFile);
- mediaPlayer.prepareAsync();
+ mMediaPlayer.reset();
+ mMediaPlayer.setDataSource(pathToFile);
+ mMediaPlayer.prepareAsync();
} catch (IOException e) {
e.printStackTrace();
isPreparing = false;
@@ -104,7 +123,7 @@ public class PodcastPlaybackService extends Service {
};
public void onEvent(TogglePlayerStateEvent event) {
- if(mediaPlayer.isPlaying()) {
+ if(mMediaPlayer.isPlaying()) {
pause();
} else {
play();
@@ -112,49 +131,91 @@ public class PodcastPlaybackService extends Service {
}
public void onEvent(WindPodcast event) {
- if(mediaPlayer != null) {
- double totalDuration = mediaPlayer.getDuration();
+ if(mMediaPlayer != null) {
+ double totalDuration = mMediaPlayer.getDuration();
int position = (int)((totalDuration / 100d) * event.toPositionInPercent);
- mediaPlayer.seekTo(position);
+ mMediaPlayer.seekTo(position);
}
}
- public void onEventBackgroundThread(OpenAudioPodcastEvent event) {
+ public void onEventBackgroundThread(OpenPodcastEvent event) {
+ this.isVideoFile = event.isVideoFile;
openFile(event.pathToFile, event.mediaTitle);
}
public void onEvent(RegisterVideoOutput videoOutput) {
- if(mediaPlayer != null) {
- //getHolder().addCallback(videoOutput);
- videoOutput.surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
+ if(mMediaPlayer != null) {
+ if(videoOutput.surfaceView == null) {
+ mMediaPlayer.setDisplay(null);
+ Log.d(TAG, "Disable Screen output!");
+
+ mMediaPlayer.setScreenOnWhilePlaying(false);
+ } else {
+ if(videoOutput.surfaceView.getHolder() != mSurfaceHolder) {
+ parentResizableView = videoOutput.parentResizableView;
+
+ videoOutput.surfaceView.getHolder().addCallback(mSHCallback);
+ //videoOutput.surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); //holder.setType(SurfaceHolder.SURFACE_TYPE_GPU);
+
+ populateVideo();
+
+ Log.d(TAG, "Enable Screen output!");
+ }
+ }
}
}
+ public void onEvent(NewPodcastPlaybackListener newListener) {
+ sendMediaStatus();
+ }
+
public void play() {
- mediaPlayer.start();
+ try {
+ int progress = mMediaPlayer.getCurrentPosition() / mMediaPlayer.getDuration();
+ if (progress >= 1) {
+ mMediaPlayer.seekTo(0);
+ }
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+
+ mMediaPlayer.start();
mHandler.removeCallbacks(mUpdateTimeTask);
mHandler.postDelayed(mUpdateTimeTask, 0);
+
+ populateVideo();
+ }
+
+ private void populateVideo() {
+ double videoHeightRel = (double) mSurfaceWidth / (double) mMediaPlayer.getVideoWidth();
+ int videoHeight = (int) (mMediaPlayer.getVideoHeight() * videoHeightRel);
+
+ if (mSurfaceWidth != 0 && videoHeight != 0 && mSurfaceHolder != null) {
+ //mSurfaceHolder.setFixedSize(mSurfaceWidth, videoHeight);
+
+ parentResizableView.getLayoutParams().height = videoHeight;
+ parentResizableView.setLayoutParams(parentResizableView.getLayoutParams());
+ }
}
public void pause() {
- if(mediaPlayer.isPlaying())
- mediaPlayer.pause();
+ if(mMediaPlayer.isPlaying())
+ mMediaPlayer.pause();
mHandler.removeCallbacks(mUpdateTimeTask);
-
sendMediaStatus();
}
public void sendMediaStatus() {
long totalDuration = 0;
long currentDuration = 0;
- if(!isPreparing) {
- totalDuration = mediaPlayer.getDuration();
- currentDuration = mediaPlayer.getCurrentPosition();
+ if(!isPreparing && canCallGetDuration) {
+ totalDuration = mMediaPlayer.getDuration();
+ currentDuration = mMediaPlayer.getCurrentPosition();
}
/*
@@ -169,21 +230,43 @@ public class PodcastPlaybackService extends Service {
songProgressBar.setProgress(progress);
*/
- UpdatePodcastStatusEvent audioPodcastEvent = new UpdatePodcastStatusEvent(currentDuration, totalDuration, mediaPlayer.isPlaying(), mediaTitle, isPreparing);
+ UpdatePodcastStatusEvent audioPodcastEvent = new UpdatePodcastStatusEvent(currentDuration, totalDuration, mMediaPlayer.isPlaying(), mediaTitle, isPreparing, canCallGetDuration, isVideoFile);
eventBus.post(audioPodcastEvent);
}
+ public class PodcastPlaybackServiceStarted {
+
+ }
+
+ /*
+ public class VideoAvailableState {
+ public VideoAvailableState(boolean isVideoAvailable) {
+ this.isVideoAvailable = isVideoAvailable;
+ }
+
+ public boolean isVideoAvailable;
+ }
+ */
+
+ int mSurfaceWidth;
+ int mSurfaceHeight;
+ SurfaceHolder mSurfaceHolder;
SurfaceHolder.Callback mSHCallback = new SurfaceHolder.Callback()
{
- public void surfaceChanged(SurfaceHolder holder, int format,
- int w, int h)
+ public void surfaceChanged(SurfaceHolder holder, int format, int surfaceWidth, int surfaceHeight)
{
- mSurfaceWidth = w;
- mSurfaceHeight = h;
- if (mIsPrepared && mVideoWidth == w && mVideoHeight == h) {
+ mSurfaceWidth = surfaceWidth;
+ mSurfaceHeight = surfaceHeight;
+
+ //populateVideo();
+
+ //Log.d(TAG, "surfaceChanged");
+
+ /*
+ if (!isPreparing && mVideoWidth == w && mVideoHeight == h) {
if (mSeekWhenPrepared != 0) {
mMediaPlayer.seekTo(mSeekWhenPrepared);
}
@@ -192,24 +275,22 @@ public class PodcastPlaybackService extends Service {
mMediaController.show();
}
}
+ */
}
public void surfaceCreated(SurfaceHolder holder)
{
mSurfaceHolder = holder;
- openVideo();
+ mMediaPlayer.setDisplay(mSurfaceHolder);
+
+ mMediaPlayer.setScreenOnWhilePlaying(true);
+
+ Log.d(TAG, "surfaceCreated");
}
public void surfaceDestroyed(SurfaceHolder holder)
{
- // after we return from this we can't use the surface any more
- mSurfaceHolder = null;
- if (mMediaController != null) mMediaController.hide();
- if (mMediaPlayer != null) {
- mMediaPlayer.reset();
- mMediaPlayer.release();
- mMediaPlayer = null;
- }
+ Log.d(TAG, "surfaceDestroyed");
}
};
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/OnPinchListener.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/OnPinchListener.java
new file mode 100644
index 00000000..03689b95
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/OnPinchListener.java
@@ -0,0 +1,44 @@
+package de.luhmer.owncloudnewsreader.view;
+
+import android.view.ScaleGestureDetector;
+
+/**
+ * Created by David on 30.06.2014.
+ */
+public class OnPinchListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
+
+ private float mScaleFactor = 1.f;
+
+ ZoomableRelativeLayout mZoomableRelativeLayout;
+
+ public OnPinchListener(ZoomableRelativeLayout mZoomableRelativeLayout) {
+ this.mZoomableRelativeLayout = mZoomableRelativeLayout;
+ }
+
+ float startingSpan;
+ float endSpan;
+ float startFocusX;
+ float startFocusY;
+
+
+ public boolean onScaleBegin(ScaleGestureDetector detector) {
+ startingSpan = detector.getCurrentSpan();
+ startFocusX = detector.getFocusX();
+ startFocusY = detector.getFocusY();
+ return true;
+ }
+
+
+
+
+ /*
+ public boolean onScale(ScaleGestureDetector detector) {
+ mZoomableRelativeLayout.scale(detector.getCurrentSpan()/startingSpan, startFocusX, startFocusY);
+ return true;
+ }
+ */
+
+ public void onScaleEnd(ScaleGestureDetector detector) {
+ //mZoomableRelativeLayout.restore();
+ }
+} \ No newline at end of file
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java
index 116db3d8..a54f3095 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java
@@ -54,19 +54,10 @@ public class PodcastNotification {
int lastDrawableId;
- long lastUpdate = 0;
- int seconds = 1;//Time of delay between each update
public void onEvent(UpdatePodcastStatusEvent podcast) {
- /*
- long current = new Date().getTime();
-
- if((lastUpdate + (1000 * seconds)) > current) {
+ if(!podcast.isFileLoaded())
return;
- } else {
- lastUpdate = current;
- }
- */
int drawableId = podcast.isPlaying() ? android.R.drawable.ic_media_pause : android.R.drawable.ic_media_play;
String actionText = podcast.isPlaying() ? "Pause" : "Play";
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastSlidingUpPanelLayout.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastSlidingUpPanelLayout.java
index 6cc2216b..650869c4 100644
--- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastSlidingUpPanelLayout.java
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastSlidingUpPanelLayout.java
@@ -25,9 +25,9 @@ public class PodcastSlidingUpPanelLayout extends SlidingUpPanelLayout{
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
- //return super.onInterceptTouchEvent(ev);
+ return super.onInterceptTouchEvent(ev);
- return isDragViewHit((int)ev.getX(), (int)ev.getY());
+ //return isDragViewHit((int)ev.getX(), (int)ev.getY());
}
private View mDragView;
diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/ZoomableRelativeLayout.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/ZoomableRelativeLayout.java
new file mode 100644
index 00000000..fdb7958a
--- /dev/null
+++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/ZoomableRelativeLayout.java
@@ -0,0 +1,242 @@
+package de.luhmer.owncloudnewsreader.view;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.GestureDetector;
+import android.view.MotionEvent;
+import android.view.ScaleGestureDetector;
+import android.widget.RelativeLayout;
+
+import de.greenrobot.event.EventBus;
+import de.luhmer.owncloudnewsreader.events.podcast.VideoDoubleClicked;
+
+/**
+ * Created by David on 30.06.2014.
+ */
+//http://stackoverflow.com/questions/10013906/android-zoom-in-out-relativelayout-with-spread-pinch
+public class ZoomableRelativeLayout extends RelativeLayout {
+ private static final int INVALID_POINTER_ID = -1;
+ private static final int INVALID_SIZE = -1;
+
+
+ public boolean disableScale = false;
+ public void setDisableScale(boolean disableScale) {
+ this.disableScale = disableScale;
+ }
+
+ private static final String TAG = "ZoomableRelativeLayout";
+
+ private GestureDetector mDoubleTapDetector;
+ private ScaleGestureDetector mScaleDetector;
+ float mScaleFactor = 1;
+ public float getScaleFactor() {
+ return mScaleFactor;
+ }
+
+ float mPosX;
+ float mPosY;
+ private float mLastTouchX;
+ private float mLastTouchY;
+ private int mActivePointerId;
+
+ private float mInitHeight = INVALID_SIZE;
+ private float mInitWidth = INVALID_SIZE;
+
+ public ZoomableRelativeLayout(Context context) {
+ super(context);
+ initZoomView(context);
+ }
+
+ public ZoomableRelativeLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ initZoomView(context);
+ }
+
+ public ZoomableRelativeLayout(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+ initZoomView(context);
+ }
+
+
+ boolean mPositionReady = false;
+ public boolean isPositionReady() {
+ return mPositionReady;
+ }
+
+ @Override
+ public void onWindowFocusChanged(boolean hasWindowFocus) {
+ if(hasWindowFocus) {
+ readVideoPosition();
+ mPositionReady = true;
+ }
+ super.onWindowFocusChanged(hasWindowFocus);
+ }
+
+
+
+ public void readVideoPosition() {
+ int position[] = new int[2];
+ getLocationOnScreen(position);
+ mVideoXPosition = position[0];
+ mVideoYPosition = position[1];
+
+ Log.d(TAG, "Grabbing new Video Wrapper Position. X:" + mVideoXPosition + " - Y:" + mVideoYPosition);
+
+ //mVideoXPosition = getX();
+ //mVideoYPosition = getY();
+ }
+
+ private void initZoomView(Context context) {
+ // Create our ScaleGestureDetector
+ mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
+ mDoubleTapDetector = new GestureDetector(context, new DoubleTapListener());
+ }
+
+ /*
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ canvas.save(Canvas.MATRIX_SAVE_FLAG);
+ canvas.scale(mScaleFactor, mScaleFactor, mPosX, mPosY);
+ super.dispatchDraw(canvas);
+ canvas.restore();
+ }*/
+
+ private class DoubleTapListener extends GestureDetector.SimpleOnGestureListener {
+
+ // event when double tap occurs
+ @Override
+ public boolean onDoubleTap(MotionEvent e) {
+ float x = e.getX();
+ float y = e.getY();
+
+ Log.d("Double Tap", "Tapped at: (" + x + "," + y + ")");
+
+ EventBus.getDefault().post(new VideoDoubleClicked());
+
+ return true;
+ }
+ }
+
+
+ private float mVideoXPosition;
+ private float mVideoYPosition;
+ public float getVideoXPosition() {return mVideoXPosition;}
+ public float getVideoYPosition() {return mVideoYPosition;}
+
+ private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
+ @Override
+ public void onScaleEnd(ScaleGestureDetector detector) {
+ if(!disableScale) {
+ readVideoPosition();
+ }
+
+ super.onScaleEnd(detector);
+ }
+
+ @Override
+ public boolean onScale(ScaleGestureDetector detector) {
+ if(disableScale)
+ return true;
+
+ if(mInitWidth == INVALID_SIZE) {
+ mInitWidth = getWidth();
+ mInitHeight = getHeight();
+ }
+
+ mScaleFactor *= detector.getScaleFactor();
+
+ // Don't let the object get too small or too large.
+ mScaleFactor = Math.max(0.1f, Math.min(mScaleFactor, 5.0f));
+
+ Log.d(TAG, "Scale:" + mScaleFactor);
+
+
+ getLayoutParams().width = (int)(mInitWidth * mScaleFactor);
+ getLayoutParams().height = (int)(mInitHeight * mScaleFactor);
+ setLayoutParams(getLayoutParams());
+
+ //invalidate();
+ return true;
+ }
+ }
+
+
+ /*
+ public void restore() {
+ mScaleFactor = 1;
+ this.invalidate();
+ }*/
+
+
+
+ @Override
+ public boolean onTouchEvent(MotionEvent ev) {
+ // Let the ScaleGestureDetector inspect all events.
+ mScaleDetector.onTouchEvent(ev);
+ mDoubleTapDetector.onTouchEvent(ev);
+
+ final int action = ev.getAction();
+ switch (action & MotionEvent.ACTION_MASK) {
+ case MotionEvent.ACTION_DOWN: {
+ final float x = ev.getX();
+ final float y = ev.getY();
+
+ mLastTouchX = x;
+ mLastTouchY = y;
+ mActivePointerId = ev.getPointerId(0);
+ break;
+ }
+
+ case MotionEvent.ACTION_MOVE: {
+ final int pointerIndex = ev.findPointerIndex(mActivePointerId);
+ final float x = ev.getX(pointerIndex);
+ final float y = ev.getY(pointerIndex);
+
+ // Only move if the ScaleGestureDetector isn't processing a gesture.
+ if (!mScaleDetector.isInProgress()) {
+ final float dx = x - mLastTouchX;
+ final float dy = y - mLastTouchY;
+
+ mPosX += dx;
+ mPosY += dy;
+
+ invalidate();
+ }
+
+ mLastTouchX = x;
+ mLastTouchY = y;
+
+ break;
+ }
+
+ case MotionEvent.ACTION_UP: {
+ mActivePointerId = INVALID_POINTER_ID;
+ break;
+ }
+
+ case MotionEvent.ACTION_CANCEL: {
+ mActivePointerId = INVALID_POINTER_ID;
+ break;
+ }
+
+ case MotionEvent.ACTION_POINTER_UP: {
+ final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK)
+ >> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+ final int pointerId = ev.getPointerId(pointerIndex);
+ if (pointerId == mActivePointerId) {
+ // This was our active pointer going up. Choose a new
+ // active pointer and adjust accordingly.
+ final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+ mLastTouchX = ev.getX(newPointerIndex);
+ mLastTouchY = ev.getY(newPointerIndex);
+ mActivePointerId = ev.getPointerId(newPointerIndex);
+ }
+ break;
+ }
+ }
+
+ return true;
+ }
+
+} \ No newline at end of file
diff --git a/News-Android-App/src/main/res/drawable-hdpi/av_download.png b/News-Android-App/src/main/res/drawable-hdpi/av_download.png
new file mode 100644
index 00000000..5bceafb1
--- /dev/null
+++ b/News-Android-App/src/main/res/drawable-hdpi/av_download.png
Binary files differ
diff --git a/News-Android-App/src/main/res/drawable-xhdpi/av_download.png b/News-Android-App/src/main/res/drawable-xhdpi/av_download.png
new file mode 100644
index 00000000..dfe81e06
--- /dev/null
+++ b/News-Android-App/src/main/res/drawable-xhdpi/av_download.png
Binary files differ
diff --git a/News-Android-App/src/main/res/layout/activity_news_detail.xml b/News-Android-App/src/main/res/layout/activity_news_detail.xml
index 75db51e2..ef0ac220 100644
--- a/News-Android-App/src/main/res/layout/activity_news_detail.xml
+++ b/News-Android-App/src/main/res/layout/activity_news_detail.xml
@@ -48,4 +48,19 @@
</de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout>
+
+
+ <de.luhmer.owncloudnewsreader.view.ZoomableRelativeLayout
+ android:id="@+id/videoPodcastSurfaceWrapper"
+ android:layout_width="@dimen/podcast_video_player_width"
+ android:layout_height="100dp"
+ android:background="#ff7c7c7c"
+ android:padding="2dp"
+ android:layout_gravity="bottom|right"
+ android:layout_marginRight="@dimen/podcast_horizontal_margin"
+ android:layout_marginBottom="@dimen/activity_vertical_margin" >
+
+ </de.luhmer.owncloudnewsreader.view.ZoomableRelativeLayout>
+
+
</FrameLayout> \ No newline at end of file
diff --git a/News-Android-App/src/main/res/layout/activity_newsreader.xml b/News-Android-App/src/main/res/layout/activity_newsreader.xml
index a0dbc936..edf04201 100644
--- a/News-Android-App/src/main/res/layout/activity_newsreader.xml
+++ b/News-Android-App/src/main/res/layout/activity_newsreader.xml
@@ -25,44 +25,64 @@
</android.support.v4.widget.DrawerLayout>
-->
-
-<android.support.v4.widget.SlidingPaneLayout
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/sliding_pane"
android:layout_width="match_parent"
- android:layout_height="match_parent">
-
-
- <!-- android:name="de.luhmer.owncloudnewsreader.NewsReaderListFragment" -->
- <FrameLayout
- android:id="@+id/left_drawer"
- android:layout_width="wrap_content"
- android:layout_height="match_parent"
- android:layout_gravity="start" />
+ android:layout_height="match_parent" >
- <!-- android:name="de.luhmer.owncloudnewsreader.NewsReaderDetailFragment" -->
+ <android.support.v4.widget.SlidingPaneLayout
- <de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout
- xmlns:sothree="http://schemas.android.com/apk/res-auto"
- android:id="@+id/sliding_layout"
+ android:id="@+id/sliding_pane"
android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:gravity="bottom"
- sothree:panelHeight="68dp"
- sothree:shadowHeight="4dp"
- sothree:paralaxOffset="100dp"
- sothree:dragView="@+id/name">
+ android:layout_height="match_parent">
- <FrameLayout
- android:id="@+id/content_frame"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ <!-- android:name="de.luhmer.owncloudnewsreader.NewsReaderListFragment" -->
<FrameLayout
- android:id="@+id/podcast_frame"
+ android:id="@+id/left_drawer"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="start" />
+
+ <!-- android:name="de.luhmer.owncloudnewsreader.NewsReaderDetailFragment" -->
+
+
+ <de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout
+ xmlns:sothree="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/sliding_layout"
android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent"
+ android:gravity="bottom"
+ sothree:panelHeight="68dp"
+ sothree:shadowHeight="4dp"
+ sothree:paralaxOffset="100dp"
+ sothree:dragView="@+id/name">
+
+ <FrameLayout
+ android:id="@+id/content_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <FrameLayout
+ android:id="@+id/podcast_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout>
+
+ </android.support.v4.widget.SlidingPaneLayout>
+
+
+ <de.luhmer.owncloudnewsreader.view.ZoomableRelativeLayout
+ android:id="@+id/videoPodcastSurfaceWrapper"
+ android:layout_width="@dimen/podcast_video_player_width"
+ android:layout_height="100dp"
+ android:background="#ff7c7c7c"
+ android:padding="2dp"
+ android:layout_gravity="bottom|right"
+ android:layout_marginRight="@dimen/podcast_horizontal_margin"
+ android:layout_marginBottom="@dimen/activity_vertical_margin" >
- </de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout>
+ </de.luhmer.owncloudnewsreader.view.ZoomableRelativeLayout>
-</android.support.v4.widget.SlidingPaneLayout> \ No newline at end of file
+</FrameLayout> \ No newline at end of file
diff --git a/News-Android-App/src/main/res/layout/activity_newsreader_twopane.xml b/News-Android-App/src/main/res/layout/activity_newsreader_twopane.xml
index 9a381234..c07c341d 100644
--- a/News-Android-App/src/main/res/layout/activity_newsreader_twopane.xml
+++ b/News-Android-App/src/main/res/layout/activity_newsreader_twopane.xml
@@ -1,43 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
-<android.support.v4.widget.SlidingPaneLayout
+
+<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
- android:id="@+id/sliding_pane"
android:layout_width="match_parent"
- android:layout_height="match_parent">
-
-
- <!-- android:name="de.luhmer.owncloudnewsreader.NewsReaderListFragment" -->
- <FrameLayout
- android:id="@+id/left_drawer"
- android:layout_width="350dp"
- android:layout_height="match_parent"
- android:layout_gravity="start" />
-
- <!-- android:name="de.luhmer.owncloudnewsreader.NewsReaderDetailFragment" -->
-
- <de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout
- xmlns:sothree="http://schemas.android.com/apk/res-auto"
- android:id="@+id/sliding_layout"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="bottom"
- sothree:panelHeight="68dp"
- sothree:shadowHeight="4dp"
- sothree:paralaxOffset="100dp"
- sothree:dragView="@+id/name">
-
- <FrameLayout
- android:id="@+id/content_frame"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
+ android:layout_height="match_parent" >
- <FrameLayout
- android:id="@+id/podcast_frame"
- android:layout_width="match_parent"
- android:layout_height="match_parent" />
-
- </de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout>
+ <android.support.v4.widget.SlidingPaneLayout
+ android:id="@+id/sliding_pane"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
-</android.support.v4.widget.SlidingPaneLayout>
+ <!-- android:name="de.luhmer.owncloudnewsreader.NewsReaderListFragment" -->
+ <FrameLayout
+ android:id="@+id/left_drawer"
+ android:layout_width="350dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="start" />
+
+ <!-- android:name="de.luhmer.owncloudnewsreader.NewsReaderDetailFragment" -->
+
+ <de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout
+ xmlns:sothree="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/sliding_layout"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:gravity="bottom"
+ sothree:panelHeight="68dp"
+ sothree:shadowHeight="4dp"
+ sothree:paralaxOffset="100dp"
+ sothree:dragView="@+id/name">
+
+ <FrameLayout
+ android:id="@+id/content_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ <FrameLayout
+ android:id="@+id/podcast_frame"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </de.luhmer.owncloudnewsreader.view.PodcastSlidingUpPanelLayout>
+
+
+ </android.support.v4.widget.SlidingPaneLayout>
+
+ <de.luhmer.owncloudnewsreader.view.ZoomableRelativeLayout
+ android:id="@+id/videoPodcastSurfaceWrapper"
+ android:layout_width="@dimen/podcast_video_player_width"
+ android:layout_height="100dp"
+ android:background="#ff7c7c7c"
+ android:padding="2dp"
+ android:layout_gravity="bottom|right"
+ android:layout_marginRight="@dimen/podcast_horizontal_margin"
+ android:layout_marginBottom="@dimen/activity_vertical_margin" >
+
+ </de.luhmer.owncloudnewsreader.view.ZoomableRelativeLayout>
+
+</FrameLayout> \ No newline at end of file
diff --git a/News-Android-App/src/main/res/layout/fragment_news_detail.xml b/News-Android-App/src/main/res/layout/fragment_news_detail.xml
index 43ac1206..a43d8558 100644
--- a/News-Android-App/src/main/res/layout/fragment_news_detail.xml
+++ b/News-Android-App/src/main/res/layout/fragment_news_detail.xml
@@ -1,10 +1,10 @@
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_height="match_parent"
tools:context=".NewsDetailActivity$NewsDetailFragment" >
-
-
+
+
<WebView
android:id="@+id/webview"
android:layout_width="match_parent"
diff --git a/News-Android-App/src/main/res/layout/fragment_podcast.xml b/News-Android-App/src/main/res/layout/fragment_podcast.xml
index a9b04b9c..38c82dda 100644
--- a/News-Android-App/src/main/res/layout/fragment_podcast.xml
+++ b/News-Android-App/src/main/res/layout/fragment_podcast.xml
@@ -32,14 +32,14 @@
android:layout_height="match_parent"
android:layout_marginRight="10dp"
android:gravity="center_vertical"
- android:paddingLeft="@dimen/activity_horizontal_margin"
+ android:paddingLeft="@dimen/podcast_horizontal_margin"
android:orientation="vertical">
<TextView
android:id="@+id/tv_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text="No title selected"
+ android:text="@string/no_podcast_selected"
android:ellipsize="end"
android:textSize="16sp"
android:textStyle="bold"
@@ -81,7 +81,7 @@
android:id="@+id/fl_playPausePodcastWrapper"
android:layout_width="wrap_content"
android:layout_height="match_parent"
- android:paddingRight="@dimen/activity_horizontal_margin">
+ android:paddingRight="@dimen/podcast_horizontal_margin">
<ImageButton
android:id="@+id/btn_playPausePodcast"
@@ -148,8 +148,8 @@
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin">
+ android:paddingLeft="@dimen/podcast_horizontal_margin"
+ android:paddingRight="@dimen/podcast_horizontal_margin">
<!--
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
@@ -218,11 +218,9 @@
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:paddingLeft="@dimen/activity_horizontal_margin"
- android:paddingRight="@dimen/activity_horizontal_margin"
- android:paddingBottom="@dimen/activity_vertical_margin"
- android:paddingTop="@dimen/activity_vertical_margin"
+ android:layout_height="@dimen/podcast_media_control_height"
+ android:paddingLeft="@dimen/podcast_horizontal_margin"
+ android:paddingRight="@dimen/podcast_horizontal_margin"
android:background="@color/slide_up_panel_slider_background_color"
android:orientation="vertical">
@@ -245,6 +243,7 @@
android:layout_width="0dip"
android:layout_height="wrap_content"
android:layout_weight="1"
+ android:gravity="center"
android:progress="0"
android:max="100" />
@@ -269,7 +268,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:layout_marginRight="10dp"
+ android:layout_marginRight="20dp"
android:background="@drawable/av_rewind"/>
<ImageButton
@@ -277,7 +276,7 @@
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center_horizontal"
- android:layout_marginRight="10dp"
+ android:layout_marginRight="20dp"
android:background="@drawable/av_play"/>
<ImageButton
diff --git a/News-Android-App/src/main/res/layout/podcast_audio_row.xml b/News-Android-App/src/main/res/layout/podcast_audio_row.xml
deleted file mode 100644
index 7bf57269..00000000
--- a/News-Android-App/src/main/res/layout/podcast_audio_row.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="match_parent"
- android:layout_height="80dp"
- android:padding="10dp"
- android:gravity="center_vertical">
-
- <TextView
- android:id="@+id/tv_title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="16sp"
- android:textStyle="bold"
- android:text="Large Tex dfs hysjd kfhsakj lfhjdaksl fh"
- android:textColor="#ff161616"
- android:ellipsize="end"
- android:maxLines="2" />
-
-
- <TextView
- android:id="@+id/tv_body"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textSize="15sp"
- android:text="3 Podcasts verfügbar!"
- android:textColor="#ff161616" />
-
-</LinearLayout> \ No newline at end of file
diff --git a/News-Android-App/src/main/res/layout/podcast_row.xml b/News-Android-App/src/main/res/layout/podcast_row.xml
new file mode 100644
index 00000000..81b8244c
--- /dev/null
+++ b/News-Android-App/src/main/res/layout/podcast_row.xml
@@ -0,0 +1,105 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingLeft="10dp"
+ android:paddingTop="10dp"
+ android:paddingBottom="10dp"
+ android:gravity="center_vertical">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+
+ <TextView
+ android:id="@+id/tv_title"
+ android:layout_width="wrap_content"
+ android:layout_height="40dp"
+ android:textSize="16sp"
+ android:textStyle="bold"
+ android:text="Large Tex dfs hysjd kfhsakj lfhjdaksl fh"
+ android:textColor="#ff161616"
+ android:ellipsize="end"
+ android:maxLines="2" />
+
+
+ <TextView
+ android:id="@+id/tv_body"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textSize="15sp"
+ android:text="3 Podcasts verfügbar!"
+ android:textColor="#ff161616" />
+
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <ProgressBar
+ style="?android:attr/progressBarStyleHorizontal"
+ android:id="@+id/pbDownloadPodcast"
+ android:layout_width="0dip"
+ android:layout_weight="1"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:max="100"
+ android:progress="0"/>
+
+ <TextView
+ android:id="@+id/tvDownloadPodcastProgress"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_marginLeft="10dp"
+ android:text="100%"
+ android:gravity="center_vertical"
+ android:textColor="#ff161616"/>
+ </LinearLayout>
+
+ </LinearLayout>
+
+ <FrameLayout
+ android:id="@+id/fl_downloadPodcastWrapper"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:paddingRight="@dimen/podcast_horizontal_margin">
+
+ <ImageButton
+ android:id="@+id/btn_downloadPodcast"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:duplicateParentState="true"
+ android:clickable="false"
+ android:focusable="false"
+ android:layout_gravity="center"
+ android:background="@drawable/av_download" />
+
+ </FrameLayout>
+
+
+ <FrameLayout
+ android:id="@+id/fl_PlayPodcastWrapper"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"
+ android:paddingRight="@dimen/podcast_horizontal_margin">
+
+ <ImageButton
+ android:id="@+id/btn_playPodcast"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:duplicateParentState="true"
+ android:clickable="false"
+ android:focusable="false"
+ android:layout_gravity="center"
+ android:background="@drawable/av_play" />
+
+ </FrameLayout>
+
+</LinearLayout> \ No newline at end of file
diff --git a/News-Android-App/src/main/res/values-el/strings.xml b/News-Android-App/src/main/res/values-el/strings.xml
index 7d6fb96f..9d3812d9 100644
--- a/News-Android-App/src/main/res/values-el/strings.xml
+++ b/News-Android-App/src/main/res/values-el/strings.xml
@@ -101,6 +101,8 @@
<string name="mtm_decision_abort">Ματαίωση</string>
<string name="mtm_notification">Επαλήθευση Πιστοποιητικού</string>
<!--Podcast-->
+ <string name="pref_header_podcast">Podcast</string>
+ <string name="pref_enable_podcasts">Ενεργοποίηση υποστήριξης Podcast</string>
<!--Settings for Display-->
<string name="pref_header_display">Εμφάνιση</string>
<string name="pref_title_app_theme">Θέμα εφαρμογής (απαιτεί επανεκκίνηση για εφαρμογή)</string>
@@ -230,4 +232,5 @@
<string name="pref_title_ringtone">Ringtone</string>
<string name="pref_ringtone_silent">Silent</string>
<string name="pref_title_vibrate">Vibrate</string>-->
+ <string name="hello_blank_fragment">Hello blank fragment</string>
</resources>
diff --git a/News-Android-App/src/main/res/values-en-rGB/strings.xml b/News-Android-App/src/main/res/values-en-rGB/strings.xml
index 32c077d7..a6f09076 100644
--- a/News-Android-App/src/main/res/values-en-rGB/strings.xml
+++ b/News-Android-App/src/main/res/values-en-rGB/strings.xml
@@ -101,6 +101,8 @@
<string name="mtm_decision_abort">Abort</string>
<string name="mtm_notification">Certificate Verification</string>
<!--Podcast-->
+ <string name="pref_header_podcast">Podcast</string>
+ <string name="pref_enable_podcasts">Enable Podcast support</string>
<!--Settings for Display-->
<string name="pref_header_display">Display</string>
<string name="pref_title_app_theme">App theme (requires restart to apply)</string>
@@ -230,4 +232,5 @@
<string name="pref_title_ringtone">Ringtone</string>
<string name="pref_ringtone_silent">Silent</string>
<string name="pref_title_vibrate">Vibrate</string>-->
+ <string name="hello_blank_fragment">Hello blank fragment</string>
</resources>
diff --git a/News-Android-App/src/main/res/values-et-rEE/strings.xml b/News-Android-App/src/main/res/values-et-rEE/strings.xml
index 5c5f3ab3..6672a4a3 100644
--- a/News-Android-App/src/main/res/values-et-rEE/strings.xml
+++ b/News-Android-App/src/main/res/values-et-rEE/strings.xml
@@ -232,4 +232,5 @@
<string name="pref_title_ringtone">Ringtone</string>
<string name="pref_ringtone_silent">Silent</string>
<string name="pref_title_vibrate">Vibrate</string>-->
+ <string name="hello_blank_fragment">Tere tühi osa</string>
</resources>
diff --git a/News-Android-App/src/main/res/values-eu/strings.xml b/News-Android-App/src/main/res/values-eu/strings.xml
index 065a10c7..2955f798 100644
--- a/News-Android-App/src/main/res/values-eu/strings.xml
+++ b/News-Android-App/src/main/res/values-eu/strings.xml
@@ -1,6 +1,8 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
+ <string name="auto_sync_string">Sinkronizazio Automatikoa</string>
<string name="app_name">ownCloud berri rakurlea</string>
+ <string name="title_activity_sync_interval_selector">Sinkronizazio Tartearen Hautatzailea</string>
<string name="title_newsreader_list">BerriIrakurlea</string>
<string name="title_newsreader_detail">BerriIrakurle xehetasuna</string>
<string name="empty_view_header">Informazioa</string>
@@ -11,16 +13,19 @@
<string name="do_you_want_to_download_without_wifi">Irudiak WiFi konexioa gabe deskargatu nahi dituzu</string>
<string name="max_items_count_reached">XX elementu kopuru maximora iritsi zara</string>
<string name="widget_header">ownCloud Berriak</string>
+ <string name="message_bar_new_articles_available">Artikulu berriak daude</string>
<string name="message_bar_reload">Birkargatu</string>
<string name="allUnreadFeeds">Irakurri gabeko elementu guztiak</string>
<string name="starredFeeds">Izardun elementuak</string>
<string name="title_activity_new_feed">Gehitu iturburu berria</string>
<!--<string name="non_sorted_articles">Nicht zugeordnete Artikel</string>-->
<string name="menu_update">Birkargatu</string>
+ <string name="menu_About_Changelog">Honi Buruz / Aldaketak</string>
<string name="menu_markAllAsRead">Markatu guztiak irakurria gisa</string>
<string name="menu_StartImageCaching">Deskargatu irudiak</string>
<string name="menu_downloadMoreItems">Deskargatu elementu gehiago</string>
<!--Import Accounts-->
+ <string name="import_account_dialog_title">Inportatu Kontua</string>
<!--EMAIL-->
<string name="email_sendMail">Bidali eposta</string>
<!--Action Bar Items-->
@@ -32,7 +37,10 @@
<string name="action_login">Zerbitzariaren ezarpenak</string>
<string name="action_save">Gorde</string>
<string name="action_settings">Ezarpenak</string>
+ <string name="action_sync_settings">Sinkronizazio Ezarpenak</string>
<string name="action_add_new_feed">Gehitu iturburu berria</string>
+ <string name="notification_new_items_ticker">Irakurri gabeko X artikulu dituzu</string>
+ <string name="notification_new_items_text">Irakurri gabeko X artikulu</string>
<!--Strings related to login-->
<string name="pref_title_username">Erabiltzaile izena</string>
<string name="pref_title_password">Pasahitza</string>
@@ -53,6 +61,7 @@
<string name="title_activity_settings">Ezarpenak</string>
<!--General settings-->
<string name="pref_header_general">Orokorra</string>
+ <string name="pref_title_general_sort_order">Antolatzeko Ordena</string>
<string-array name="pref_general_sort_order">
<item>Berria -&gt; Zaharra</item>
<item>Zaharra -&gt; Berria</item>
@@ -74,13 +83,19 @@
<string name="pref_title_AutoSyncOnStart">Sinkronizatu abioan</string>
<string name="pref_title_ShowOnlyUnread">Erakutsi irakurri gabeko artikuluak bakarrik</string>
<!--<string name="pref_title_AllowAllSSLCertificates">Allow all SSL Certificates</string>-->
+ <string name="pref_title_DisableHostnameVerification">Ezgaitu Hostalari Izenaren Egiaztapena</string>
<string name="pref_title_NavigateWithVolumeButtons">Mugitu bolumen botoiekin</string>
+ <string name="pref_title_OpenInBrowserDirectly">Saltatu zehaztapen bistaratzea eta ireki artikulua arkataztailean</string>
+ <string name="pref_title_notification_new_articles_available">Bistaratu jakinarazpenak artikulu berriak daudenean</string>
<!--MemorizingTrustManager-->
+ <string name="mtm_accept_cert">Onartu Ziurtagiri Ezezaguna</string>
<string name="mtm_decision_always">Beti</string>
<string name="mtm_decision_once">Behin</string>
<string name="mtm_decision_abort">Bertan-behera utzi</string>
<string name="mtm_notification">Ziurtagiriaren Egiaztapena</string>
<!--Podcast-->
+ <string name="pref_header_podcast">Podcast</string>
+ <string name="pref_enable_podcasts">Gaitu Podcastak</string>
<!--Settings for Display-->
<string name="pref_header_display">Bistaratzea</string>
<string name="pref_title_app_theme">App gaia (ezartzeko berrabiaraztea beharrezkoa)</string>
@@ -143,6 +158,30 @@
<item>5000</item>
<item>10000</item>
</string-array>
+ <string-array name="array_sync_interval">
+ <item>5 Minutu</item>
+ <item>15 Minutu</item>
+ <item>30 Minutu</item>
+ <item>45 Minutu</item>
+ <item>1 Ordu</item>
+ <item>2 Ordu</item>
+ <item>3 Ordu</item>
+ <item>6 Ordu</item>
+ <item>12 Ordu</item>
+ <item>24 Ordu</item>
+ </string-array>
+ <string-array name="array_sync_interval_values">
+ <item>5</item>
+ <item>15</item>
+ <item>30</item>
+ <item>45</item>
+ <item>60</item>
+ <item>120</item>
+ <item>180</item>
+ <item>360</item>
+ <item>720</item>
+ <item>1440</item>
+ </string-array>
<!--<string name="pref_title_sync_frequency">Sync frequency</string>
<string-array name="pref_sync_frequency_titles">
diff --git a/News-Android-App/src/main/res/values-fr/strings.xml b/News-Android-App/src/main/res/values-fr/strings.xml
index 87e3f590..fab3e818 100644
--- a/News-Android-App/src/main/res/values-fr/strings.xml
+++ b/News-Android-App/src/main/res/values-fr/strings.xml
@@ -101,6 +101,8 @@
<string name="mtm_decision_abort">Annuler</string>
<string name="mtm_notification">Vérification du certificat</string>
<!--Podcast-->
+ <string name="pref_header_podcast">Podcast</string>
+ <string name="pref_enable_podcasts">Activer le support des Podcasts</string>
<!--Settings for Display-->
<string name="pref_header_display">Affichage</string>
<string name="pref_title_app_theme">Thème (nécessite un redémarrage)</string>
diff --git a/News-Android-App/src/main/res/values-gl/strings.xml b/News-Android-App/src/main/res/values-gl/strings.xml
index d0760bd6..36e0dd8c 100644
--- a/News-Android-App/src/main/res/values-gl/strings.xml
+++ b/News-Android-App/src/main/res/values-gl/strings.xml
@@ -232,4 +232,5 @@
<string name="pref_title_ringtone">Ringtone</string>
<string name="pref_ringtone_silent">Silent</string>
<string name="pref_title_vibrate">Vibrate</string>-->
+ <string name="hello_blank_fragment">Ola, fragmento en branco</string>
</resources>
diff --git a/News-Android-App/src/main/res/values-nb-rNO/strings.xml b/News-Android-App/src/main/res/values-nb-rNO/strings.xml
index af9176b4..1c3f92c4 100644
--- a/News-Android-App/src/main/res/values-nb-rNO/strings.xml
+++ b/News-Android-App/src/main/res/values-nb-rNO/strings.xml
@@ -101,6 +101,8 @@
<string name="mtm_decision_abort">Avbryt</string>
<string name="mtm_notification">Sertifikatverifikasjon</string>
<!--Podcast-->
+ <string name="pref_header_podcast">Podcast</string>
+ <string name="pref_enable_podcasts">Aktiver støtte for Podcast</string>
<!--Settings for Display-->
<string name="pref_header_display">Vis</string>
<string name="pref_title_app_theme">Applikasjonstema (krever omstart)</string>
@@ -230,4 +232,5 @@
<string name="pref_title_ringtone">Ringtone</string>
<string name="pref_ringtone_silent">Silent</string>
<string name="pref_title_vibrate">Vibrate</string>-->
+ <string name="hello_blank_fragment">Hallo tomt fragment</string>
</resources>
diff --git a/News-Android-App/src/main/res/values-nl/strings.xml b/News-Android-App/src/main/res/values-nl/strings.xml
index 49b58b26..016fa274 100644
--- a/News-Android-App/src/main/res/values-nl/strings.xml
+++ b/News-Android-App/src/main/res/values-nl/strings.xml
@@ -101,6 +101,8 @@
<string name="mtm_decision_abort">Afbreken</string>
<string name="mtm_notification">Certificaat verificatie</string>
<!--Podcast-->
+ <string name="pref_header_podcast">Podcast</string>
+ <string name="pref_enable_podcasts">Activeren Podcast ondersteuning</string>
<!--Settings for Display-->
<string name="pref_header_display">Weergeven</string>
<string name="pref_title_app_theme">App thema (vereist herstarten)</string>
@@ -230,4 +232,5 @@
<string name="pref_title_ringtone">Ringtone</string>
<string name="pref_ringtone_silent">Silent</string>
<string name="pref_title_vibrate">Vibrate</string>-->
+ <string name="hello_blank_fragment">Hallo blanco fragment</string>
</resources>
diff --git a/News-Android-App/src/main/res/values-pl/strings.xml b/News-Android-App/src/main/res/values-pl/strings.xml
index 32a8a39e..026746c7 100644
--- a/News-Android-App/src/main/res/values-pl/strings.xml
+++ b/News-Android-App/src/main/res/values-pl/strings.xml
@@ -101,6 +101,8 @@
<string name="mtm_decision_abort">Anuluj</string>
<string name="mtm_notification">Certyfikat weryfikacji</string>
<!--Podcast-->
+ <string name="pref_header_podcast">Podcast</string>
+ <string name="pref_enable_podcasts">Włącz obsługę Podcastów</string>
<!--Settings for Display-->
<string name="pref_header_display">Wygląd</string>
<string name="pref_title_app_theme">Szablon aplikacji (wymagany restart aplikacji)</string>
@@ -230,4 +232,5 @@
<string name="pref_title_ringtone">Ringtone</string>
<string name="pref_ringtone_silent">Silent</string>
<string name="pref_title_vibrate">Vibrate</string>-->
+ <string name="hello_blank_fragment">Witam pusty fragment</string>
</resources>
diff --git a/News-Android-App/src/main/res/values-pt-rBR/strings.xml b/News-Android-App/src/main/res/values-pt-rBR/strings.xml
index cad5ce87..3de77a61 100644
--- a/News-Android-App/src/main/res/values-pt-rBR/strings.xml
+++ b/News-Android-App/src/main/res/values-pt-rBR/strings.xml
@@ -101,6 +101,8 @@
<string name="mtm_decision_abort">Abortar</string>
<string name="mtm_notification">Verificação de Certificado</string>
<!--Podcast-->
+ <string name="pref_header_podcast">Podcast</string>
+ <string name="pref_enable_podcasts">Ativar o suporte Podcast</string>
<!--Settings for Display-->
<string name="pref_header_display">Exibir</string>
<string name="pref_title_app_theme">Tema do aplicativo (é preciso reiniciar o aplicativo para as mudanças terem efeito)</string>
@@ -230,4 +232,5 @@
<string name="pref_title_ringtone">Ringtone</string>
<string name="pref_ringtone_silent">Silent</string>
<string name="pref_title_vibrate">Vibrate</string>-->
+ <string name="hello_blank_fragment">Olá fragmento em branco</string>
</resources>
diff --git a/News-Android-App/src/main/res/values-ro/strings.xml b/News-Android-App/src/main/res/values-ro/strings.xml
index a398e730..62902f17 100644
--- a/News-Android-App/src/main/res/values-ro/strings.xml
+++ b/News-Android-App/src/main/res/values-ro/strings.xml
@@ -1,8 +1,9 @@
<?xml version='1.0' encoding='UTF-8'?>
<resources>
+ <string name="auto_sync_string">Sincronizare Auto</string>
<string name="empty_view_header">Informaţii</string>
<string name="no_wifi_available">Nu exista conexiune WiFi</string>
- <string name="message_bar_reload">Reîncarca</string>
+ <string name="message_bar_reload">Reîncarcă</string>
<string name="title_activity_new_feed">Adaugă flux nou</string>
<!--<string name="non_sorted_articles">Nicht zugeordnete Artikel</string>-->
<string name="menu_update">Împrospătare</string>
@@ -14,10 +15,12 @@
<!--Action Bar Items-->
<string name="action_starred">Marcat</string>
<string name="action_read">Citeşte</string>
+ <string name="action_openInBrowser">Deschide in Browser</string>
<string name="action_Share">Partajează</string>
<string name="action_login">Setările serverului</string>
<string name="action_save">Salvează</string>
<string name="action_settings">Setări</string>
+ <string name="action_sync_settings">Setări Sincronizare</string>
<string name="action_add_new_feed">Adaugă flux nou</string>
<!--Strings related to login-->
<string name="pref_title_username">Nume utilizator</string>
@@ -45,6 +48,7 @@
<!--<string name="pref_title_AllowAllSSLCertificates">Allow all SSL Certificates</string>-->
<string name="pref_title_NavigateWithVolumeButtons">Navigheaza cu tastele de volum </string>
<!--MemorizingTrustManager-->
+ <string name="mtm_accept_cert">Accepta Certificat Necunoscut?</string>
<string name="mtm_decision_always">Întotdeauna</string>
<string name="mtm_decision_once">O data</string>
<string name="mtm_decision_abort">Anuleaza</string>
@@ -56,6 +60,8 @@
<string name="login_dialog_title_security_warning">Avertisment de securitate</string>
<!--Data & Sync-->
<!--<string name="pref_title_data_sync_max_items">Max number of items to sync</string>-->
+ <string name="pref_title_clearCache">Sterge cache</string>
+ <string name="pref_title_Max_Cache_Size">Mărime maximă Cache</string>
<!--<string name="pref_title_sync_frequency">Sync frequency</string>
<string-array name="pref_sync_frequency_titles">
diff --git a/News-Android-App/src/main/res/values-sl/strings.xml b/News-Android-App/src/main/res/values-sl/strings.xml
index 24ea6211..9c7f34c2 100644
--- a/News-Android-App/src/main/res/values-sl/strings.xml
+++ b/News-Android-App/src/main/res/values-sl/strings.xml
@@ -101,6 +101,8 @@
<string name="mtm_decision_abort">Prekini</string>
<string name="mtm_notification">Overitev digitalnih potrdil</string>
<!--Podcast-->
+ <string name="pref_header_podcast">Podcast</string>
+ <string name="pref_enable_podcasts">Omogoči podporo protokolu podcast</string>
<!--Settings for Display-->
<string name="pref_header_display">Prikaz</string>
<string name="pref_title_app_theme">Tema programa (pred uporabo je treba program ponovno zagnati)</string>
@@ -230,4 +232,5 @@
<string name="pref_title_ringtone">Ringtone</string>
<string name="pref_ringtone_silent">Silent</string>
<string name="pref_title_vibrate">Vibrate</string>-->
+ <string name="hello_blank_fragment">To je prazno sporočilo</string>
</resources>
diff --git a/News-Android-App/src/main/res/values-sv/strings.xml b/News-Android-App/src/main/res/values-sv/strings.xml
index 1b62f3ba..27b39649 100644
--- a/News-Android-App/src/main/res/values-sv/strings.xml
+++ b/News-Android-App/src/main/res/values-sv/strings.xml
@@ -101,6 +101,8 @@
<string name="mtm_decision_abort">Avbryt</string>
<string name="mtm_notification">Verifikation av certifikat</string>
<!--Podcast-->
+ <string name="pref_header_podcast">Podcast</string>
+ <string name="pref_enable_podcasts">Aktivera Podcast support</string>
<!--Settings for Display-->
<string name="pref_header_display">Visa</string>
<string name="pref_title_app_theme">Tema (kräver omstart för att aktiveras)</string>
diff --git a/News-Android-App/src/main/res/values-tr/strings.xml b/News-Android-App/src/main/res/values-tr/strings.xml
index 02827f02..603c3384 100644
--- a/News-Android-App/src/main/res/values-tr/strings.xml
+++ b/News-Android-App/src/main/res/values-tr/strings.xml
@@ -101,6 +101,8 @@
<string name="mtm_decision_abort">İptal Et</string>
<string name="mtm_notification">Sertifika Doğrulama</string>
<!--Podcast-->
+ <string name="pref_header_podcast">Podcast</string>
+ <string name="pref_enable_podcasts">Podcast desteğini etkinleştir</string>
<!--Settings for Display-->
<string name="pref_header_display">Görüntüle</string>
<string name="pref_title_app_theme">Uygulama teması (uygulanması için yeniden başlatma gerekli)</string>
@@ -230,4 +232,5 @@
<string name="pref_title_ringtone">Ringtone</string>
<string name="pref_ringtone_silent">Silent</string>
<string name="pref_title_vibrate">Vibrate</string>-->
+ <string name="hello_blank_fragment">Merhaba boşluk parçası</string>
</resources>
diff --git a/News-Android-App/src/main/res/values/dimens.xml b/News-Android-App/src/main/res/values/dimens.xml
index 47dbea4c..c81e4012 100644
--- a/News-Android-App/src/main/res/values/dimens.xml
+++ b/News-Android-App/src/main/res/values/dimens.xml
@@ -8,12 +8,19 @@
<dimen name="listview_row_margin_right">10dp</dimen>
<dimen name="listview_row_margin_top">5dp</dimen>
<dimen name="listview_row_margin_bottom">5dp</dimen>
-
+
<dimen name="color_bar_of_feeds">4dp</dimen>
<dimen name="exp_listview_row_height">50dp</dimen>
-
-
+
+
<dimen name="listview_row_height_simple_view">80dp</dimen>
-
+
+
+ <dimen name="podcast_video_player_width">170dp</dimen>
+
+ <dimen name="podcast_horizontal_margin">16dp</dimen>
+
+ <dimen name="podcast_media_control_height">80dp</dimen>
+
</resources> \ No newline at end of file
diff --git a/News-Android-App/src/main/res/values/strings.xml b/News-Android-App/src/main/res/values/strings.xml
index 1a9b6cac..0ec9b21e 100644
--- a/News-Android-App/src/main/res/values/strings.xml
+++ b/News-Android-App/src/main/res/values/strings.xml
@@ -124,6 +124,8 @@
<!-- Podcast -->
<string name="pref_header_podcast">Podcast</string>
<string name="pref_enable_podcasts">Enable Podcast support</string>
+ <string name="no_podcast_selected">No podcast selected</string>
+
<!-- Settings for Display -->
diff --git a/News-Android-App/src/main/res/values/styles.xml b/News-Android-App/src/main/res/values/styles.xml
index f9333e39..4bc862e8 100644
--- a/News-Android-App/src/main/res/values/styles.xml
+++ b/News-Android-App/src/main/res/values/styles.xml
@@ -16,6 +16,7 @@
<!-- </style> -->
<!-- <style name="AppBaseTheme" parent="android:Theme.Light"></style> -->
+ <!-- <style name="AppBaseTheme" parent="@style/android:Theme.Material"></style> -->
<style name="AppBaseTheme" parent="@style/Theme.Sherlock"></style>
<!-- Application theme. -->