はじめに
Androidアプリから任意の動画がセットしてある状態のTwitterの投稿画面を起動することを目標とした記事です。
手順
1 MediaStore(ギャラリー)で動画を選択
2 動画のpathを取得
3 FileProviderで他のアプリにコンテンツ(今回は動画)を渡せるようにする
4 Twitter起動
MediaStoreで動画を選択
端末のギャラリーにアクセスするにはパーミッションを取得する必要がありますが、今回パーミッションについての説明は省きます。
僕が参考にした記事はこちらです
https://pisuke-code.com/android-show-permission-dialog/
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
ギャラリーを開くために READ_EXTERNAL_STORAGE と Twitterを使うので INTERNET も記述。
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 {
}
}
}
}
続いてギャラリーを開きます
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ですが、中に入れる数値自体に意味はないので他のコードと被らなければなんでも良いと思います。
アプリを開いたときにこのようなダイアログが出て来れば成功です。
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を使います。
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というわけです。
<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 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>
渡すコンテンツがどこに保存されているかによって内容が変わってきます。
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アプリ起動
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で投稿したい内容を追加していきましょう。
以上です