From c9021b7b8a430cc77a38b7cfac8345d560ff0f2f Mon Sep 17 00:00:00 2001 From: gmjgh Date: Tue, 13 Feb 2018 19:33:16 +0200 Subject: [PATCH 1/4] Extensions for Activity, Fragment and Context --- src/main/java/androidx/content/Activity.kt | 60 +++++++++++ src/main/java/androidx/content/Context.kt | 114 +++++++++++++++++++++ src/main/java/androidx/content/Fragment.kt | 92 +++++++++++++++++ 3 files changed, 266 insertions(+) create mode 100644 src/main/java/androidx/content/Activity.kt create mode 100644 src/main/java/androidx/content/Fragment.kt diff --git a/src/main/java/androidx/content/Activity.kt b/src/main/java/androidx/content/Activity.kt new file mode 100644 index 00000000..a7fc76c0 --- /dev/null +++ b/src/main/java/androidx/content/Activity.kt @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.content + +import android.app.Activity +import android.content.Intent +import android.graphics.Rect +import android.net.Uri +import android.provider.MediaStore +import android.support.annotation.RequiresApi + +/** + * Screen [Rect] + */ +val Activity.screenRect: Rect + get() { + val displayRectangle = Rect() + window.decorView.getWindowVisibleDisplayFrame(displayRectangle) + return displayRectangle + } + +/** + * Opens link in new window of an app that can view Internet links + */ +fun Activity.viewLink(link: String = "http://www.google.com") { + startActivity(Intent(Intent.ACTION_VIEW, Uri.parse(link))) +} + +/** + * Opens filesystem file picker. Result is delivered into onActivityResult + * Requires runtime permission [android.Manifest.permission.READ_EXTERNAL_STORAGE] + */ +@RequiresApi(19) +fun Activity.getFileFromFilesystem(requestCode: Int = 22, type: String = "image/*") { + val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) + intent.addCategory(Intent.CATEGORY_OPENABLE) + intent.type = type + startActivityForResult(intent, requestCode) +} + +/** + * Opens default camera. Result is delivered into onActivityResult + * Requires runtime permission [android.Manifest.permission.CAMERA] + */ +fun Activity.getImageFromCamera(requestCode: Int = 23) = + startActivityForResult(Intent(MediaStore.ACTION_IMAGE_CAPTURE), requestCode) diff --git a/src/main/java/androidx/content/Context.kt b/src/main/java/androidx/content/Context.kt index 128f0602..6a2e7578 100644 --- a/src/main/java/androidx/content/Context.kt +++ b/src/main/java/androidx/content/Context.kt @@ -18,10 +18,27 @@ package androidx.content import android.content.Context import android.content.res.TypedArray +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Point +import android.graphics.drawable.Drawable +import android.net.Uri +import android.provider.MediaStore import android.support.annotation.AttrRes +import android.support.annotation.LayoutRes import android.support.annotation.RequiresApi import android.support.annotation.StyleRes import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.view.WindowManager +import java.io.File +import java.io.FileNotFoundException +import java.io.FileOutputStream +import java.io.IOException +import java.net.MalformedURLException +import java.nio.charset.Charset /** * Return the handle to a system-level service by class. @@ -91,3 +108,100 @@ inline fun Context.withStyledAttributes( typedArray.recycle() } } + +/** + * Screen [Point] dimens + */ +val Context.screenPointDimens: Point + get() { + val point = Point() + (getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay + .getSize(point) + return point + } + +/** + * Screen aspect ration + */ +val Context.screenAspectRatio: Float + get() { + val point = screenPointDimens + return point.x.toFloat() / point.y.toFloat() + } + +/** + * Return string asset for given [path] and [charset] + * + * Throws [IOException] + */ +@Throws(IOException::class) +fun Context.getStringAsset(path: String, charset: String = "UTF-8"): String? { + val inputStream = javaClass.classLoader.getResourceAsStream("assets/$path") + val size = inputStream.available() + val buffer = ByteArray(size) + inputStream.read(buffer) + inputStream.close() + return String(buffer, Charset.forName(charset)) +} + +/** + * Return image asset for given [path] and [charset] like [Bitmap] + */ +fun Context.getImageAssetAsBitmap(path: String): Bitmap?{ + val ims = javaClass.classLoader.getResourceAsStream("assets/$path") + return BitmapFactory.decodeStream(ims) +} + +/** + * Return image asset for given [path] and [charset] like [Drawable] + */ +fun Context.getImageAssetAsDrawable(path: String): Drawable?{ + val ims = javaClass.classLoader.getResourceAsStream("assets/$path") + return Drawable.createFromStream(ims, path) +} + +/** + * Creates temp file from given bitmap. All exception are caught - returns null in case of exception + */ +fun Context.createTempFileFromBitmap( + image: Bitmap?, + fileName: String = "image_${System.currentTimeMillis()}.jpg" +): File? { + try { + val fileTemp = File(externalCacheDir, fileName) + fileTemp.createNewFile() + val fos = FileOutputStream(fileTemp) + image?.compress(Bitmap.CompressFormat.JPEG, 90, fos) + fos.close() + return fileTemp + } catch (e: FileNotFoundException) { + e.printStackTrace() + return null + } catch (e: MalformedURLException) { + e.printStackTrace() + return null + } catch (e: IOException) { + e.printStackTrace() + return null + } +} + +/** + * Creates bitmap from Uri of image file + * + * Throws [FileNotFoundException] and [IOException] + */ +@Suppress("HasPlatformType") +@Throws(FileNotFoundException::class, IOException::class) +fun Context.createBitmapFromFile(file: Uri) = MediaStore.Images.Media.getBitmap(contentResolver, file) + +/** + * Inflates view for given [layout] + * + * Throws [IOException] + */ +fun Context.inflateView( + @LayoutRes layout: Int, root: ViewGroup? = null, + attachToRoot: Boolean = false +): View = + LayoutInflater.from(this).inflate(layout, root, attachToRoot) \ No newline at end of file diff --git a/src/main/java/androidx/content/Fragment.kt b/src/main/java/androidx/content/Fragment.kt new file mode 100644 index 00000000..47bf0857 --- /dev/null +++ b/src/main/java/androidx/content/Fragment.kt @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.content + +import android.app.Activity +import android.app.Fragment +import android.graphics.Rect +import android.support.annotation.RequiresApi + +/** + * Screen [Rect] + */ +val Fragment.screenRect: Rect + get() { + val displayRectangle = android.graphics.Rect() + activity.window.decorView.getWindowVisibleDisplayFrame(displayRectangle) + return displayRectangle + } + +/** + * Opens filesystem file picker. Result is delivered into onActivityResult + * Requires runtime permission [android.Manifest.permission.READ_EXTERNAL_STORAGE] + */ +@RequiresApi(19) +fun Fragment.getFileFromFilesystem(requestCode: Int = 22, type: String = "image/*") { + val intent = android.content.Intent(android.content.Intent.ACTION_OPEN_DOCUMENT) + intent.addCategory(android.content.Intent.CATEGORY_OPENABLE) + intent.type = type + startActivityForResult(intent, requestCode) +} + +/** + * Opens default camera. Result is delivered into onActivityResult + * Requires runtime permission [android.Manifest.permission.CAMERA] + */ +fun Fragment.getImageFromCamera(requestCode: Int = 23) = + startActivityForResult( + android.content.Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE), + requestCode + ) + +/** + * Convenient function that gives access to specific [Activity] context inside the [Fragment] + * + * ``` + * Example : + * withActivity{ + * supportActionBar?.title = "Hello World" + * } + * ``` + */ +@Throws(ClassCastException::class) +inline fun Fragment.withActivity(block: T.() -> Unit) { + if (activity != null && isAdded) { + block(activity as T) + } +} + + +/** + * Convenient function that gives access to specific [Activity] context inside the [Fragment] + * and returns value + * + * ``` + * Example : + * val title = withActivity{ + * supportActionBar?.title.toString() + * } + * printLn(title) // MainActivity + * ``` + */ +@Throws(ClassCastException::class) +inline fun Fragment.withActivity(block: T.() -> R): R? = + if (activity != null && isAdded) { + block(this as T) + } else { + null + } \ No newline at end of file From 9ff94f7dc07cb582f53d776f55033e3be1f6c20b Mon Sep 17 00:00:00 2001 From: gmjgh Date: Tue, 13 Feb 2018 19:41:45 +0200 Subject: [PATCH 2/4] Tests for extensions for Activity, Fragment and Context --- src/androidTest/assets/test_text.txt | 1 + .../java/androidx/content/ActivityTest.kt | 44 ++++++++++ .../java/androidx/content/ContextTest.kt | 83 +++++++++++++++++++ .../java/androidx/content/FragmentTest.kt | 59 +++++++++++++ .../kotlin/TestActivityWithFragment.kt | 31 +++++++ .../androidx/kotlin/fragment/TestFragment.kt | 23 +++++ .../layout/test_activity_with_fragment.xml | 30 +++++++ 7 files changed, 271 insertions(+) create mode 100644 src/androidTest/assets/test_text.txt create mode 100644 src/androidTest/java/androidx/content/ActivityTest.kt create mode 100644 src/androidTest/java/androidx/content/FragmentTest.kt create mode 100644 src/androidTest/java/androidx/kotlin/TestActivityWithFragment.kt create mode 100644 src/androidTest/java/androidx/kotlin/fragment/TestFragment.kt create mode 100644 src/androidTest/res/layout/test_activity_with_fragment.xml diff --git a/src/androidTest/assets/test_text.txt b/src/androidTest/assets/test_text.txt new file mode 100644 index 00000000..3e8cd294 --- /dev/null +++ b/src/androidTest/assets/test_text.txt @@ -0,0 +1 @@ +android-ktx \ No newline at end of file diff --git a/src/androidTest/java/androidx/content/ActivityTest.kt b/src/androidTest/java/androidx/content/ActivityTest.kt new file mode 100644 index 00000000..53516d13 --- /dev/null +++ b/src/androidTest/java/androidx/content/ActivityTest.kt @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.content + +import android.app.Activity +import android.content.Intent +import android.graphics.Rect +import android.net.Uri +import android.provider.MediaStore +import android.support.annotation.RequiresApi +import android.support.test.rule.ActivityTestRule +import androidx.kotlin.TestActivity +import org.junit.Assert.assertEquals +import org.junit.Rule +import org.junit.Test + +class ActivityTest { + + @JvmField + @Rule + val rule = ActivityTestRule(TestActivity::class.java) + + @Test + fun testScreenRect() { + val displayRectangle = Rect() + rule.activity.window.decorView.getWindowVisibleDisplayFrame(displayRectangle) + assertEquals(rule.activity.screenRect, displayRectangle) + } + +} diff --git a/src/androidTest/java/androidx/content/ContextTest.kt b/src/androidTest/java/androidx/content/ContextTest.kt index 4ea5406a..ed286f21 100644 --- a/src/androidTest/java/androidx/content/ContextTest.kt +++ b/src/androidTest/java/androidx/content/ContextTest.kt @@ -16,15 +16,27 @@ package androidx.content +import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Point +import android.graphics.drawable.Drawable +import android.provider.MediaStore import android.support.test.InstrumentationRegistry import android.support.test.filters.SdkSuppress import android.test.mock.MockContext +import android.view.LayoutInflater +import android.view.WindowManager import androidx.getAttributeSet import androidx.kotlin.test.R +import androidx.os.toUri import org.junit.Assert.assertEquals import org.junit.Assert.assertSame import org.junit.Assert.assertTrue import org.junit.Test +import java.io.File +import java.io.FileOutputStream +import java.nio.charset.Charset class ContextTest { private val context = InstrumentationRegistry.getContext() @@ -70,4 +82,75 @@ class ContextTest { assertTrue(getInt(R.styleable.SampleAttrs_sample, -1) != -1) } } + + @Test + fun testScreenPointDimens() { + val point = Point() + (context.getSystemService(Context.WINDOW_SERVICE) as WindowManager).defaultDisplay + .getSize(point) + val testPoint = context.screenPointDimens + assertEquals(point.x, testPoint.x) + assertEquals(point.y, testPoint.y) + } + + @Test + fun testScreenAspectRatio() { + val point = context.screenPointDimens + val aspectRatio = point.x.toFloat() / point.y.toFloat() + val testAspectRatio = context.screenAspectRatio + assertEquals(aspectRatio, testAspectRatio) + } + + @Test + fun testGetStringAsset() { + val inputStream = javaClass.classLoader.getResourceAsStream("assets/test_text.txt") + val size = inputStream.available() + val buffer = ByteArray(size) + inputStream.read(buffer) + inputStream.close() + val resultString = String(buffer, Charset.forName("UTF-8")) + val testString = context.getStringAsset("test_text.txt") + assertEquals(resultString, testString) + } + + @Test + fun testGetImageAssetAsBitmap() { + val ims = javaClass.classLoader.getResourceAsStream("assets/red.png") + val bitmap = BitmapFactory.decodeStream(ims) + val testBitmap = context.getImageAssetAsBitmap("red.png") + assertEquals(bitmap, testBitmap) + } + + @Test + fun testImageAssetAsDrawable() { + val ims = javaClass.classLoader.getResourceAsStream("assets/red.png") + val drawable = Drawable.createFromStream(ims, "red.png") + val testDrawable = context.getImageAssetAsDrawable("red.png") + assertEquals(drawable, testDrawable) + } + + @Test + fun testCreateTempFileFromBitmapAndViceVersa() { + val image = context.getImageAssetAsBitmap("red.png") + val fileTemp = File(context.externalCacheDir, "test.jpg") + fileTemp.createNewFile() + val fos = FileOutputStream(fileTemp) + image?.compress(Bitmap.CompressFormat.JPEG, 90, fos) + fos.close() + val file = fileTemp + val testFileUri = context.createTempFileFromBitmap(image) + assertEquals(file.exists(), testFileUri?.exists()) + assertEquals(file.length(), testFileUri?.length()) + val bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, file.toUri()) + val testBitmap = context.createBitmapFromFile(file.toUri()) + assertEquals(bitmap, testBitmap) + context.externalCacheDir.delete() + } + + @Test + fun testInflateView() { + val view = LayoutInflater.from(context).inflate(R.layout.test_activity, null, false) + val testView = context.inflateView(R.layout.test_activity) + assertEquals(view, testView) + } } diff --git a/src/androidTest/java/androidx/content/FragmentTest.kt b/src/androidTest/java/androidx/content/FragmentTest.kt new file mode 100644 index 00000000..7a7bb71d --- /dev/null +++ b/src/androidTest/java/androidx/content/FragmentTest.kt @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.content + +import android.graphics.Rect +import android.support.test.rule.ActivityTestRule +import androidx.kotlin.TestActivityWithFragment +import org.junit.Assert.assertEquals +import org.junit.Rule +import org.junit.Test + +class FragmentTest { + + @JvmField + @Rule + val rule = ActivityTestRule(TestActivityWithFragment::class.java) + + @Test + fun testScreenRect() { + val fragment = rule.activity.fragmentManager.fragments[0] + val displayRectangle = Rect() + rule.activity.window.decorView.getWindowVisibleDisplayFrame(displayRectangle) + assertEquals(fragment.screenRect, displayRectangle) + } + + @Test + fun testWithActivity() { + val fragment = rule.activity.fragmentManager.fragments[0] + var localSuccess = false + fragment.withActivity { + localSuccess = success + } + assertEquals(localSuccess, true) + } + + @Test + fun testWithActivityReturns() { + val fragment = rule.activity.fragmentManager.fragments[0] + val localSuccess = fragment.withActivity { + success + } + assertEquals(localSuccess, true) + } + +} \ No newline at end of file diff --git a/src/androidTest/java/androidx/kotlin/TestActivityWithFragment.kt b/src/androidTest/java/androidx/kotlin/TestActivityWithFragment.kt new file mode 100644 index 00000000..462d8256 --- /dev/null +++ b/src/androidTest/java/androidx/kotlin/TestActivityWithFragment.kt @@ -0,0 +1,31 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.kotlin + +import android.app.Activity +import android.os.Bundle +import androidx.kotlin.test.R + +class TestActivityWithFragment : Activity() { + + val success = true + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.test_activity_with_fragment) + } +} \ No newline at end of file diff --git a/src/androidTest/java/androidx/kotlin/fragment/TestFragment.kt b/src/androidTest/java/androidx/kotlin/fragment/TestFragment.kt new file mode 100644 index 00000000..1a2dc88b --- /dev/null +++ b/src/androidTest/java/androidx/kotlin/fragment/TestFragment.kt @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2018 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package androidx.kotlin.fragment + +import android.app.Fragment + +class TestFragment: Fragment(){ + +} \ No newline at end of file diff --git a/src/androidTest/res/layout/test_activity_with_fragment.xml b/src/androidTest/res/layout/test_activity_with_fragment.xml new file mode 100644 index 00000000..7353cdf6 --- /dev/null +++ b/src/androidTest/res/layout/test_activity_with_fragment.xml @@ -0,0 +1,30 @@ + + + + + + + + \ No newline at end of file From 508ea7fe1a8a35eb37f1fe1330978f121834f56b Mon Sep 17 00:00:00 2001 From: gmjgh Date: Wed, 14 Feb 2018 14:00:14 +0200 Subject: [PATCH 3/4] Tests for extensions for Activity, Fragment and Context, small typo fix --- api/current.txt | 23 +++++++++++++++ src/androidTest/AndroidManifest.xml | 1 + .../java/androidx/content/ActivityTest.kt | 2 ++ .../java/androidx/content/ContextTest.kt | 15 +++++----- .../java/androidx/content/FragmentTest.kt | 22 ++++++++++----- .../androidx/kotlin/fragment/TestFragment.kt | 19 ++++++++++++- src/androidTest/res/layout/test_fragment.xml | 28 +++++++++++++++++++ src/main/java/androidx/content/Context.kt | 6 ++-- src/main/java/androidx/content/Fragment.kt | 2 +- src/main/java/androidx/os/File.kt | 2 +- 10 files changed, 100 insertions(+), 20 deletions(-) create mode 100644 src/androidTest/res/layout/test_fragment.xml diff --git a/api/current.txt b/api/current.txt index f2c469ae..816b1582 100644 --- a/api/current.txt +++ b/api/current.txt @@ -16,6 +16,14 @@ package androidx.animation { package androidx.content { + public final class ActivityKt { + ctor public ActivityKt(); + method @RequiresApi(19) public static final void getFileFromFilesystem(android.app.Activity, int requestCode = "22", String type = "\"image/*\""); + method public static final void getImageFromCamera(android.app.Activity, int requestCode = "23"); + method public static final android.graphics.Rect getScreenRect(android.app.Activity); + method public static final void viewLink(android.app.Activity, String link = "\"http://www.google.com\""); + } + public final class ContentValuesKt { ctor public ContentValuesKt(); method public static final error.NonExistentClass contentValuesOf(kotlin.Pair... pairs); @@ -23,10 +31,25 @@ package androidx.content { public final class ContextKt { ctor public ContextKt(); + method public static final android.graphics.Bitmap! createBitmapFromFile(android.content.Context, android.net.Uri file) throws java.io.FileNotFoundException, java.io.IOException; + method public static final java.io.File? createTempFileFromBitmap(android.content.Context, android.graphics.Bitmap? image, String fileName = "\"image_${System.currentTimeMillis()}.jpg\""); + method public static final android.graphics.Bitmap? getImageAssetAsBitmap(android.content.Context, String path); + method public static final android.graphics.drawable.Drawable? getImageAssetAsDrawable(android.content.Context, String path); + method public static final float getScreenAspectRatio(android.content.Context); + method public static final android.graphics.Point getScreenPointDimens(android.content.Context); + method public static final String? getStringAsset(android.content.Context, String path, String charset = "\"UTF-8\"") throws java.io.IOException; + method public static final android.view.View inflateView(android.content.Context, @LayoutRes int layout, android.view.ViewGroup? root = "null", boolean attachToRoot = "false"); method public static final void withStyledAttributes(android.content.Context, android.util.AttributeSet? set = "null", int[] attrs, @AttrRes int defStyleAttr = "0", @StyleRes int defStyleRes = "0", kotlin.jvm.functions.Function1 block); method public static final void withStyledAttributes(android.content.Context, @StyleRes int resourceId, int[] attrs, kotlin.jvm.functions.Function1 block); } + public final class FragmentKt { + ctor public FragmentKt(); + method @RequiresApi(19) public static final void getFileFromFilesystem(android.app.Fragment, int requestCode = "22", String type = "\"image/*\""); + method public static final void getImageFromCamera(android.app.Fragment, int requestCode = "23"); + method public static final android.graphics.Rect getScreenRect(android.app.Fragment); + } + public final class SharedPreferencesKt { ctor public SharedPreferencesKt(); method public static final void edit(android.content.SharedPreferences, kotlin.jvm.functions.Function1 action); diff --git a/src/androidTest/AndroidManifest.xml b/src/androidTest/AndroidManifest.xml index 1cd9512f..cac5b7f3 100644 --- a/src/androidTest/AndroidManifest.xml +++ b/src/androidTest/AndroidManifest.xml @@ -2,5 +2,6 @@ package="androidx.kotlin"> + diff --git a/src/androidTest/java/androidx/content/ActivityTest.kt b/src/androidTest/java/androidx/content/ActivityTest.kt index 53516d13..a0cc4326 100644 --- a/src/androidTest/java/androidx/content/ActivityTest.kt +++ b/src/androidTest/java/androidx/content/ActivityTest.kt @@ -22,6 +22,7 @@ import android.graphics.Rect import android.net.Uri import android.provider.MediaStore import android.support.annotation.RequiresApi +import android.support.test.InstrumentationRegistry import android.support.test.rule.ActivityTestRule import androidx.kotlin.TestActivity import org.junit.Assert.assertEquals @@ -38,6 +39,7 @@ class ActivityTest { fun testScreenRect() { val displayRectangle = Rect() rule.activity.window.decorView.getWindowVisibleDisplayFrame(displayRectangle) + InstrumentationRegistry.getInstrumentation().waitForIdleSync() assertEquals(rule.activity.screenRect, displayRectangle) } diff --git a/src/androidTest/java/androidx/content/ContextTest.kt b/src/androidTest/java/androidx/content/ContextTest.kt index ed286f21..c4f27dcd 100644 --- a/src/androidTest/java/androidx/content/ContextTest.kt +++ b/src/androidTest/java/androidx/content/ContextTest.kt @@ -28,6 +28,7 @@ import android.test.mock.MockContext import android.view.LayoutInflater import android.view.WindowManager import androidx.getAttributeSet +import androidx.graphics.drawable.toBitmap import androidx.kotlin.test.R import androidx.os.toUri import org.junit.Assert.assertEquals @@ -103,7 +104,7 @@ class ContextTest { @Test fun testGetStringAsset() { - val inputStream = javaClass.classLoader.getResourceAsStream("assets/test_text.txt") + val inputStream = context.assets.open("test_text.txt") val size = inputStream.available() val buffer = ByteArray(size) inputStream.read(buffer) @@ -115,18 +116,18 @@ class ContextTest { @Test fun testGetImageAssetAsBitmap() { - val ims = javaClass.classLoader.getResourceAsStream("assets/red.png") + val ims = context.assets.open("red.png") val bitmap = BitmapFactory.decodeStream(ims) val testBitmap = context.getImageAssetAsBitmap("red.png") - assertEquals(bitmap, testBitmap) + assertEquals(bitmap.byteCount, testBitmap?.byteCount) } @Test fun testImageAssetAsDrawable() { - val ims = javaClass.classLoader.getResourceAsStream("assets/red.png") + val ims = context.assets.open("red.png") val drawable = Drawable.createFromStream(ims, "red.png") val testDrawable = context.getImageAssetAsDrawable("red.png") - assertEquals(drawable, testDrawable) + assertEquals(drawable.toBitmap().byteCount, testDrawable?.toBitmap()?.byteCount) } @Test @@ -143,7 +144,7 @@ class ContextTest { assertEquals(file.length(), testFileUri?.length()) val bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, file.toUri()) val testBitmap = context.createBitmapFromFile(file.toUri()) - assertEquals(bitmap, testBitmap) + assertEquals(bitmap.byteCount, testBitmap?.byteCount) context.externalCacheDir.delete() } @@ -151,6 +152,6 @@ class ContextTest { fun testInflateView() { val view = LayoutInflater.from(context).inflate(R.layout.test_activity, null, false) val testView = context.inflateView(R.layout.test_activity) - assertEquals(view, testView) + assertEquals(view.drawableState, testView.drawableState) } } diff --git a/src/androidTest/java/androidx/content/FragmentTest.kt b/src/androidTest/java/androidx/content/FragmentTest.kt index 7a7bb71d..e2e100de 100644 --- a/src/androidTest/java/androidx/content/FragmentTest.kt +++ b/src/androidTest/java/androidx/content/FragmentTest.kt @@ -16,10 +16,12 @@ package androidx.content +import android.app.Fragment import android.graphics.Rect import android.support.test.rule.ActivityTestRule import androidx.kotlin.TestActivityWithFragment import org.junit.Assert.assertEquals +import org.junit.Before import org.junit.Rule import org.junit.Test @@ -29,19 +31,26 @@ class FragmentTest { @Rule val rule = ActivityTestRule(TestActivityWithFragment::class.java) + var fragment: Fragment? = null + + @Before + fun setup() { + rule.runOnUiThread { + fragment = rule.activity.fragmentManager.fragments[0] + } + } + @Test fun testScreenRect() { - val fragment = rule.activity.fragmentManager.fragments[0] val displayRectangle = Rect() rule.activity.window.decorView.getWindowVisibleDisplayFrame(displayRectangle) - assertEquals(fragment.screenRect, displayRectangle) + assertEquals(fragment?.screenRect, displayRectangle) } @Test fun testWithActivity() { - val fragment = rule.activity.fragmentManager.fragments[0] var localSuccess = false - fragment.withActivity { + fragment?.withActivity { localSuccess = success } assertEquals(localSuccess, true) @@ -49,10 +58,9 @@ class FragmentTest { @Test fun testWithActivityReturns() { - val fragment = rule.activity.fragmentManager.fragments[0] - val localSuccess = fragment.withActivity { + val localSuccess = fragment?.withActivity { success - } + } == true assertEquals(localSuccess, true) } diff --git a/src/androidTest/java/androidx/kotlin/fragment/TestFragment.kt b/src/androidTest/java/androidx/kotlin/fragment/TestFragment.kt index 1a2dc88b..d8c142c4 100644 --- a/src/androidTest/java/androidx/kotlin/fragment/TestFragment.kt +++ b/src/androidTest/java/androidx/kotlin/fragment/TestFragment.kt @@ -17,7 +17,24 @@ package androidx.kotlin.fragment import android.app.Fragment +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.kotlin.test.R.layout -class TestFragment: Fragment(){ +class TestFragment : Fragment() { + + override fun onCreateView( + inflater: LayoutInflater?, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + return inflater?.inflate(layout.test_fragment, container, false) ?: super.onCreateView( + inflater, + container, + savedInstanceState + ) + } } \ No newline at end of file diff --git a/src/androidTest/res/layout/test_fragment.xml b/src/androidTest/res/layout/test_fragment.xml new file mode 100644 index 00000000..8df0653a --- /dev/null +++ b/src/androidTest/res/layout/test_fragment.xml @@ -0,0 +1,28 @@ + + + + + + + + \ No newline at end of file diff --git a/src/main/java/androidx/content/Context.kt b/src/main/java/androidx/content/Context.kt index 6a2e7578..877bdb52 100644 --- a/src/main/java/androidx/content/Context.kt +++ b/src/main/java/androidx/content/Context.kt @@ -136,7 +136,7 @@ val Context.screenAspectRatio: Float */ @Throws(IOException::class) fun Context.getStringAsset(path: String, charset: String = "UTF-8"): String? { - val inputStream = javaClass.classLoader.getResourceAsStream("assets/$path") + val inputStream = assets.open(path) val size = inputStream.available() val buffer = ByteArray(size) inputStream.read(buffer) @@ -148,7 +148,7 @@ fun Context.getStringAsset(path: String, charset: String = "UTF-8"): String? { * Return image asset for given [path] and [charset] like [Bitmap] */ fun Context.getImageAssetAsBitmap(path: String): Bitmap?{ - val ims = javaClass.classLoader.getResourceAsStream("assets/$path") + val ims = assets.open(path) return BitmapFactory.decodeStream(ims) } @@ -156,7 +156,7 @@ fun Context.getImageAssetAsBitmap(path: String): Bitmap?{ * Return image asset for given [path] and [charset] like [Drawable] */ fun Context.getImageAssetAsDrawable(path: String): Drawable?{ - val ims = javaClass.classLoader.getResourceAsStream("assets/$path") + val ims = assets.open(path) return Drawable.createFromStream(ims, path) } diff --git a/src/main/java/androidx/content/Fragment.kt b/src/main/java/androidx/content/Fragment.kt index 47bf0857..a9c63efc 100644 --- a/src/main/java/androidx/content/Fragment.kt +++ b/src/main/java/androidx/content/Fragment.kt @@ -86,7 +86,7 @@ inline fun Fragment.withActivity(block: T.() -> Unit) { @Throws(ClassCastException::class) inline fun Fragment.withActivity(block: T.() -> R): R? = if (activity != null && isAdded) { - block(this as T) + block(activity as T) } else { null } \ No newline at end of file diff --git a/src/main/java/androidx/os/File.kt b/src/main/java/androidx/os/File.kt index e6863bfa..02f73e81 100644 --- a/src/main/java/androidx/os/File.kt +++ b/src/main/java/androidx/os/File.kt @@ -24,6 +24,6 @@ import java.io.File /** * Creates a Uri from the given file. * - * @see Uri.parse + * @see Uri.fromFile */ inline fun File.toUri(): Uri = Uri.fromFile(this) From 7c5e872d31323beaef8d548e51cb6e0edaf7d9f7 Mon Sep 17 00:00:00 2001 From: gmjgh Date: Wed, 14 Feb 2018 15:07:46 +0200 Subject: [PATCH 4/4] Removed extensions for Fragments due to https://github.com/android/android-ktx/pull/161 --- api/current.txt | 7 -- src/androidTest/AndroidManifest.xml | 1 - .../java/androidx/content/FragmentTest.kt | 67 -------------- .../kotlin/TestActivityWithFragment.kt | 31 ------- .../androidx/kotlin/fragment/TestFragment.kt | 40 -------- .../layout/test_activity_with_fragment.xml | 30 ------ src/androidTest/res/layout/test_fragment.xml | 28 ------ src/main/java/androidx/content/Fragment.kt | 92 ------------------- 8 files changed, 296 deletions(-) delete mode 100644 src/androidTest/java/androidx/content/FragmentTest.kt delete mode 100644 src/androidTest/java/androidx/kotlin/TestActivityWithFragment.kt delete mode 100644 src/androidTest/java/androidx/kotlin/fragment/TestFragment.kt delete mode 100644 src/androidTest/res/layout/test_activity_with_fragment.xml delete mode 100644 src/androidTest/res/layout/test_fragment.xml delete mode 100644 src/main/java/androidx/content/Fragment.kt diff --git a/api/current.txt b/api/current.txt index 816b1582..6aa6f9d8 100644 --- a/api/current.txt +++ b/api/current.txt @@ -43,13 +43,6 @@ package androidx.content { method public static final void withStyledAttributes(android.content.Context, @StyleRes int resourceId, int[] attrs, kotlin.jvm.functions.Function1 block); } - public final class FragmentKt { - ctor public FragmentKt(); - method @RequiresApi(19) public static final void getFileFromFilesystem(android.app.Fragment, int requestCode = "22", String type = "\"image/*\""); - method public static final void getImageFromCamera(android.app.Fragment, int requestCode = "23"); - method public static final android.graphics.Rect getScreenRect(android.app.Fragment); - } - public final class SharedPreferencesKt { ctor public SharedPreferencesKt(); method public static final void edit(android.content.SharedPreferences, kotlin.jvm.functions.Function1 action); diff --git a/src/androidTest/AndroidManifest.xml b/src/androidTest/AndroidManifest.xml index cac5b7f3..1cd9512f 100644 --- a/src/androidTest/AndroidManifest.xml +++ b/src/androidTest/AndroidManifest.xml @@ -2,6 +2,5 @@ package="androidx.kotlin"> - diff --git a/src/androidTest/java/androidx/content/FragmentTest.kt b/src/androidTest/java/androidx/content/FragmentTest.kt deleted file mode 100644 index e2e100de..00000000 --- a/src/androidTest/java/androidx/content/FragmentTest.kt +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.content - -import android.app.Fragment -import android.graphics.Rect -import android.support.test.rule.ActivityTestRule -import androidx.kotlin.TestActivityWithFragment -import org.junit.Assert.assertEquals -import org.junit.Before -import org.junit.Rule -import org.junit.Test - -class FragmentTest { - - @JvmField - @Rule - val rule = ActivityTestRule(TestActivityWithFragment::class.java) - - var fragment: Fragment? = null - - @Before - fun setup() { - rule.runOnUiThread { - fragment = rule.activity.fragmentManager.fragments[0] - } - } - - @Test - fun testScreenRect() { - val displayRectangle = Rect() - rule.activity.window.decorView.getWindowVisibleDisplayFrame(displayRectangle) - assertEquals(fragment?.screenRect, displayRectangle) - } - - @Test - fun testWithActivity() { - var localSuccess = false - fragment?.withActivity { - localSuccess = success - } - assertEquals(localSuccess, true) - } - - @Test - fun testWithActivityReturns() { - val localSuccess = fragment?.withActivity { - success - } == true - assertEquals(localSuccess, true) - } - -} \ No newline at end of file diff --git a/src/androidTest/java/androidx/kotlin/TestActivityWithFragment.kt b/src/androidTest/java/androidx/kotlin/TestActivityWithFragment.kt deleted file mode 100644 index 462d8256..00000000 --- a/src/androidTest/java/androidx/kotlin/TestActivityWithFragment.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.kotlin - -import android.app.Activity -import android.os.Bundle -import androidx.kotlin.test.R - -class TestActivityWithFragment : Activity() { - - val success = true - - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContentView(R.layout.test_activity_with_fragment) - } -} \ No newline at end of file diff --git a/src/androidTest/java/androidx/kotlin/fragment/TestFragment.kt b/src/androidTest/java/androidx/kotlin/fragment/TestFragment.kt deleted file mode 100644 index d8c142c4..00000000 --- a/src/androidTest/java/androidx/kotlin/fragment/TestFragment.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.kotlin.fragment - -import android.app.Fragment -import android.os.Bundle -import android.view.LayoutInflater -import android.view.View -import android.view.ViewGroup -import androidx.kotlin.test.R.layout - -class TestFragment : Fragment() { - - override fun onCreateView( - inflater: LayoutInflater?, - container: ViewGroup?, - savedInstanceState: Bundle? - ): View { - return inflater?.inflate(layout.test_fragment, container, false) ?: super.onCreateView( - inflater, - container, - savedInstanceState - ) - } - -} \ No newline at end of file diff --git a/src/androidTest/res/layout/test_activity_with_fragment.xml b/src/androidTest/res/layout/test_activity_with_fragment.xml deleted file mode 100644 index 7353cdf6..00000000 --- a/src/androidTest/res/layout/test_activity_with_fragment.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/androidTest/res/layout/test_fragment.xml b/src/androidTest/res/layout/test_fragment.xml deleted file mode 100644 index 8df0653a..00000000 --- a/src/androidTest/res/layout/test_fragment.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/src/main/java/androidx/content/Fragment.kt b/src/main/java/androidx/content/Fragment.kt deleted file mode 100644 index a9c63efc..00000000 --- a/src/main/java/androidx/content/Fragment.kt +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2018 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package androidx.content - -import android.app.Activity -import android.app.Fragment -import android.graphics.Rect -import android.support.annotation.RequiresApi - -/** - * Screen [Rect] - */ -val Fragment.screenRect: Rect - get() { - val displayRectangle = android.graphics.Rect() - activity.window.decorView.getWindowVisibleDisplayFrame(displayRectangle) - return displayRectangle - } - -/** - * Opens filesystem file picker. Result is delivered into onActivityResult - * Requires runtime permission [android.Manifest.permission.READ_EXTERNAL_STORAGE] - */ -@RequiresApi(19) -fun Fragment.getFileFromFilesystem(requestCode: Int = 22, type: String = "image/*") { - val intent = android.content.Intent(android.content.Intent.ACTION_OPEN_DOCUMENT) - intent.addCategory(android.content.Intent.CATEGORY_OPENABLE) - intent.type = type - startActivityForResult(intent, requestCode) -} - -/** - * Opens default camera. Result is delivered into onActivityResult - * Requires runtime permission [android.Manifest.permission.CAMERA] - */ -fun Fragment.getImageFromCamera(requestCode: Int = 23) = - startActivityForResult( - android.content.Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE), - requestCode - ) - -/** - * Convenient function that gives access to specific [Activity] context inside the [Fragment] - * - * ``` - * Example : - * withActivity{ - * supportActionBar?.title = "Hello World" - * } - * ``` - */ -@Throws(ClassCastException::class) -inline fun Fragment.withActivity(block: T.() -> Unit) { - if (activity != null && isAdded) { - block(activity as T) - } -} - - -/** - * Convenient function that gives access to specific [Activity] context inside the [Fragment] - * and returns value - * - * ``` - * Example : - * val title = withActivity{ - * supportActionBar?.title.toString() - * } - * printLn(title) // MainActivity - * ``` - */ -@Throws(ClassCastException::class) -inline fun Fragment.withActivity(block: T.() -> R): R? = - if (activity != null && isAdded) { - block(activity as T) - } else { - null - } \ No newline at end of file