20210322のAndroidに関する記事は13件です。

Activityを保持しない場合のonActivityResult

はじめに

Activityを保持しない場合も動作するように修正しようとしたら、ハマってしまい苦労したので備忘録として書きます。

Intentで他のアプリを起動した場合など、Activityがバックグラウンドに移動した時にメモリが足らなくなると、
もともと起動していたアプリ(Activity)を終了してメモリを確保するみたいです。
この時、アプリが復帰する動作が通常とは異なる動きをするので注意が必要です。
ただ、裏ですごいリッチでグラフィカルなゲームを起動してるとか、動かしてるアプリがめちゃめちゃメモリ喰うとか、端末が古くてすごい非力な場合とかの少し特殊な場合でしか起こり得ないことなので気づきにくいかもしれません。

結論

onActivityResultとonStartの呼び出し順が変わるので注意!!

再現方法

開発者向けオプションから「アクティビティを保持しない」の項目をONにすることで、Activityがバックグラウンドに移動した場合に常に終了するようにできます。

ライフサイクル

Activityを保持する/しないの両方共動くようにしようとしたら、思ったように動かせなくてActivityのライフサイクルの動作を確認したら次のようになっていました。

Activityを保持する場合(通常動作)

onCreate
→ onStart
→ onResume
→ (アプリを操作、startActivityForResult)
→ onPause
→ onStop
→ (Intentで他のアプリを起動) ※ここまでは一緒
onActivityResult
onStart
→ onResume

Activityを保持しない場合

onCreate
→ onStart
→ onResume
→ (アプリを操作、startActivityForResult)
→ onPause
→ onStop
→ (Intentで他のアプリを起動) ※ここまでは一緒
→ onDestroy
→ onCreate
onStart
onActivityResult
→ onResume

上記の両者を比較すれば分かると思いますが、
onStartとonActivityResultの順番が変わっています。

Activityを保持しないのでonDestroyとonCreateが増えるのは想定通りでしたが、ライフサイクルの実行順が変わるのは想定外でした。
(ライフサイクルをちゃんと理解できていないだけ?)
とりあえずonStartで設定する内容は気をつけないといけない。。。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Kotlinで文字列を選択できるドラムロールをシンプルに実装

NumberPickerを使ってドラムロールを実装する

Kotlinならドラムロールはわりと簡単に実装できます。

ドラムロールを実装

レイアウトにドラムロールとなるNumberPickerを追加します。

activity_main.xml
<NumberPicker
    android:id="@+id/picker"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

onCreateメソッドでNumberPickerに文字列をセットしていきます。

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

    //ドラムロール表示用の配列作成
    val fruits = arrayOf("りんご", "いちご", "みかん")
    //NumberPickerを取得
    val picker = findViewById<NumberPicker>(R.id.picker)
    //配列のインデックス最小、最大を指定
    picker.minValue = 0
    picker.maxValue = fruits.size - 1
    //NumberPickerに配列をセットする
    picker.displayedValues = fruits

値の取得

決定ボタンのクリックリスナーなどで値を取得します。

MainActivity.kt
//選択されている項目のインデックス番号を取得
val index = picker.value
//フルーツの配列からインデックス番号を指定して取得
val fruit = fruits[index]

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Android/Java] Jetpack LiveData (Jetpack ViewModel MVVM+Repositoryパターン)

Android Studio 4.1.3(windows版) での流れとなります

ここではMutableLiveDataをRepositoryで持ち単純なデータのModelを扱うだけの
シンプルな構成で一連の流れを説明します

以下の記事のプロジェクトベースでの説明となります

Android DeveloperのJetpack LiveData/MVVM+Repositoryパターンの説明は以下です

Layoutの準備

ここではViewBindingを使用して実装します
ViewBindingの設定方法を知りたい方は以下を参照してください

MainFragmentのテンプレートにあるTextViewはidが指定されていないため
ここではtextViewを指定します

image.png

データのModelを作成

ここでは単純なString Nameだけを持つUserModelを用意します

UserModel.java
public class UserModel {
    public String Name;
}

Repositoryを作成

ここではUserModelを扱うMutableLiveDataとそのgetterとNameをセットするメソッドを用意します
※ データの更新を行うためMutableLiveDataを使用します
setValue()/postValue()の違いを詳しく知りたい方は他の方の記事でいくつか説明がありますので探してみてください

MainRepository.java
public class MainRepository{
    final MutableLiveData<UserModel> user = new MutableLiveData<>();
    public MutableLiveData<UserModel> getUser() {
        return user;
    }

    public void setName(String name) {
        UserModel userModel = user.getValue();
        if (userModel == null) {
            Log.d("MainRepository", "user = null");
            userModel = new UserModel();
        }
        userModel.Name = name;
        // setValue()はメインスレッドから呼び出す必要があります
        //user.setValue(userModel);
        user.postValue(userModel);
    }
}

ViewModelの実装

Repositoryのインスタンスを生成
Repositoryのメソッドの呼び出し用のメソッドを用意します

MainViewModel.java
public class MainViewModel extends ViewModel {
    // TODO: Implement the ViewModel
    final MainRepository repository = new MainRepository();

    public MutableLiveData<UserModel> getUser() {
        return repository.getUser();
    }

    public void setName(String name) {
        repository.setName(name);
    }
}

Fragmentの実装

Fragmentの新規作成時に自動生成されたコードにViewModelの処理を追加します
Nameに値を設定するとobserveのonChanged()が呼び出されTextViewの内容が書き換えられます

MainFragment.java
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    mViewModel = new ViewModelProvider(this).get(MainViewModel.class);
    // setを実行するとobserveのonChanged()が呼び出されます
    mViewModel.setName("test");

    mViewModel.getUser().observe(getViewLifecycleOwner(), new Observer<UserModel>() {
        @Override
        public void onChanged(UserModel user) {
            Log.d("MainFragment", user.Name);
            binding.textView.setText(user.Name);

            // getValue()で値の取得もできます
            Log.d("MainFragment", "getValue: " + mViewModel.getUser().getValue().Name);
        }
    });
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Android] Jetpack LiveData (Jetpack ViewModel MVVM+Repositoryパターン)

Android Studio 4.1.3(windows版) での流れとなります

ここではMutableLiveDataをRepositoryで持ち単純なデータのModelを扱うだけの
シンプルな構成で一連の流れを説明します

以下の記事のプロジェクトベースでの説明となります

Android DeveloperのJetpack LiveData/MVVM+Repositoryパターンの説明は以下です

Layoutの準備

ここではViewBindingを使用して実装します
ViewBindingの設定方法を知りたい方は以下を参照してください

MainFragmentのテンプレートにあるTextViewはidが指定されていないため
ここではtextViewを指定します

image.png

データのModelを作成

ここでは単純なString Nameだけを持つUserModelを用意します

UserModel.java
public class UserModel {
    public String Name;
}

Repositoryを作成

ここではUserModelを扱うMutableLiveDataとそのgetterとNameをセットするメソッドを用意します
※ データの更新を行うためMutableLiveDataを使用します
setValue()/postValue()の違いを詳しく知りたい方は他の方の記事でいくつか説明がありますので探してみてください

MainRepository.java
public class MainRepository{
    final MutableLiveData<UserModel> user = new MutableLiveData<>();
    public MutableLiveData<UserModel> getUser() {
        return user;
    }

    public void setName(String name) {
        UserModel userModel = user.getValue();
        if (userModel == null) {
            Log.d("MainRepository", "user = null");
            userModel = new UserModel();
        }
        userModel.Name = name;
        // setValue()はメインスレッドから呼び出す必要があります
        //user.setValue(userModel);
        user.postValue(userModel);
    }
}

ViewModelの実装

Repositoryのインスタンスを生成
Repositoryのメソッドの呼び出し用のメソッドを用意します

MainViewModel.java
public class MainViewModel extends ViewModel {
    // TODO: Implement the ViewModel
    final MainRepository repository = new MainRepository();

    public MutableLiveData<UserModel> getUser() {
        return repository.getUser();
    }

    public void setName(String name) {
        repository.setName(name);
    }
}

Fragmentの実装

Fragmentの新規作成時に自動生成されたコードにViewModelの処理を追加します
Nameに値を設定するとobserveのonChanged()が呼び出されTextViewの内容が書き換えられます

MainFragment.java
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    mViewModel = new ViewModelProvider(this).get(MainViewModel.class);
    // setを実行するとobserveのonChanged()が呼び出されます
    mViewModel.setName("test");

    mViewModel.getUser().observe(getViewLifecycleOwner(), new Observer<UserModel>() {
        @Override
        public void onChanged(UserModel user) {
            Log.d("MainFragment", user.Name);
            binding.textView.setText(user.Name);

            // getValue()で値の取得もできます
            Log.d("MainFragment", "getValue: " + mViewModel.getUser().getValue().Name);
        }
    });
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

backgroundとbackgroundTintの違い

android:background

背景として使用するドローワブルで、描画可能なリソース(PNG画像、9パッチ1、 シェイプドローワブル2、色を指定します。

色の形式は「#rgb#argb#rrggbb#aarrggbb」があります。

android:backgroundTint

backgroundにカラーフィルターをかけて色を変化させることが出来ます。

例えば、android:background="#FF0000"(赤)で、android:backgroundTint="#00FF00"(緑)を指定すると、#FFFF00(黄色)になります。

3原色と色度図より

色の形式はandroid:backgroundと同じく、「#rgb#argb#rrggbb#aarrggbb」があります。

backgroundTintには、android:backgroundTintModeというものがあり、色合いの「ブレンディングモード」を設定することが出来ます。

android:backgroundTintMode

android:backgroundTintMode="add"

色合いと描画可能なカラーおよびアルファチャネルを組み合わせて、結果を有効なカラー値にクランプ(合わせるみたいな意味?)します(S + D)

android:backgroundTint="multiply"

ドローアブルのカラーチャンネルとアルファチャンネルに色合いのチャンネルを掛けます。 [Sa * Da、Sc * Dc]

android:backgroundTint="screen"

[Sa + Da - Sa * Da, Sc + Dc - Sc * Dc]

android:backgroundTint="src_atop"

色合いはドローアブルの上に描画されますが、ドローアブルのアルファチャネルが結果をマスクします。 [Da、Sc * Da +(1-Sa)* Dc]

android:backgroundTint="src_in"

色合いは、ドローアブルのアルファチャネルによってマスクされます。ドローアブルのカラーチャンネルは破棄されます。 [Sa * Da、Sc * Da]

android:backgroundTint="src_over"

ドローアブルの上に色合いが描かれています。 [Sa +(1-Sa)* Da、Rc = Sc +(1-Sa)* Dc]


  1. コンテンツや画面の大きさに合わせて、サイズが伸縮するビットマップ画像 

  2. 色やグラデーションなどを含む図形を定義するXMLファイル)などの状態ファイル 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UnityでFacebookSDKのAndroidでログインエラーの解決方法

概要

UnityでFacebookSDKを使用してAndroidでログインエラーが出てしまう問題の解決方法

問題点

KeyStoreの作り方がFacebookで紹介されているものと別であったため、Unity上で表示されたキーハッシュが間違っていた

解決方法

確実なキーハッシュの取得方法はIResultのRawResultの中に記載されている

// 初期化等は割愛

FB.LogInWithReadPermissions(・・・, OnLogin);


void OnLogin(IResult result)
{
    // こいつを確認する!!!
    Debug.Log($"Raw:[{result.RawResult}]");
}

その他エラー解消のための参考文献

公式
ザ・ゆるふわ
cloudpack.media

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Android] Jetpack Navigation 画面遷移とFragment間のデータ受け渡し

Android Studio 4.1.3(windows版) での流れとなります

以下の記事のプロジェクトベースでの説明となります

Android DeveloperのJetpack Navigationの画面遷移とFragment間のデータ受け渡しの説明は以下です

SafeArgs を追加する

※ 現時点ではandroidx.navigation:navigation-safe-args-gradle-pluginをimplementationでは動作しないようです
※ androidx.navigationのバージョンに合わせて設定してください

build.gradle(Project)
buildscript {
    dependencies {
        def nav_version = "2.3.4"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}
build.gradle(Module)
apply plugin: "androidx.navigation.safeargs"

画面遷移の準備

+ボタンを押してここではNextFragmentを追加します
image.png
MainFragmentのActionsの+ボタンを押して画面遷移を追加します
image.png
DestinationでnextFragmentを指定してAddボタンで追加します
image.png
Actionが追加されました
image.png
MainFragmentに画面遷移実行用のボタンとボタンイベントを追加します
ボタンイベントの設定方法を詳しく知りたい場合は以下を参考にしてください
ここではMainFragmentにonClickButtonメソッドを追加しJetpack Databindingでボタンイベントの紐づけをします

画面遷移処理の実装

MainFragment.java
public void onClickButton() {
    final View view = binding.getRoot();
    // MainFragmentDirectionsはsafeargsを有効にすることで自動生成されます
    NavDirections directions = MainFragmentDirections.actionMainFragmentToNextFragment();
    Navigation.findNavController(view).navigate(directions);
}

Fragment間でデータを受け渡す場合

NextFragmentのArgumentsの+ボタンを押します
image.png
ここではName:Text Type:String とします
image.png
Action(やじるし)のArgument Default Values のdefault value に値を設定します
ここではnoneを設定 ※default valueを設定しないとActionクラスが自動生成されません
image.png

NextFragmentに渡したい値(ここでは"xxx")をsetします

MainFragment.java
public void onClickButton() {
    final View view = binding.getRoot();
    // MainFragmentDirections.ActionMainFragmentToNextFragment/setText()は自動生成されます
    MainFragmentDirections.ActionMainFragmentToNextFragment action = MainFragmentDirections.actionMainFragmentToNextFragment();
    action.setText("xxx");
    Navigation.findNavController(view).navigate(action);
}

値を受け取ります
※ ここでは説明を簡略化してますが、実際はJetpack View/DataBindingを使用して値を設定してください

NextFragment.java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.next_fragment, container, false);
    // NextFragmentArgsは自動生成されます
    String text = NextFragmentArgs.fromBundle(getArguments()).getText();
    TextView tv = view.findViewById(R.id.textView);
    tv.setText(text);
    return view;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[Android/Java] Jetpack Navigation 画面遷移とFragment間のデータ受け渡し

Android Studio 4.1.3(windows版) での流れとなります

以下の記事のプロジェクトベースでの説明となります

Android DeveloperのJetpack Navigationの画面遷移とFragment間のデータ受け渡しの説明は以下です

SafeArgs を追加する

※ 現時点ではandroidx.navigation:navigation-safe-args-gradle-pluginをimplementationでは動作しないようです
※ androidx.navigationのバージョンに合わせて設定してください

build.gradle(Project)
buildscript {
    dependencies {
        def nav_version = "2.3.4"
        classpath "androidx.navigation:navigation-safe-args-gradle-plugin:$nav_version"
    }
}
build.gradle(Module)
apply plugin: "androidx.navigation.safeargs"

画面遷移の準備

+ボタンを押してここではNextFragmentを追加します
image.png
MainFragmentのActionsの+ボタンを押して画面遷移を追加します
image.png
DestinationでnextFragmentを指定してAddボタンで追加します
image.png
Actionが追加されました
image.png
MainFragmentに画面遷移実行用のボタンとボタンイベントを追加します
ボタンイベントの設定方法を詳しく知りたい場合は以下を参考にしてください
ここではMainFragmentにonClickButtonメソッドを追加しJetpack Databindingでボタンイベントの紐づけをします

画面遷移処理の実装

MainFragment.java
public void onClickButton() {
    final View view = binding.getRoot();
    // MainFragmentDirectionsはsafeargsを有効にすることで自動生成されます
    NavDirections directions = MainFragmentDirections.actionMainFragmentToNextFragment();
    Navigation.findNavController(view).navigate(directions);
}

Fragment間でデータを受け渡す場合

NextFragmentのArgumentsの+ボタンを押します
image.png
ここではName:Text Type:String とします
image.png
Action(やじるし)のArgument Default Values のdefault value に値を設定します
ここではnoneを設定 ※default valueを設定しないとActionクラスが自動生成されません
image.png

NextFragmentに渡したい値(ここでは"xxx")をsetします

MainFragment.java
public void onClickButton() {
    final View view = binding.getRoot();
    // MainFragmentDirections.ActionMainFragmentToNextFragment/setText()は自動生成されます
    MainFragmentDirections.ActionMainFragmentToNextFragment action = MainFragmentDirections.actionMainFragmentToNextFragment();
    action.setText("xxx");
    Navigation.findNavController(view).navigate(action);
}

値を受け取ります
※ ここでは説明を簡略化してますが、実際はJetpack View/DataBindingを使用して値を設定してください

NextFragment.java
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    final View view = inflater.inflate(R.layout.next_fragment, container, false);
    // NextFragmentArgsは自動生成されます
    String text = NextFragmentArgs.fromBundle(getArguments()).getText();
    TextView tv = view.findViewById(R.id.textView);
    tv.setText(text);
    return view;
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

android:translationX(translationY)とは

android:translationX(translationY)は、「座標」を使ってViewを位置を指定する属性です。

android:translationX(translationY)共に、画面中央を0として「X座標」「Y座標」を指定します。

リファレンスによると、「px/dp/sp/in/mm」を指定出来るとのことです。

使い方

まずは、何も設定していない状態です。

android:translationX="100dp"を指定すると、右側に「100dp」だけ移動します。

もし左側に移動させたい場合は、android:translationX="-100dp"のようにマイナスを指定します。

次は、Y座標で移動させるためにandroid:translationY="100dp"を指定します。

上に移動させたいときはX座標のときと同様に、android:translationY="-100dp"にマイナスを指定します。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Kotlin 初心者】アプリにロゴを設置する方法

アプリにロゴを設置する方法

アプリを作る際には必ずロゴを設置しなければいけません。
手順はとても簡単です。

Android Studioなら簡単にロゴを設定できます。

手順

  • app > res > New > image Assetをクリック

  • このような画面が出てきます

ここでロゴ画像をアップロードやテキストでアプリ名を入力し、Next > Finishをクリックすれば完了です

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Kotlin 初心者】カメラ、ローカルの画像を表示するには

Androidアプリでカメラ、ローカルから画像を表示する方法

シンプルにファイル or カメラのどちらかを選択し画像を表示してみます

イメージサンプル

  • カメラを機能を有効にする
<manifest>
        <uses-feature android:name="android.hardware.camera"
                      android:required="true" />
</manifest>   
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/upload_image"
        android:layout_width="300dp"
        android:layout_height="300dp"
        android:background="@color/teal_700"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.kt
package com.example.myapplication

import android.content.Intent
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.os.Bundle
import android.provider.MediaStore
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity

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

        val uploadImage = findViewById<ImageView>(R.id.upload_image)

        uploadImage.setOnClickListener {
            selectPhoto()
        }
    }

    companion object {
        private const val READ_REQUEST_CODE: Int = 42
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)

        val uploadImage = findViewById<ImageView>(R.id.upload_image)

        if (resultCode != AppCompatActivity.RESULT_OK) {
            return
        }

        when (requestCode) {
            READ_REQUEST_CODE -> {
                try {
                    data?.data?.also { uri ->
                        val inputStream = contentResolver?.openInputStream(uri)
                        val image = BitmapFactory.decodeStream(inputStream)
                        uploadImage.setImageBitmap(image)
                    }
                } catch (e: Exception) {
                    Toast.makeText(this, "READ_REQUEST_CODEのエラーが発生しました", Toast.LENGTH_LONG).show()
                }
            }
        }
    }

    private fun selectPhoto() {

        val documentIntent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
            addCategory(Intent.CATEGORY_OPENABLE)
            type = "image/*"
        }

        val cameraIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE).also { takePictureIntent ->

        }

        val target: List<Intent> = listOf(documentIntent,cameraIntent)

        val intent = Intent(Intent.ACTION_VIEW)
        if(intent.resolveActivity(getPackageManager()) != null) {
            val chooser = Intent.createChooser(documentIntent,"写真を選択").apply {
                putExtra(Intent.EXTRA_INITIAL_INTENTS , target.toTypedArray())
            }
            startActivityForResult(chooser, READ_REQUEST_CODE)
        }
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

国外のPlayストアのランキングを見る方法(クエリ使うだけ)

以前アフリカのザンビアに住んでいたことがあるのですが、ふと、「ザンビアでの今のGooglePlayストアのランキングってどうなってるんだろ?」と気になりました。

ググるとプロキシ変える方法やApp Annieを使う方法が出てきましたが、PlayStoreのURL( https://play.google.com/store/apps/top )にクエリ(?hl=ja&gl={2文字の国コード}1)を加えるだけでもできるようです。
※国コードである根拠はないのですが、挙動見る限り合ってそう。

余談ですが、中国では有料アプリをPlayストアからインストールできない2ので、無料アプリのランキングしかないですね。

参考


  1. 国コード検索
    - https://www.iso.org/obp/ui/#search (Alpha-2 codeを使う) 

  2. Google Play ユーザーへの配布がサポートされている国や地域 | 購入者の現地通貨と価格帯
    - https://support.google.com/googleplay/android-developer/table/3541286 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

海外のPlayストアのランキングを見る方法(クエリ使うだけ)

以前アフリカのザンビアに住んでいたことがあるのですが、ふと、「ザンビアでの今のGooglePlayストアのランキングってどうなってるんだろ?」と気になりました。

ググるとプロキシ変える方法やApp Annieを使う方法が出てきましたが、PlayStoreのURL( https://play.google.com/store/apps/top )にクエリ(?hl=ja&gl={2文字の国コード}1)を加えるだけでも国外のPlayストアの情報を見ることができるようです。
※国コードである根拠はないのですが、挙動見る限り合ってそう。

余談ですが、中国では有料アプリをPlayストアからインストールできない2ので、無料アプリのランキングしかないですね。

参考


  1. 国コード検索
    - https://www.iso.org/obp/ui/#search (Alpha-2 codeを使う) 

  2. Google Play ユーザーへの配布がサポートされている国や地域 | 購入者の現地通貨と価格帯
    - https://support.google.com/googleplay/android-developer/table/3541286 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む