moyashidaisuke's diary

平日はエンジニア、土日はミュージシャン(自称)のダイスケです。プログラム関連とかギター関連とかなんでも。

身の回りの設定を英語にした

TL;DR

  • 少しでも英語に触れる時間を増やすため、PCやスマホの設定を英語にしてみました。
  • やらないよりはやったほうが絶対良い

スマホ

Huawayの格安スマホ、nova lite2を使っています。 Androidのバージョンは8.0です。 moyashidaisuke.hatenablog.com

手順

www.iscle.com

興味本位でEnglishじゃなくて全然読めない言語(アラビア語とか)にすると、復帰するのが大変なので(どこから言語設定を元に戻すかまったくわからなくなる)気をつけましょう。(経験)

結果

before

f:id:moyashidaisuke:20180804164104j:plain

after

f:id:moyashidaisuke:20180804164119j:plain f:id:moyashidaisuke:20180804164218j:plain

所感

Android本体だけじゃなくて、設定されているものはアプリも英語になります。

googleの公式アプリや、海外サービスのアプリだけでなくて、Lineもなりました。メルカリはならなかったです。アプリ自体を国内用と海外用で別にしているのかな?

電話アプリが「Dialer」、google mapは「Maps(sがつく)」とか、意外と意識してない名前があって面白いです。

あと、Google Assistant (siriみたいなやつ)が英語で話しかけてきます。試しに英語で会話してみましたが、全然伝わらなかったです。発音がね、、、まだ何も対策してないからね、、、

Mac

手順

support.apple.com

再起動が必要です。

結果

before

f:id:moyashidaisuke:20180804170140p:plain

after

f:id:moyashidaisuke:20180804170221p:plain

所感

普段から英語のアプリケーション(開発用のコンソールとかエディタとか)を使っているのであまり違和感は感じなかったです。

地味なところで、スクリーンショットのファイル名が変わったりします。 (スクリーンショット XXXX.png -> Screen Shot XXXX.png

あとOffice系も自動的に言語が変わりました。

google

手順

英語サイトのみをGoogle検索結果に表示 - PC設定のカルマ

恒久設定の方です。

結果

before

f:id:moyashidaisuke:20180804172018p:plain

after

f:id:moyashidaisuke:20180804172029p:plain

所感

これはけっこう影響が大きいです。 日本語で検索した場合はそんなに変わらないですが、英語で検索した場合(技術用語とか)、全部英語で出てきます。wikipediaも英語です。

技術用語は英語の方が鮮度が良いことが多いので、英語の勉強関係なく、エンジニアの人は普段からこっちの設定の方が良い気がしてきました、、、

各種SNS

SNSに限らないですが、サービス内で独自に言語設定を持っているものがあります。

手順

Twitter

help.twitter.com

Facebook

www.facebook.com

所感

最近あまりSNSやってないので影響あまりありませんが、SNSに浸かってる方はけっこう影響あると思います。

SmartNews

ニュースアプリのSmartNewsを普段使っているのですが、こちらにも設定がありました。

手順

knowl.jp

私は日本のニュースも読みたいので、チャンネルを追加しました。 「英語学習」というそのままのやつと、「BBC(英語)」と「TechCrunch(英語)」を追加しました。

所感

TechCrunchは技術用語が少し(あまり深い話は無いけど、、、)出てくるので良いですね。

まとめ

まだ設定変えてそんなに時間たってないのですが、色んなものが勝手に英語になるので、英語で考える場面が増えて良いです。 (でも食べログとか固有名詞が英語になってるのはつらいです、、)

公式TOEIC Listening & Reading問題集1のTEST1を解いて見直した

前回の

moyashidaisuke.hatenablog.com

TL;DR

  • 問題集解いてみた
  • 単語が課題
  • リスニングで単語がつながると聞き取れない問題

目的とか

ひとまずは自分の状況を確認しないと対策も何も取れない&本番テストは1ヶ月後なので、過去問を解いてみようと思ったのですが、TOEICは過去問は提供されていない代わりに、公式問題集があるという事で、解いて結果を分析してみました。

公式 TOEIC Listening & Reading 問題集 1

公式 TOEIC Listening & Reading 問題集 1

これ以外にも、同じ名前の2と3、「TOEICテスト公式問題集 新形式問題対応編」(ナンバリングされてるやつと何が違うんだ、、、)というのがあるらしいのですが、違いがよくわからないので、とりあえず本屋さんで山積みされていたこれにしてみました。

「公式 TOEIC Listening & Reading 問題集 1」について

本番形式の問題が2セット含まれています。マークシートもついてるし、本番のナレーターと同じ人がリスニング問題のナレーターをしています。

解答の解説はちょっと内容薄めだと思います。単語の説明はわかりやすいですが、文法の解説は結論だけ書いてる感じです。

やり方

昔の(もう15年以上前かぁ、、、)受験勉強のやり方を思い出しつつ、大人の知識を加えてこのやり方にしてみました。

  1. 本番想定の時間を測りながら解く
  2. 機械的に答え合わせ
  3. 時間気にせずもう1回解いてから解説を理解する
    • 間違った理由をメモ
    • わからなかった単語をメモ
  4. 3を参考に、対策を考える
  5. 対策する
  6. 1〜5を繰り返す

解答とかメモはGoogleスプレッドシートで管理しています。 仕事するようになって身につけたやつですねw

f:id:moyashidaisuke:20180729191153p:plain

知らない単語はいい感じのマイ単語帳にしようと思っていますが、まだ未着手。

結果

全体

- listening reading 合計
min 260 295 555
max 335 385 720

全部で200問で990点満点なので、単純計算だと1問あたり5点なのですが、問題によって加重が違うらしく、実際には1問5点になりません。 なので、公式の問題集でも正解数によって、何点〜何点くらいですね、という結果になります。

900点を目指しているので、listeningとreadingそれぞれで450点が目標の目安になります。

パート毎の正解率

Part 問題数 正解数 正解率 課題
1 6 6 100.00%
2 25 14 56.00% 最初の単語が聞き取れない。where'd とかの省略形が聞き取れない。
3 39 24 61.54% 知らない単語がまあまあある。単語がつながると聞き取れない。
4 30 17 56.67% 知らない単語がまあまあある。単語がつながると聞き取れない。
5 30 22 73.33% 文法は大体大丈夫。単語がだめ。
6 16 11 68.75% よく考えればわかるはずだったが、、、問題の慣れ?時間?
7 54 40 74.07% 知らない単語を前後の文脈から推測しているので時間がかかるし、集中力が切れてしまっている。10問は時間切れ。

Part1〜4がlistening、5〜7がreadingです。

振り返り

全体

  • 思ったよりは点数が良かった
  • listeningの方が良くないのも想定通り
  • 最後の方は時間が足りなくなった(10問くらい)

できてる事

  • 文法 -> 大学受験の知識で大丈夫
  • 文脈の理解 -> stack over flowとかGitHubのissueが理解できれば大丈夫そう

課題

知らない単語

listeningもreadingも明らかに足りないです。 単語が知らないために間違えた問題が、listeningで20問、readingが10問くらい。

readingで時間が足りない原因の一つが単語の知識量不足(わからない単語を前後の文脈から推測してるので時間がかかる)なので、これも含めるとreadingは20問。

単語は読めるけど聞き取れない

10問くらい。 tour -> ツアーじゃなくてトゥアー みたいなやつ。

単語がつながると聞き取れない

check it out -> ちぇけらー みたいなやつです。

5問くらいだけど、全体的にきつい。

まともに頭に残ってる発音なんて、高校の時の先生のカタカナ英語だけなんで、さっぱりでした、、 読めばわかるけど、全然聞き取れない、、、

受験英語に出てこない言い回し

Where'd とか should you have any questions〜 とか。 全体で5問くらい。

まとめ

  • まずは単語(リスニングも含めて)
  • 単語つながると聞き取れない問題は別途対策が必要

おまけ

エンジニアなら知ってる単語(function, submitとか)がけっこうあるので、エンジニアという仕事は英語を習得するのに有利な仕事だと思いました。 良く考えたら、日本語で仕事してるのに英語の事を一番考えてる職業なんじゃないかと。この機能の名前何にしよう(できれば英語で)とか、いつも考えますよね。

typoするとエディターが勝手に知らせてくれるし。

社会人になって10年だけど今から英語の勉強をする事にした

英語を勉強する事にしました。

最終目標

  • 海外でエンジニアの仕事ができるくらいになる

きっかけ、モチベーション

仕事で

前から必要だよな〜とは思っていたものの、必要性を感じる事が多くなってました。

  • 英語を使えるか使えないかで、情報の鮮度が全然違う
    • ITの世界は日進月歩 && 中心は英語なので(最近中国語が増えてきましたが)、日本語情報だけだと一歩遅れる
      • 英語でバズってる有名なエンジニアの記事
      • 英語のマニュアル
      • 英語の技術書
  • 英語を使えないと、コミュニケーションが取れなくて不便な場面が多くなってきた
    • ライブラリの使い方をコミュニティ(英語)に質問する
    • ライブラリがバグってるのはわかってるし、直し方もわかるのに、issueとPRでどう伝えればいいかわからない

プライベートで

  • 旅行好きなので、海外でも快適に旅行したい

勉強の進め方とか

まずはTOEIC900点目指すよ

社会人で英語勉強するならまずはTOEICでしょ、という固定概念があるのは否めないですが、とりあえずTOEICやろうと思います。 TOEIC的には900点超えれば最高峰らしいので、せっかくなのでここまで目指します。 800点超えたら、ぼちぼちスピーキングの勉強もしますが、それまではTOEICだけで。

enjoylifeinenglish.blog112.fc2.com

良い(と思う)ところ

  • 成果が数字で出る
    • 数字の目標設定を置きやすい
  • 情報が多い
    • 勉強の仕方
    • 書籍
    • スクール
  • 国内では資格としての強さがある
  • 個人的に試験は得意
  • スピーキングの勉強するにしても最低限の色々(単語とか)は知ってないと効率悪そうなので

よくない(と思う)ところ

  • 話す能力が求められない
  • 試験なのでテクニックでカバーできてしまう
  • ITの専門用語は出てこない

今どれくらい?

  • TOEIC受けたこと無い
  • 大学受験の時に勉強した
    • なので文法は大丈夫だと思う
    • リスニングは無かったのでできない
    • スピーキングもできない
  • 仕事で英語のマニュアルを読んだりはする
    • google翻訳無くてもITの事ならなんとなくわかる

試験申し込んだ

試験として考えると、まずは自分の位置を把握しないと対策も何もできないので、とりあえず試験を申し込みました。

www.iibc-global.org

(この記事を書いていたタイミングでは)次回の実施は9/9で、結果がわかるのが10/9。けっこう先ですね、、、 というか、今年は後3回しか無いのか、、、

※ 記事公開前に見直したら次の会(10/28)が申し込み可能になっていたので、そちらにも申し込みました

勉強のコントロール

むかーし一瞬だけ登録して放置してたStudyPlusに、記録を付けていこうと思います。

english-seeker.com

細かい目標とか参考書選びはこれから考えます。

はてなブログ「Material」テーマのカスタマイズ

前回はMaterialテーマを設定しました。

moyashidaisuke.hatenablog.com

数ヶ月たっていくつか気になるところが出てきたので、色々カスタマイズします。

headingタグ(h1、h2とか。見出しタグ)

before

f:id:moyashidaisuke:20180718202115p:plain

h1とh2とh3がほぼ同じ見た目なので、記事のブロックがわかりにくいです。 こういう事です。私にはほぼ同じに見えます。

after

f:id:moyashidaisuke:20180718214003p:plain

かっこよくなりました。

やったこと

fontawesomeの設定

www.marorika.com

これだけでは見た目変わりませんが、この後使います。

cssの設定

hitsuzi.hatenablog.com

こちらの「みだし3種」を参考にいれました。

コードはこちらです。 - h1〜h3を対象に変光 - 色の変更(テーマカラーに合わせています) - 文字サイズをいい感じに調整 - marginとかpaddingをいい感じに調整

.entry-content h1 {
  padding: 4px 10px;
  background: #f3f3f3;
  border-left: 8px solid #3F51B5;
  margin:80px 0 30px 0;
  font-size: 180%;
}
.entry-content h2 {
  position: relative;
  border-bottom: 4px solid #f3f3f3;
  padding: 3px 10px;
  margin:40px 0 30px 0;
  font-size: 140%;
}
  
.entry-content h2::before {
  position: absolute;
  top: 100%;
  left: 0;
  width: 20%;
  height: 4px;
  background:#3F51B5;
  z-index: 2;
  content: '';
}
.entry-content h3 {
  position: relative;
  padding-left: 1.2em;
  line-height: 1.4;
  margin:30px 0 8px 0;
  font-size: 130%;
}
.entry-content h3:before{
  font-family: Font Awesome\ 5 Free;
  /*アイコンユニコード*/
  content: "\f00c";
  /*アイコン色*/
  color: #000; 
  position: absolute;
  font-size: 1em;
  left: 0;
  top: 0;
}

これを、「デザイン」->「カスタマイズ」->「デザインcss」に追記しています。(追記じゃないと以前の変更が消えちゃうので追記です)

本文の調整

本文って言っているのは、h1とかじゃないところです。ここみたいなメインの文章ですね。

headingタグをいい感じにした結果、本文が - 左に寄りすぎている - 行ごとの隙間がせまい

と思ったので調整します。

before

f:id:moyashidaisuke:20180718215050p:plain

after

f:id:moyashidaisuke:20180718215544p:plain

すきまが多くなって見やすくなったと思います。

やったこと

.entry-content p{
  margin:0 1em 1.5em 1em;
  line-height: 27px;
}

これをさっきと同じく、「デザイン」->「カスタマイズ」->「デザインcss」に追記しています。

font変える

before

f:id:moyashidaisuke:20180719231259p:plain

after

f:id:moyashidaisuke:20180719231715p:plain

やったこと

body {
    font-family: "メイリオ", Meiryo;
    color: #555555
}

フォントの変更と、ちょっと色が薄すぎるな、と思ったので色の調整です。

これもさっきと同じく、「デザイン」->「カスタマイズ」->「デザインcss」に追記しています。

SNSボタンかっこよく

before

f:id:moyashidaisuke:20180719234552p:plain

after

f:id:moyashidaisuke:20180719234604p:plain

やったこと

Materialテーマの作者さんの紹介記事そのままです。

webgaku.hateblo.jp

最終的なデザインCSS

/* <system section="theme" selected="8454420450093337097"> */
@import url("https://blog.hatena.ne.jp/-/theme/8454420450093337097.css");
/* </system> */


/* 2カラムレイアウト */
#container #content {
  width: 1160px;
}
#main {
  width: 800px;
  float: left;
}
#box2 {
  width: 300px;
  padding: 24px;
  float: right;
  margin-top: 0;
  margin-bottom: 60px;
  background-color: #fff;
  box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.26);
  border-radius: 2px;
  -webkit-animation-duration: 0.4s;
  -webkit-animation-duration: 0.4s;
  -webkit-animation-fill-mode: both;
  -webkit-animation-fill-mode: both;
  -webkit-animation-name: slideRight;
  -webkit-animation-name: slideRight;
  -webkit-animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  -webkit-animation-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
  position: relative;
}
@-webkit-keyframes slideRight {
  0% {
    -webkit-transform: translateX(6.25em);
    transform: translateX(6.25em);
  }
  100% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
  }
}
@keyframes slideRight {
  0% {
    -webkit-transform: translateX(6.25em);
    transform: translateX(6.25em);
  }
  100% {
    -webkit-transform: translateX(0);
    transform: translateX(0);
  }
}
#box2-inner {
  width: auto;
}
.hatena-module {
  text-align: left;
  padding-right: 0;
  width: 300px;
  float: left;
}
@media (max-width: 1024px) {
  #container #content {
    width: 95%;
  }
  #main, #box2, .hatena-module {
    width: 100%;
    float: none;
  }
  #box2 {
    padding: 0;
    background-color: transparent;
    box-shadow: none;
    border-radius: initial;
    -webkit-animation-duration: initial;
    -webkit-animation-duration: initial;
    -webkit-animation-fill-mode: none;
    -webkit-animation-fill-mode: none;
    -webkit-animation-name: initial;
    -webkit-animation-name: initial;
    -webkit-animation-timing-function: initial;
    -webkit-animation-timing-function: initial;
  }
}

/* Responsive: yes */


.entry-content h1 {
  padding: 4px 10px;
  background: #f3f3f3;
  border-left: 8px solid #3F51B5;
  margin:80px 0 30px 0;
  font-size: 180%;
}
.entry-content h2 {
  position: relative;
  border-bottom: 4px solid #f3f3f3;
  padding: 3px 10px;
  margin:40px 0 30px 0;
  font-size: 140%;
}
  
.entry-content h2::before {
  position: absolute;
  top: 100%;
  left: 0;
  width: 20%;
  height: 4px;
  background:#3F51B5;
  z-index: 2;
  content: '';
}
.entry-content h3 {
  position: relative;
  padding-left: 1.2em;
  line-height: 1.4;
  margin:30px 0 8px 0;
  font-size: 130%;
}
.entry-content h3:before{
  font-family: Font Awesome\ 5 Free;
  /*アイコンユニコード*/
  content: "\f00c";
  /*アイコン色*/
  color: #000; 
  position: absolute;
  font-size: 1em;
  left: 0;
  top: 0;
}

.entry-content p{
  margin:0 1em 1.5em 1em;
  line-height: 27px;
}


body {
    font-family: "メイリオ", Meiryo;
    color: #555555
}




.sns-header, .sns-footer {
    padding: 0 24px;
}

.sns-area {
    margin: 30px auto 10px;
    padding: 0;
    overflow: hidden;
    table-layout: fixed;
    display: table;
    width: 100%;
}

.sns-area li {
    list-style-type: none;
    display: table-cell;
    vertical-align: middle;
}

.sns-area li:last-child {
    margin-right: 0
}

.sns-link {
    position: relative;
    display: block;
    color: #fff;
    text-align: center;
    text-decoration: none;
    outline: none;
    overflow: hidden;
    height: 42px;
    line-height: 42px;
}

.sns-link::after {
    position: absolute;
    top: 50%;
    left: 50%;
    z-index: 2;
    display: block;
    content: '';
    width: 0;
    height: 0;
    background-color: rgba(255,255,255,.3);
    border-radius: 50%;
    -webkit-transform: translate(-50%, -50%);
    transform: translate(-50%, -50%);
    opacity: 0;
}

.sns-link:hover {
    text-decoration: none;
}

.sns-link:hover::after {
    -webkit-animation: circle .75s;
    animation: circle .75s;
}
@-webkit-keyframes circle {
    50% {
        opacity: 1;
    }
    100% {
        width: 300px;
        height: 300px;
    }
}
@keyframes circle {
    50% {
        opacity: 1;
    }
    100% {
        width: 300px;
        height: 300px;
    }
}

.sns-twitter {
    background: #55acee;
}

.sns-facebook {
    background: #3a5795;
}

.sns-bookmark {
    background: #00A5DE;
}

.sns-pocket {
    background: #ED4055;
}

.blogicon-twitter,
.blogicon-facebook,
.blogicon-bookmark,
.blogicon-chevron-down {
    margin-right: 5px;
}

@media only screen and (max-width: 767px) {
    .sns-txt {
       display: none;
    }
   .blogicon-twitter,
   .blogicon-facebook,
   .blogicon-bookmark,
   .blogicon-chevron-down {
       margin-right: 0;
   }
}


/* 読者になる */
.hatena-follow-button {
  color: #fff !important;
  background: #4eacd1!important;
}

だんだん大げさになってきて、管理が大変そうになってきました、、、

Unityのビルドでエラー「com.android.dex.DexException: Multiple dex files define」

とあるassetを追加後に発生。

CommandInvokationFailure: Gradle build failed. 
/Library/Java/JavaVirtualMachines/jdk1.8.0_121.jdk/Contents/Home/bin/java -classpath "/Applications/Unity5.6/PlaybackEngines/AndroidPlayer/Tools/gradle/lib/gradle-launcher-2.14.jar" org.gradle.launcher.GradleMain "assembleDebug"

stderr[

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':transformClassesWithDexForDebug'.
> com.android.build.api.transform.TransformException: com.android.ide.common.process.ProcessException: java.util.concurrent.ExecutionException: com.android.dex.DexException: Multiple dex files define Lcom/google/android/gms/actions/ItemListIntents;

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
]
stdout[
Incremental java compilation is an incubating feature.
:preBuild UP-TO-DATE
:preDebugBuild UP-TO-DATE
:checkDebugManifest

〜省略〜

BUILD FAILED

Total time: 1 mins 14.779 secs
]
exit code: 1
UnityEditor.Android.Command.Run (System.Diagnostics.ProcessStartInfo psi, UnityEditor.Android.WaitingForProcessToExit waitingForProcessToExit, System.String errorMsg)
UnityEditor.Android.GradleWrapper.RunJava (System.String args, System.String workingdir, UnityEditor.Android.Progress progress)
Rethrow as GradleInvokationException: Gradle build failed
UnityEditor.Android.GradleWrapper.RunJava (System.String args, System.String workingdir, UnityEditor.Android.Progress progress)
UnityEditor.Android.GradleWrapper.Run (System.String workingdir, System.String task, UnityEditor.Android.Progress progress)
UnityEditor.Android.PostProcessor.Tasks.BuildGradleProject.Execute (UnityEditor.Android.PostProcessor.PostProcessorContext context)
UnityEditor.Android.PostProcessor.PostProcessRunner.RunAllTasks (UnityEditor.Android.PostProcessor.PostProcessorContext context)
UnityEditor.HostView:OnGUI()

原因はjarなり、aarなりが重複している事。 追加されたファイルを確認し、似たような名前のjarやaarが無いか確認。 合った場合、バージョンが古い方を削除すればOK。

例のごとく、assetにplay-store系のjarやaarが直接含まれている場合に起こりがちなエラー。

今回は、以下の2つが重複していました。

play-services-basement-11.0.4.aar com.google.android.gms.play-services-basement-15.0.1

「play-services-basement-11.0.4.aar」を削除すればOK。

UnityのiPhoneX対応で苦労したポイントメモ

当時のログがあまり残ってないのもあって、不完全ですが、メモという事でご容赦ください。

やるべき事(ざっくり)

Submitting iOS apps to the App Store - Apple Developer

moyashidaisuke.hatenablog.com

  1. iOS 11 SDKでビルドする
  2. iPhoneXのSupreRetinaディスプレイに対応する

iOS 11 SDKでビルドする

必要要件の確認

iOS 11 SDKでビルドするためには、XCodeの9以上にする必要があります。

qiita.com

そして、XCodeの9.0〜9.2まではSierra、9.3以降はHighSierraに更新する必要があります。(9.2でSierraという組み合わせも考えられなくは無いですが、敢えて古いバージョンを使う理由がなければ、この際最新にした方が良いと思います。)

そして、HighSierraにするには、Unityのバージョンが問題になる事があります。

helpdesk.unity3d.co.jp

最低でもUnity 5.5.4p5 以上が必須になります。

必要要件まとめ

  • iOS 11 SDK
  • XCodeの9以上
  • HighSierra
  • Unity 5.5.4p以上

はい、明らかに大変そうな予感がぷんぷんします。 特にしんどそうなのが、Unityのバージョンアップが必要な場合です。

変更前 * iOS 11 SDK * XCodeの9.3 * HighSierra * Unity 5.6.

にを採用する事にしました。 Unityが5.6系なのは2017系だと更新が激しすぎてしんどそうだったためです。 5.5系よりは寿命が長そうとの判断もあります。(5.X系の最新なので)

もろもろバージョンアップ

OSのアップデート

普通にやればOK

XCodeのアップデート

普通にやればOK

ビルドで失敗する、、、(iOS) podが壊れてるっぽいエラーが出てたので最新化したら通りました。 https://qiita.com/Yuta/items/a20f4ea3207635b4ef9e

Unityのアップデート

インストールまでは普通にやればOK。 基本的には既存のUnityとは別でインストールする事をおすすめしますが、今回はHighSierraにした時点で過去のUnityが使い物にならなくなるので、上書きでも良いと思います。

コンパイルエラー潰す

gettype使えない対応 http://tsubakit1.hateblo.jp/entry/2016/11/25/235315#Unity-55%E4%BB%A5%E9%99%8D%E3%81%AE%E5%A0%B4%E5%90%88

targetSDKVersionはどちらにしろあげないといけないので、全て26に統一しました。

iPhoneXのSupreRetinaディスプレイに対応する

自分で書いたアプリのディスプレイ対応

Unity公式のを参考に

chocolattips.hatenablog.com

外部ライブラリ対応

あと、外部ライブラリを使っている場合、ライブラリの更新が必要になるケースが多いです。(広告とか)

これがまた大変です、、、

Unityのライブラリはunitypackageという、関連ファイルをまとめたものを展開する方式が一般的ですが、これは上書き機能しかありません。

Aというファイルが、新しいsdkでAというファイルのまま更新される分には問題ないですが、AというファイルがBというファイルにリネームされた(ディレクトリ構造が変わった場合含む)場合、sdkを更新してもAというファイルは残り続けます。 古いファイルが残っていると、大体コンパイルエラーで動かなくなります。

なので、sdkを更新する前に、古いsdkのファイル郡を一旦削除する、という手順を踏む事になりますが、そもそもどれかunitypackageから展開されたものなのか、という関連性はどこにも残っていません。 バージョン管理しているのであればその履歴から、ディレクトリにまとまっているものであればディレクトリ単位で削除、といった手段が考えられますが、これも問題があります。

削除してくれるAssetもあったようですが、今見たら入手不可能になっていました、、

baba-s.hatenablog.com

中にはお作法が悪くて、ディレクトリがまとまってないものが存在したり、インポートした後に、手動でマージ(AndroidManifest等)を強制されるライブラリもあったりするので、試行錯誤して消すしかありません。 AndroidManifestといえば、一生懸命書いた既存のAndroidManifestを無慈悲に上書きしようとしてくるやつもいるので注意が必要です。

また、native系のファイル(jarとか)も同じようなもので、昔のやつだとplaysotre系のjarとかaarが直接unitypackageに含まれていて、それが別のライブラリに含まれているバージョンと競合したりします。

unitypackageとのひもづけをproject上に残しておいて、一括で削除する機能、公式でください、、、

Android64k問題

trouble writing output: Too many field references to fit in one dex file: 92846; max is 65536.

qiita.com

sdkを更新したらなぜか死ぬほど増えた。

MultiDexビルドも頑張ってやったけどアプリが安定せず、困ったな〜と思ってたら、5.6で追加されたgradleでのビルドにしたらあっさり通った。

docs.unity3d.com

特に Unity では、DEX (Dalvik Executable 形式) ファイルのメソッド参照数が減少します。つまり、DEX 制限問題に遭遇する可能性は低くなります。

特にカスタムすることなく、デフォルト設定であっけなく動いた、、、

UnityでAndroid64k問題にぶちあたった場合は、是非試してみてください。

感想

iPhoneX対応うんぬんより、unitypackageの更新しんどい問題が一番やばかった、、、

UnityでAndroid O向けに通知をする

概要

Android O では通知にChannel(チャンネル)という概念が導入されています。

Android O というのはAndroid8系の事で、APIバージョン26でAndroidManifestで言う所のtargetSdkVersion=26の事です。

で、Channelというのは通知をグルーピングして設定を変えたりできる類のものなのですが、Android O ではこの新機能のChannelを使う事が必須になっています。

使わない結果は↓の通りです。 チャンネルが無いよ(No Channel found)ってエラーが出ます。

07-08 13:28:25.682 1152-2944/? E/NotificationService: No Channel found for pkg=com.XXXXX.XXXXXXX, channelId=null, id=560, tag=null, opPkg=com.XXXXXX.XXXXXX, callingUid=10219, userId=0, incomingUserId=0, notificationUid=10219, notification=Notification(channel=null pri=0 contentView=null vibrate=[250,500,250,500] sound=android.resource://com.XXXXXX.XXXXXX/2131034112 defaults=0x4 flags=0x11 color=0x00000000 vis=PRIVATE)

当然Unityでも通知はAndroidの機能を使っていますので影響がありますので、既存アプリで通知機能があるアプリは更新が必要です。

対応案

案1:targetSdkVersionを25以下にする

急場はしのげるかもしれませんが、2018年の後半にはtargetSdkVersion=26以上がアプリの更新に必要となりますので、おすすめできません。 www.telemarks.co.jp

案2:自前で実装する

Androidのネイティブ処理詳しい方はどうぞ。 公式にサンプルコードがあります。

Notifications Overview  |  Android Developers

案3:Assetを使う

AssetStoreで通知(Notification)で検索すると、Assetがけっこうな数ヒットします。 Asset Store

ここで気をつけなければいけないのが、「Android Oに対応してる」「Channelに対応している」と明記されているかどうかです。

f:id:moyashidaisuke:20180713013615p:plain

こんな感じで書いてあれば多分大丈夫。更新が2017年の8月より昔のもの(まだAndroid Oが出ていない)や、明記されてないものは動かない可能性が高いです。

今回はこれを使ってみましたが、どれもそんなに変わらないと思います。

Android Local Notification Plugin - Asset Store

実装例

初期処理

private const string ANDROID_CHANNEL_ID = "channel1";

void Start(){
       #if UNITY_EDITOR
        // nothing
       #elif UNITY_IOS

       #elif UNITY_ANDROID
        LocalNotificationUnity.CreateChannel(ANDROID_CHANNEL_ID, Define.APP_TITLE, Define.APP_TITLE, NotificationImportance.HIGH, true, true, "soundName", NotificationSoundContentType.UNKNOWN);
       #endif
    }

割と適当ですが、こんな感じで最初に起動する処理のStart() あたりでChannelを作ってあげましょう。 Channelを複数作って〜という事であればもっと複雑になりますが、とりあえず通知したいだけならこれで十分。 通知の時の音とかもこのタイミングで指定するようです。

通知処理

public static void SetAndroidLocalNotification(int id, int sec, string body){
       #if UNITY_EDITOR
        Debug.Log("localnotify " + body);
       #elif UNITY_ANDROID

        DateTime now = DateTime.Now;
        TimeSpan secTS = new TimeSpan(0, 0, sec);
        LocalNotificationUnity.SendNotification(ANDROID_CHANNEL_ID, Define.APP_TITLE, body, now.Add(secTS), id);

       #endif
    }

このAssetはDatetimeを引数に取るタイプだったので、使いやすいようにラップする関数を適当に作ります。 通知するChanelも一緒に指定しますが、今回は1Channelしかないので固定値でOK。

つぶやき

  • iOSはUnityの組み込み処理で通知ができるのになぜAndroidは無いのか
  • このAssetは全部キャンセル処理がなぜか無かったです、、、
  • Channel必須にしなくてもいいのになぁ、、、