読者です 読者をやめる 読者になる 読者になる

古事連記帖

趣味のこと、技術的なこと、適当につらつら書きます。

Bluetooth で OBD2 と接続して Mikaboshi で表示したい

UWP Windows 10 Windows Phone プログラミング Advent Calendar

この記事は、Windows 10 Mobile / Windows Phone Advent Calendar 2016 の 3 日目の記事です
www.adventar.org

先日の記事で、開発・公開している Windows 10 アプリ「Mikaboshi (みかぼし)」について書きましたが、きょうは今後予定している機能のうちのひとつを、開発手法とあわせて紹介します。

Mikaboshi のダウンロードはこちらからどうぞ
www.microsoft.com


Mikaboshi は、主に車載向け (自動車・バイク・自転車など) を想定して作っていますが、GPS の情報に頼る性質上、例えば高い建物の間を移動していたり、トンネル内を移動していたりしたときは地図の更新も、推定移動速度も更新されなくなります。そんな中でも、移動速度だけは更新させたいという気持ちから、OBD2 を使った移動速度の検知を試してみました。

OBD2 とは、いわゆる「自動車の自己診断機能」のことで、本来は自動車の故障個所などを検知する目的で使われるもののようですが、その情報の中には移動速度なども含まれており、また車からの情報なので即時性・正確性が高く、これを利用したアプリや車載機器*1が多くあります。


実装するにあたり、電話で使うので Bluetooth 接続できた方がありがたいですよね。Bluetooth 接続できる OBD2 アダプターデバイスは結構多く存在します。適当に Amazon でポチポチしてもいいと思いますが、なぜか当たりはずれの大きいものばかりなので、既に Windows Phone 向けにも OBD2 を使った情報収集できるアプリ「OBD Info-san!」を開発した がんち さんが紹介している OBD II マルチメーター M-OBD-V01 が割と安定して使えるかなと思います。ほかのやつと比べるとちょっと高いですけどね。

Mikaboshi で OBD2 検知機能を実装するにあたり、がんちさんのアプリには大変お世話になりました。

Bluetoothバイスを見つけて接続する

まず Bluetooth 接続を実装する前に、Package.appxmanifest で Bluetooth を使うように宣言します。
開いて、「機能」タブから「Bluetooth」にチェックを入れてください。これでアプリで Bluetooth が使えるようになります。

次に、使える Bluetoothバイスを列挙します。何が OBD2 アダプターなのかわかりませんからね。

使えるデバイスの一覧を拾うには、 Windows.Devices.Enumeration.DeviceInformation が使えます。
こんな感じ。

using Windows.Devices.Bluetooth.Rfcomm;
using Windows.Devices.Enumeration;

public async Task<DeviceInformationCollection> GetAvailableDevicesAsync()
{
    var services = await DeviceInformation.FindAllAsync(RfcommDeviceService.GetDeviceSelector(RfcommServiceId.SerialPort));
    return services;
}

OBD2 アダプターがシリアルポートとして動くので、シリアルポートとして動くデバイスを探して列挙しておきます。

次に接続します。さきほど見つかったデバイスのうち、OBD2 アダプターデバイスを見つけておいてください*2。見つけたデバイスの DeviceInformation のインスタンスを保持しておきます。
そして接続します。こんな感じ。

using Windows.Devices.Bluetooth.Rfcomm;
using Windows.Devices.Enumeration;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;

private StreamSocket socket;
private DataWriter writer;

public async Task ConnectAsync(DeviceInformation device)
{
    var service = await RfcommDeviceService.FromIdAsync(device.Id);

    this.socket = new StreamSocket();
    await this.socket.ConnectAsync(
        service.ConnectionHostName,
        service.ConnectionServiceName,
        SocketProtectionLevel.BluetoothEncryptionAllowNullAuthentication);
    this.writer = new DataWriter(this.socket.OutputStream);
}

StreamSocket.ConnectAsync() したとき、はじめての場合システムから許可を求められます。許可することで接続が確立します。2 回目以降は特にいわれませんので、ConnectAsync() してすぐに接続が確立します。

Bluetoothバイスとデータを送受信する (準備)

OBD2 アダプターデバイスは、データの送信と受信を一対一でおこないます。クライアントはデータを送信したら、OBD2 から受信を待機して、受け取った情報を解析するような流れをとります。
ですので、送信した後すぐ待機するようなコードを組むようにします。

using System.IO;
using Windows.Devices.Bluetooth.Rfcomm;
using Windows.Devices.Enumeration;
using Windows.Networking.Sockets;
using Windows.Storage.Streams;

// これらに、すでにインスタンスが上記コードを使って入ってるものとします
private StreamSocket socket;
private DataWriter writer;

public async Task SendCommandAsync(string message)
{
    // OBD2 のコマンド終端は \r
    var bytes = Encoding.ASCII.GetBytes(message + '\r');
    this.writer.WriteBytes(bytes);

    // OBD2 へここでデータを投げる
    var result = await this.writer.StoreAsync();

    if (result == bytes.Length)
    {
        // たぶん成功してる
        await AnalyzeAsync();
    }
}

private async Task AnalyzeAsync()
{
    var stream = this.socket.InputStream.AsStreamForRead();
    var result = new List<byte>();

    while (true)
    {
        var b = stream.ReadByte();

        if (b <= 0) continue;

        result.Add((byte)b);

        // > がきたら応答が終わったとみなす
        if ((char)b == '>') break;
    }
    // 以下省略、続きは次で
}

こんな感じ。これで形はできました。
OBD2 のインターフェースである ELM327 がプロンプト形式でやりとりするので、「>」はユーザーからの入力待ちモードになってるって感じです。ユーザーからコマンドと「\r」をもらったら、それに応じて情報を返して、「>」で終わるという具合。
なので、「>」がきたらデバイスからの応答は終わったとみなしてOKでしょう。

Bluetoothバイスとデータを送受信する (送信と解析)

実際に送信してみましょう。
コマンドについては ELM327 のデータシートも参考にしながら。
https://www.elmelectronics.com/wp-content/uploads/2016/07/ELM327DS.pdf

まずリセットコマンドを送信しておきます。
リセットコマンドは次の 3 つです。

at z
at l0
at e0

z は初期化コマンド、e0 はコマンドのエコーをするかどうか (これでエコーしないようになります)、l0 はラインフィードを追加するか (これで追加しないようになります) を設定します。

OBD2 へ送信するコマンドはいろいろあります。先ほどのデータシートにもありますが、英語版 Wikipedia にも一覧が載っています。

OBD-II PIDs - Wikipedia

速度情報は Mode 01 に書かれているので、コマンドはこんな感じ。

01 0D

これを送信することで、応答に速度情報が返ってきます。
これらを先ほどのコードで実装した SendCommandAsync() に投げます。

そしてこれらの応答を解析するコードを実装します。

// 上記コードからの続き

public int Speed { get; private set; }

private async Task AnalyzeAsync()
{
    var result = new List<byte>();
    // 省略
    result = /* OBD2 応答 */;

    // 応答をバイト配列から文字列にしておく
    var buffer = result.Where(w => w > 0).Select(s => (char)s).ToArray();
    var resultStr = new string(buffer);

    // 文字列にした応答を、半角スペースと改行で配列に分ける
    var data = resultStr.Split(new[] { ' ', '\r' }, StringSplitOptions.RemoveEmptyEntries).ToArray();

    // 初期化処理以外で 41 で始まるデータが返ってこなければ、それは失敗してる
    if (data[0] != "41")
        return;

    switch (data[1])
    {
        case "0D":
            // 速度情報
            break;
        default:
            return;
    }
}

private AnalyzeVehicleSpeed(string[] data)
{
    // 使うデータは 3 バイト目
    var speedData = data[2];
    var speedValue = 0;
    int.TryParse(speedData, NumberStyles.AllowHexSpecifier, CultureInfo.CurrentUICulture, out speedValue);

    this.Speed = speedValue;
}

こんな感じ。
初期化コマンドの応答については処理について特に書いてませんが、ちゃんと返ってきます。

> at z
ELM327 v1.5
> at l0
OK
> at e0
>

特に処理する必要もないですが、初期化してから各種コマンドを投げた方がいいです。初期化については「41」で始まる応答を返しませんが、エラー扱いにすると危ないので気を付けた方がいいです。

そして、送信した速度情報のコマンドの応答は

41 0D 28

となっています。成功を示す「41」と、速度情報に応答したと示す「0D」のあとに続く「28」を解析してやればOK。単に 16 進数ですので、数字に変換してやれば速度情報になります。
つまり、OBD2 で得られる速度情報は、0 ~ 255 km/h までということですね。


速度情報はたいていの車で返してもらえると思いますが、車によっては返してもらえなかったり、返す値が微妙に違う (同じ応答を 2 つ返すなど) するらしいので、その辺の情報がちょっとほしいなあと思ったりはしています。
また、ほかのコマンドを叩けば、その情報も得ることができますし、先述の Wikipedia の記事にはフォーマットもありますので、割と楽に取れるかと思います。
取得する車が何のコマンドが使えるかは、「OBD Info-san!」を使うと一覧化してくれます。試用版でもできるので、拾いたい情報をそこから探すという手もあります。


…というのを、Mikaboshi で実装していて、現在テスト中です。速度情報のほかにエンジン回転数も表示できるようにする予定でいます。
実際使ってみるとかなり楽しいというか、目指してたものが実現できたので割と満足しています。

割と古い開発中のころのスクリーンショットですが、こんな感じ。
f:id:ChiiAyano:20161202100208p:plain


少し気になるのが、OBD2 アダプターデバイスの個体差があるのかもしれませんが、OBD2 から得られる情報の更新頻度が急に落ちたり、応答がなくなったりすることがときたま起きます。
再接続したり、アダプターデバイスの電源を入れなおしたり、コマンド送信から受信までタイムアウト時間を設けて、一定時間返ってこなければ自動再接続したりするなど対策はしていますが、更新頻度の低下はうまく検知できてない状態です。
このあたりうまくやれる方法があれば教えていただけると助かります…。
また、まだテストしてる車が、家のホンダ フィット (GP6) しかなく、ほかの車でも動かせるかどうかを確認したいところです。
準備ができ次第リリースするので、協力いただける方がいればよろしくお願いします。

寄付をお願いします

1 日目に引き続いて恐縮ですが、アプリの「?」をタップして表示される「バージョン情報」に「作者に寄付する」ボタンがあります。実際に使ってみて、よければ寄付ください。アプリ内課金を利用しています。寄付額は選べませんが、寄付いただければ例えば Xamarin 使ったマルチプラットフォーム対応とかやる気が起きます。お願いします。

Advent Calendar でした

4 日目は od_10z さんです。誰もが息をのむような、すごい記事に期待しています。
twitter.com

*1:油圧メーターなどの付加メーターやレーダー探知機など

*2:先述のデバイスの場合、たいてい「SPP」といった名前で見つかると思います

Windows 10 アプリ「Mikaboshi (みかぼし)」の紹介

Windows 10 Windows Phone スマートフォン Advent Calendar

この記事は、Windows 10 Mobile / Windows Phone Advent Calendar 2016 の 1 日目の記事です
www.adventar.org

先日リリースしたアプリを、このブログで紹介してなかったので、Advent Calendar のネタとして投下します。


10 月 10 日に「Mikaboshi (みかぼし)」ってアプリを、Windows 10 PC / Mobile (主に Mobile 向け) でリリースしました。いわゆる位置情報を可視化するアプリです。

www.microsoft.com


主に自動車、バイク、自転車などにくくりつけて使うような想定で作ってますので、例えば Windows 10 Mobile デバイスだと GPS もついてるので使い勝手がいいかと思います。


やってることは簡単で、GPS などの位置情報センサーを使って、現在の位置を地図に出したり、GPS から割り出される航行速度を表示したり、移動距離ごとに住所を割り出して表示したりなどしています。割り出した住所と前に取得した住所を比較して、都道府県や市区町村が変化するようなときは、それを読み上げてくれる機能もあります。

上記ウェブサイトで載せてるような機能紹介をただ繰り返すだけじゃ面白くないので、紹介してない機能とか、表面的にしか紹介してない機能とかの深掘りしておきます。


住所読み上げ機能は、音声合成の性質上、漢字の読みなどを間違えることが多いです。そこで、Mikaboshi では「都道府県」と「政令指定都市の市と区」は漢字読み、それ以外はすべてひらがな読みにすることで、間違いを極力減らせるようにしました。それでも、政令指定都市でも漢字読みに失敗する例*1もあったり、また逆にひらがなだと「は・へ」の読み替えがうまくいかない例*2*3などがあるので、一度通った住所を端末で記録しておいて、あとから読み方を変えられるようにしました。
設定画面に [住所アナウンス設定] があるので、そこをタップ/クリックすると、これまで通った住所が一覧ででてきますので、読み方を変えたい項目を右か左にスワイプすることで、読み方を切り替えることができます。PC で変更する場合は右クリックで変更ができます。項目をタップ/クリックするとプレビュー再生するので、読み方が正しいかどうかも確認できます。
f:id:ChiiAyano:20161129101251p:plain
漢字読み/ひらがな読みで同じ読み方になる場合でも、読み上げのイントネーションに変化があったりするので、どっちがいいか選ぶことができます。ちょっと面白いです。音声合成の特性上、やっぱりたどたどしさというか、変な感じになるのは仕方ないです。Cortana さんの音声合成使わせてください。


何回かのバージョンアップで、地図表示のスタイルを少し更新しました。「マップモード」ができました。現在地の日の出・日没時刻を見て、日の出を過ぎると明るく、日没を過ぎると暗くなります。設定で抑止することもできます。が、現在バグで「日の出・日没をまたいでもしばらく地図が切り替わらない*4」問題がありますが、次リリースするバージョンで解決します。ごめんなさい。


Mikaboshi は、位置情報を共有するサービス Locapos (ろけぽす) にも対応しています。というか、 id:tmyt にお願いして作ってもらいました。
当初、 今ココなう!(β) を使って同じようなアプリを書いてリリースしてたことはあります*5が、サービスが事実上停止状態になり、新たなサービスを立ち上げる必要が出てきたわけです。

Mikaboshi を使ってできる Locapos の機能は、

  • 現在位置を送信する
  • 誰かの現在位置を地図表示上にプロットする (現時点では相手の名前は見えません)

の 2 点です。別端末で Locapos のポータルサイトを開いておくというスタイルを想定しています*6

locapos.com

今後やりたいこと

マルチプラットフォーム対応はぜひやりたいところです。Xamarin か…。厳しい闘いになりそうだ…。だれか教えてください。
他にもいくつかやりたいことがありますが、それは 3 日目の Advent Calendar に書きます。

寄付をお願いします

アプリの「?」をタップして表示される「バージョン情報」に「作者に寄付する」ボタンがあります。実際に使ってみて、よければ寄付ください。アプリ内課金を利用しています。寄付額は選べませんが、寄付いただければ例えば上記の Xamarin 使ったマルチプラットフォーム対応とかやる気が起きます。お願いします。


www.microsoft.com

Advent Calendar でした

2 日目は ipponshimeji さんです。

*1:[神奈川県]横浜市保土ヶ谷区は「よこはまし、ほつちけやく」と読んでしまう

*2:[神奈川県]秦野市は「わだのし」と読んでしまう

*3:「町」はすべて「ちょう」と読んでしまう

*4:日の出・日没をまたいだ次の時刻同期処理時に地図が切り替わります

*5:現在は公開停止

*6:これだとあまりよくない気がするので今後考えます

fitbit charge 2 買いました

デジモノ 私事

2016年10月21日に発売になった fitbit charge 2。発売日にヨドバシ akiba で営業時間外店頭受け取りを利用して買いました。

以前から fitbit one を使っていましたが、リストバンドタイプを使うのは初めてで、腕時計代わりになればいいなということで。



fitbit ってなんぞや?というのは割愛します。仲間内と健康を競い合えるソーシャルフィットネスみたいなやーつです。


つけた感じはスタイリッシュな腕時計という感じで、割と好きです。そこまで重くないです。
心拍数がリアルタイムで見れるのは面白くて楽しいです。
モニターは日本語表記対応で、海外のアプリでよくあるようなたどたどしい日本語ではないのが好印象。この辺は fitbit アプリも同様です。アプリとペアリングすることで、時計表示はカスタマイズができます。今は時計表示と、歩数計・心拍数計が表示できるタイプにしました。


Windows 10 Mobile 版の fitbit アプリでもペアリング・同期ができますが、21日に試した段階では、システムが日本語設定だとうまくペアリングできず、英語設定に切り替えることでうまくいきました。
また、腕に装着するという仕組みからか、歩数は one よりもあいまいになり、例えばゲーセンで音ゲーするなどの腕を激しく動かすような動作をすると、それだけで歩数カウントされてしまうなどの問題はありました*1
one と charge 2 を併用できる場合、歩数は one で、心拍数は charge 2 で、という具合で役割分担ができるといいのですが…。

充電する際は腕から外す必要があり、内側から挟み込むクリップタイプです。その状態でも側面のボタンへはアクセスできますが、爪で押す必要がありました。充電中はそのボタンを押すことで充電状態を知ることができます。


僕としては、時計にもなる歩数・心拍数計というイメージです。時計は便利ですが、秒数が見れないので、その点で気になるかもしれません。
その点で、2万円ほどというのはもしかすると割に合わないかもしれないです。
歩数計だけほしいなら、one などにすると 1万円弱で買えるのでオススメです。心拍数も取りたいなら、fitbit では charge 2 が一番安いみたいです。
僕は charge 2 を買って満足してます。まずは one を買ってみるというのも手です。


(2016/10/24 19:10 追記)
はてブコメントより、設定により秒数が出せるという指摘をいただきました

fitbit charge 2 買いました - 古事連記帖

「時計の文字盤」でいちばん右の文字盤を選べば秒表示出来ますよ。

2016/10/24 12:42
b.hatena.ne.jp

試しにやってみました。確かにでてきましたね。

ただ、このデザインはあまり好きではないなあというところでした (´・ω・`)


【日本正規代理店品】Fitbit One Black ブラック FB103BK-JP

【日本正規代理店品】Fitbit One Black ブラック FB103BK-JP

*1:これは charge 2 に限った問題ではないと思います

AppxBundle ファイルを Windows 10 Mobile にインストールする方法

Windows 10 プログラミング

id:shiba-yan の記事を見て書きました

blog.shibayan.jp

Windows 10 Mobile で、AppxBundle ファイルをインストールする方法は、しばやん氏のやり方のほかに 2 つあります。

端末で実行してインストールする

HockeyApp などから、端末で AppxBundle ファイルをダウンロードし、そのファイルを直接実行することでもインストールができます。「開発者モード」を有効にする必要があり、インストールするときは確認のダイアログだけが出て、インストール状況は端末には出ません。また、端末上に必要とするライブラリパッケージがない場合、インストールに失敗します。インストールに失敗したかどうかも端末では確認できません。

バイス ポータルを使ってインストールする

「開発者モード」を有効にすると使用できる デバイス ポータル を使ってインストールすることができます。こちらを使うと、インストールの進捗やインストール中のエラーを見ることができ、またライブラリパッケージもあわせてインストールすることができますが、必要なパッケージは開発者側から受け取る必要があります。接続方法は以下の記事をご参照ください。

Windows Device Portal の概要


どっちもめんどくさいので、使えるなら Package Flight にしたほうが実はいいかもしれないです。

Visual Studio Team Services からストアに自動申請する

C# Windows 10 プログラミング

Visual Studio Team Services (VSTS) には、プロジェクトの自動ビルドの他に、特定のサービスへのデプロイメントもすることができます。その中でも注目なのは Windows ストアへの自動申請ができることだと思います。ドキュメントを見ていたら、いつのまにか Submission API が用意されていたようです。

msdn.microsoft.com

この記事にあるように、エンドポイントが用意されていて、必ずしも VSTS を利用するということではなく、例えば Jenkins などのサービスを使っても同じことが出来るようになるわけです。
今すぐに利用可能というわけではなく、ちょっと準備が必要だったりします。

今回は UWP アプリケーションの申請をメインに話を進めます。

準備しておくもの

  • 開発者アカウントが必要です。
  • 一度デベロッパーセンターで申請するアプリを追加して下さい。そこで得られるアプリケーションの情報を使用します。
  • Package Flight を利用する場合、まず本申請を通して下さい。本申請したアプリは非公開にする手もあります。
  • Package Flight を利用する場合、ダッシュボード上でパッケージフライトを追加してください。フライト名を使用します。

API の利用申請をする

上記記事の「Important」にあるとおり、原則的には、Developer アカウントすべてで API が使える状態になっている訳では無いので、まず申請が必要です。

This API can only be used for Windows Dev Center accounts that have been given permission to use the API. This permission is being enabled to developer accounts in stages, and not all accounts have this permission enabled at this time. To request earlier access, log on to the Dev Center dashboard, click Feedback at the bottom of the dashboard, select Submission API for the feedback area, and submit your request. You'll receive an email when this permission is enabled for your account.


デベロッパーセンターの右下にちょこっとある「フィードバック」をクリックしてください。

f:id:ChiiAyano:20160925223254p:plain

種類は何でも良いと思います。「当てはまる領域をお選び下さい」の部分は「申請 API」にします。フィードバックの内容は「API使わせて下さい」的なノリの英語を気合いで書きました。
これでOKです。利用可能になった時点でメールが来るはずです*1

Azure AD を取得しておく

申請が通るまでに準備だけしておきましょう。API の使用には Azure Active Directory (Azure AD) を準備しておく必要があります。

https://msdn.microsoft.com/ja-jp/windows/uwp/publish/manage-account-usersmsdn.microsoft.com

登録の仕方はだいたいこの記事に載っています。すみません、ここでは割愛します。登録が完了したら、「Azure AD アプリケーションの追加」をします。

f:id:ChiiAyano:20160925224334p:plain

名前は何でも良いと思います。実際のアプリの名前を入れるのが適当かと思います。
「応答URL」「アプリ ID URI」はひとまず有効な URL を適当に入れておきます*2
「役割」はとりあえず「マネージャー」にでもしておくと良いと思います。

ここでできあがった「テナント ID」「クライアント ID」は VSTS 側で必要となります。
「キー」も必要になります。「新しいキーの追加」をクリックして得られたキーはどこかにメモしておいて下さい。一度しか表示されず、もう一度取得するためには一度削除するか、もう一回キーを追加する必要があります。

VSTS 側の準備をする

実際に申請をする拡張機能をインストールします。実は Microsoft 公式で申請用の拡張機能が用意されています。

marketplace.visualstudio.com

これを利用するのも手ですが、本申請しか現時点では出来ないので、Package Flight 向けに利用したい場合は、今のところサードパーティ拡張機能を利用することになります。

marketplace.visualstudio.com

ただ、2016年9月25日現在、公式側も Package Flight へ申請できるようにするアップデートを予定しているので、待ってみるのも手かもしれません。

github.com

今回は後者の Windows Store Automation を利用して進めます。

インストールしたら、VSTS のプロジェクトから設定を選び、「Services」を選びます。
「New Service Endpoint」を選んだら、「Windows Dev Center」を選択して下さい。

f:id:ChiiAyano:20160925225459p:plain

「Connection Name」はわかりやすい名前をつけます。
「Tenant Id」は先ほどの「テナント ID」を入力します。
「Client Id」は「クライアント ID」を入力します。
API Token」はメモしておいた「キー」を入力します。

ビルド環境を整える

ここで、あらかじめ Visual Studio 側でプロジェクトのストアとの関連づけを進めておき、生成した証明書をリポジトリに含めておいてください。申請パッケージを生成するために必要です。

UWP アプリのパッケージ化


設定から離れ、ビルドの準備が出来ていないようであれば「Build Definitions」に移動します。
「New」をクリックし、テンプレートは UWP であれば「Universal Windows Platform」を選んで下さい。
「Repository」は通常であれば既に選ばれているものを、「Default branch」はビルド対象にしたいブランチ名を選んで下さい。
「Default agent queue」は通常「Hosted」を選ぶと良いでしょう。自前で Agent を生成している場合はそちらを選択することが出来ます。

いろいろとビルドステップが準備されます。
僕の環境ではステップをこのようにしておきました。

f:id:ChiiAyano:20160925230528p:plain

まず「Delete files」でビルド生成物を一度全部削除します。ビルドが積み重なるごとに、前に生成したバイナリまで生成物として含まれてしまうので、このような形にしました。「Source Folder」は「$(Build.BinariesDirectory)」、「Contents」は「*」にしています。
「Update Appx Version」でビルド番号を自動インクリメントしています。「Manifest File」でアプリの appxmanifest を入れ、「Build Id」は「$(BuildId.BuildId)」にしておきます。こうすることで、「1.0.100.0」といったバージョン番号の「100」の部分が自動で置き換わるようになります。
「NuGet Installer」は「Path to solution or packages.config」をソリューションファイルに変更するだけでOKです。
Visual Studio Build」は、「MSBuild Arguments」が既定ではストア申請用のパッケージを生成しないので、「/p:UapAppxPackageBuildMode=StoreUpload」を追記してください。「Configuration」に「$(BuildConfiguration)」を追加しておけば、あとはOKです。必要に応じてパラメーターを設定して下さい。

https://msdn.microsoft.com/en-us/library/ms164311.aspxmsdn.microsoft.com

「Index Sources & Publish Symbols」はそのままでOKです。
「Publish Build Artifacts」は「Path to Publish」を「$(Build.BinariesDirectory)\AppxPackages」にしておけばOKです。

これでビルド環境は整いました。一度ビルドしておくと、この後が楽です。

リリースの準備をする

「Releases」に移動します。
「Create Release Definition」を選択し、テンプレートがいくつか表示されますが「Empty」を選択します。

「Add tasks」をクリックして、「Publish to Windows Store」を「Add」してください。「Close」してポップアップを閉じます。
「Service Endpoint」を、さきほど設定で準備したものにします。プルダウンを開くと、おそらくひとつだけ出てくると思うのでそれです。
「App Id」は申請するアプリケーションの ID です。デベロッパーセンターのダッシュボードから「アプリ管理」->「アプリ ID」に切り替え、「ストア ID」を入力します。
「Flight Name」は本申請の場合は不要です。Package Flight で使用する場合は、その名前を入力します。
「Appxupload」はビルド時に生成した「.appxupload」のパスを設定してください。パス名には「* (アスタリスク)」が使用できます。

これでリリース環境は整いました。

申請を投げてみる

とりあえず申請を投げてみましょう。「Releases」で生成した定義を選び、「Release」から「Create Release」を選びます。
表示されたポップアップで「Artifacts」にある赤いドロップダウンを選択して、申請したいビルドを選び、「Create」をクリックして下さい。これで申請が始まります。
申請中のタスクを開き、「Logs」を選ぶと、現在の進捗を見ることが出来ます。

こんな感じです。API 利用申請をしたばかりですとたぶん 「error: {"code":"Unauthorized","message":"Authorization: Account is not allowed to access this api"}」と言われて失敗すると思います。


これでうまくいけば、あとは良い感じにしていきましょう。ビルド完了後自動的に申請を投げることも出来るようになります。

*1:僕の場合メール来ませんでしたが、申請後10日ほどした時ふと試したら使えるようになっていました

*2:僕はひとまず自分のサイト URL にしました。たぶん大丈夫だと思います

Microsoft.NETCore.UniversalWindowsPlatform をアップデートすると、VSTS でビルドが通らなくなる問題の対策

C# プログラミング

UWP でアプリを書いているとき、ふと NuGet で Microsoft.NETCore.UniversalWindowsPlatform に更新が来ていたりします。
アップデートする分には問題ないですが、アップデートした状態で Visual Studio Team Services でビルド掛けるとなぜかビルドに失敗します。

2016-08-24T15:52:49.2593806Z System.Net.WebHeaderCollection 4.0.1 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2593806Z Microsoft.NETCore.Targets 1.0.2 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2593806Z System.Net.WebSockets 4.0.0 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2593806Z Microsoft.Win32.Primitives 4.0.1 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2593806Z System.Net.Sockets 4.1.0 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2593806Z System.Text.Encoding.CodePages 4.0.1 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2593806Z System.Diagnostics.StackTrace 4.0.2 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2593806Z System.Net.WebSockets.Client 4.0.0 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2593806Z System.Net.NameResolution 4.0.0 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2593806Z System.Reactive.Interfaces 3.0.0 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2593806Z System.Reactive.Linq 3.0.0 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2593806Z Microsoft.NETCore.Platforms 1.0.1 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2593806Z System.Security.Cryptography.X509Certificates 4.1.0 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2750080Z System.IO.FileSystem.Primitives 4.0.1 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2750080Z System.IO.FileSystem 4.0.1 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2750080Z System.Private.DataContractSerialization 4.1.1 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2750080Z System.Runtime.Handles 4.0.1 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2750080Z System.Xml.XmlDocument 4.0.1 is not compatible with UAP,Version=v10.0.
2016-08-24T15:52:49.2750080Z System.Reflection.DispatchProxy 4.0.1 is not compatible with UAP,Version=v10.0.

... (中略) ...

2016-08-24T15:52:49.8843904Z ##[debug]rc:1
2016-08-24T15:52:49.8843904Z ##[debug]success:false
2016-08-24T15:52:49.8843904Z ##[debug]Processing: ##vso[task.issue type=error;]Error: C:\agent\externals\nuget\nuget.exe failed with return code: 1
2016-08-24T15:52:49.9000123Z ##[error]Error: C:\agent\externals\nuget\nuget.exe failed with return code: 1
2016-08-24T15:52:49.9000123Z ##[debug]Processing: ##vso[task.issue type=error;]Packages failed to install
2016-08-24T15:52:49.9000123Z ##[error]Packages failed to install
2016-08-24T15:52:49.9000123Z ##[debug]task result: Failed
2016-08-24T15:52:49.9000123Z ##[debug]Processing: ##vso[task.issue type=error;]Return code: 1
2016-08-24T15:52:49.9000123Z ##[error]Return code: 1
2016-08-24T15:52:49.9000123Z ##[debug]Processing: ##vso[task.complete result=Failed;]Return code: 1

みたいな感じでずらずらーっと怒られます。
仕方ないので元のバージョンに戻すのがいいんですが、他の NuGet パッケージによっては依存関係にある場合もあるのでなかなか悩ましい。

もし、ビルドサーバーを自前で立てていて、Agent として登録しているのであれば解決することが出来ます。


この issue が役に立ちました。
github.com

要するに、Agent のパッケージに含まれる NuGet をアップデートして 3.4.4-rtm-final にしてやればいいのです。

C:\agent\externals\nuget> ./nuget update -self

コマンドはこんな感じ。これでアップデートできますので、終わったらビルドしてみましょう。あと、少し前に配布されていた agent のパッケージを使っている場合、いつの間にか Legacy になってるので、これを期に新しいやつ (ちょっと前まで preview だとか beta になってたやつ) に差し替えておくといいと思います。



ちなみに VSTS が用意する Hosted を使っている場合は現時点ではやり方はわかりませんでした。なのでアップデートを待つしかありません。
もしやり方があるのようでしたらご教示いただけると助かります。

ソフトバンクから Windows 10 Mobile 搭載 SoftBank 503LV が発表になったみたいです

Windows 10 Windows Phone

唐突ですね。レノボの電話らしいですよ
news.microsoft.com
www.softbank.jp

Continuum for Phone 対応みたいですので、RAM 3GB あって、ROM 32GB は割と普通なのかなと思いつつ、CPU は MSM8952 なので Snapdragon 617 ですね。NuAns NEO や VAIO Phone Biz と同じです。
neo.nuans.jp
vaio.com

対応バンドは FDD-LTE 1/8/(18/26)/19、W-CDMA 1/8、そして AXGP に対応してるとのことで、W10M 初の AXGP 対応デバイスになりそうな予感。

2016年10月下旬以降発売を予定しているみたいです。まだ価格は発表になっておらず、法人向けとのことで、個人でも買えるのかは気になるところ。
法人向けなら指紋認証とか、その辺あるとよかったのかなあと思ったり。法人向けだと逆にダメだったりするのかしら。