- 投稿日:2019-07-04T23:35:51+09:00
RxjavaとRetrofitで非同期通信を行う
Androidで非同期通信を使おうとして、AsyncTaskLoaderを使うと、コードが長くなり、考慮する点も多いので、Rxhjavaを使ってみました。
今ではこちらの方が主流な理由がわかりました。①ライブラリの追加
下記ライブラリを追加しました。
build.gradleimplementation 'com.squareup.retrofit2:retrofit:2.6.0' implementation 'io.reactivex.rxjava2:rxjava:2.2.9' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' implementation 'com.squareup.retrofit2:converter-simplexml:2.3.0' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'rxJavaのAndroid版のrxAndroidも導入しています。
②Retrofitの実装
今回はxmlをparseする処理を行うので、Retrofitを使います。
タグの名前を指定すれば、値が取得できるので、便利です。
まずは、interfaceの作成です。interface RssClient { @GET("{rssPath}") fun get(@Path("rssPath") path: String) : Observable<BlogEntity> }Rxjavaで使うため、戻り値をObservable型にしています。
また、@Path("rssPath")で実際に使用するときに引数を使うことで、カスタマイズできます。
その時に"{rssPath}"が同じ値になります。
なので、動的にURLを作成したいときに使えます。次にEntityを作成します。
Entityについては下記の記事を参照してください!
Retrofitでxmlの値を取得するここまででRetrofitを使えるようになりました。
③Rxjavaの実装
最後に、Rxjavaを使って、非同期処理を行います。
手順としてはRetrofitを作成し、対象のURLで通信を行い、取得したデータを使って、その後処理を行うという流れです。MainActivity.ktval retrofit = Retrofit.Builder() .baseUrl(https://×××××××××××/) .client(client) .addConverterFactory(SimpleXmlConverterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .build() val response = retrofit.create(RssClient::class.java).get("rss") // 非同期で記事を取得し、メインスレッドでその後の処理を行う response.observeOn(AndroidSchedulers.mainThread()) .subscribeOn(Schedulers.newThread()) .subscribe( { //UIの更新など取得したデータを使って処理を行う }, { Log.e("ERROR", it.cause.toString()) })
.addConverterFactory(SimpleXmlConverterFactory.create())でxmlをパースすることを定義し、.addCallAdapterFactory(RxJava2CallAdapterFactory.create())でRetrofitの処理結果を、RxJava2が利用できる形にしています。
そして、interfaceで定義したget()を実行します。
1点注意しないといけないのが、baseURLは末尾に/がないとエラーが発生します。
.subscribeOn(Schedulers.newThread())で新しい別スレッドで実行することを定義し、observeOn(AndroidSchedulers.mainThread())で取得結果をメインスレッドで受け取るようにしています。subscribeの前半の{}は成功したときの処理、こうはんはエラーが発生したときの処理になっています。AsyncTaskLoaderを継承させてみたいなややこしい処理はいらず、エラー処理も単純なので、記述も減ります。最後に使ってみて見やすくて、便利でした。また、処理のチェーンなども手軽にできそうで何より、コード量が減るのがいいですね。
参照
Connect to an API With Retrofit, RxJava 2, and Kotlin
Android working with Retrofit and RxJava in Kotlin
- 投稿日:2019-07-04T23:21:13+09:00
キラッとプリ☆チャンのコーデ管理アプリを作ってみた話
前置き
Qiitaで記事投稿やってみた!という気持ちで大変恐縮ではあります。
本題
職業訓練校で学んだ程度ではあるのだが、Androidのアプリを作ることはできる。
下記の書籍を参考にしながら、タイトルのアプリを簡単ではあるけど、作った。基礎&応用力をしっかり育成! Androidアプリ開発の教科書 なんちゃって開発者にならないための実践ハンズオン
とあるフォロワーの要望からすべてが始まった
勉強も兼ねて、先ほど紹介した書籍のサンプルプログラムをサクサクっと作った。
「勉強するわけだから、自分でも楽しく作れるものを作りたいな」という気持ちが出てくる。
最初は、アイカツ!キャラクターのような喋り口で、お天気予報とか、マストドンのインスタンス「キラキラッター」にアクセスするような、簡単なアプリを作ろうとしていた。…で、言ってみた。すると。
ちゃんぷりのコーデ管理アプリ作って定期的にメンテしてくれたらたぶん首位いくレベルでDLされるよ?
とか言われちゃったので、本気にした。
どう作ったの、おじさん?
コーデ保存ってことは、SharedPreferenceかSQLite?
と思ったので、まずは書籍のサンプルプログラムでSQLiteを軽く理解して制作を始めようと思った。イメージ画像としてはこんな感じ。メモ書きなので見づらいのはご容赦。
実際は、画像内の「それか、こうか」以下の実装になりましたとさ。おわり。ソースコード
なにかの参考になればと思ったので、一部抜粋なテイで載せてみた。
// ListViewオブジェクトを取得 ListView lvPrichan = findViewById(R.id.lv_prichan); // リストビューに表示するプリチャン稼働弾のリストオブジェクトを作成 List<String> prichanCorde = new ArrayList<>(); // リストデータの登録。プリチャン稼働弾が増えたとしても // 簡単に追記できるようにした prichanCorde.add("キラッとプリ☆チャン ジュエル1弾"); prichanCorde.add("キラッとプリ☆チャン ジュエル2弾"); prichanCorde.add("キラッとプリ☆チャン ジュエル3弾"); // アダプターオブジェクトを作成 ArrayAdapter<String> adapter = new ArrayAdapter<>(MainActivity.this, android.R.layout.simple_list_item_1,prichanCorde); lvPrichan.setAdapter(adapter); lvPrichan.setOnItemClickListener(new ListItemClickListener()); } private class ListItemClickListener implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { switch (position) { case 0: // ジュエル1弾のコーデリスト Intent priJ1intent = new Intent(MainActivity.this,PrichanJewel1.class); startActivity(priJ1intent); break; case 1: // ジュエル2弾のコーデリスト Intent priJ2intent = new Intent(MainActivity.this,PrichanJewel2.class); startActivity(priJ2intent); break; case 2: // ジュエル3弾のコーデリスト Toast.makeText(MainActivity.this,"まだないよ",Toast.LENGTH_SHORT).show(); break;上記はメイン画面処理。コーデ管理画面の処理は下記。
// 選択されたコーデの主キーIDを表すフィールド int _prichanId = -1; // 選択されたコーデ名を表すフィールド String _prichanCordeName = ""; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_prichan_jewel1); // リストビューを取得 ListView lvJprichan = findViewById(R.id.lv_J1prichan); // リスナーを登録 lvJprichan.setOnItemClickListener(new ListItemClickListener()); // 長押しリスナーを登録 lvJprichan.setOnItemLongClickListener(new ListItemLongClickListener()); } private class ListItemClickListener implements AdapterView.OnItemClickListener { @Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { // タップされた行番号をフィールドの主キーIDに代入 _prichanId = position; // タップされた行のデータを取得してフィールドに代入 _prichanCordeName = (String) parent.getItemAtPosition(position); // データベースヘルパーオブジェクトを作成 J1DatabaseHelper helper = new J1DatabaseHelper(PrichanJewel1.this); // データベース接続オブジェクトを作成 SQLiteDatabase db = helper.getWritableDatabase(); String cordeGet = ""; try { String sql = "select * from J1prichancorde where _id = " + _prichanId; Cursor cursor = db.rawQuery(sql, null); if (cursor.moveToNext()) { int idxCorde = cursor.getColumnIndex("cordeget"); cordeGet = cursor.getString(idxCorde); } } finally { db.close(); } if (cordeGet.equals("true")) { // 所持データを保持されたことを表示 Toast.makeText(PrichanJewel1.this, "持っているコーデカードだよ。", Toast.LENGTH_SHORT).show(); } else { Toast.makeText(PrichanJewel1.this, "持っていないコーデカードだよ。", Toast.LENGTH_SHORT).show(); } } } private class ListItemLongClickListener implements AdapterView.OnItemLongClickListener { @Override public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { // タップされた行番号をフィールドの主キーIDに代入 _prichanId = position; // タップされた行のデータを取得してフィールドに代入 _prichanCordeName = (String) parent.getItemAtPosition(position); // データベースヘルパーオブジェクトを作成 J1DatabaseHelper helper = new J1DatabaseHelper(PrichanJewel1.this); // データベース接続オブジェクトを作成 SQLiteDatabase db = helper.getWritableDatabase(); try { // インサート文を用意 String sqlInsert = "insert into J1prichancorde (_id, name, cordeget) values (?,?,?)"; // SQL文字列を元にプリペアードステートメントを取得 SQLiteStatement stmt = db.compileStatement(sqlInsert); // 変数のバインド stmt.bindLong(1, _prichanId); stmt.bindString(2, _prichanCordeName); stmt.bindString(3,"true"); stmt.executeInsert(); } finally { // データベースを閉じる db.close(); } Toast.makeText(PrichanJewel1.this, "登録完了!",Toast.LENGTH_SHORT).show(); } // 通常のクリックイベントを発生させない return true;最初、これで無事動くじゃろ~~~
と思ってたおじさんが馬鹿だった。Insert処理の問題で、アプリが落ちるという出来事が起きた。
// タップされた行番号をフィールドの主キーIDに代入 _prichanId = position; // タップされた行のデータを取得してフィールドに代入 _prichanCordeName = (String) parent.getItemAtPosition(position); // データベースヘルパーオブジェクトを作成 J1DatabaseHelper checkhelper = new J1DatabaseHelper(PrichanJewel1.this); // データベース接続オブジェクトを作成 SQLiteDatabase checkdb = checkhelper.getWritableDatabase(); String cordeGet = ""; try { String sql = "select * from J1prichancorde where _id = " + _prichanId; Cursor cursor = checkdb.rawQuery(sql, null); if (cursor.moveToNext()) { int idxCorde = cursor.getColumnIndex("cordeget"); cordeGet = cursor.getString(idxCorde); } } finally { checkdb.close(); } if (cordeGet.equals("true")) { Toast.makeText(PrichanJewel1.this,"既に登録しているから、登録できないよ!", Toast.LENGTH_SHORT).show(); }既にInsertでデータベースに挿入してて、長押ししてしまった時とかあるじゃろ?
そういう時に
「既に入ってるからInsertはさせんよ。じゃあの。(エラーで終了)」
となるので、こうした。ここまで作るのにおじさんは一日かかりました。
で、使ってもらった。
十分管理できる!
と嬉しい言葉をいただきましたァん♪
また、こんな言葉も頂いた。リストでチェックマーク選べて最終確定できて中で保持できてたらそれだけでも違う!
この実装に関しては、調査が必要だが、できないことでもないだろう。と思っているので
やってみようと思う。以上です。
- 投稿日:2019-07-04T22:27:47+09:00
Android 広告IDの取り扱い方
広告ID - Play Console ヘルプより
https://support.google.com/googleplay/android-developer/answer/6048248?hl=ja広告 ID は、ユーザーがリセットできる広告用の固有の ID で、Google Play 開発者サービスから提供されるものです。この広告 ID によってユーザーの管理性は向上し、デベロッパーはシンプルな標準システムで引き続きアプリを収益化できます。また、ユーザーは ID をリセットしたり、Google Play アプリ内のパーソナライズド広告(以前のインタレスト ベース広告)をオプトアウトしたりできます。
広告IDとは
- ユーザーを識別するためのID
広告の配信や、ユーザーの分析に使用します。
広告IDの特徴
- ユーザーが任意のタイミングでリセットできる
- ユーザーがオプトアウトすることができる
オプトアウトとは
個人情報の第三者提供に関し、個人データの第三者への提供を本人の求めに応じて停止すること。
ユーザーが広告のカスタマイズをオプトアウトしている場合は、
以下の目的で、広告IDを使用してはいけない。
- 広告目的のプロフィール構築
- パートナライズド広告のターゲット設定
オプトアウト設定方法
設定アプリ > Google > 広告 > 広告のカスタマイズをオプトアウトする
※Android 5.2以下ではGoogle設定アプリから設定広告IDの使用規約
Android 広告IDの使用より
https://play.google.com/intl/ja_ALL/about/monetization-ads/ads/ad-id/広告IDを使用するためには規約があります。
広告ID使用上の注意点
- 広告とユーザーの分析以外で使用してはいけない。
- 広告IDの収集と使用、規約への遵守について、ユーザーに開示する必要がある。
- ユーザーのオプトアウト設定を遵守する必要がある。
ユーザーがオプトアウト設定している場合
- 広告目的でユーザーのプロフィールを作成したり、ユーザーをパーソナライズド広告のターゲットに設定したりするために広告IDを使用してはいけない。
- ただし、コンテンツ ターゲット広告、フリークエンシー キャップ、コンバージョン トラッキング、レポート、セキュリティや不正行為の検出などに使用することはできる。
ユーザーの同意なしにしてはいけないこと
- 個人を特定できる情報や、永続的なデバイス ID(SSAID、MAC アドレス、IMEI など)に関連付けたりしてはいけない。
- 新しい広告IDを、以前の広告IDや以前の広告IDからのデータに紐づけてはいけない。
- 投稿日:2019-07-04T15:56:52+09:00
Koin2.0でお手軽DI(Android)
この記事ではAndroidでのKoinの使い方を扱います。
Koinとは
KoinとはKotlin用のDependency injection Framework (依存性注入フレームワーク)です。
AndroidでDI FrameworkといえばDaggerやKodeinなどもありますが、Koinは
- Kotlin100%で書かれていること
- シンプルな使い方
が特徴です。めっちゃシンプルです。
AAC ViewModelが秒でInjectionできます。
簡単すぎる!!!!!!!!!!!!!!!!幸せ❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣ ってなる。この記事ではバージョン
2.0.1を用いています。DIとは
DIとはDependency injectionの略で日本語で依存性注入と言います。
詳しくは、こちらの記事 (猿でも分かる! Dependency Injection: 依存性の注入)
などがわかりやすく解説してくれてるので見てください。実際に使う
物は試し、まずは触ってみましょう。
アプリに導入する
以下を
build.gradle(app)のdependenciesに追加してください。build.gradle(app)def koin_version = "2.0.1" implementation "org.koin:koin-core:$koin_version" implementation "org.koin:koin-core-ext:$koin_version" implementation "org.koin:koin-android:$koin_version" implementation "org.koin:koin-android-scope:$koin_version" implementation "org.koin:koin-android-viewmodel:$koin_version" implementation "org.koin:koin-android-ext:$koin_version"syncして完了です。
実装
今回はViewModeに依存するFragmentを例に進めていきます。
class MainFragment : Fragment() { // ここにViewModelを持ちたい。 } class MainViewModel : ViewModel() { /* functions */ }moduleを用意し、koinをスタートさせる
Applicationクラスを継承したクラスで、
injectしたいクラスらを記述したmoduleを用意しstartKoinメソッドを呼ぶとKoinをスタートさせることができます。
moduleにinjectしたいクラスを記述する際には、
Singletonにしたい場合 single{} AAC ViewModelを使う場合 viewModel{} その他 factory{} 今回はAAC ViewModelをinjectするので、
viewModel{}を用います。App.ktclass App : Application() { override fun onCreate() { startKoin{ androidContext(applicationContext) modules(module) } } val module = module { viewModel { MainViewModel()} } }injectする
あとはinjectしたい場所でinjectするだけです。
変数に対して
by inject()をしてあげることでinjectすることができます。
ViewModelをinjectする際はby viewModel()を用います。今回は、例に沿って
MainFragmentでMainViewModelをinjectします。
ですのでby viewModel()を用います。MainFragment.ktclass MainFragment : Fragment() { val viewModel by ViewModel() //... }これでinjectできました!!!!!!!!!!!!!!!!!!!!!!!!
簡単すぎる!!!!!!!!!!!!!!!!幸せ❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣ViewModelがRepositoryを持つ場合
MainViewModelが引数にRepositoryを持つ場合も試してみましょう。class Repository(){ //get~~() etc... } class MainViewModel(val repository : Repository) { //... }まず、先程の
App.ktのmoduleの中に引数にinjectしたいRepositoryを記述します。
今回RepositoryはSingletonであってほしいので、single{}メソッドを用います。引数にinjectするには
get()メソッドを呼ぶと勝手に必要なものを引数にinjectしてくれます。App.ktclass App : Application() { override fun onCreate() { startKoin{ androidContext(applicationContext) modules(module) } } val module = module { single { Repository()} viewModel { MainViewModel(get())} // add } }簡単すぎる!!!!!!!!!!!!!!!!幸せ❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣
まとめ
少ない記述で済ませられるので、小規模なアプリこそKoinを用いるのが良いと思います。
Koin使うと幸せ❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣❣ って感じですね!!!!!間違い等ありましたらコメント下さい...申し訳ありません
- 投稿日:2019-07-04T14:14:04+09:00
Android開発時にR.*が全部無効になった場合
レイアウトXMLの確認とかClean ProjectとかInvalidate Cacheとか一通り試して駄目だった場合
import android.Rが何かの拍子で追加されて邪魔してる場合があるので、コレを消す
- 投稿日:2019-07-04T11:11:23+09:00
React Native製Androidアプリでコマンドラインビルドすると画像が表示されないことがある
--assets-dest android/app/src/main/resをreact-native bundleのオプションに付与する。すると画像リソースとしてresディレクトリ以下に配置されるようになる。
でもこれを付与しなくても動くときもあるのが謎。。
- 投稿日:2019-07-04T11:01:02+09:00
Flutter実行環境の構築(Android StudioとXcode)
概要
急遽Flutterの検証を行う必要があったので備忘録兼ねて構築からインストールまでを記事にまとめたいと思います。
iOSでの実行も確認したいので、Xcodeでの実行もまとめていますが、メインはAndroid Studioでの環境構築となります。各種手順
Android Studioと各種ツールのインストール
Xcodeインストール
Flutterインストール
Android Studioに対するFlutterプラグインのインストール
Flutterプロジェクト作成
Flutterの各種初期設定(初回のみ)
Flutterアプリケーション起動確認Android Studio
インストールまで
Android Studio公式に接続して「Download Android Studio」をクリック
利用規約の「同意します」にチェックを入れダウンロード
下記のファイルがダウンロードされるので実行Windows:
android-studio-ide-183.5522156-windows
Mac:android-studio-ide-183.5522156-mac.dmgWindowsの場合
ダウンロードされたexeファイルを実行して「Next」をクリック
Macの場合
上記のファイルを実行して生成される「Android Studio.app」をアプリケーションフォルダに入れた後appを実行する初期設定
インストールが完了したAndroid Studioを起動する
「Do not import settings」にチェックがついた状態で「OK」をクリック
「Custom」にチェックが入っていることを確認して「Next」をクリック
「Standard」の場合、テーマ選択以降は省略される
※「Custom」の場合表示
インストールするコンポーネントとAndroid SDKのインストール先を指定して「Next」をクリックAndroid SDKのインストール先を変更した場合
Flutterはデフォルトインストール先を基にしてAndroid SDKを確認するので、変更した場合は
環境変数ANDROID_HOMEを作成し、パスはAndroid SDK Locationを指定すること
HAXMのインストールに失敗した場合
HAXM installation failedと表示された場合HAXM公式サイトに接続後、「Downloads」欄の
hereをクリック
zipを解凍後にできたアプリケーションを実行
「続ける」をクリック
Windows:intelhaxm-android.exe
Mac:IntelHAXM_7.5.1.dmg
インストール先の変更が必要でなければ「インストール」をクリック
インストール後に下記の図のメッセージが表示される場合は機能拡張を許可する必要がある
「システム環境設定」の「セキュリティとプライバシー」を開き、
ダウンロードしたアプリケーションの実行許可下部にIntel HAXMへの権限を確認する文章が追加されているので「許可」をクリック
実行確認
Macの場合
MacでAndroidエミュレータが起動しない(HAXMが起動しない)とき
kextstat | grep intelを実行した場合に何らかの文字列が出力されたらインストールが完了しているHAXMのアンインストール
HAXMで何らかの不具合が発生している場合は一旦アンインストールしてインストールをし直した方が良い
Windowsの場合
Intel Hardware Accelerated Execution Manager(HAXM) インストールとアンインストール
【インストール先もしくはダウンロードしたファイル先】/silent_install.bat -uを実行するMacの場合
sudo 【インストール先もしくはインストール時にダウンロードしたファイル先】/silent_install.sh -uを実行するAndroid Studioの日本語化
Android Studio / IntelliJ IDEA の日本語化と設定
MacでAndroid Studioを日本語化するPleiades プラグインに接続して使用しているOSのプラグインをダウンロード
ダウンロードされたzipファイルを解凍後、以下のアプリケーションを起動
Mac:解凍先/pleiades-mac/setup.app
「選択」をクリックして先ほどインストールした「【インストール先】/Android Studio/bin/studio64.exe」もしくは「Android Studio.app」をクリックして「開く」を選択
Android Studioを起動して日本語化されていることを確認する
AVDの作成
今回は仮想デバイスを作成したいだけなのでHAXMを使用した高速AVDでの構築を行なっておりません。
高速AVDで仮想デバイスを構築したい場合は下記の記事がとても参考になります。
Windowsで高速AVDを利用するまでの手順をものすごく詳しく解説「ツール」、「AVDマネージャー」をクリックして
Android仮想デバイス・マネージャーを起動後、「仮想デバイスの作成」をクリック
既にシステムイメージのダウンロードが完了している場合は選択するだけで良いが、目的のイメージがインストールされていない場合は
「Download」をクリックし、ダウンロードが完了したら再度選択をして「次へ」をクリックする
シミュレータの起動
「ツール」、「AVDマネージャー」をクリックして作成したデバイスの右側にある「▶︎」をクリック
ばらくするとOSが起動するので動作を確認し、正常に動くことを確認する
完全アンインストール
こちらの記事を書いている最中、Android Studioを壊してしまったので完全アンインストール方法を探していたのですが
Windows、Mac共に削除だけだと消えないそうなのでまとめました。
再インストール前に全ての環境を初期化したい場合は下記を実行すれば全削除を行うことができます。Windowsの場合
Android studioを完全にアンインストールしたい。
下記フォルダを削除すれば設定を削除して初期化を行う事が可能
# Android SDKのインストール先を変更している場合、下記フォルダではなくANDROID_HOMEのパスを確認する C:/Users/【ユーザ名】/AppData/Local/Android/sdk # .AndroidStudioX.Xはバージョン番号によってフォルダ名が異なる C:/Users/【ユーザ名】/.AndroidStudioX.X C:/Users/【ユーザ名】/.gradleMacの場合
Android SDKを削除する場合のコマンドは
rm -r ~/Library/Android*だが、インストール先を変更している場合はANDROID_HOMEのパスを確認することXcode
インストールまで
App Storeを起動してXcodeで検索して「インストール」をクリック
インストールが完了後、初めて起動する場合はライセンス規約が出るので「Agree」をクリック
シミュレータの起動
Xcodeでの起動
「Xcode」、「Open Developer Tool」、「Simulator」をクリック
しばらくするとOSが起動するので動作を確認し、正常に動くことを確認する
Android Studioでの起動
※Flutterの各種設定が終了後に実行可能
画面右上のデバイス表示部分をクリック後、「Open iOS Simulator」をクリック
しばらくするとXcodeでの起動と同じく、エミュレータが起動する
Flutterインストール
SDKインストール
Flutter公式にアクセスして「Get started」をクリック
対応するOSの部分をクリックして以下のファイルをダウンロード
Windows:flutter_windows_v1.5.4-hotfix.2-stable.zip
Mac:flutter_macos_v1.5.4-hotfix.2-stable.zip
Windowsの場合
ダウンロード後に解凍して任意のフォルダに入れる
今回はC:/develop配下に格納した格納後、環境変数
PathにC:/develop/flutter/binを追加するMacの場合
ダウンロード後に解凍して任意のフォルダに入れる
今回は/Users/ユーザフォルダ/develop配下に格納した格納後、パスを通すために
.bash_profileを編集してパスを追加する# vimで.bash_profileを編集する vim ~/.bash_profile # 実行直後にiキーを押して挿入モードに移行後、以下の行を追加 # 追加後にEscキーを押してノーマルモードに戻った後、:wqで保存してvimを終了させる export PATH="$HOME/develop/flutter/bin:$PATH"完了後、.bash_profileを再読み込みする
source ~/.bash_profile実行確認
完了したら正常にパスが通っていることを確認する
flutter --version # パスが通っていたら以下のような出力が行われる Flutter 1.5.4-hotfix.2 • channel stable • https://github.com/flutter/flutter.git Framework • revision 7a4c33425d (9 weeks ago) • 2019-04-29 11:05:24 -0700 Engine • revision 52c7a1e849 Tools • Dart 2.3.0 (build 2.3.0-dev.0.5 a1668566e5) ╔════════════════════════════════════════════════════════════════════════════╗ ║ Welcome to Flutter! - https://flutter.dev ║ ║ ║ ║ The Flutter tool anonymously reports feature usage statistics and crash ║ ║ reports to Google in order to help Google contribute improvements to ║ ║ Flutter over time. ║ ║ ║ ║ Read about data we send with crash reports: ║ ║ https://github.com/flutter/flutter/wiki/Flutter-CLI-crash-reporting ║ ║ ║ ║ See Google's privacy policy: ║ ║ https://www.google.com/intl/en/policies/privacy/ ║ ║ ║ ║ Use "flutter config --no-analytics" to disable analytics and crash ║ ║ reporting. ║ ╚════════════════════════════════════════════════════════════════════════════╝Android Studioプラグインインストール
「ファイル」もしくは「Android Studio」から「環境設定」をクリック
上の検索欄に
Flutterを入力してEnterキーを押すとプラグイン一覧が検索されるのでFlutterをインストール
※Flutter i18nは多言語対応プラグイン
インストールが完了したら「Restart IDE」をクリックしてAndroid Studioを再起動
Flutterプロジェクト作成
新規にプロジェクトを作成する場合
「ファイル」、「新規」、「New Flutter Project」をクリック
「Flutter Application」をクリックして「次へ」をクリック
「Flutter SDK path」で先程設定したFlutterのフォルダを指定して「次へ」をクリック
既存のFlutterプロジェクトを開く場合
既存のプロジェクトをインポートして開いた場合、
Dart SDK is not configuredと表示されることがある
この場合、FlutterとDartのSDKへのパスが設定されていないのでパスを設定する
Dart SDK is not configured横の「Open Dart settings」をクリック
クリック後、SDKのパスを設定するウィンドウが開かれるのでFlutterとDartのSDKに下記を設定する
Flutter:【インストール先】/flutter
Dart:【インストール先】/flutter/bin/cache/dart-sdk
設定後、「OK」をクリックすれば環境チェックが行われる
インポート後にエラーが出る場合
'package get' has not been runと出力される「表示」、「ツール・ウィンドウ」、「ターミナル」とクリック後に下記コマンドを実行する
※flutterコマンドが見つからないというエラーが発生する場合はFlutterの環境変数に誤りがあるflutter packages get
Waiting for another flutter command to release the startup lock...と表示されて進まない
プロセスがロックされてしまっている
flutterコマンドを打った時に"Waiting for another flutter command to release the startup lock..."が出た時の対処法
【FlutterSDKのパス】/bin/cache/lockfileを削除して再実行
※プロセスが全て終了していることを確認することプロジェクト起動後に実行すること(初回のみ)
flutter doctorを実行してセットアップを完了するために必要なプラットフォームの依存関係があるかどうかを確認する
基本的には下記のように、実行するべきコマンドが表示されているのでコピーして実行する[!] Android toolchain - develop for Android devices (Android SDK version 29.0.0) • Android SDK at /Users/【ユーザ名】/Library/Android/sdk • Android NDK location not configured (optional; useful for native profiling support) • Platform android-29, build-tools 29.0.0 • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_152-release-1343-b01) # エラー個所は✗、警告箇所は!で示される ! Some Android licenses not accepted. To resolve this, run: flutter doctor --android-licenses
Xcode installation is incompleteというエラーが発生するXcodeをインストールしただけではコマンドラインツールのバージョンが古いままになっている
下記コマンドを実行してコマンドラインツールのバージョンを更新する[✗] iOS toolchain - develop for iOS devices ✗ Xcode installation is incomplete; a full installation is necessary for iOS development. Download at: https://developer.apple.com/xcode/download/ Or install Xcode via the App Store. Once installed, run: sudo xcode-select --switch /Applications/Xcode.app/Contents/Developerエラーを解消後、再度
flutter doctorを実行して全ての項目に✗が付くことを確認するアプリケーション実行
Androidでの実行
※Android Studioを実行してプロジェクトを開いていること
Androidデバイスを接続するかエミュレータを起動後、画面右上の「▶︎」をクリックしてFlutterプロジェクトを実行する
iOSでの実行
※Android Studioを実行してプロジェクトを開いていること
Android StudioでiOSのエミュレータを起動後、画面右上の「▶︎」をクリックしてFlutterプロジェクトを実行する
Flutterアップデート
Flutterのバージョンを更新したい場合は以下のコマンドを実行する
flutter upgrade最後に
Android及びiPhoneの開発経験はあまりないので手順を忘れそうだと思いまとめました
割と突貫で書いているので誤字などあるかもしれません参考
MacでAndroidエミュレータが起動しない(HAXMが起動しない)とき
Intel Hardware Accelerated Execution Manager(HAXM) インストールとアンインストール
Android Studio / IntelliJ IDEA の日本語化と設定
MacでAndroid Studioを日本語化する
Windowsで高速AVDを利用するまでの手順をものすごく詳しく解説
Android studioを完全にアンインストールしたい。
MacでAndroidStudioを完全アンインストール
flutterコマンドを打った時に"Waiting for another flutter command to release the startup lock..."が出た時の対処法
- 投稿日:2019-07-04T09:45:30+09:00
aapt.exeのエラーが出たときの備忘
androidアプリをビルドしていたら、見慣れないエラーが出た。
Process 'command 'C:\Users\XXXXXXXXXX\AppData\Local\Android\Sdk\build-tools\24.0.2\aapt.exe'' finished with non-zero exit value 1aapt.exeを実行したときの終了コードが0じゃないってことは分かったけど、じゃぁどこでエラーになっているのか探してみても、これ以上のログは出ていない。
Gradleをインストールする
調べてみたところ、Gradleなるものを使えば詳細なログが出るらしい。
(Gradleとは、Groovyで記述するビルド自動化システム)
ということで、以下を参考にしてGradleのインストールをしてみた。参考にした記事:
【Java】Gradleのインストールと基本的な使い方(画像付きで解説)インストールできているか確認する。
C:\Users\XXXXXXXX>gradle -v ------------------------------------------------------------ Gradle 3.2.1 ------------------------------------------------------------ Build time: 2016-11-22 15:19:54 UTC Revision: 83b485b914fd4f335ad0e66af9d14aad458d2cc5 Groovy: 2.4.7 Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015 JVM: 1.7.0_80 (Oracle Corporation 24.80-b11) OS: Windows 8.1 6.3 amd64ビルドログを確認する
Gradleのインストールができたため、さっそく以下を実行してログを確認する。
C:\Users\XXXXXX\AndroidStudioProjects\DataBaseApp2>gradlew assembleDebug --info …………… Successfully started process 'command 'C:\Users\XXXXXXX\AppData\Local\Android\Sdk\build-tools\24.0.2\aapt.exe'' C:\Users\XXXXXXX\AndroidStudioProjects\DataBaseApp2\app\src\main\res\layout\activity_main.xml:25:32-40: AAPT: String types not allowed (at 't extColor' with value ' #F5F5F5'). C:\Users\XXXXXXX\AndroidStudioProjects\DataBaseApp2\app\build\intermediates\res\merged\debug\layout\activity_main.xml:18: error: Error: Strin g types not allowed (at 'textColor' with value ' #F5F5F5').カラーコードにスペース入ってる…!!!
ということで削除し再ビルドしたら解決した。
- 投稿日:2019-07-04T09:00:12+09:00
Android GestureDetectorの使い方
アンドロイドのGestureDetectorの使い方を紹介いたします
背景
ウェブビューをスワイプことによって、前のページに戻ったりしたいです
コアソースコード
MainActivity.java
public class MainActivity extends AppCompatActivity { WebView webView; private GestureDetector mGestureDetector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initializa(); } private void initializa(){ initialGesutre(); initlaWebView(); } private void initialGesutre(){ mGestureDetector = new GestureDetector(this,mOnGestureListener); } private void initlaWebView(){ webView = (WebView) findViewById(R.id.webView); webView.loadUrl("https://www.yahoo.co.jp"); webView.getSettings().setJavaScriptEnabled(true); webView.setWebViewClient(new android.webkit.WebViewClient() { @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); } }); webView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { mGestureDetector.onTouchEvent(event); return false; } }); } private final GestureDetector.SimpleOnGestureListener mOnGestureListener = new GestureDetector.SimpleOnGestureListener(){ @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { float distance_x_vector = e2.getX() - e1.getX(); float distance_x = Math.abs(e2.getX() - e1.getX()); float distance_y = Math.abs(e2.getY() - e1.getY()); //ここから判断します、左スワイプしているか、右へスワイプしているか //判断したら、WebViewにJavascriptインジェクトします //webGoAndForward() return false; } @Override public boolean onSingleTapUp(MotionEvent e) { return super.onSingleTapUp(e); } }; private void webGoAndForward(Boolean forward){ if (webView == null){ return; } if(forward){ webView.goForward(); }else{ webView.goBack(); } } }activity_main/xml
<?xml version="1.0" encoding="utf-8"?> <android.support.constraint.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"> <WebView android:id="@+id/webView" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintRight_toRightOf="parent" app:layout_constraintTop_toTopOf="parent" /> </android.support.constraint.ConstraintLayout>結論
自分はネットでGestureDetectorについて色々調べて、やっと実装しました。ここでシンプルなコードを載せます。
皆に参考になれば幸いです
- 投稿日:2019-07-04T03:53:44+09:00
Bitrise で google_services.json を扱う
毎回 google_services.json を扱うプロジェクトを Bitrise に載せる時に忘れているので記録まで。初めて扱う人の参考にもなれば。
google_services.json は一般的に .gitignore に記述して git にコミットしないので、CI で Lint を掛けるとコケます。Bitrise の場合はワークフローにファイルを生成するステップを追加できるのでそこで google_services.json を生成するようにして回避します。
- Secrets に変数を定義して google_services.json の中身を保存します(青く記述されている部分に登録するシークレットの中身は、Expose for Pull Request を有効にしない限り安全である旨書かれています)。ここでは GOOGLE_SERVICES_JSON と云う名前の変数を定義しています。
- Workflows で Android Lint の前に Generate Text File のステップを追加します。File Name はプロジェクトに合わせて変更する必要があります。このプロジェクトでは app/ 以下に google_services.json を置いてあるので app/google_services.json のパスでファイルを生成します。ファイルの中身は Insert Variable で先に定義したシークレットを選択します。
bitrise.yaml にもちゃんとステップが追加されています。
- generate-text-file@0.1.0: inputs: - file_content: "$GOOGLE_SERVICES_JSON" - file_name: app/google-services.jsonこれで Lint でコケることなくビルドを通すことができます。
















































