たった数日でFire TV Stickを箱に戻した
先日、AmazonのセールでFire TV Stickを購入しました。
購入した主な理由はプライムビデオを大画面のTVで見たい
見るものがなくなったらいずれはNetflixあたりも。。
という感じです。
が、「本日、ネットでPS4でプライムビデオを見ることができる」ということを知りました。。。
また、最近のテレビでは最初から対応しているようです。
というわけで、早速帰宅してからPS4で試してみました。
アプリをダウンロードしてAmazonアカウントでログインすると何事もなくプライムビデオを視聴することができました。
PS4はスペックもFire TV Stickよりはるかに良いので、サクサクです。
さらにコントローラーも持ち慣れている上にスタンバイモードからの起動も一瞬です。
というわけで、今後はPS4でプライムビデオを見ることにしました。
Fire TV Stickは、、帰省したときにでも実家に置いてこようと思います。
Fire TV Stick購入!
Fire TV Stickを購入しました。
http://www.amazon.co.jp/Amazon-W87CUN-Fire-TV-Stick/dp/B00ZVNYLS8
以前はChrome Castを使用していました。
Chrome CastからFire TV Stickに切り替えた理由としては以下の通りです。
- Fire TV Stickがセールで安くなっていた
- Chrome CastはAmazon Prime Video非対応
- Fire TV Stickはリモコン付き
- YouTubeはあまり見ない
Prime会員なので、オーダーした翌日には到着しました。
パッケージはこんな感じです。
外のパッケージを外すと意外に地味なパッケージ
蓋を開けると、リモコンとFire TV Stick本体。
音声入力機能は特に必要なかったので通常のリモコン版です。
さらにその下には、
- 説明書
- 電源アダプタ
- USBケーブル
- 電池
- HDMI延長ケーブル(USBケーブルの下に入っています)
が入っていました。
電池が入っているのは親切です。
安っぽさが無いのは好印象でした。
実際にテレビに接続してWi-Fiのセットアップまですると、自分のAmazonアカウントと紐付けされていました。
Fireタブレットもそうですが、一体どうやっているんだろう・・
オーダー時にシリアルIDか何かと紐付けているんでしょうか・・
ともあれ特に難しい設定もなく、40インチのテレビでPrime Videoを見ることができるようになりました。
画面が大きいと画像が荒くなるかなと懸念していましたが、通信回線が安定していればそんなこともなくキレイな映像が楽しめます。
Prime Videoは作品が少ないと言われていますが、見たい作品は沢山あるので自分としては満足です。
そのうち、見たいものがなくなってきたらNetflixあたりを検討するかもしれません。
それもFire TV Stickがあれば楽しめるので気兼ねなく利用できそうです。
とりあえず、弱虫ペダルを全部観ようと思います。
Android学習(DI・DB編)
前回↓に引き続き、mixiのAndroidTrainingで時間を見つけてはAndroid開発について学んでいます。
今回は、2.基礎編 10.データベースの項です。
RDBは仕事でも使うので、取っ付きやすい章でした。
せっかくなので、SQLiteOpenHelperではなくORMを利用してみることにしました。
Android用のORMは色々なライブラリが公開されていましたが、今回はAndroid Ormaを利用してみました!
GitHub - gfx/Android-Orma: A lightning-fast ORM for Android as a wrapper of SQLiteDatabase
また、作者の方が公開しているチュートリアルを参考にさせていただきました。
その中で、OrmaDatabase
クラスのインスタンスをDIで@Singleton
をおすすめとの記述があったので、合わせてDagger2にも挑戦してみることにしました。
Dagger2については、こちらの記事を参考にさせていただきました。
Dagger2 導入Step By Step - Qiita
依存ライブラリ等の定義
プロジェクト直下のbuild.gradle
に
- repositoryにmavenCentralを追加
- dependenciesにaptの定義を設定
repositories { jcenter() mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:2.1.0' classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' }
続いてプロジェクト/app下のbuild.gradle
の依存関係に
- Dagger2の定義を追加
- Ormaの定義を追加
以下のような順に追記しました。
dependencies { ・・・ compile 'com.google.dagger:dagger:2.0.2' apt 'com.google.dagger:dagger-compiler:2.0.2' provided 'javax.annotation:jsr250-api:1.0' apt 'com.github.gfx.android.orma:orma-processor:2.4.7' compile 'com.github.gfx.android.orma:orma:2.4.7' }
Moduleクラスの作成
import部分等は省略していますが、こんな感じで作ってみました。
OrmaDatabaseもここで@Singleton
で定義しています。
@Module public class ApplicationModule { private final Application application; public ApplicationModule(Application application) { this.application = application; } @Provides @Singleton Context provideApplicationContext() { return application.getApplicationContext(); } @Singleton @Provides public OrmaDatabase provideOrmaDataBase(Context context) { return OrmaDatabase.builder(context).build(); } }
ComponentInterfaceの作成
@Singleton @Component(modules = ApplicationModule.class) public interface ApplicationComponent { void inject(MainActivity mainActivity); }
Applicationクラスの作成
public class MainApplication extends Application { private ApplicationComponent applicationComponent; @Override public void onCreate() { super.onCreate(); initializeInjector(); } private void initializeInjector() { applicationComponent = DaggerApplicationComponent.builder() .applicationModule(new ApplicationModule(this)) .build(); } public ApplicationComponent getApplicationComponent() { return applicationComponent; } }
AndroidManifest.xml
にも忘れずに定義します。
<application android:name=".MainApplication" ・・・> ・・・ </application>
実際にDIしてみる
以下の様な感じでApplicationComponent
を取得してinjectメソッドを実行することで、@Inject
と定義しているormaにDIすることができました。
public class MainActivity extends AppCompatActivity { @Inject OrmaDatabase orma; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getApplicationComponent().inject(this); } private ApplicationComponent getApplicationComponent() { return ((MainApplication) getApplication()).getApplicationComponent(); } }
Ormaを利用してDBを扱う
テーブルは課題に合わせて以下の様な感じで作りました。
アノテーションで属性等を定義できるので分かりやすいです。
@Table public class AndroidCodeName { @PrimaryKey(autoincrement = true) public long id; @Column(indexed = true) public String name; @Column @Nullable public String version; public static AndroidCodeName_Relation relation(OrmaDatabase orma) { return orma.relationOfAndroidCodeName().orderByIdDesc(); } }
今回はinsertとselectだけ載せておきます。
insertはこんな感じ。
private void insert() { AndroidCodeName androidCodeName = new AndroidCodeName(); androidCodeName.name = appNameEditText.getText().toString(); androidCodeName.version = appVersionEditText.getText().toString(); orma.insertIntoAndroidCodeName(androidCodeName); Toast.makeText(MainActivity.this, "insert success", Toast.LENGTH_SHORT).show(); }
さらにselect
private void select() { AndroidCodeName_Relation relation = AndroidCodeName.relation(orma); // Relationを利用してデータを取得 Log.d(TAG, "from Relation"); for (AndroidCodeName androidCodeName :relation) { Log.d(TAG, androidCodeName.name + ":" + androidCodeName.version); } // Helper経由でデータを取得 Log.d(TAG, "from Helper"); AndroidCodeName_Selector selector = orma.selectFromAndroidCodeName() .orderByIdAsc(); for (AndroidCodeName androidCodeName : selector) { Log.d(TAG, androidCodeName.name + ":" + androidCodeName.version); } }
今回はDaggerでOrmaDatabaseをDIする所を中心に挑戦してみましたが、OrmaがRxJava用のインターフェースを備えているようなので、RxJavaを絡めて学んでみたいなと思います。
※RxJavaも触ったことがありません。。
Android開発者は今から始めると学ぶことが多いですね。。
スターオーシャン5購入
発売から2ヶ月以上経過していますが、ようやくスターオーシャン5を購入しました。
スターオーシャン5 -Integrity and Faithlessness- | SQUARE ENIX
というのも、Amazonでの評価があまり良くなかったので見送っていました・・
購入したときにはAmazon限定版で3300円程だったので、思い切って購入しました。
(今は少し値上がりしているみたいですが。。、限定版じゃなければ3000円以下で買えるようです。
数時間遊んでみたのでその感想を。
カメラワーク
まずはカメラワークが酷いというレビューが多かったので自分も気になっていたのですが、確かに上下に揺れて酔いそうになる感じ・・
これは辛いなーと思い設定を見ていると、「カメラの上下の感度」が設定できるようになっていたので低めに設定すると大きく改善し、快適にプレイできるようになりました。
イベントスキップできない
これが地味に効いて来ます。
普段はまぁ、別にいいかという感じなのですが、ボスバトル前にイベントが入る事が多く、ボスで全滅して再度挑戦するときにスキップできないのが辛いです。
それでいて町中のmobの会話は表示されても一瞬で消えてしまうので何言ってるか分からない。。
ストーリー
レビューでも書かれていますが、短いという印象。
まだクリアしていませんが、攻略サイトでどのあたりかな〜と確認して見たところ、そろそろ中盤あたりでした。
(街とフィールドが少し登場したくらい・・)
とはいえ、内容は嫌いではないです。
ベタなパターンが多い気はしますが。
バトル
プレイ前はシームレスバトルと聞いてもあまりピンとこなかったのですが、これはアリだと思います。
(ダークソウル3プレイした後だからかも・・?)
敵味方が入り乱れる攻城戦なんかでは、敵の部隊を倒す -> 近くの戦闘に介入といった流れが非常にスムーズで楽しめました。
また、パーティーメンバーに控えという概念がなく、全員で戦闘というのも迫力があっていい感じです。
味方のメンバーが多いので、難易度調整のために敵の攻撃力が高めに設定されている印象が高いですが。。
また、3竦み?がうまく機能しているのか・・?と疑問に。
そもそもパーティーメンバーが多く、バトルエフェクトも派手なので狙ってやるのはなかなか難しいのですが、それでもこちらの小攻撃で相手の大攻撃をキャンセルできないことが多い気がします。
ガードも簡単に破られるし・・
とりあえず、まだクリアしていないのでこんな所で・・。
個人的には☆3.5くらいで、そこまで悪くはないなという印象です。
定価で買っていたらちょっと・・・となっていたかもしれないですが。。
とりあえず、クリアまではプレイしようと思います。
やりこみはその時の満足度次第ということで・・!
Androidで嵌った所(HTTP request編)
仕事が忙しくてなかなか進まないのですが、空いた時間を見つけてはmixiのAndroidトレーニングを進めています。
現在は2.基礎編 9.ネットワーク通信のセクションです。
実習1の
- 画面のEditTextに入力されているURLを取得して、
- そのURLにGETリクエストを送り、
- レスポンスを画面のTextViewに表示する
だけの簡単なお仕事です(のはずでした)。
まずはAndroidManifest.xml
に、ネットワークのパーミッションを定義
<uses-permission android:name="android.permission.INTERNET" />
今回は折角なのでOkHttpを使ってみました。
まずはbuild.gradle
にOkHttpの依存関係を追加します。
dependencies { ~ compile 'com.squareup.okhttp3:okhttp:3.2.0' }
続いて通信処理を書いていきます。
MainActivity#onCreate
に書いてみたところ、NetworkOnMainThreadException
が発生してしまいました。
メインスレッドからネットワーク処理ができないようです。。
こちらの記事を参考にさせていただきました。
shirusu-ni-tarazu.hatenablog.jp
今回関係なさそうな所は省略していますが、以下のような感じになりました。
MainActivity.java
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // GetButton View buttonGet = findViewById(R.id.buttonGet); buttonGet.setOnClickListener(getButtonOnClickListener); } private View.OnClickListener getButtonOnClickListener = new View.OnClickListener() { @Override public void onClick(View view) { // EditTextからURLを取得 EditText accessUrlText = (EditText) findViewById(R.id.accessUrl); final String accessUrl = accessUrlText.getText().toString(); // Builderにセット Uri.Builder builder = new Uri.Builder(); builder.path(accessUrl); // 別スレッドでリクエストを実行 AsyncHttpRequest task = new AsyncHttpRequest(MainActivity.this); task.execute(builder); } };
AsyncHttpRequest.java
private Activity mainActivity; public AsyncHttpRequest(Activity mainActivity) { // 呼び出し元のアクティビティ this.mainActivity = mainActivity; } // 非同期で呼ばれる処理 @Override protected String doInBackground(Uri.Builder... builders) { Uri.Builder builder = builders[0]; try { URL url = new URL(builder.build().getPath()); Request request = new Request.Builder() .url(url) .build(); OkHttpClient client = new OkHttpClient(); Response response = client.newCall(request).execute(); return response.body().string(); // 例外処理は今回適当 } catch (IOException e) { e.printStackTrace(); } return null; } // 非同期処理の後に呼ばれる処理 // doInBackgroundのreturn値が引数で渡されます。 @Override protected void onPostExecute(String result) { TextView responseText = (TextView) mainActivity.findViewById(R.id.responce); responseText.setText(result); }
嵌った所は以下のとおり
- OnClickListener内でAsyncHttpRequestのコンストラクタにActivityをどうやって渡せば。。
- new AsyncHttpRequest(MainActivity.this);でいけました。
- Builderにpathをセットする際に、
builder.addPath(url)
でセットすると先頭に/
がついてしましまう。builder.path(url)
でいけました。
- request投げているのにresponseが帰ってこない
Android開発のFragmentで嵌った
GW前に前々から読みたいと思ってAmazonの欲しいものリストに入れていたCode CompleteのKindle版が上下巻とも半額だったので衝動買いし、GW中は、Code Completeを読んでいました。
書評は既に多くの方が書いているので割愛。
今回はCode Completeを読み終えたので、過去に途中で辞めてしまった、Androidアプリ開発に再度挑戦してみました。
※AndroidがSwiftで開発できるようになるといった噂も出たりしていますが、果たしてどうなるのか。。
参考資料
今回はmixiさんが公開している、AndroidTrainingを利用させていただき、学習を進めています。
※昔、別の入門書をやったことがありますが、結局作りたいアプリのイメージが沸かずに途中で止めてしまったため、あまり覚えていません・・
今回はトレーニング完了までに作りたいアプリのイメージを固めねば。。
1. アプリのレイアウト作成
このセクションは大きく嵌まる事もなく終了。
以下のレイアウトについて学べました。
- LinerLayout
- RelativeLayout
- FrameLayout
- ScrollView
Android Support Library 23.0からPercentRelativeLayout
とPercentFrameLayout
というものが登場しているようなので、こちらも別途学習する必要がありそう。
また、マテリアルデザインについても別途学習が必要な気がします。
2.ActivityとFragment
ここの実習で結構ハマりました。
新しいActivityの実装は特に問題なく終了
新しいFragmentの実装部分で特に実習には書かれていなかったのですが、Bundle経由でパラメータを渡して表示してみようと思い、実装してみました。
↓最初の状態がこちら
public class Main3Fragment extends Fragment { public Main3Fragment() { // Required empty public constructor } public static Fragment createInstance(int hoge) { Fragment fragment = new Main3Fragment(); Bundle args = new Bundle(); args.putInt("hoge", hoge); fragment.setArguments(args); return fragment; } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_main3, container, false); TextView hogeText = (TextView) view.findViewById(R.id.hoge); hogeText.setText(savedInstanceState.getInt("hoge")); return view; } }
onCreateView
メソッドに渡される引数のsavedInstanceState
がBundle
型なので、createInstance
メソッドで設定したhoge
というパラメータがsavedInstanceState
から取得できるのかと思いきや、null
となってしまいました。
色々調べた結果、以下のようにgetArguments
でBundler
を取得するように書き換えることでうまくいきました。
// onCreateViewメソッドだけ抜粋 @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.fragment_main3, container, false); Bundle arguments = getArguments(); TextView hogeText = (TextView) view.findViewById(R.id.hoge); int hoge = arguments.getInt("hoge"); hogeText.setText(String.valueOf(hoge)); return view; }
※呼び出し元のActivityはこんな感じ
public class Main3Activity extends FragmentActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main3); if (savedInstanceState == null) { FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction transaction = fragmentManager.beginTransaction(); // ここでMain3Fragmentのインスタンス生成とreplace transaction.replace(R.id.Main3FragmentContainer, Main3Fragment.createInstance(999)); transaction.addToBackStack("main3FragmentContainerReplace"); transaction.commit(); } } }
他にもonCreateView
ではなくonCreate
に実装してしまっていたりと・・色々ありましたが、今回はこんな感じです。
実習・課題形式なので、実際に入門書をそのまま写経するよりも身についているという実感があるのがいい感じです。
念願のPS4を手に入れた・・!
↓のような記事を書いてからだいぶ時間が空いてしまいましたが、
よくやくPS4を購入しました!
(といっても少し前なのですが。。)
平日は仕事が忙しくて殆どプレイできず、土日も休日出勤だったり仕事の反動で寝てしまっていたり。。といった具合で、あまり遊べませんでした。
↓一緒に買ったソフトはこちら
色々悩みましたが、発売してあまり日が経っていないというのと、amazonでの評価で選びました。
ソウルシリーズやってみたかったし。
このGWで集中して一気にプレイしました。
忙しくてPS Plusに入るのに躊躇していたので、基本的にオフラインで進めました。
感想としては
- 他のRPGでは味わえない難易度
- ボスだけでなく道中で何度死んだことか・・
- 時にイライラしますが、攻略できたときの達成感があります
- ダークソウル3から始めるとストーリーに入り込めず置いてきぼりに
- 「灰の人って何だ・・」という感じ
- 装備の変更方法なんかも基本的にはチュートリアルがなかった(気がする)ので最初、操作を覚えるのが大変
- ステータスの見方や弓の使い方が最後の方まで分からなかった
死んでも「もう1回」という感じで何時間もぶっ通しでゲームをしたのは久しぶりです。
ここまでハマれるゲームはなかなか無い・・!
ボスの攻略に関しては、YouTubeの色々な動画を参考にしました。
攻略動画見なかったら未だにクリアできなかったんじゃないだろうか。。
クリア時の状態はこんな感じです ラスボス用に、弓とかは外して重量70%を超えないようギリギリの装備で挑みました。(羽騎士シリーズとかだったかも)
- プレイ時間 42時間
- レベル 100
- ダークソード + 10
- 竜紋章の盾 + 2
キャラや武器のレベルを上げ過ぎるとマッチングしにくくなるらしいのですが、今回はオフラインモードでやってたのでそこはあまり気にせず。
あと、ウイイレ2016がプライスダウンして発売していたので、こちらも衝動買い。
時間のあるときにやりたいと思います。
今回、PS4を購入したことで新作が出ても購入のハードルが大きく下がりました。
FF15、PSVRの準備万端!