share pictures across apps (#129)
* share implemented * added test for share intent
This commit is contained in:
parent
20a2fd51ad
commit
db594bbda2
@ -4,19 +4,27 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import androidx.test.core.app.ActivityScenario
|
import androidx.test.core.app.ActivityScenario
|
||||||
import androidx.test.espresso.Espresso.onView
|
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.click
|
||||||
import androidx.test.espresso.action.ViewActions.longClick
|
import androidx.test.espresso.action.ViewActions.longClick
|
||||||
import androidx.test.espresso.assertion.ViewAssertions.matches
|
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.RootMatchers
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withId
|
import androidx.test.espresso.matcher.ViewMatchers.withId
|
||||||
import androidx.test.espresso.matcher.ViewMatchers.withText
|
import androidx.test.espresso.matcher.ViewMatchers.withText
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
|
import androidx.test.rule.GrantPermissionRule
|
||||||
import com.h.pixeldroid.objects.Account
|
import com.h.pixeldroid.objects.Account
|
||||||
import com.h.pixeldroid.objects.Attachment
|
import com.h.pixeldroid.objects.Attachment
|
||||||
import com.h.pixeldroid.objects.Status
|
import com.h.pixeldroid.objects.Status
|
||||||
import com.h.pixeldroid.testUtility.MockServer
|
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.Before
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
@ -43,6 +51,7 @@ class PostTest {
|
|||||||
Context.MODE_PRIVATE)
|
Context.MODE_PRIVATE)
|
||||||
preferences.edit().putString("accessToken", "azerty").apply()
|
preferences.edit().putString("accessToken", "azerty").apply()
|
||||||
preferences.edit().putString("domain", baseUrl.toString()).apply()
|
preferences.edit().putString("domain", baseUrl.toString()).apply()
|
||||||
|
Intents.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -100,4 +109,62 @@ class PostTest {
|
|||||||
).check(matches(isDisplayed()))
|
).check(matches(isDisplayed()))
|
||||||
Thread.sleep(5000)
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -51,6 +51,10 @@ class ImageFragment : Fragment() {
|
|||||||
ImageUtils.downloadImage(requireActivity(), view.context, imgUrl)
|
ImageUtils.downloadImage(requireActivity(), view.context, imgUrl)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
R.id.image_popup_menu_share_picture -> {
|
||||||
|
ImageUtils.downloadImage(requireActivity(), view.context, imgUrl, share = true)
|
||||||
|
true
|
||||||
|
}
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,13 @@
|
|||||||
package com.h.pixeldroid.objects
|
package com.h.pixeldroid.objects
|
||||||
|
|
||||||
import android.app.Activity
|
import android.content.ContentValues
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Typeface
|
import android.graphics.Typeface
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.net.Uri
|
||||||
|
import android.provider.MediaStore
|
||||||
import android.text.Spanned
|
import android.text.Spanned
|
||||||
import android.text.method.LinkMovementMethod
|
import android.text.method.LinkMovementMethod
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@ -16,15 +20,15 @@ import android.widget.LinearLayout
|
|||||||
import android.widget.PopupMenu
|
import android.widget.PopupMenu
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
|
import androidx.core.content.ContextCompat.startActivity
|
||||||
import androidx.core.text.toSpanned
|
import androidx.core.text.toSpanned
|
||||||
|
import androidx.core.view.drawToBitmap
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import androidx.viewpager2.adapter.FragmentStateAdapter
|
import androidx.viewpager2.adapter.FragmentStateAdapter
|
||||||
import androidx.viewpager2.widget.ViewPager2
|
|
||||||
import com.bumptech.glide.RequestBuilder
|
import com.bumptech.glide.RequestBuilder
|
||||||
import com.google.android.material.tabs.TabLayoutMediator
|
import com.google.android.material.tabs.TabLayoutMediator
|
||||||
import com.h.pixeldroid.ImageFragment
|
import com.h.pixeldroid.ImageFragment
|
||||||
import com.h.pixeldroid.MainActivity
|
|
||||||
import com.h.pixeldroid.R
|
import com.h.pixeldroid.R
|
||||||
import com.h.pixeldroid.api.PixelfedAPI
|
import com.h.pixeldroid.api.PixelfedAPI
|
||||||
import com.h.pixeldroid.fragments.feeds.PostViewHolder
|
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.postPicture
|
||||||
import kotlinx.android.synthetic.main.post_fragment.view.postTabs
|
import kotlinx.android.synthetic.main.post_fragment.view.postTabs
|
||||||
import kotlinx.android.synthetic.main.post_fragment.view.profilePic
|
import kotlinx.android.synthetic.main.post_fragment.view.profilePic
|
||||||
|
import retrofit2.http.Url
|
||||||
|
import java.io.OutputStream
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
import java.net.URL
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Represents a status posted by an account.
|
Represents a status posted by an account.
|
||||||
@ -316,6 +323,10 @@ data class Status(
|
|||||||
downloadImage(activity, view.context, getPostUrl()!!)
|
downloadImage(activity, view.context, getPostUrl()!!)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
R.id.image_popup_menu_share_picture -> {
|
||||||
|
downloadImage(activity, view.context, getPostUrl()!!, share = true)
|
||||||
|
true
|
||||||
|
}
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,24 @@
|
|||||||
package com.h.pixeldroid.utils
|
package com.h.pixeldroid.utils
|
||||||
|
|
||||||
import android.app.DownloadManager
|
import android.app.DownloadManager
|
||||||
|
import android.content.ContentValues
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
import android.database.Cursor
|
import android.database.Cursor
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
import android.provider.Settings.Global.getString
|
import android.provider.MediaStore.Images
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
import com.h.pixeldroid.R
|
import com.h.pixeldroid.R
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
|
||||||
class ImageUtils {
|
class ImageUtils {
|
||||||
companion object {
|
companion object {
|
||||||
fun downloadImage(activity: FragmentActivity, context: Context, url: String) {
|
fun downloadImage(activity: FragmentActivity, context: Context, url: String, share: Boolean = false) {
|
||||||
var msg = ""
|
var msg = ""
|
||||||
var lastMsg = ""
|
var lastMsg = ""
|
||||||
val directory = File(Environment.DIRECTORY_PICTURES)
|
val directory = File(Environment.DIRECTORY_PICTURES)
|
||||||
@ -24,6 +29,7 @@ class ImageUtils {
|
|||||||
as DownloadManager
|
as DownloadManager
|
||||||
val downloadUri = Uri.parse(url)
|
val downloadUri = Uri.parse(url)
|
||||||
val title = url.substring(url.lastIndexOf("/") + 1)
|
val title = url.substring(url.lastIndexOf("/") + 1)
|
||||||
|
val ext = url.substring(url.lastIndexOf("."))
|
||||||
val request = DownloadManager.Request(downloadUri).apply {
|
val request = DownloadManager.Request(downloadUri).apply {
|
||||||
setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI
|
setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI
|
||||||
or DownloadManager.Request.NETWORK_MOBILE)
|
or DownloadManager.Request.NETWORK_MOBILE)
|
||||||
@ -43,35 +49,50 @@ class ImageUtils {
|
|||||||
downloading = false
|
downloading = false
|
||||||
}
|
}
|
||||||
val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
|
val status = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS))
|
||||||
msg = when (status) {
|
if(!share) {
|
||||||
DownloadManager.STATUS_FAILED ->
|
msg = when (status) {
|
||||||
context.getString(R.string.image_download_failed)
|
DownloadManager.STATUS_FAILED ->
|
||||||
DownloadManager.STATUS_RUNNING ->
|
context.getString(R.string.image_download_failed)
|
||||||
context.getString(R.string.image_download_downloading)
|
DownloadManager.STATUS_RUNNING ->
|
||||||
DownloadManager.STATUS_SUCCESSFUL ->
|
context.getString(R.string.image_download_downloading)
|
||||||
context.getString(R.string.image_download_success)
|
DownloadManager.STATUS_SUCCESSFUL ->
|
||||||
else -> ""
|
context.getString(R.string.image_download_success)
|
||||||
}
|
else -> ""
|
||||||
if (msg != lastMsg && msg != "") {
|
|
||||||
activity.runOnUiThread {
|
|
||||||
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
}
|
||||||
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()
|
cursor.close()
|
||||||
}
|
}
|
||||||
}).start()
|
}).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 -> ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,4 +2,6 @@
|
|||||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
<item android:id="@+id/image_popup_menu_save_to_gallery"
|
<item android:id="@+id/image_popup_menu_save_to_gallery"
|
||||||
android:title="@string/save_to_gallery"/>
|
android:title="@string/save_to_gallery"/>
|
||||||
|
<item android:id="@+id/image_popup_menu_share_picture"
|
||||||
|
android:title="@string/share_picture"/>
|
||||||
</menu>
|
</menu>
|
||||||
|
@ -49,4 +49,5 @@
|
|||||||
<string name="image_download_failed">Download has been failed, please try again</string>
|
<string name="image_download_failed">Download has been failed, please try again</string>
|
||||||
<string name="image_download_downloading">Downloading…</string>
|
<string name="image_download_downloading">Downloading…</string>
|
||||||
<string name="image_download_success">Image downloaded successfully</string>
|
<string name="image_download_success">Image downloaded successfully</string>
|
||||||
|
<string name="share_picture">Share picture...</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user