share pictures across apps (#129)

* share implemented

* added test for share intent
This commit is contained in:
Ulysse Widmer 2020-05-01 09:01:13 +02:00 committed by GitHub
parent 20a2fd51ad
commit db594bbda2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 136 additions and 30 deletions

View File

@ -4,19 +4,27 @@ import android.content.Context
import android.content.Intent
import androidx.test.core.app.ActivityScenario
import androidx.test.espresso.Espresso.onView
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.action.ViewActions.click
import androidx.test.espresso.action.ViewActions.longClick
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.intent.Intents
import androidx.test.espresso.intent.matcher.IntentMatchers
import androidx.test.espresso.intent.rule.IntentsTestRule
import androidx.test.espresso.matcher.RootMatchers
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.rule.GrantPermissionRule
import com.h.pixeldroid.objects.Account
import com.h.pixeldroid.objects.Attachment
import com.h.pixeldroid.objects.Status
import com.h.pixeldroid.testUtility.MockServer
import org.hamcrest.CoreMatchers
import org.hamcrest.Matcher
import org.junit.After
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@ -43,6 +51,7 @@ class PostTest {
Context.MODE_PRIVATE)
preferences.edit().putString("accessToken", "azerty").apply()
preferences.edit().putString("domain", baseUrl.toString()).apply()
Intents.init()
}
@Test
@ -100,4 +109,62 @@ class PostTest {
).check(matches(isDisplayed()))
Thread.sleep(5000)
}
}
@Test
fun shareTestSimplePost() {
val expectedIntent: Matcher<Intent> = IntentMatchers.hasAction(Intent.ACTION_CHOOSER)
val attachment = Attachment(
id = "12",
url = "https://wiki.gnugen.ch/lib/tpl/gnugen/images/logo_web.png"
)
val post = Status(
id = "12",
account = Account(
id = "12",
username = "douze"
),
media_attachments = listOf(attachment)
)
val intent = Intent(context, PostActivity::class.java)
intent.putExtra(Status.POST_TAG, post)
ActivityScenario.launch<PostActivity>(intent)
onView(withId(R.id.postPicture)).perform(longClick())
onView(withText(R.string.share_picture)).inRoot(RootMatchers.isPlatformPopup()).perform(click())
Thread.sleep(2000)
Intents.intended(expectedIntent)
}
@Test
fun shareIntentAlbumTest() {
val expectedIntent: Matcher<Intent> = IntentMatchers.hasAction(Intent.ACTION_CHOOSER)
val attachment1 = Attachment(
id = "12",
url = "https://wiki.gnugen.ch/lib/tpl/gnugen/images/logo_web.png"
)
val attachment2 = Attachment(
id = "13",
url = "https://wiki.gnugen.ch/lib/tpl/gnugen/images/logo_web.png"
)
val post = Status(
id = "12",
account = Account(
id = "12",
username = "douze"
),
media_attachments = listOf(attachment1, attachment2)
)
val intent = Intent(context, PostActivity::class.java)
intent.putExtra(Status.POST_TAG, post)
ActivityScenario.launch<PostActivity>(intent)
onView(withId(R.id.imageImageView)).perform(longClick())
onView(withText(R.string.share_picture)).inRoot(RootMatchers.isPlatformPopup()).perform(click())
Thread.sleep(2000)
Intents.intended(expectedIntent)
}
@After
fun after() {
Intents.release()
}
}

View File

@ -51,6 +51,10 @@ class ImageFragment : Fragment() {
ImageUtils.downloadImage(requireActivity(), view.context, imgUrl)
true
}
R.id.image_popup_menu_share_picture -> {
ImageUtils.downloadImage(requireActivity(), view.context, imgUrl, share = true)
true
}
else -> false
}
}

View File

@ -1,9 +1,13 @@
package com.h.pixeldroid.objects
import android.app.Activity
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Typeface
import android.graphics.drawable.Drawable
import android.net.Uri
import android.provider.MediaStore
import android.text.Spanned
import android.text.method.LinkMovementMethod
import android.util.Log
@ -16,15 +20,15 @@ import android.widget.LinearLayout
import android.widget.PopupMenu
import android.widget.TextView
import android.widget.Toast
import androidx.core.content.ContextCompat.startActivity
import androidx.core.text.toSpanned
import androidx.core.view.drawToBitmap
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import androidx.viewpager2.adapter.FragmentStateAdapter
import androidx.viewpager2.widget.ViewPager2
import com.bumptech.glide.RequestBuilder
import com.google.android.material.tabs.TabLayoutMediator
import com.h.pixeldroid.ImageFragment
import com.h.pixeldroid.MainActivity
import com.h.pixeldroid.R
import com.h.pixeldroid.api.PixelfedAPI
import com.h.pixeldroid.fragments.feeds.PostViewHolder
@ -42,7 +46,10 @@ import kotlinx.android.synthetic.main.post_fragment.view.postPager
import kotlinx.android.synthetic.main.post_fragment.view.postPicture
import kotlinx.android.synthetic.main.post_fragment.view.postTabs
import kotlinx.android.synthetic.main.post_fragment.view.profilePic
import retrofit2.http.Url
import java.io.OutputStream
import java.io.Serializable
import java.net.URL
/*
Represents a status posted by an account.
@ -316,6 +323,10 @@ data class Status(
downloadImage(activity, view.context, getPostUrl()!!)
true
}
R.id.image_popup_menu_share_picture -> {
downloadImage(activity, view.context, getPostUrl()!!, share = true)
true
}
else -> false
}
}

View File

@ -1,19 +1,24 @@
package com.h.pixeldroid.utils
import android.app.DownloadManager
import android.content.ContentValues
import android.content.Context
import android.content.Intent
import android.database.Cursor
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Environment
import android.provider.Settings.Global.getString
import android.provider.MediaStore.Images
import android.widget.Toast
import androidx.fragment.app.FragmentActivity
import com.h.pixeldroid.R
import java.io.File
class ImageUtils {
companion object {
fun downloadImage(activity: FragmentActivity, context: Context, url: String) {
fun downloadImage(activity: FragmentActivity, context: Context, url: String, share: Boolean = false) {
var msg = ""
var lastMsg = ""
val directory = File(Environment.DIRECTORY_PICTURES)
@ -24,6 +29,7 @@ class ImageUtils {
as DownloadManager
val downloadUri = Uri.parse(url)
val title = url.substring(url.lastIndexOf("/") + 1)
val ext = url.substring(url.lastIndexOf("."))
val request = DownloadManager.Request(downloadUri).apply {
setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI
or DownloadManager.Request.NETWORK_MOBILE)
@ -43,35 +49,50 @@ class ImageUtils {
downloading = false
}
val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
msg = when (status) {
DownloadManager.STATUS_FAILED ->
context.getString(R.string.image_download_failed)
DownloadManager.STATUS_RUNNING ->
context.getString(R.string.image_download_downloading)
DownloadManager.STATUS_SUCCESSFUL ->
context.getString(R.string.image_download_success)
else -> ""
}
if (msg != lastMsg && msg != "") {
activity.runOnUiThread {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show()
if(!share) {
msg = when (status) {
DownloadManager.STATUS_FAILED ->
context.getString(R.string.image_download_failed)
DownloadManager.STATUS_RUNNING ->
context.getString(R.string.image_download_downloading)
DownloadManager.STATUS_SUCCESSFUL ->
context.getString(R.string.image_download_success)
else -> ""
}
lastMsg = msg
if (msg != lastMsg && msg != "") {
activity.runOnUiThread {
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show()
}
lastMsg = msg
}
} else if (status == DownloadManager.STATUS_SUCCESSFUL) {
val icon: Bitmap = BitmapFactory.decodeFile(
Uri.parse(cursor.getString(
cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI)
)).path
)
val intentShare = Intent(Intent.ACTION_SEND)
intentShare.type = "image/$ext"
val values = ContentValues()
values.put(Images.Media.TITLE, title)
values.put(Images.Media.MIME_TYPE, "image/$ext")
val uri: Uri = context.contentResolver.insert(
Images.Media.EXTERNAL_CONTENT_URI,
values
)!!
try {
val outstream = context.contentResolver.openOutputStream(uri)!!
icon.compress(Bitmap.CompressFormat.JPEG, 100, outstream)
outstream.close()
} catch(e: Exception) {
e.printStackTrace()
}
intentShare.putExtra(Intent.EXTRA_STREAM, uri)
context.startActivity(Intent.createChooser(intentShare, "Share Image"))
}
cursor.close()
}
}).start()
}
private fun statusMessage(url: String, directory: File, status: Int, context: Context): String {
return when (status) {
DownloadManager.STATUS_FAILED -> context.getString(R.string.image_download_failed)
DownloadManager.STATUS_RUNNING -> "Downloading..."
DownloadManager.STATUS_SUCCESSFUL -> "Image downloaded successfully in $directory" + File.separator + url.substring(
url.lastIndexOf("/") + 1
)
else -> ""
}
}
}
}

View File

@ -2,4 +2,6 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/image_popup_menu_save_to_gallery"
android:title="@string/save_to_gallery"/>
<item android:id="@+id/image_popup_menu_share_picture"
android:title="@string/share_picture"/>
</menu>

View File

@ -49,4 +49,5 @@
<string name="image_download_failed">Download has been failed, please try again</string>
<string name="image_download_downloading">Downloading…</string>
<string name="image_download_success">Image downloaded successfully</string>
<string name="share_picture">Share picture...</string>
</resources>