diff options
author | Niedermann IT-Dienstleistungen <stefan-niedermann@users.noreply.github.com> | 2021-10-18 12:34:17 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-10-18 12:34:17 +0300 |
commit | fae4740719f753d71ff21061fd90d7fa888aba39 (patch) | |
tree | 4edc24519533ac69ec1f5344d402f7aacb5efc99 /app/src | |
parent | 93831d49f70fc3c6ef637ff32f07f2fad8c8aa0e (diff) |
Raise targetSdk to 31, adjust widgets and manifest
Signed-off-by: Stefan Niedermann <info@niedermann.it>
Diffstat (limited to 'app/src')
13 files changed, 137 insertions, 28 deletions
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4fb80997..a913213f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -25,7 +25,8 @@ <activity android:name=".SplashscreenActivity" android:label="@string/app_name" - android:theme="@style/SplashTheme"> + android:theme="@style/SplashTheme" + android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> @@ -37,7 +38,8 @@ <activity android:name=".main.MainActivity" - android:label="@string/app_name"> + android:label="@string/app_name" + android:exported="false"> <intent-filter> <action android:name="android.intent.action.SEARCH" /> @@ -57,7 +59,8 @@ <activity android:name=".AppendToNoteActivity" - android:label="@string/append_to_note"> + android:label="@string/append_to_note" + android:exported="true"> <intent-filter> <action android:name="android.intent.action.SEND" /> @@ -93,7 +96,8 @@ android:label="@string/simple_edit" android:launchMode="singleTask" android:parentActivityName=".main.MainActivity" - android:windowSoftInputMode="stateHidden"> + android:windowSoftInputMode="stateHidden" + android:exported="true"> <intent-filter android:label="@string/action_create"> <action android:name="android.intent.action.SEND" /> <category android:name="android.intent.category.DEFAULT" /> @@ -120,13 +124,15 @@ android:label="@string/simple_about" android:parentActivityName=".main.MainActivity" /> - <activity android:name=".widget.singlenote.SingleNoteWidgetConfigurationActivity"> + <activity android:name=".widget.singlenote.SingleNoteWidgetConfigurationActivity" + android:exported="true"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> </intent-filter> </activity> - <activity android:name=".widget.notelist.NoteListWidgetConfigurationActivity"> + <activity android:name=".widget.notelist.NoteListWidgetConfigurationActivity" + android:exported="true"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" /> @@ -135,7 +141,8 @@ <receiver android:name=".widget.createnote.CreateNoteWidget" - android:label="@string/widget_create_note"> + android:label="@string/widget_create_note" + android:exported="true"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> @@ -148,7 +155,8 @@ <receiver android:name=".widget.singlenote.SingleNoteWidget" - android:label="@string/widget_single_note_title"> + android:label="@string/widget_single_note_title" + android:exported="true"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> @@ -161,7 +169,8 @@ <receiver android:name=".widget.notelist.NoteListWidget" - android:label="@string/widget_note_list_title"> + android:label="@string/widget_note_list_title" + android:exported="true"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> @@ -185,7 +194,8 @@ android:description="@string/action_create" android:icon="@drawable/ic_launcher_foreground_full" android:label="@string/action_create" - android:permission="android.permission.BIND_QUICK_SETTINGS_TILE"> + android:permission="android.permission.BIND_QUICK_SETTINGS_TILE" + android:exported="true"> <intent-filter> <action android:name="android.service.quicksettings.action.QS_TILE" /> </intent-filter> diff --git a/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java b/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java index 5616daec..06953006 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/edit/BaseNoteFragment.java @@ -4,6 +4,7 @@ import static java.lang.Boolean.TRUE; import static it.niedermann.owncloud.notes.NotesApplication.isDarkThemeActive; import static it.niedermann.owncloud.notes.branding.BrandingUtil.tintMenuIcon; import static it.niedermann.owncloud.notes.edit.EditNoteActivity.ACTION_SHORTCUT; +import static it.niedermann.owncloud.notes.shared.util.WidgetUtil.pendingIntentFlagCompat; import android.app.PendingIntent; import android.content.Context; @@ -254,7 +255,7 @@ public abstract class BaseNoteFragment extends BrandedFragment implements Catego .setIntent(new Intent(getActivity(), EditNoteActivity.class).putExtra(EditNoteActivity.PARAM_NOTE_ID, note.getId()).setAction(ACTION_SHORTCUT)) .build(); - ShortcutManagerCompat.requestPinShortcut(context, pinShortcutInfo, PendingIntent.getBroadcast(context, 0, ShortcutManagerCompat.createShortcutResultIntent(context, pinShortcutInfo), 0).getIntentSender()); + ShortcutManagerCompat.requestPinShortcut(context, pinShortcutInfo, PendingIntent.getBroadcast(context, 0, ShortcutManagerCompat.createShortcutResultIntent(context, pinShortcutInfo), pendingIntentFlagCompat(0)).getIntentSender()); } else { Log.i(TAG, "RequestPinShortcut is not supported"); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NoteUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NoteUtil.java index 3d5a118c..aae6c472 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NoteUtil.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/NoteUtil.java @@ -69,6 +69,7 @@ public class NoteUtil { return ""; } if (!TextUtils.isEmpty(title)) { + assert title != null; final String trimmedTitle = removeMarkdown(replaceCheckboxesWithEmojis(title.trim())); if (content.startsWith(trimmedTitle)) { content = content.substring(trimmedTitle.length()); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/shared/util/WidgetUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/WidgetUtil.java new file mode 100644 index 00000000..dc53fb3f --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/shared/util/WidgetUtil.java @@ -0,0 +1,30 @@ +package it.niedermann.owncloud.notes.shared.util; + +import android.app.PendingIntent; +import android.os.Build; + +public class WidgetUtil { + + private WidgetUtil() { + throw new UnsupportedOperationException("This class must not get instantiated"); + } + + /** + * Android S requires either {@link PendingIntent#FLAG_MUTABLE} or + * {@link PendingIntent#FLAG_IMMUTABLE} to be set on a {@link PendingIntent}. + * This is enforced by Android and will lead to an app crash if neither of those flags is + * present. + * To keep the app working, this compatibility method can be used to add the + * {@link PendingIntent#FLAG_MUTABLE} flag on Android S and higher to restore the behavior of + * older SDK versions. + * + * @param flags wanted flags for {@link PendingIntent} + * @return {@param flags} | {@link PendingIntent#FLAG_MUTABLE} + */ + public static int pendingIntentFlagCompat(int flags) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { + return flags | PendingIntent.FLAG_MUTABLE; + } + return flags; + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/widget/createnote/CreateNoteWidget.java b/app/src/main/java/it/niedermann/owncloud/notes/widget/createnote/CreateNoteWidget.java index 7f5fc7c9..67eb48ee 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/widget/createnote/CreateNoteWidget.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/widget/createnote/CreateNoteWidget.java @@ -1,5 +1,7 @@ package it.niedermann.owncloud.notes.widget.createnote; +import static it.niedermann.owncloud.notes.shared.util.WidgetUtil.pendingIntentFlagCompat; + import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; @@ -22,8 +24,7 @@ public class CreateNoteWidget extends AppWidgetProvider { final var views = new RemoteViews(context.getPackageName(), R.layout.widget_create_note); final var intent = new Intent(context, EditNoteActivity.class); - final var pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); - views.setOnClickPendingIntent(R.id.widget_create_note, pendingIntent); + views.setOnClickPendingIntent(R.id.widget_create_note, PendingIntent.getActivity(context, 0, intent, pendingIntentFlagCompat(PendingIntent.FLAG_UPDATE_CURRENT))); // Instruct the widget manager to update the widget appWidgetManager.updateAppWidget(appWidgetId, views); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/widget/notelist/NoteListWidget.java b/app/src/main/java/it/niedermann/owncloud/notes/widget/notelist/NoteListWidget.java index 7b2d2639..7342b08c 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/widget/notelist/NoteListWidget.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/widget/notelist/NoteListWidget.java @@ -1,5 +1,7 @@ package it.niedermann.owncloud.notes.widget.notelist; +import static it.niedermann.owncloud.notes.shared.util.WidgetUtil.pendingIntentFlagCompat; + import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; @@ -35,13 +37,11 @@ public class NoteListWidget extends AppWidgetProvider { serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))); - final var pendingIntent = PendingIntent.getActivity(context, 0, new Intent(), PendingIntent.FLAG_UPDATE_CURRENT | Intent.FILL_IN_COMPONENT); - Log.v(TAG, "-- data - " + data); views = new RemoteViews(context.getPackageName(), R.layout.widget_note_list); views.setRemoteAdapter(R.id.note_list_widget_lv, serviceIntent); - views.setPendingIntentTemplate(R.id.note_list_widget_lv, pendingIntent); + views.setPendingIntentTemplate(R.id.note_list_widget_lv, PendingIntent.getActivity(context, 0, new Intent(), pendingIntentFlagCompat(PendingIntent.FLAG_UPDATE_CURRENT | Intent.FILL_IN_COMPONENT))); views.setEmptyView(R.id.note_list_widget_lv, R.id.widget_note_list_placeholder_tv); awm.notifyAppWidgetViewDataChanged(appWidgetId, R.id.note_list_widget_lv); diff --git a/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidget.java b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidget.java index b86a4848..77339e3e 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidget.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/widget/singlenote/SingleNoteWidget.java @@ -1,5 +1,7 @@ package it.niedermann.owncloud.notes.widget.singlenote; +import static it.niedermann.owncloud.notes.shared.util.WidgetUtil.pendingIntentFlagCompat; + import android.app.PendingIntent; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProvider; @@ -33,15 +35,13 @@ public class SingleNoteWidget extends AppWidgetProvider { if (data != null) { templateIntent.putExtra(BaseNoteFragment.PARAM_ACCOUNT_ID, data.getAccountId()); - final var templatePendingIntent = PendingIntent.getActivity(context, appWidgetId, templateIntent, - PendingIntent.FLAG_UPDATE_CURRENT); - final var serviceIntent = new Intent(context, SingleNoteWidgetService.class); serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); serviceIntent.setData(Uri.parse(serviceIntent.toUri(Intent.URI_INTENT_SCHEME))); final var views = new RemoteViews(context.getPackageName(), R.layout.widget_single_note); - views.setPendingIntentTemplate(R.id.single_note_widget_lv, templatePendingIntent); + views.setPendingIntentTemplate(R.id.single_note_widget_lv, PendingIntent.getActivity(context, appWidgetId, templateIntent, + pendingIntentFlagCompat(PendingIntent.FLAG_UPDATE_CURRENT))); views.setRemoteAdapter(R.id.single_note_widget_lv, serviceIntent); views.setEmptyView(R.id.single_note_widget_lv, R.id.widget_single_note_placeholder_tv); diff --git a/app/src/main/res/layout/widget_note_list.xml b/app/src/main/res/layout/widget_note_list.xml index ebc3aded..a3e7e163 100644 --- a/app/src/main/res/layout/widget_note_list.xml +++ b/app/src/main/res/layout/widget_note_list.xml @@ -5,10 +5,10 @@ android:layout_height="match_parent" android:background="@drawable/widget_background" android:orientation="vertical" - android:paddingStart="@dimen/spacer_1x" - android:paddingTop="@dimen/spacer_1x" - android:paddingEnd="@dimen/spacer_1hx" - android:paddingBottom="@dimen/spacer_1x"> + android:paddingStart="@dimen/widget_inner_padding_horizontal" + android:paddingTop="@dimen/widget_inner_padding_vertical" + android:paddingEnd="@dimen/widget_inner_padding_horizontal" + android:paddingBottom="@dimen/widget_inner_padding_vertical"> <ListView android:id="@+id/note_list_widget_lv" diff --git a/app/src/main/res/layout/widget_single_note.xml b/app/src/main/res/layout/widget_single_note.xml index 2b936258..053a059d 100644 --- a/app/src/main/res/layout/widget_single_note.xml +++ b/app/src/main/res/layout/widget_single_note.xml @@ -9,7 +9,10 @@ android:id="@+id/single_note_widget_lv" android:layout_width="match_parent" android:layout_height="match_parent" - android:padding="@dimen/spacer_1x" + android:paddingStart="@dimen/widget_inner_padding_horizontal" + android:paddingTop="@dimen/widget_inner_padding_vertical" + android:paddingEnd="@dimen/widget_inner_padding_horizontal" + android:paddingBottom="@dimen/widget_inner_padding_vertical" tools:listitem="@layout/widget_single_note_content" /> <TextView diff --git a/app/src/main/res/values-v31/dimens.xml b/app/src/main/res/values-v31/dimens.xml new file mode 100644 index 00000000..8c5b1ff4 --- /dev/null +++ b/app/src/main/res/values-v31/dimens.xml @@ -0,0 +1,43 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + + <!-- Default screen margins, per the Android Design guidelines. --> + <dimen name="spacer_1qx">2dp</dimen> + <dimen name="spacer_1hx">4dp</dimen> + <dimen name="spacer_1x">8dp</dimen> + <dimen name="spacer_2x">16dp</dimen> + <dimen name="spacer_3x">24dp</dimen> + <dimen name="spacer_5x">40dp</dimen> + + <dimen name="avatar_size">36dp</dimen> + + <dimen name="spacer_activity_sides">0dp</dimen> + + <!-- Drawer header --> + <dimen name="drawer_header_height">100dp</dimen> + <dimen name="drawer_header_logo_size">42dp</dimen> + + <!-- Buttons --> + <dimen name="button_padding">@dimen/spacer_2x</dimen> + + <dimen name="primary_font_size">16sp</dimen> + <dimen name="secondary_font_size">14sp</dimen> + + <!-- Font Sizes --> + <dimen name="note_font_size_small">16sp</dimen> + <dimen name="note_font_size_medium">18sp</dimen> + <dimen name="note_font_size_large">22sp</dimen> + + <item format="float" name="note_line_spacing" type="dimen">1.15</item> + + <!-- Widgets --> + <dimen name="widget_outer_radius">@android:dimen/system_app_widget_background_radius</dimen> + <dimen name="widget_margin">@android:dimen/system_app_widget_background_radius</dimen> + <dimen name="widget_inner_padding_vertical">@android:dimen/system_app_widget_inner_radius</dimen> + <dimen name="widget_inner_padding_horizontal">@dimen/spacer_1x</dimen> + <dimen name="widget_note_list_outer_padding">4dp</dimen> + <dimen name="widget_note_list_inner_padding">4dp</dimen> + <dimen name="widget_note_list_fav_icon_width">26dp</dimen> + <dimen name="widget_note_list_fav_icon_height">20dp</dimen> + +</resources> diff --git a/app/src/main/res/values/dimens.xml b/app/src/main/res/values/dimens.xml index ebf6b15f..69eb2300 100644 --- a/app/src/main/res/values/dimens.xml +++ b/app/src/main/res/values/dimens.xml @@ -7,6 +7,7 @@ <dimen name="spacer_1x">8dp</dimen> <dimen name="spacer_2x">16dp</dimen> <dimen name="spacer_3x">24dp</dimen> + <dimen name="spacer_4x">36dp</dimen> <dimen name="spacer_5x">40dp</dimen> <dimen name="avatar_size">36dp</dimen> @@ -31,8 +32,10 @@ <item format="float" name="note_line_spacing" type="dimen">1.15</item> <!-- Widgets --> - <dimen name="widget_outer_radius">@dimen/spacer_1x</dimen> - <dimen name="widget_margin">@dimen/spacer_1x</dimen> + <dimen name="widget_outer_radius">@dimen/spacer_4x</dimen> + <dimen name="widget_margin">@dimen/spacer_4x</dimen> + <dimen name="widget_inner_padding_vertical">@dimen/spacer_2x</dimen> + <dimen name="widget_inner_padding_horizontal">@dimen/spacer_1x</dimen> <dimen name="widget_note_list_outer_padding">4dp</dimen> <dimen name="widget_note_list_inner_padding">4dp</dimen> <dimen name="widget_note_list_fav_icon_width">26dp</dimen> diff --git a/app/src/test/java/it/niedermann/owncloud/notes/shared/util/NoteUtilTest.java b/app/src/test/java/it/niedermann/owncloud/notes/shared/util/NoteUtilTest.java index 72c7d957..ff0ca4e6 100644 --- a/app/src/test/java/it/niedermann/owncloud/notes/shared/util/NoteUtilTest.java +++ b/app/src/test/java/it/niedermann/owncloud/notes/shared/util/NoteUtilTest.java @@ -1,10 +1,15 @@ package it.niedermann.owncloud.notes.shared.util; +import android.os.Build; + +import androidx.core.text.HtmlCompat; + import junit.framework.TestCase; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; +import org.robolectric.annotation.Config; import it.niedermann.android.markdown.MarkdownUtil; @@ -71,7 +76,6 @@ public class NoteUtilTest extends TestCase { // content has markdown while titles markdown is already stripped assertEquals("", NoteUtil.generateNoteExcerpt("# Title", "Title")); assertEquals("Foo", NoteUtil.generateNoteExcerpt("Title\n- Foo", "Title")); - assertEquals("Title Bar", NoteUtil.generateNoteExcerpt("# Title\n- Title\n- Bar", "Title")); // title has markdown while contents markdown is stripped assertEquals("", NoteUtil.generateNoteExcerpt("Title", "# Title")); @@ -83,4 +87,16 @@ public class NoteUtilTest extends TestCase { assertEquals("Foo", NoteUtil.generateNoteExcerpt("# Title\n- Foo", "- Title")); assertEquals("Title Bar", NoteUtil.generateNoteExcerpt("- Title\nTitle\nBar", "- Title")); } + + /** + * Has known issues on {@link Build.VERSION_CODES#LOLLIPOP_MR1} and + * {@link Build.VERSION_CODES#M} due to incompatibilities of + * {@link HtmlCompat#fromHtml(String, int)} + */ + @Test + @Config(sdk = {30}) + public void testGenerateNoteExcerpt_sdk_30() { + // content has markdown while titles markdown is already stripped + assertEquals("Title Bar", NoteUtil.generateNoteExcerpt("# Title\n- Title\n- Bar", "Title")); + } }
\ No newline at end of file diff --git a/app/src/test/resources/robolectric.properties b/app/src/test/resources/robolectric.properties new file mode 100644 index 00000000..cf370c6f --- /dev/null +++ b/app/src/test/resources/robolectric.properties @@ -0,0 +1 @@ +sdk=22, 30
\ No newline at end of file |