diff options
author | stefan-niedermann <info@niedermann.it> | 2020-03-14 01:04:38 +0300 |
---|---|---|
committer | stefan-niedermann <info@niedermann.it> | 2020-03-14 01:04:38 +0300 |
commit | e97eaa95c5484cf88cd91d71f71c614de9415d73 (patch) | |
tree | c2ba6791f43189b9eda50cc3212ddad5313c846f | |
parent | 87a9dbf3be27564555703a1bd29a19ab3ccf124e (diff) |
Move contents of nextcloud-commons-lib back to project
Signed-off-by: stefan-niedermann <info@niedermann.it>
15 files changed, 436 insertions, 40 deletions
diff --git a/app/build.gradle b/app/build.gradle index 0a0628a9..f44b56bc 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,8 @@ android { applicationId "it.niedermann.owncloud.notes" minSdkVersion 14 targetSdkVersion 29 - versionCode 81 - versionName "2.10.3" + versionCode 2011000 + versionName "2.11.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -34,8 +34,7 @@ android { } dependencies { - implementation "com.github.nextcloud:Android-SingleSignOn:0.5.0-rc3" - implementation 'com.github.stefan-niedermann:nextcloud-commons:0.0.2' + implementation "com.github.nextcloud:Android-SingleSignOn:0.5.0" implementation 'com.yydcdut:markdown-processor:0.1.3' implementation 'com.yydcdut:rxmarkdown-wrapper:0.1.3' diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3e640093..14ad435e 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -7,7 +7,7 @@ <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <application - android:name="it.niedermann.owncloud.notes.util.Notes" + android:name=".util.Notes" android:allowBackup="true" android:fullBackupContent="true" android:icon="@mipmap/ic_launcher" @@ -19,7 +19,7 @@ tools:targetApi="n"> <activity - android:name="it.niedermann.owncloud.notes.android.activity.SplashscreenActivity" + android:name=".android.activity.SplashscreenActivity" android:theme="@style/SplashTheme"> <intent-filter> <action android:name="android.intent.action.MAIN" /> @@ -31,7 +31,7 @@ </activity> <activity - android:name="it.niedermann.owncloud.notes.android.activity.NotesListViewActivity" + android:name=".android.activity.NotesListViewActivity" android:label="@string/app_name"> <intent-filter> @@ -43,24 +43,24 @@ android:resource="@xml/searchable" /> <meta-data android:name="android.app.default_searchable" - android:value="it.niedermann.owncloud.notes.android.activity.NotesListViewActivity" /> + android:value=".android.activity.NotesListViewActivity" /> </activity> <activity - android:name="it.niedermann.owncloud.notes.android.activity.ExceptionActivity" + android:name=".android.activity.ExceptionActivity" android:label="@string/app_name" /> <activity - android:name="it.niedermann.owncloud.notes.android.activity.PreferencesActivity" + android:name=".android.activity.PreferencesActivity" android:label="@string/action_settings" - android:parentActivityName="it.niedermann.owncloud.notes.android.activity.NotesListViewActivity" + android:parentActivityName=".android.activity.NotesListViewActivity" android:windowSoftInputMode="stateHidden" /> <activity - android:name="it.niedermann.owncloud.notes.android.activity.EditNoteActivity" + android:name=".android.activity.EditNoteActivity" android:label="@string/simple_edit" android:launchMode="singleTask" - android:parentActivityName="it.niedermann.owncloud.notes.android.activity.NotesListViewActivity" + android:parentActivityName=".android.activity.NotesListViewActivity" android:windowSoftInputMode="stateHidden"> <intent-filter android:label="@string/action_create"> <action android:name="android.intent.action.SEND" /> @@ -84,9 +84,9 @@ </activity> <activity - android:name="it.niedermann.owncloud.notes.android.activity.AboutActivity" + android:name=".android.activity.AboutActivity" android:label="@string/simple_about" - android:parentActivityName="it.niedermann.owncloud.notes.android.activity.NotesListViewActivity" /> + android:parentActivityName=".android.activity.NotesListViewActivity" /> <activity android:name=".android.activity.SelectSingleNoteActivity"> <intent-filter> @@ -115,7 +115,7 @@ </receiver> <receiver - android:name="it.niedermann.owncloud.notes.android.appwidget.SingleNoteWidget" + android:name=".android.appwidget.SingleNoteWidget" android:label="@string/widget_single_note_title"> <intent-filter> @@ -128,7 +128,7 @@ </receiver> <receiver - android:name="it.niedermann.owncloud.notes.android.appwidget.NoteListWidget" + android:name=".android.appwidget.NoteListWidget" android:label="@string/widget_note_list_title"> <intent-filter> @@ -149,7 +149,7 @@ android:permission="android.permission.BIND_REMOTEVIEWS" /> <service - android:name="it.niedermann.owncloud.notes.android.quicksettings.NewNoteTileService" + android:name=".android.quicksettings.NewNoteTileService" android:description="@string/action_create" android:icon="@drawable/ic_quicksettings_new" android:label="@string/action_create" diff --git a/app/src/main/java/it/niedermann/owncloud/notes/ExceptionHandler.java b/app/src/main/java/it/niedermann/owncloud/notes/ExceptionHandler.java new file mode 100644 index 00000000..8fdc2ebb --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/ExceptionHandler.java @@ -0,0 +1,48 @@ +package it.niedermann.owncloud.notes; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; + +import androidx.annotation.NonNull; + +import it.niedermann.owncloud.notes.android.activity.ExceptionActivity; + + +public class ExceptionHandler implements Thread.UncaughtExceptionHandler { + + private static final String TAG = ExceptionHandler.class.getCanonicalName(); + private Context context; + private Class<? extends Activity> errorActivity; + public static final String KEY_THROWABLE = "T"; + + public ExceptionHandler(Context context) { + super(); + this.context = context; + this.errorActivity = ExceptionActivity.class; + } + + public ExceptionHandler(Context context, Class<? extends Activity> errorActivity) { + super(); + this.context = context; + this.errorActivity = errorActivity; + } + + @Override + public void uncaughtException(@NonNull Thread t, @NonNull Throwable e) { + Log.e(TAG, e.getMessage(), e); + Intent intent = new Intent(context.getApplicationContext(), errorActivity); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); + Bundle extras = new Bundle(); + intent.putExtra(KEY_THROWABLE, e); + extras.putSerializable(KEY_THROWABLE, e); + intent.putExtras(extras); + context.getApplicationContext().startActivity(intent); + if (context instanceof Activity) { + ((Activity) context).finish(); + } + Runtime.getRuntime().exit(0); + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/ExceptionUtil.java b/app/src/main/java/it/niedermann/owncloud/notes/ExceptionUtil.java new file mode 100644 index 00000000..c5de5d13 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/ExceptionUtil.java @@ -0,0 +1,72 @@ +package it.niedermann.owncloud.notes; + +import android.app.Activity; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; + +import com.nextcloud.android.sso.helper.VersionCheckHelper; + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.List; + +public class ExceptionUtil { + + private ExceptionUtil() { + + } + + public static String getDebugInfos(Activity activity, Throwable throwable) { + List<Throwable> throwables = new ArrayList<>(); + throwables.add(throwable); + return getDebugInfos(activity, throwables); + } + + public static String getDebugInfos(Activity activity, List<Throwable> throwables) { + StringBuilder debugInfos = new StringBuilder("" + + getAppVersions(activity) + + "\n\n---\n" + + getDeviceInfos() + + "\n\n---" + + "\n\n"); + for (Throwable throwable : throwables) { + debugInfos.append(getStacktraceOf(throwable)); + } + return debugInfos.toString(); + } + + private static String getAppVersions(Activity activity) { + String versions = ""; + try { + PackageInfo pInfo = activity.getApplicationContext().getPackageManager().getPackageInfo(activity.getApplicationContext().getPackageName(), 0); + versions += "App Version: " + pInfo.versionName; + versions += "\nApp Version Code: " + pInfo.versionCode; + } catch (PackageManager.NameNotFoundException e) { + versions += "\nApp Version: " + e.getMessage(); + e.printStackTrace(); + } + + try { + versions += "\nFiles App Version Code: " + VersionCheckHelper.getNextcloudFilesVersionCode(activity); + } catch (PackageManager.NameNotFoundException e) { + versions += "\nFiles App Version Code: " + e.getMessage(); + e.printStackTrace(); + } + return versions; + } + + private static String getDeviceInfos() { + return "" + + "\nOS Version: " + System.getProperty("os.version") + "(" + android.os.Build.VERSION.INCREMENTAL + ")" + + "\nOS API Level: " + android.os.Build.VERSION.SDK_INT + + "\nDevice: " + android.os.Build.DEVICE + + "\nModel (and Product): " + android.os.Build.MODEL + " (" + android.os.Build.PRODUCT + ")"; + } + + private static String getStacktraceOf(Throwable e) { + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + return sw.toString(); + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/ExceptionActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/ExceptionActivity.java index 3a8b5652..4b232cc4 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/ExceptionActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/ExceptionActivity.java @@ -4,51 +4,47 @@ import android.annotation.SuppressLint; import android.content.ClipData; import android.content.ClipboardManager; import android.os.Bundle; -import android.widget.TextView; import android.widget.Toast; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; -import androidx.appcompat.widget.Toolbar; import java.util.Objects; -import it.niedermann.nextcloud.exception.ExceptionUtil; +import it.niedermann.owncloud.notes.ExceptionUtil; import it.niedermann.owncloud.notes.R; +import it.niedermann.owncloud.notes.databinding.ActivityExceptionBinding; + +import static it.niedermann.owncloud.notes.ExceptionHandler.KEY_THROWABLE; -import static it.niedermann.nextcloud.exception.ExceptionHandler.KEY_THROWABLE; public class ExceptionActivity extends AppCompatActivity { - private TextView stacktrace; + private ActivityExceptionBinding binding; @SuppressLint("SetTextI18n") // only used for logging @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.activity_exception); - super.onCreate(savedInstanceState); - - Toolbar toolbar = findViewById(R.id.toolbar); - TextView message = findViewById(R.id.message); - stacktrace = findViewById(R.id.stacktrace); + binding = ActivityExceptionBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); - findViewById(R.id.copy).setOnClickListener((v) -> copyStacktraceToClipboard()); - findViewById(R.id.close).setOnClickListener((v) -> close()); + binding.copy.setOnClickListener((v) -> copyStacktraceToClipboard()); + binding.close.setOnClickListener((v) -> close()); - setSupportActionBar(toolbar); + setSupportActionBar(binding.toolbar); Throwable throwable = (Throwable) Objects.requireNonNull(getIntent().getSerializableExtra(KEY_THROWABLE)); throwable.printStackTrace(); - toolbar.setTitle(getString(R.string.simple_error)); - message.setText(throwable.getMessage()); - stacktrace.setText(ExceptionUtil.getDebugInfos(this, throwable)); + binding.toolbar.setTitle(getString(R.string.simple_error)); + binding.message.setText(throwable.getMessage()); + binding.stacktrace.setText(ExceptionUtil.getDebugInfos(this, throwable)); } private void copyStacktraceToClipboard() { final ClipboardManager clipboardManager = (ClipboardManager) Objects.requireNonNull(getSystemService(CLIPBOARD_SERVICE)); - ClipData clipData = ClipData.newPlainText(getString(R.string.simple_exception), "```\n" + this.stacktrace.getText() + "\n```"); + ClipData clipData = ClipData.newPlainText(getString(R.string.simple_exception), "```\n" + binding.stacktrace.getText() + "\n```"); clipboardManager.setPrimaryClip(clipData); Toast.makeText(this, R.string.copied_to_clipboard, Toast.LENGTH_SHORT).show(); } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/LockedActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/LockedActivity.java index 346d7cfe..0a96cd1d 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/LockedActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/LockedActivity.java @@ -10,7 +10,7 @@ import android.util.Log; import androidx.annotation.Nullable; import androidx.appcompat.app.AppCompatActivity; -import it.niedermann.nextcloud.exception.ExceptionHandler; +import it.niedermann.owncloud.notes.ExceptionHandler; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.util.Notes; diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/NotesListViewActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/NotesListViewActivity.java index 623adbc3..0c4fea97 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/NotesListViewActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/NotesListViewActivity.java @@ -128,6 +128,8 @@ public class NotesListViewActivity extends LockedActivity implements ItemAdapter protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + Integer.parseInt("as"); + binding = DrawerLayoutBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot()); this.coordinatorLayout = binding.activityNotesListView.activityNotesListView; diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/SelectSingleNoteActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/SelectSingleNoteActivity.java index 877514bd..97626182 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/SelectSingleNoteActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/SelectSingleNoteActivity.java @@ -12,7 +12,7 @@ import android.view.View; import androidx.appcompat.widget.Toolbar; import androidx.swiperefreshlayout.widget.SwipeRefreshLayout; -import it.niedermann.nextcloud.exception.ExceptionHandler; +import it.niedermann.owncloud.notes.ExceptionHandler; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.android.appwidget.SingleNoteWidget; import it.niedermann.owncloud.notes.model.DBNote; diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/SplashscreenActivity.java b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/SplashscreenActivity.java index c6b8ad98..c05f5b47 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/android/activity/SplashscreenActivity.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/android/activity/SplashscreenActivity.java @@ -5,7 +5,7 @@ import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; -import it.niedermann.nextcloud.exception.ExceptionHandler; +import it.niedermann.owncloud.notes.ExceptionHandler; /** diff --git a/app/src/main/java/it/niedermann/owncloud/notes/glide/SingleSignOnLibraryGlideModule.java b/app/src/main/java/it/niedermann/owncloud/notes/glide/SingleSignOnLibraryGlideModule.java new file mode 100644 index 00000000..4c265701 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/glide/SingleSignOnLibraryGlideModule.java @@ -0,0 +1,33 @@ +package it.niedermann.owncloud.notes.glide; + +import android.content.Context; +import android.util.Log; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.Registry; +import com.bumptech.glide.annotation.GlideModule; +import com.bumptech.glide.load.model.GlideUrl; +import com.bumptech.glide.module.LibraryGlideModule; + +import java.io.InputStream; + +/** + * Registers OkHttp related classes via Glide's annotation processor. + * + * <p>For Applications that depend on this library and include an {@link LibraryGlideModule} and Glide's + * annotation processor, this class will be automatically included. + */ +@GlideModule +public final class SingleSignOnLibraryGlideModule extends LibraryGlideModule { + + private static final String TAG = SingleSignOnLibraryGlideModule.class.getCanonicalName(); + + @Override + public void registerComponents( + @NonNull Context context, @NonNull Glide glide, @NonNull Registry registry) { + Log.v(TAG, "Replacing default implementation for " + GlideUrl.class.getSimpleName() + "."); + registry.replace(GlideUrl.class, InputStream.class, new SingleSignOnUrlLoader.Factory(context)); + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/glide/SingleSignOnStreamFetcher.java b/app/src/main/java/it/niedermann/owncloud/notes/glide/SingleSignOnStreamFetcher.java new file mode 100644 index 00000000..a70c816c --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/glide/SingleSignOnStreamFetcher.java @@ -0,0 +1,81 @@ +package it.niedermann.owncloud.notes.glide; + +import android.util.Log; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.Priority; +import com.bumptech.glide.load.DataSource; +import com.bumptech.glide.load.data.DataFetcher; +import com.bumptech.glide.load.model.GlideUrl; +import com.nextcloud.android.sso.aidl.NextcloudRequest; +import com.nextcloud.android.sso.api.NextcloudAPI; +import com.nextcloud.android.sso.api.Response; + +import java.io.InputStream; +import java.net.MalformedURLException; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * Fetches an {@link InputStream} using the sso library. + */ +public class SingleSignOnStreamFetcher implements DataFetcher<InputStream> { + + private final NextcloudAPI client; + private final GlideUrl url; + + // Public API. + @SuppressWarnings("WeakerAccess") + public SingleSignOnStreamFetcher(NextcloudAPI client, GlideUrl url) { + this.client = client; + this.url = url; + } + + @Override + public void loadData(@NonNull Priority priority, @NonNull final DataCallback<? super InputStream> callback) {Log.v("yey", "yey fetcher"); + try { + NextcloudRequest.Builder requestBuilder = new NextcloudRequest.Builder() + .setMethod("GET") + .setUrl(url.toURL().getPath()); + Map<String, List<String>> header = new HashMap<>(); + for (Map.Entry<String, String> headerEntry : url.getHeaders().entrySet()) { + header.put(headerEntry.getKey(), Collections.singletonList(headerEntry.getValue())); + } + requestBuilder.setHeader(header); + NextcloudRequest nextcloudRequest = requestBuilder.build(); + Response response = client.performNetworkRequestV2(nextcloudRequest); + callback.onDataReady(response.getBody()); + } catch (MalformedURLException e) { + callback.onLoadFailed(e); + } catch (Exception e) { + callback.onLoadFailed(e); + } + + } + + @Override + public void cleanup() { + + } + + @Override + public void cancel() { + + } + + @NonNull + @Override + public Class<InputStream> getDataClass() { + return InputStream.class; + } + + @NonNull + @Override + public DataSource getDataSource() { + return DataSource.REMOTE; + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/glide/SingleSignOnUrlLoader.java b/app/src/main/java/it/niedermann/owncloud/notes/glide/SingleSignOnUrlLoader.java new file mode 100644 index 00000000..a9a57875 --- /dev/null +++ b/app/src/main/java/it/niedermann/owncloud/notes/glide/SingleSignOnUrlLoader.java @@ -0,0 +1,88 @@ +package it.niedermann.owncloud.notes.glide; + +import android.content.Context; +import android.util.Log; + +import androidx.annotation.NonNull; + +import com.bumptech.glide.load.Options; +import com.bumptech.glide.load.model.GlideUrl; +import com.bumptech.glide.load.model.ModelLoader; +import com.bumptech.glide.load.model.ModelLoaderFactory; +import com.bumptech.glide.load.model.MultiModelLoaderFactory; +import com.google.gson.GsonBuilder; +import com.nextcloud.android.sso.api.NextcloudAPI; +import com.nextcloud.android.sso.exceptions.NextcloudFilesAppAccountNotFoundException; +import com.nextcloud.android.sso.exceptions.NoCurrentAccountSelectedException; +import com.nextcloud.android.sso.helper.SingleAccountHelper; + +import java.io.InputStream; + +/** + * A simple model loader for fetching media over http/https using OkHttp. + */ +public class SingleSignOnUrlLoader implements ModelLoader<GlideUrl, InputStream> { + + private static final String TAG = SingleSignOnUrlLoader.class.getCanonicalName(); + private final NextcloudAPI client; + + // Public API. + @SuppressWarnings("WeakerAccess") + public SingleSignOnUrlLoader(@NonNull NextcloudAPI client) { + this.client = client; + } + + @Override + public boolean handles(@NonNull GlideUrl url) { + return true; + } + + @Override + public LoadData<InputStream> buildLoadData( + @NonNull GlideUrl model, int width, int height, @NonNull Options options) { + return new LoadData<>(model, new SingleSignOnStreamFetcher(client, model)); + } + + /** + * The default factory for {@link SingleSignOnUrlLoader}s. + */ + // Public API. + @SuppressWarnings("WeakerAccess") + public static class Factory implements ModelLoaderFactory<GlideUrl, InputStream> { + private SingleSignOnUrlLoader loader; + + /** + * Constructor for a new Factory that runs requests using given client. + */ + public Factory(@NonNull Context context) { + try { + loader = new SingleSignOnUrlLoader(new NextcloudAPI(context, SingleAccountHelper.getCurrentSingleSignOnAccount(context), new GsonBuilder().create(), new NextcloudAPI.ApiConnectedListener() { + @Override + public void onConnected() { + Log.v(TAG, "SSO API successfully initialized"); + } + + @Override + public void onError(Exception ex) { + Log.e(TAG, ex.getMessage(), ex); + } + })); + } catch (NextcloudFilesAppAccountNotFoundException e) { + e.printStackTrace(); + } catch (NoCurrentAccountSelectedException e) { + e.printStackTrace(); + } + } + + @NonNull + @Override + public ModelLoader<GlideUrl, InputStream> build(MultiModelLoaderFactory multiFactory) { + return loader; + } + + @Override + public void teardown() { + // Do nothing, this instance doesn't own the client. + } + } +} diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteServerSyncHelper.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteServerSyncHelper.java index e499e95a..26088d77 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteServerSyncHelper.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteServerSyncHelper.java @@ -42,7 +42,7 @@ import java.util.Map; import java.util.Objects; import java.util.Set; -import it.niedermann.nextcloud.exception.ExceptionUtil; +import it.niedermann.owncloud.notes.ExceptionUtil; import it.niedermann.owncloud.notes.R; import it.niedermann.owncloud.notes.model.CloudNote; import it.niedermann.owncloud.notes.model.DBNote; diff --git a/app/src/main/res/layout/activity_exception.xml b/app/src/main/res/layout/activity_exception.xml new file mode 100644 index 00000000..cbee5779 --- /dev/null +++ b/app/src/main/res/layout/activity_exception.xml @@ -0,0 +1,76 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <androidx.appcompat.widget.Toolbar + android:id="@+id/toolbar" + android:layout_width="match_parent" + android:layout_height="?attr/actionBarSize" + android:background="?attr/colorPrimary" + android:theme="@style/toolbarStyle" + app:contentInsetStartWithNavigation="0dp" + app:elevation="4dp" + app:titleMarginStart="0dp" + tools:title="@string/simple_exception" /> + + <TextView + android:id="@+id/message" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="@dimen/activity_margin" + android:hint="An error appeared." + tools:ignore="HardcodedText" /> + + <TextView + android:id="@+id/stacktrace" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_marginStart="@dimen/activity_margin" + android:layout_marginLeft="16dp" + android:layout_marginEnd="16dp" + android:layout_marginRight="16dp" + android:layout_weight="1" + android:background="@color/bg_highlighted" + android:padding="8dp" + android:scrollbars="horizontal|vertical" + android:textIsSelectable="true" + android:typeface="monospace" + tools:text="@string/android_get_accounts_permission_not_granted_exception_message" /> + + <LinearLayout + style="?android:buttonBarStyle" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_margin="16dp" + android:gravity="end" + android:orientation="horizontal" + android:weightSum="1.0"> + + <Button + android:id="@+id/close" + style="?android:buttonBarButtonStyle" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_weight=".5" + android:text="@string/simple_close" /> + + <Button + android:id="@+id/copy" + style="?android:buttonBarButtonStyle" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_marginTop="6dp" + android:layout_marginBottom="6dp" + android:layout_weight=".5" + android:background="@color/primary" + android:foreground="?attr/selectableItemBackground" + android:text="@string/simple_copy" + android:textColor="@color/fg_contrast" + tools:ignore="UnusedAttribute" /> + + </LinearLayout> +</LinearLayout>
\ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/2011000.txt b/fastlane/metadata/android/en-US/changelogs/2011000.txt new file mode 100644 index 00000000..e4ae4069 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/2011000.txt @@ -0,0 +1 @@ +- 🔒 Password protection (#354) - special thanks to @beatbrot |