diff options
author | David Luhmer <david-dev@live.de> | 2020-01-19 20:54:22 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-01-19 20:54:22 +0300 |
commit | fa8a30045ce69a90d7babe6637a596737bc2c030 (patch) | |
tree | 5581a0a6e81c29010340096e31e9ff3bcc616d42 | |
parent | 90da311ecd00d909686ef0c19b5d7e6e53b0d342 (diff) | |
parent | b4f961cc07fa947442483580e33aa9fb6ea2aec9 (diff) |
Merge pull request #816 from nextcloud/refactoringsv.0.9.9.32
Refactorings
12 files changed, 101 insertions, 32 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 5dc1bbc6..ea70014b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +0.9.9.32 +--------------------- +- Fix bug that items containing "image/jpeg" as enclosure, are interpreted as podcasts +- Fix app crash when changing server settings +- Improve opml import / export + + 0.9.9.31 --------------------- - Feature - <a href="https://github.com/nextcloud/news-android/issues/787">#787 - Display profile avatar in the sidenav</a> diff --git a/News-Android-App/build.gradle b/News-Android-App/build.gradle index a1b18746..43826fd3 100644 --- a/News-Android-App/build.gradle +++ b/News-Android-App/build.gradle @@ -136,20 +136,20 @@ dependencies { // https://mvnrepository.com/artifact/androidx.legacy/legacy-support-v4 implementation "androidx.legacy:legacy-support-v4:1.0.0" - implementation "androidx.core:core:1.2.0-alpha01" + implementation "androidx.core:core:1.2.0-rc01" implementation "androidx.appcompat:appcompat:1.1.0-alpha05" - implementation "androidx.preference:preference:1.1.0-alpha05" + implementation "androidx.preference:preference:1.1.0" // https://mvnrepository.com/artifact/com.google.android.material/material implementation "com.google.android.material:material:1.1.0-alpha06" //implementation "com.google.android.material:material:1.0.0" implementation "androidx.palette:palette:1.0.0" implementation "androidx.recyclerview:recyclerview:1.1.0-alpha05" - implementation "androidx.browser:browser:1.0.0" + implementation "androidx.browser:browser:1.2.0" implementation "androidx.cardview:cardview:1.0.0" //implementation 'de.mrmaffen:holocircularprogressbar:1.0.1' implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' - implementation 'com.google.code.gson:gson:2.8.5' + implementation 'com.google.code.gson:gson:2.8.6' implementation 'com.jakewharton:butterknife:10.1.0' implementation 'androidx.constraintlayout:constraintlayout:1.1.3' annotationProcessor 'com.jakewharton:butterknife-compiler:10.1.0' @@ -173,10 +173,10 @@ dependencies { implementation "com.google.dagger:dagger:${DAGGER_VERSION}" annotationProcessor "com.google.dagger:dagger-compiler:${DAGGER_VERSION}" - implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' + implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' // Because RxAndroid releases are few and far between, it is recommended you also // explicitly depend on RxJava's latest version for bug fixes and new features. - implementation 'io.reactivex.rxjava2:rxjava:2.1.4' + implementation 'io.reactivex.rxjava2:rxjava:2.2.16' implementation "com.squareup.retrofit2:adapter-rxjava2:$RETROFIT_VERSION" implementation "com.squareup.retrofit2:retrofit:$RETROFIT_VERSION" @@ -184,7 +184,7 @@ dependencies { implementation "com.squareup.okhttp3:okhttp:${OKHTTP_VERSION}" implementation "com.squareup.okhttp3:logging-interceptor:${OKHTTP_VERSION}" - implementation 'com.nbsp:library:1.02' // MaterialFilePicker + implementation 'com.nbsp:library:1.8' // MaterialFilePicker //extraImplementation 'com.github.tommus:youtube-android-player-api:1.2.2' diff --git a/News-Android-App/src/main/AndroidManifest.xml b/News-Android-App/src/main/AndroidManifest.xml index 5c68a749..4886abc4 100644 --- a/News-Android-App/src/main/AndroidManifest.xml +++ b/News-Android-App/src/main/AndroidManifest.xml @@ -3,8 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" package="de.luhmer.owncloudnewsreader" android:installLocation="internalOnly" - android:versionCode="150" - android:versionName="0.9.9.31"> + android:versionCode="151" + android:versionName="0.9.9.32"> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.INTERNET" /> diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/Constants.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/Constants.java index eb38556f..6fe1b75f 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/Constants.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/Constants.java @@ -17,6 +17,7 @@ public class Constants { protected static final int MIN_NEXTCLOUD_FILES_APP_VERSION_CODE = 30030052; + public static final String USER_INFO_STRING = "USER_INFO"; protected static boolean isNextCloud(SharedPreferences prefs) { int[] version = extractVersionNumberFromString(prefs.getString(Constants.NEWS_WEB_VERSION_NUMBER_STRING, "")); diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewFeedActivity.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewFeedActivity.java index b3ff3471..13c4fdba 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewFeedActivity.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewFeedActivity.java @@ -1,12 +1,15 @@ package de.luhmer.owncloudnewsreader; +import android.Manifest; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.app.ProgressDialog; import android.content.Context; import android.content.Intent; +import android.content.pm.PackageManager; import android.os.AsyncTask; import android.os.Bundle; +import android.os.Environment; import android.text.TextUtils; import android.util.Log; import android.util.Xml; @@ -19,6 +22,7 @@ import android.widget.EditText; import android.widget.Spinner; import android.widget.Toast; +import com.nbsp.materialfilepicker.MaterialFilePicker; import com.nbsp.materialfilepicker.ui.FilePickerActivity; import org.json.JSONException; @@ -35,6 +39,8 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.URL; +import java.text.SimpleDateFormat; +import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -45,6 +51,9 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AppCompatActivity; import androidx.appcompat.widget.Toolbar; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; + import butterknife.BindView; import butterknife.ButterKnife; import butterknife.OnClick; @@ -53,7 +62,6 @@ import de.luhmer.owncloudnewsreader.database.model.Feed; import de.luhmer.owncloudnewsreader.database.model.Folder; import de.luhmer.owncloudnewsreader.di.ApiProvider; import de.luhmer.owncloudnewsreader.helper.AsyncTaskHelper; -import de.luhmer.owncloudnewsreader.helper.NewsFileUtils; import de.luhmer.owncloudnewsreader.helper.OpmlXmlParser; import de.luhmer.owncloudnewsreader.helper.ThemeChooser; import de.luhmer.owncloudnewsreader.helper.URLConnectionReader; @@ -67,6 +75,9 @@ public class NewFeedActivity extends AppCompatActivity { private static final String TAG = NewFeedActivity.class.getCanonicalName(); public final static String ADD_NEW_SUCCESS = "success"; + private static final int PERMISSIONS_REQUEST_READ_CODE = 0; + private static final int PERMISSIONS_REQUEST_WRITE_CODE = 1; + private final static int REQUEST_CODE_OPML_IMPORT = 2; // UI references. protected @BindView(R.id.et_feed_url) EditText mFeedUrlView; @@ -147,18 +158,57 @@ public class NewFeedActivity extends AppCompatActivity { @OnClick(R.id.btn_import_opml) public void importOpml() { - Intent intentFilePicker = new Intent(this, FilePickerActivity.class); - startActivityForResult(intentFilePicker, 1); + String permission = Manifest.permission.READ_EXTERNAL_STORAGE; + + if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { + if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) { + Toast.makeText(this, "Allow external storage reading", Toast.LENGTH_SHORT).show(); + } else { + ActivityCompat.requestPermissions(this, new String[]{permission}, PERMISSIONS_REQUEST_READ_CODE); + } + } else { + openFilePicker(); + } + } + private void openFilePicker() { + new MaterialFilePicker() + .withActivity(this) + .withRequestCode(REQUEST_CODE_OPML_IMPORT) + //.withFilter(Pattern.compile(".*\\.opml$")) // Filtering files and directories by file name using regexp + .withFilterDirectories(true) // Set directories filterable (false by default) + .withHiddenFiles(true) // Show hidden files and folders + .start(); + } + + + @OnClick(R.id.btn_export_opml) public void exportOpml() { + String permission = Manifest.permission.WRITE_EXTERNAL_STORAGE; + + if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { + if (ActivityCompat.shouldShowRequestPermissionRationale(this, permission)) { + Toast.makeText(this, "Allow external storage writing", Toast.LENGTH_SHORT).show(); + } else { + ActivityCompat.requestPermissions(this, new String[]{permission}, PERMISSIONS_REQUEST_WRITE_CODE); + } + } else { + exportOpmlFile(); + } + } + + private void exportOpmlFile() { String xml = OpmlXmlParser.GenerateOPML(this); - String path = NewsFileUtils.getCacheDirPath(this) + "/../subscriptions.opml"; + //String path = NewsFileUtils.getCacheDirPath(this) + "/subscriptions.opml"; + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd"); + String filename = "subscriptions-" + format.format(new Date()) + ".opml"; + File path = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), filename); try { - FileOutputStream fos = new FileOutputStream(new File(path)); + FileOutputStream fos = new FileOutputStream(path); OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fos); outputStreamWriter.write(xml); outputStreamWriter.close(); @@ -180,7 +230,7 @@ public class NewFeedActivity extends AppCompatActivity { protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); - if (requestCode == 1 && resultCode == RESULT_OK) { + if (requestCode == REQUEST_CODE_OPML_IMPORT && resultCode == RESULT_OK) { String filePath = data.getStringExtra(FilePickerActivity.RESULT_FILE_PATH); AsyncTaskHelper.StartAsyncTask(new ImportOpmlSubscriptionsTask(filePath, NewFeedActivity.this)); @@ -216,7 +266,7 @@ public class NewFeedActivity extends AppCompatActivity { String opmlContent; try { if(mUrlToFile.startsWith("http")) {//http[s] - opmlContent = URLConnectionReader.getText(mUrlToFile.toString()); + opmlContent = URLConnectionReader.getText(mUrlToFile); } else { opmlContent = getStringFromFile(mUrlToFile); } @@ -232,12 +282,9 @@ public class NewFeedActivity extends AppCompatActivity { final HashMap<String, Long> existingFolders = new HashMap<>(); - mApi.getAPI().folders().blockingSubscribe(new Consumer<List<Folder>>() { - @Override - public void accept(@io.reactivex.annotations.NonNull List<Folder> folders) throws Exception { - for(Folder folder : folders) { - existingFolders.put(folder.getLabel(), folder.getId()); - } + mApi.getAPI().folders().blockingSubscribe(folders -> { + for(Folder folder : folders) { + existingFolders.put(folder.getLabel(), folder.getId()); } }); 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 6a972e91..19d52239 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 @@ -387,8 +387,9 @@ public class NewsDetailActivity extends PodcastFragmentActivity { PodcastItem podcastItem = DatabaseConnectionOrm.ParsePodcastItemFromRssItem(this, rssItem); boolean podcastAvailable = !"".equals(podcastItem.link); - if(menuItem_PlayPodcast != null) - menuItem_PlayPodcast.setVisible(podcastAvailable); + if(menuItem_PlayPodcast != null) { + menuItem_PlayPodcast.setVisible(podcastAvailable); + } if(isStarred && menuItem_Starred != null) @@ -549,7 +550,9 @@ public class NewsDetailActivity extends PodcastFragmentActivity { */ private void startTTS(int currentPosition) { RssItem rssItem = rssItems.get(currentPosition); - TTSItem ttsItem = new TTSItem(rssItem.getId(), rssItem.getAuthor(), rssItem.getTitle(), rssItem.getTitle() + "\n\n " + Html.fromHtml(rssItem.getBody()).toString(), rssItem.getFeed().getFaviconUrl()); + String text = rssItem.getTitle() + "\n\n " + Html.fromHtml(rssItem.getBody()).toString(); + // Log.d(TAG, text); + TTSItem ttsItem = new TTSItem(rssItem.getId(), rssItem.getAuthor(), rssItem.getTitle(), text, rssItem.getFeed().getFaviconUrl()); openMediaItem(ttsItem); } 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 af202be5..63ffde85 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 @@ -927,10 +927,9 @@ public class NewsReaderListActivity extends PodcastFragmentActivity implements if(requestCode == RESULT_SETTINGS) { // Extra is set if user entered/modified server settings - if (data.getBooleanExtra(SettingsActivity.PREF_SERVER_SETTINGS,false)) { + if (data == null || data.getBooleanExtra(SettingsActivity.PREF_SERVER_SETTINGS,false)) { resetUiAndStartSync(); } else { - //Update settings of image Loader mApi.initApi(new NextcloudAPI.ApiConnectedListener() { @Override diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListFragment.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListFragment.java index 69ebbec2..b15d9ee4 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListFragment.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListFragment.java @@ -75,6 +75,7 @@ import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; import uk.co.deanwild.materialshowcaseview.MaterialShowcaseView; +import static de.luhmer.owncloudnewsreader.Constants.USER_INFO_STRING; import static de.luhmer.owncloudnewsreader.LoginDialogActivity.RESULT_LOGIN; /** @@ -339,8 +340,6 @@ public class NewsReaderListFragment extends Fragment implements OnCreateContextM .show(); } - private static final String USER_INFO_STRING = "USER_INFO"; - public void startAsyncTaskGetUserInfo() { mApi.getAPI().user() .subscribeOn(Schedulers.newThread()) diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SettingsFragment.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SettingsFragment.java index 9577f01a..e8c5808f 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SettingsFragment.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SettingsFragment.java @@ -38,6 +38,7 @@ import de.luhmer.owncloudnewsreader.helper.NewsFileUtils; import de.luhmer.owncloudnewsreader.helper.PostDelayHandler; import static android.app.Activity.RESULT_OK; +import static de.luhmer.owncloudnewsreader.Constants.USER_INFO_STRING; import static de.luhmer.owncloudnewsreader.LoginDialogActivity.RESULT_LOGIN; import static de.luhmer.owncloudnewsreader.SettingsActivity.CB_MARK_AS_READ_WHILE_SCROLLING_STRING; import static de.luhmer.owncloudnewsreader.SettingsActivity.CB_NAVIGATE_WITH_VOLUME_BUTTONS_STRING; @@ -276,7 +277,7 @@ public class SettingsFragment extends PreferenceFragmentCompat { clearCachePref.setOnPreferenceClickListener(preference -> { - mPrefs.edit().remove("USER_INFO").apply(); + mPrefs.edit().remove(USER_INFO_STRING).apply(); checkForUnsycedChangesInDatabaseAndResetDatabase(prefFrag.getActivity()); return true; }); @@ -374,7 +375,7 @@ public class SettingsFragment extends PreferenceFragmentCompat { debugInfo += "\n\n---\n\n"; - List<String> excludedSettings = Arrays.asList(EDT_USERNAME_STRING, EDT_PASSWORD_STRING, EDT_OWNCLOUDROOTPATH_STRING, Constants.LAST_UPDATE_NEW_ITEMS_COUNT_STRING); + List<String> excludedSettings = Arrays.asList(EDT_USERNAME_STRING, EDT_PASSWORD_STRING, EDT_OWNCLOUDROOTPATH_STRING, Constants.LAST_UPDATE_NEW_ITEMS_COUNT_STRING, USER_INFO_STRING); Map<String, ?> allEntries = mPrefs.getAll(); for (Map.Entry<String, ?> entry : allEntries.entrySet()) { String key =entry.getKey(); diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnectionOrm.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnectionOrm.java index 69e56494..0148b3b9 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnectionOrm.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnectionOrm.java @@ -481,6 +481,12 @@ public class DatabaseConnectionOrm { podcastItem.mimeType = rssItem.getEnclosureMime(); podcastItem.favIcon = feed.getFaviconUrl(); + if("image/jpeg".equals(podcastItem.mimeType)) { + // We don't want to accidentally think that enclosed images are podcasts + podcastItem.link = ""; + podcastItem.mimeType = ""; + } + podcastItem.isVideoPodcast = Arrays.asList(DatabaseConnectionOrm.VIDEO_FORMATS).contains(podcastItem.mimeType); File file = new File(PodcastDownloadService.getUrlToPodcastFile(context, podcastItem.link, false)); diff --git a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/OpmlXmlParser.java b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/OpmlXmlParser.java index 000fe854..eba5a48b 100644 --- a/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/OpmlXmlParser.java +++ b/News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/OpmlXmlParser.java @@ -1,6 +1,7 @@ package de.luhmer.owncloudnewsreader.helper; import android.content.Context; +import android.util.Log; import android.util.Xml; import org.xmlpull.v1.XmlPullParser; @@ -21,6 +22,8 @@ import de.luhmer.owncloudnewsreader.database.model.Folder; */ public class OpmlXmlParser { + private static final String TAG = OpmlXmlParser.class.getCanonicalName(); + //Create XML public static String GenerateOPML(Context context) { XmlSerializer serializer = Xml.newSerializer(); @@ -65,6 +68,9 @@ public class OpmlXmlParser { serializer.endTag("", "body"); serializer.endTag("", "opml"); serializer.endDocument(); + + Log.d(TAG, writer.toString()); + return writer.toString(); } catch (Exception e) { throw new RuntimeException(e); diff --git a/build.gradle b/build.gradle index 20f52874..01a60b13 100644 --- a/build.gradle +++ b/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.2' + classpath 'com.android.tools.build:gradle:3.5.3' } } |