AndroidでURLエンコード
通信用ライブラリにはVolleyを利用していますが、クエリに日本語が含まれるとうまくリクエストが正常に通らないという事象が起きました。
まぁ当たり前といえば当たり前ですが、iOSのAFNetworkingなんかはその辺をよしなにやってくれるので、ちょっと面食らったという話です。
だったらURL作るときに自分でやってあげましょうねということで、Androidで文字列をURLエンコードする方法を調べました。
java.net.URLEncoder
というクラスがあるようで、
String encodedString = URLEncoder.encode("おすし", "UTF-8");
とやってあげるだけでエンコードで来てしまいます。
iOSのURLエンコードには結構罠があったりするのですが、URLEncoder
はどうなのかというと*
と-
と_
はエンコードしてくれないようなので、自分で対応してねとのことでした。
Androidのmenu itemのtextColor
「の」ばっかり続く文章はアホっぽく見えるわけですが、Androidアプリをつくっていて、menu itemのtextColorを変えたかったのでメモです。
結論のみ。android:itemTextAppearance
をオーバライドしてあげましょということみたいです。
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"> <item name="android:itemTextAppearance">@style/MenuTextAppearance</item> </style> <style name="MenuTextAppearance" parent="@android:style/TextAppearance.Widget.IconMenu.Item"> <item name="android:textColor">@color/text_black</item> </style>
このstylesあたりがまだマスターしきれてない感じあるので頑張りたい
AndroidのWebViewでJavaScriptが動かない
グッドモーニング。しののめです。
掲題の件ですが、セキュリティ対策でデフォルトでJavaScriptの実行が無効になっている模様です。
コイツをむりくり有効にするには
mWebView = (WebView) findViewById(R.id.webview); mWebView.getSettings().setJavaScriptEnabled(true); mWebView.loadUrl("http://some-awesome-web-page~~~~");
上記コードの2行目 setJavaScriptEnabled(true)
してあげると無事JavaScriptを実行することができるようになります。
このコードを書くと「XSS脆弱性を仕込む可能性があるから注意してね〜」とAndroid Studioさんが警告してくれますので、心当たりがある方は注意してくださいまし
Xcodeでターゲットを複数設定してそれぞれにcocoapodsを適用させる
備忘録として。 私のために誰かのために。
Xcodeではプロジェクトにターゲットを追加していくことができますが、全てのターゲットで同じライブラリ郡を使いたいみたいなシーンはよくありそうです。
が、ターゲットを追加して諸々の設定をしていざビルド!とするとライブラリが読み込めません。 そんな時はここを設定したら解決しましたよ〜というメモです。
Xcodeでターゲットのページではなく「プロジェクトのページ」を開いてinfo
→ Configurations
のDebug
とRelease
にそれぞれPods.debug
とPods.release
が設定されているか確認しましょう。
ただターゲットを追加するだけではここがNoneになっていると思われます。これでcocoapodsを利用してインストールしたライブラリ群を利用できるようになります。
ちなみに、cocoapodsの設定は色んな所にあるので(もちろん追加するターゲットの性質にもよりますが)、同じような設定で利用したい場合は追加よりもベースのターゲットをduplicateして変更箇所を変えていったほうがスムーズかもしれません。
AppleMusicはもしかしてすごくいいかもしれない
2015年7月1日から始まったApple Musicですが、これもしかしてすごくよいかもーと思いました。
最近日本でもAWAとか、LINE MUSICとか、ストリーミング配信系のサービス界隈が賑わっておりまして、AppleMusicもそんなサービスです。
料金体系
AppleMusicが他のサービスと比べて良い!ということを言いたいわけではないのですが、まぁ名前が出てきましたし一応各サービスの料金体系を書いてみます。機能的な違いとかは自分で調べて下さい(なげやり)
サービス | 料金 | 対応端末 |
---|---|---|
MUSIC | 980円/月 (最初の3ヶ月間無料) | Apple製品全般・Windows(2015年秋にAndroidにも対応予定) |
AWA | Liteプラン 380円/月・Premium Plan 1,080円/月 | iOS/Android |
LINE MUSIC | ベーシックプラン 500円/月・プレミアムプラン 1,080円/月 (2015年8月9日まで無料) | iOS/Android |
ちなみにSpotifyは9.99ドル/月です。
AppleMusicはなにがいいの?
自分の環境的にすごくいいなーというところは、AppleのサービスだけあってApple製品とかなり密にインテグレートされているわけです。
私の環境としては、自宅にiMac、持ち歩き用・普段仕事用にMacBook Air、携帯はiPhone 6 Plus、あとiPadももってるよーという感じで、Apple信者ばりにAppleデバイスに囲まれています。
そんな感じでスーパー囲い込まれているわけですが、Apple IDひとつで全デバイスにシームレスに同期できるというのは素晴らしく良い所です。
仕事中を含むパソコンつけている時はだいたい音楽を流しています。シチュエーションによってiPhoneで聞いたりMacで聞いたりするので「この曲きこう!」と思った時に聞きたい方に楽曲が入ってないとかなり切ない気持ちになるんですね。
昔iPodを使っていた時に、出先で「あ!楽曲同期してくるの忘れた!!」ってよくなったじゃないですか。アレです。
なので自分のマシンに入ってる楽曲たちは綺麗に同期されていてほしいわけです。しかも勝手に。
iTunesMatch
というわけで、昨年始まったiTunesのクラウド同期サービスiTunes Match(3,980円/年)を契約して利用していました。
これも自分にとってすごい便利で、そもそもiPhoneとかMacBook Airってすぐ保存領域いっぱいになっちゃうのでたくさん楽曲をマシンに入れておけないんですよ。自分の場合、楽曲全部で70GBくらいあるので、そもそも64GBのiPhone買ったとしても全部はいらないわけです。なので、データはiMac全て入っています。
それらをクラウドに置いといて聞きたいときにだけストリーミング・またはダウンロードして聞けるというのはかなり重宝していました。同期漏れとかもなくなりましたし。
これに年間3,980円(ひとつきあたり約332円)を安いととるか高いととるかはあなた次第です…
AppleMusicいざ。
これAWAもLINE MUSICも使ってないのでその他のサービスがどうかはわからないのですが、ビックリしたのですが、AppleMusicを利用して曲を聞いていて、このアルバムいいな~とか思ったら
この「+」ボタンをクリックするとマイミュージックに追加され、
MacのiTunesのミュージックの所に反映されます。うん!これこれ!
そして右っちょに雲のマークが有るということは楽曲はダウンロードできるようようです。(まだ試してない)
一度ダウンロードしてしまえばネット環境ないところでも聞けますね。
これちょっと感激してしまいまして、2秒で契約しようと決心してしまいました。
そしてiTunes Matchも契約してると自分がiTunesMatchにあげている楽曲も一緒くたにマイミュージックに表示されるので、自分のライブラリがドンドン拡張されていきます…
ちなみに、Appleによると
Q. Apple MusicはiTunes Matchと連係しますか? A. はい。Apple MusicとiTunes Matchはそれぞれが独立したものですが、補完的な関係にあります。
だそうです。確かに補完的ですな。
とういこうとで、とりあえずはiTunes MatchとAppleMusicをどっちも契約して使っていこうと思います。
AppleMusicおすすめな人
- 音楽好きで色んな音楽を聞いてみたい・聞いてみたいアーティストがたくさんいるけどお金が…><な人
- Apple製品たくさん持ってる人
たぶん注意しないといけないところ
AppleMusicにかぎらずストリーミング配信サービス全部そうですが、長時間利用する時はWiFi環境下で利用しないと通信制限かかっちゃうよというところです。
あとは当たり前ですが地球上全てのアーティストがいるわけではないので、自分が聞きたい曲全て聞けるとも限りません。
画面が回転するとFragmentが初期化されて困る問題
Androidアプリ開発については結構初心者なんですが、Androidアプリって画面が回転するとActivityが再生成されちゃうんですね。
その時、ActivityにくっついてるFragmentがもつ変数とかが全部初期化されてしまってヌルポで落ちるみたいな現象に直面しました。
この手の問題は結構みんな通る道らしく、ぐぐってみるとsetRetainInstance(true)
しようよ!って記事が沢山出てきました。
もちろんどういうふうに実装してるのかによると思うんですが、私の環境だとこれだけだと治りませんでした。
というのも、下記のようにActivity側のonCreate()
でFragmentを追加してたんですが
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); FragmentManager manager = getFragmentManager(); Fragment fragment = OsushiFragment.newInstance(); FragmentTransaction fragmentTransaction = manager.beginTransaction(); fragmentTransaction.replace(android.R.id.content, fragment); fragmentTransaction.commit(); }
よく考えたら、Activityが再生性されるときもonCreate
を通るのだから、ここでFragment初期化する処理自分で書いてるぞ!!ってことで、以下のようにsavedInstanceState
がnullかどうかのチェックをカチこんで、2回目からは初期化されないようにしたらうまくいきましたとさ。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (savedInstanceState == null) { FragmentManager manager = getFragmentManager(); Fragment fragment = OsushiFragment.newInstance(); FragmentTransaction fragmentTransaction = manager.beginTransaction(); fragmentTransaction.replace(android.R.id.content, fragment); fragmentTransaction.commit(); } }
ActiveRecordでidがないテーブルにデータを保存しようとすると"nil is not a symbol"とか言われる
すんげハマったのでめも。
背景
create_join_table
でつくった中間テーブルのデータを更新したくて、中間テーブル用のモデルからsave!
とかupdate!
とかしようとしたわけです。
たとえば、 下記の用にOsushiクラスとNetaクラス、そして中間テーブル用のNetaOsushiクラスがあるとします。
class Osushi < ActiveRecord::Base has_many :neta_osushi end class Neta < ActiveRecord::Base has_many :neta_osushi end class NetaOsushi < ActiveRecord::Base belongs_to :osushi belongs_to :neta end
このNetaOsushiクラスのmigrationクラスは以下のようになるでしょう。
class CreateJoinTableNetaOsushi < ActiveRecord::Migration def change create_join_table :neta, :osushi do |t| t.index :neta_id t.index :osushi_id t.timestamps end end end
で、大人の事情でこのクラスのデータを更新しないといけなくなった場合に、
neta_osushi = NetaOsushi.find_by(neta_id: neta_id, osushi_id: osushi_id) # # 某かの代入などの処理 # neta_osushi.save!
とかすると、nil is not a symbol
とかすごい剣幕で怒られてしまい
「nil is not a symbol…!!!」
とみおちゃんばりの剣幕で困り果ててしまいました。
解決方法
さてこれかなりドンピシャなQiitaの記事を発見したので御覧ください。
まさにこの状況ですなー。 ということで、複合主キーを設定しましょう。
まずは、複合主キーを扱うために、composite_primary_keysというgemを入れましょう。
Gemfileに下記一行追加してbundle install
します。
gem 'composite_primary_keys', '~> 8.0.0'
ちなみにお使いのActiveRecordのバージョンによってインストールするバージョンも違うので、詳しくはcomposite_primary_keysのリポジトリのREADMEを御覧ください。
ちなみに8.xはActiveRecord4.2.x用です。
そんで、neta_osushiテーブルにunique indexをはります。
class AddIdnexToNetaOsushi < ActiveRecord::Migration def change add_index :neta_osushi, [:neta_id, :osushi_id], unique: true, name: 'composite_index' end end
最後に、モデル側で、こいつらがprimary keyだよ〜と教えてあげます。ここは、primary_key
ではなく、primary_keys
と複数なので注意。
class NetaOsushi < ActiveRecord::Base self.primary_keys = :neta_id, :osushi_id belongs_to :osushi belongs_to :neta end
これで往年の悩みは解決されました。
ゆるしてヒヤシンス!!!