2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

[Android, Kotlin] IntentでTwitterアプリを起動して動画を投稿する

Last updated at Posted at 2021-06-14

はじめに

Androidアプリから任意の動画がセットしてある状態のTwitterの投稿画面を起動することを目標とした記事です。

手順

1 MediaStore(ギャラリー)で動画を選択
2 動画のpathを取得
3 FileProviderで他のアプリにコンテンツ(今回は動画)を渡せるようにする
4 Twitter起動

MediaStoreで動画を選択

端末のギャラリーにアクセスするにはパーミッションを取得する必要がありますが、今回パーミッションについての説明は省きます。
僕が参考にした記事はこちらです
https://pisuke-code.com/android-show-permission-dialog/

AndroidManifest.xml
   <uses-permission
        android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.INTERNET" />

ギャラリーを開くために READ_EXTERNAL_STORAGE と Twitterを使うので INTERNET も記述。

MainActivity.kt
private val GALLERY_CODE = 1000

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        if (Build.VERSION.SDK_INT >= 23) {

            if (ActivityCompat.checkSelfPermission(
                    this,
                    Manifest.permission.READ_EXTERNAL_STORAGE
                )
                != PackageManager.PERMISSION_GRANTED
            ) {
                ActivityCompat.requestPermissions(
                    this, arrayOf(
                        Manifest.permission.READ_EXTERNAL_STORAGE
                    ),
                    GALLERY_CODE
                )
            }
        }

override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<out String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        when (requestCode) {
            GALLERY_CODE -> for (i in 0..permissions.size) {
                if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                } else {
                }
            }
        }
    }

続いてギャラリーを開きます

MainActivity.kt
fun openGallery() {
        Intent(
            Intent.ACTION_PICK,
            MediaStore.Video.Media.EXTERNAL_CONTENT_URI
        ).also { galleryIntent ->
            galleryIntent.resolveActivity(this.packageManager).also {
                startActivityForResult(
                    galleryIntent,
                    GALLERY_CODE
                )
            }
        }
    }

先ほどから出てきているGALLRY_CODEですが、中に入れる数値自体に意味はないので他のコードと被らなければなんでも良いと思います。
アプリを開いたときにこのようなダイアログが出て来れば成功です。
スクリーンショット 2021-06-14 11.02.12.png

MainActivity.kt
Intent(
            Intent.ACTION_PICK,
            MediaStore.Video.Media.EXTERNAL_CONTENT_URI
        ).also { galleryIntent ->
            galleryIntent.resolveActivity(this.packageManager).also {
                startActivityForResult(
                    galleryIntent,
                    GALLERY_CODE
                )
            }
        }

Intent.ACTION_PICK,
MediaStore.Video.Media.EXTERNAL_CONTENT_URI あたりが肝です。MediaStoreから動画を選択してUriを取得する必要があるので今回はこのようになります。

動画のpathを取得

アクティビティの結果を受け取ってくれるonActivityResultを使います。

MainActivity.kt
private lateinit var videoPath: String

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            GALLERY_CODE ->
                data?.data.also { uri ->
                    val columns: Array<String> = arrayOf(MediaStore.Video.Media.DATA)
                    val cursor = this.contentResolver?.query(uri!!, columns, null, null, null)
                    cursor?.moveToFirst()
                    videoPath = cursor?.getString(0)!!
                }
        }
    }

when(requestCode)としていますが、どのアプリの結果が返ってきているのかによって行いたい処理は変わってくるのでrequestCodeで分岐しています。
これでvideoPathに動画のpathが格納されるようになりました。

FileProvider

あるアプリから他のアプリにコンテンツを渡す際、受信側のアプリにアクセス券を付与する必要があるそうです。
僕はこの記事を参考にしました
https://azunobu.hatenablog.com/entry/2019/06/27/120908  
それを行ってくれるのがFileProviderというわけです。

AndroidManifest.xml
<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:grantUriPermissions="true"
            android:exported="false">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_provider" />
        </provider>

続いてresource-xmlにfile_provider.xmlを作って以下を記述

file_provider.xml
<file_provider xmlns:android="http://schemas.android.com/apk/res/android">
    <paths xmlns:android="http://schemas.android.com/apk/res/android">
        <external-path name="external_files" path="."/>
    </paths>
</file_provider>

渡すコンテンツがどこに保存されているかによって内容が変わってきます。

MainActivity.kt
private fun createOutPutFile(): Uri {
        val selectedVideo = videoPath
        val file = File(selectedVideo)

        val uri = FileProvider.getUriForFile(
            this,
            this.packageName + ".provider",
            file
        )
        return uri
    }

先ほど取得した動画のpathからFileを作り、他のアプリへ渡せる形のUriにしています。

Twitterアプリ起動

MainActivity.kt
private fun launchTwitter() {
        val tweetText = "今回初めて記事を書いてみましたが、解説というより自分のコードをペタペタ貼っていっただけになってしまいました。🦬"

        val intent = Intent(Intent.ACTION_SEND)
            .putExtra(Intent.EXTRA_TEXT, "$tweetText\n#ハッシュタグの前には改行を入れると良い感じ")
            .putExtra(Intent.EXTRA_STREAM, createOutPutFile())
            .setType("video/*")
            .setPackage("com.twitter.android")
        startActivityForResult(intent, TWITTER_CODE)
    }

Twitterを開いて投稿したいので、Intent.ACTION_SENDとなります。
putExtraで投稿したい内容を追加していきましょう。

以上です

スクリーンショット 2021-06-14 12.14.07.png

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?