Hatena::ブログ(Diary)

hishidaのblog このページをアンテナに追加 RSSフィード

プロフィール

hishida

hishida

EB series support page 管理人 ブログ

2016-12-28

[] 読書尚友のSDカード対応他

以前、Nexus5が故障してASUS Zenfone 3 Laser を購入した顛末を書いた。

Nexus 5 恐怖の無限ループからの脱出 - hishidaのblog

性能的には3年前のNexus 5 と際立った違いはない気もするが、Zenfone 3 Laserに変えて良かったことの一つは、外部Micro SDカードが使えるようになったことである。Nexus5 では外部SDカードによる拡張ができなかったので、拙作の読書尚友でも外部SD青空文庫データを置くことができなかった(ということに作者が気づかなかった)。予定外の出費だったが、外部SDカードに対応できるようになったという意味では怪我の功名だったと思う。

Androidでの外部ストレージの扱いはAPIバージョンごとに変遷がある。古き良き時代はWRITE_EXTERNAL_STORAGEのパーミッションがあれば外部ストレージのどこにでも読み書きができた。ところが、kitkat Android4.4以降、外部SDカードへの書き込みが制限されるようになり、Storage Access Frameworkを使わないとSDカードにアクセスできなくなった。これは通常のファイルアクセスのAPIと異なるのが問題で、内部ストレージと同様に透過的にアクセスできないと、アプリが複雑になってしまう。

実は簡単な解決策があった。外部ストレージのパスの取得にgetExternalFilesDirを使うと、<外部ストレージのルート>/Android/data/<パッケージ名>/filesというアプリ専用のフォルダが作成される。(ここで「外部ストレージ」というのは実は外部SDカードのことではなく、内蔵メモリなのでややこしい。)

ここで外部SDカードをマウントしていた場合、外部SDカードのルート下にも同時に/Android/data/<パッケージ名>/filesが自動的に作られる。この領域は外部SDカードであっても、アプリから読み書きが許されている。簡単なことだが、Nexus5ではSDカードを拡張できないので、この挙動がわからなかった。

今回、読書尚友のデータ保存先を外部SDカードAndroid/data/<パッケージ名>/filesに変更できるようにした。これで、メモリの少ない端末の場合、青空文庫全データをSDカードに逃がせるようになった。

2016-12-23

[] 僕は明日、昨日の君とデートする

青春恋愛映画の名手といわれる、三木孝浩監督の最新作。この監督のすべての作品を見たわけではないが、『陽だまりの彼女』『くちびるに歌を』は特にお気に入りである。今年は『青空エール』とこの2作品が公開され、三木監督ファンとしてはうれしい限りだ。

美大生の主人公は通学電車で出会った初対面の彼女に一目惚れする。とんとん拍子に理想的な恋人同士になるが、彼女には秘密があり、なぜか彼の未来を知っているようだった‥

ファンタジー色の強い作品で、ネタバレすると、彼女は平行世界からきた別の世界の住人であり、5年ごとに40日しか滞在できないというルールがある。二つの世界はそっくりだが、時間の流れが反対であり、彼が5歳の時彼女は35歳、彼が10歳の時彼女は30歳、彼が15歳の時彼女は25歳‥という関係になっている。二人が同じ20歳で会えるのは、現在の40日しかない。物語を成り立たせる舞台装置を理解すると、この40日の物語がとてもせつなく、貴重で愛おしいものに見えてくる。

時間の流れが逆なら会話も全て逆回しになるはずじゃないかとか、SF的考証がどうとかは、ファンタジーだから棚上げしていい。たぶん二つの地球は公転が逆で自転方向が同じということにしておこう。素直に感動できる良作に仕上がっていた。

原作者はいわゆるライトノベル出身だが、作者自身の経験や年輪が加わってくると、純文学や文芸作品との差はなくなってくる。むしろ現代では、漫画原作やライトノベルの作者のなかに、昔であれば文豪になったような才能が集まっているのかもしれない、と感じた。

2016-12-19

[]格安Windows 10 mobile 端末購入

NTT-X Storeで格安のWindows 10 mobile端末を購入してしまった(WPJ40-10 4,980円)

どうせ使い物にならないことはわかっているが、貴重な開発用実機が入手できたのは吉。4万円台の高級機を買っても、Windows 10 mobileが使えない端末であることは全く同様だ。これでもOffice mobileや音楽プレーヤ、FMラジオ等は即使用可能なので、値段分の値打ちはある。

Windows mobileの出荷ベースのシェアは既に1%を割っており、いまからWindows mobile用のアプリを作る意味はほとんどない。

鈴木淳也の「Windowsフロントライン」:失速するWindows 10 Mobileは生き残れるのか? (1/2) - ITmedia PC USER

それにもかかわらずWindows 10 mobile端末を買ったのは、EBPocket のWindows mobile版を提供していないことに、個人的に引け目があるからだ。

以前EBPocket for WinRT版を出したことがあるが、その頃はWindows Phone 8端末は国内では発売されていなかったため、Windows デスクトップ版のみサポートしていた。その後サポートが続かず、現在ではストアから削除されている。

EBPocket for WinRT

とはいってもストアアプリは色々と制限が厳しくて思うようなアプリを作れないので、EBPocket for Windows Phoneの提供を約束出来るかどうかわからない。だが、少しずつ検討を始めようと思う。

まず第1週は、Visual Studio 2015でサンプルアプリを作り、実機に転送して実行するところまではできた。MacVMWare 上のWindows10でWndows Phoneエミュレータを使用するのは難しいので、実機があると捗る。

ストアアプリEPWINGビューアがなぜ難しいか

「ストアアプリの制限」というのは、アプリがアクセスできる場所が厳密にサンドボックスに限られており、SDカードやドキュメントフォルダへのアクセスが、原則禁止されているということである。EPWINGは辞書データがアプリと独立していることが最大のメリットだが、ストアアプリとは相性が悪い。

例外はあって、ファイルピッカーで選択する場合は自由選択できる。また、SDカードやドキュメントフォルダは、マニフェスト拡張子を登録すると使用出来る。ただ、EPWINGのファイル名には拡張子がないので、マニフェストに登録ができない!(CATALOGやHONMONなど)。

回避方法として3つぐらい案がある:

1) ファイルピッカーでEPWING辞書を選択させ、サンドボックスにコピーする。以前EBPocket for WinRTではこの方法を使った。だがSDカードでの運用ができないので、実用性が低い。

2) ドキュメントフォルダよりも制限の低いピクチャフォルダやミュージックフォルダに辞書を配置する。ただし、Microsoftの審査を通るかどうかが不透明

3) 必ずebzip圧縮することとし、拡張子.ebzをマニフェストに記載する。ただユーザに「ebzip圧縮しないと使えないよ」ということを説明しないといけない。

どれも一長一短あって、この時点で開発意欲が50%ぐらいなくなる。

UWPの悩み

それから、現在Windows 10 mobile向けアプリを作るとした場合、UWPとWindows 8.1ユニバーサルアプリ選択肢がある。MicrosoftのオススメはUWPだ。だがUWPはアプリテンプレートが空白しかなく、自分で実装する作業量が大きい。Windows 8.1ユニバーサルアプリだと、テンプレートに「ハブアプリ」があり、テンプレートをもとに逐次的に開発していくことができる。したがって、もし開発を始めるとしたら、Windows 8.1ユニバーサルアプリを選ぶと思う。

以前に提供したEBPocket for WinRTは、実はWindows8アプリで、テンプレートの内容がWindows 8.1アプリとは大きく違うために、ソースを流用できない。新たにコードを書いたほうが早い。開発のスタートが半年遅れていれば、Windows8.1アプリになって現在でも通用したのに、残念だ。いろいろ考えると、作業量の大きさに比べて、ユーザ数が少なすぎて、開発意欲が萎えてくる。

最近Microsoftクアルコムと提携してsnapdragonWindows10を提供することを発表したが、これはUWPをMicrosoft自身が否定したことになる。WindowsRTが打ち切られたように、Windows 10 mobileも終了になる可能性はある。

マイクロソフトがARM向けWindows 10の構想を発表--Win32アプリも動作 - ZDNet Japan

ということで、あまり期待はしないで、生暖かく見守っていただければ幸い。

2016-12-06

[]Nexus 5 恐怖の無限ループからの脱出

数ヶ月前からNexus5 の挙動がおかしくなり、勝手に再起動する現象がたまに起きていた。だましだまし使っていたが、ついに起動時に無限ループが起きるようになった。起動時のGoogle のロゴが表示されたところで再起動し、これが無限に繰り返される。電源と音量ボタンを同時に押してもダメ。万事休すだ。

この症状はNexus5では割と有名らしい。原因については諸説あり、Android6.0.1にファームアップした機種で起きやすいとか、バッテリが劣化すると起きるとか、電源スイッチの接触不良とか、いろいろと言われている。

スマホがないと仕事に差し支えるので、しかたなくBic cameraに駆け込んで、発売されたばかりの ASUS Zenfone 3 laserを衝動買いしてしまった。これ自体は非常によい機種だが、ポイントが1%しかつかないので、あまり賢くない買い方をしたかもしれない。少なくともASUSのサイトから購入すれば、純正ケースがもらえたらしい。P9 liteのほうが安価だが、Nexus 5から移行するためにはmicro SIMからnano SIMに交換しないといけない。Zenfone 3 laser はmicro SIMとnano SIMの両方に対応しているので(ただしダブル待受はできないが)、Nexus 5のmicro SIMをそのまま差し替えられる。

さてNexus5の方だが、発売当初に購入したのですでに3年は経っており、バッテリが劣化している可能性は高い。そこで自分でバッテリを交換してみる事にした。Nexus5 の純正バッテリを入手することはできないが、Amazonで互換バッテリを簡単に入手できる。交換にはコテやY字ドライバが必要らしいので、工具と一緒になったセットを買ってみた。

(細かな手順は写真付きの親切なサイトがたくさんあるので省略するが)イヤホンのあたりからコテを差し込んで裏蓋を剥がし、Y字ドライバでネジを6本外し、コネクタを外して、やっとバッテリを外せる。バッテリは超強力な糊で固定されており、壊すのではないかとヒヤヒヤした。

なんとかバッテリ交換して起動してみたが、起動無限ループの症状はまったく同じだった。うーん、バッテリではなかったのか。

あらためて検索してみると、「起動時に電源スイッチを連打する」と直ったという事例がたくさん報告されている。半信半疑で電源スイッチを押してみること10分、なんと起動したではないか!

一度起動すれば、あとは何事もなかったかのように使用出来る。ひょっとしたらバッテリ交換は必要なかったかもしれない。だが3年も使用すれば確実に劣化しているはずなので、ちょうど替え時だったと思う。

Zenfone 3 laserも Nexus5 と同じく Android 6.0.1だが、新しい機種なので、きっとAndroid 7.0のアップデートがくると信じている(アナウンスはされていないが)。

Nexus 5Android 6.0.1の実証機として、動態保存する予定である。

2016-12-01

[][][]EBWin4 の高DPI化について

EBWin4の高DPI化を行ったので、忘備録として作業内容をまとめておこうと思う。

事の発端は、Macbook pro retina 13" Early2015を購入したこと(2016-11-19 - hishidaのblog)。retinaディスプレイではVMWare Fusion上のWindowsの文字が極端に小さくなり、文字サイズを拡大しないと使用できなくなった。

Macbook pro retina 13"の実解像度は2560x1600だが、Mac OS Xでは擬似解像度1280x800にスケーリングされて表示される。だがVMWare 上のWindowsではドットバイドットで表示されるので、2560x1600の実解像度のまま表示され、文字が小さくなってしまう。

ディスプレイ設定」→「テキスト、アプリ、その他の項目のサイズを変更する:」で150%〜200%に拡大すると、DPIのスケーリングに従ってアプリも拡大されて表示される。だがEBWin4のように高DPIに対応していないアプリだと、下図のように文字がにじんで表示されてしまう。Surface Proなどの高解像度の端末では、以前から問題になっていたと思う。

図:高DPIに対応していない場合、文字サイズを拡大するとにじんで表示される:

f:id:hishida:20161202110628p:image

Windows Form アプリの高DPI化作業について

DPI化全般については、下記のマイクロソフト田中達彦氏のブログが詳しい。

アプリの高DPI(High DPI)対応について 第1回 ~ 高DPIとは ~ – 田中達彦のブログ

WPFで開発したソフトは自動的にdpiAwareになるが、昔ながらのWindows Formで開発したソフトは、デフォルトでは高DPIに非対応となる。

Windwos FormでアプリをdpiAwareにする方法は簡単で、前述のブログにあるように、app.manifestを追加してdpiAwareをtrueにすればいい。

app.manifestは、Visual Studio でプロジェクトで右クリック→追加(D)→新規項目(W)で簡単に追加できる。

ただしdpiAwareの雛型が作られるのはVisual Studio 2013以降なので(現行のVisual Studio Community 2015もOK)、Visual Studio 2010以前のバージョンを使用している場合は、記述を手動で追加する必要がある。

app.manifestに追加した記述:

  <application xmlns="urn:schemas-microsoft-com:asm.v3">
    <windowsSettings>
      <dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
    </windowsSettings>
  </application>

基本的には、これだけでdpiAwareになり、文字サイズを拡大しても文字がにじまなくなる。

ただEBWin4の場合はEPWINGの外字をビットマップイメージで表示しており、文字サイズを変えても外字ビットマップは小さいままなので、表示のバランスが非常に悪くなる。

つまり現在のWindowsの文字サイズの倍率を取得して、ビットマップ画像も拡大しなければならない。

様々なサイトを参考にして、現在のDPIを取得するサポートクラスを追加した:(100%なら96dpiを返す)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.InteropServices;


namespace EBWin4
{
    public static class ScreenExtensions
    {
        public static void GetDpi(this System.Windows.Forms.Screen screen, DpiType dpiType, 
                   out uint dpiX, out uint dpiY)
        {
            try
            {
                var pnt = new System.Drawing.Point(screen.Bounds.Left + 1, screen.Bounds.Top + 1);
                var mon = MonitorFromPoint(pnt, 2/*MONITOR_DEFAULTTONEAREST*/);
                GetDpiForMonitor(mon, dpiType, out dpiX, out dpiY);
            }
            catch
            {
                dpiX = 96;
                dpiY = 96;
            }
        }

        //https://msdn.microsoft.com/en-us/library/windows/desktop/dd145062(v=vs.85).aspx
        [DllImport("User32.dll")]
        private static extern IntPtr MonitorFromPoint([In]System.Drawing.Point pt, [In]uint dwFlags);

        //https://msdn.microsoft.com/en-us/library/windows/desktop/dn280510(v=vs.85).aspx
        [DllImport("Shcore.dll")]
        private static extern IntPtr GetDpiForMonitor([In]IntPtr hmonitor, [In]DpiType dpiType, [Out]out uint dpiX, [Out]out uint dpiY);
    }

    //https://msdn.microsoft.com/en-us/library/windows/desktop/dn280511(v=vs.85).aspx
    public enum DpiType
    {
        Effective = 0,
        Angular = 1,
        Raw = 2,
    }
}

上記クラスを使用して、現在の文字サイズのスケールを取得する関数

        /// <summary>
        /// ScreenのDPIスケールを得る
        /// </summary>
        /// <returns></returns>
        private double GetDPIScale()
        {
            double dpiScale = 1.0;
            try {
                //  現在フォームのあるスクリーンを得る
                System.Windows.Forms.Screen s =
                    System.Windows.Forms.Screen.FromControl(this);
                uint x, y;
                s.GetDpi(DpiType.Effective, out x, out y);
                dpiScale = ( x / 96.0);
            }
            catch {
            }
            return dpiScale;
        }

DPIスケールに合わせて画像を拡大する関数

      /// <summary>
        /// DPIに応じて拡大したImage画像を作成
        /// </summary>
        /// <param name="image"></param>
        /// <param name="dpiScale"></param>
        /// <returns></returns>
        private Image GetImageStretchedDPI(Image image, double dpiScale)
        {
            Size newSize = image.Size;
            newSize.Width = (int)(newSize.Width * dpiScale);
            newSize.Height = (int)(newSize.Height * dpiScale);

            Bitmap newBitmap = new Bitmap(image, newSize);

            image.Dispose();
            return newBitmap;

        }

これで高DPIで美しく文字が表示されるようになった。

図:高DPI化されたEBWin4

f:id:hishida:20161202110623p:image

DPI時代のEPWINGビューアとして、もうしばらく延命できることとなった。