Window.Current.Bounds.Height の罠
Mobileで実行しているUWPで画面いっぱいにポップアップを出す際の注意点です。
最初に結論から言うと、
- ポップアップを開く前にcs上でポップアップのサイズを動的に指定して画面いっぱいにする
- Window.Current.Bounds は危険
- Mobileは通知領域やOSボタンを考慮しましょう(GetForCurrentView().VisibleBoundsを使えば大丈夫!)
です。
今回使用したサンプルアプリは一番下にまるまる載せているので、ご参考までに。
サンプルアプリの概要
- 画面上にデバイスファミリー、Window.Current.Bounds(画面サイズ)、ApplicationView.GetForCurrentView().VisibleBoundsのサイズを表示
- アプリをフルスクリーンモードへの切り替え
- Window.Current.Boundsのサイズと同じサイズのポップアップを表示する
- ページの一番上の階層のGridのサイズと同じサイズのポップアップを表示する
では実際に見てみましょう。
PCでサイズの確認
サンプルアプリを動かすと以下のようになります。
タイトルバーやツールバーの有無が変わるので、それぞれのモードで数字は違いますが、
Window.Current.BoundsとVisibleBoundsは両方同じ数字になってますね。
Windowモード時
フルスクリーンモード時
PCでPopup表示
Window.Current.Boundsを設定する方法
ポップアップを開く前にWindow.Current.Boundsをポップアップに設定して表示します。
ポップアップにはテキストを並べてスクロールするようになっています。
「1」を並べて、一番下だけ「2」になっています。
grdPop.Height = Window.Current.Bounds.Height;
grdPop.Width = Window.Current.Bounds.Width;
popTest.IsOpen = true;
当然ながら一番下までスクロールできますね。
VisibleBoundsを設定する方法
最初に確認した通り、数字が一緒なので、同じ結果になります。
同じなので、画像は割愛します。
var view = ApplicationView.GetForCurrentView();
grdPop.Height = view.VisibleBounds.Height;
grdPop.Width = view.VisibleBounds.Width;
popTest.IsOpen = true;
それでは問題のMobileです。
Mobileで確認
同じアプリをNuAns NEOで表示してみます。
フルスクリーンモードでは同じですが、Windowモードの場合、
Window.Current.Bounds.HeightとVisibleBounds.Heightの数字が異なっています。
そうです。
こいつが諸悪の根源です。
Windowモード時
フルスクリーンモード時
Window.Current.Boundsだと、Mobileの通知領域やOS標準のボタン領域も含めた単純な画面サイズが取得されてしまいます。
ApplicationView.GetForCurrentView().VisibleBounds だと、現在のビューに表示されている領域のサイズが取得されます。
そのため、このような差が生まれてしまうのですね。
では続いてポップアップを表示してみましょう。
MobileでPopup表示
Window.Current.Boundsを設定する方法
最終行である「2」がボタン領域の下に隠れてしまっています。
VisibleBoundsを設定する方法
正常にすべて表示されます。
まとめ
PCでは同じだけど、Mobileだと異なるっていうのがいやらしいですね。
ウチのアプリの場合、PC版を作って後からMobileに対応ってパターンがあるので、ハマりがちです。
全部見直さないと。。。。。
ソース
MainPage.xaml.cs
using Windows.System.Profile; using Windows.UI.ViewManagement; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Input; namespace WindowSizeTest { public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private void grdMain_SizeChanged(object sender, SizeChangedEventArgs e) { //Page_SizeChangeはなぜかMobileのFullスクリーンモードの切り替えだと動いてくれないため、 //GridのSizeChangeでTextの再設定を行う setText(); } private void ToggleButton_Checked(object sender, RoutedEventArgs e) { changeViewMode(true); } private void ToggleButton_Unchecked(object sender, RoutedEventArgs e) { changeViewMode(false); } private void btnShowPopupWindowBounds_Click(object sender, RoutedEventArgs e) { grdPop.Height = Window.Current.Bounds.Height; grdPop.Width = Window.Current.Bounds.Width; popTest.IsOpen = true; } private void btnShowPopupVisibleBounds_Click(object sender, RoutedEventArgs e) { var view = ApplicationView.GetForCurrentView(); grdPop.Height = view.VisibleBounds.Height; grdPop.Width = view.VisibleBounds.Width; popTest.IsOpen = true; } private void grdPop_Tapped(object sender, TappedRoutedEventArgs e) { popTest.IsOpen = false; } private void changeViewMode(bool isFull) { var view = ApplicationView.GetForCurrentView(); if (isFull) { view.TryEnterFullScreenMode(); } else { view.ExitFullScreenMode(); } } private void setText() { txtDevice.Text = AnalyticsInfo.VersionInfo.DeviceFamily; txtWindowHeight.Text = Window.Current.Bounds.Height.ToString(); txtWindowWidth.Text = Window.Current.Bounds.Width.ToString(); var view = ApplicationView.GetForCurrentView(); txtVisibleBoundsHeight.Text = view.VisibleBounds.Height.ToString(); txtVisibleBoundsWidth.Text = view.VisibleBounds.Width.ToString(); } } }
MainPage.xaml
<Page x:Class="WindowSizeTest.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="using:WindowSize" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.Resources> <Style TargetType="TextBlock"> <Setter Property="FontSize" Value="28" /> </Style> <Style x:Key="txtValueStyle" TargetType="TextBlock"> <Setter Property="FontSize" Value="28" /> <Setter Property="Foreground" Value="Red" /> </Style> <Style TargetType="Button"> <Setter Property="Margin" Value="10" /> <Setter Property="FontSize" Value="28" /> </Style> <Style TargetType="ToggleButton"> <Setter Property="FontSize" Value="28" /> </Style> </Page.Resources> <Grid x:Name="grdMain" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" SizeChanged="grdMain_SizeChanged"> <Viewbox VerticalAlignment="Top"> <Grid x:Name="grdContent"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <StackPanel Margin="10,0"> <TextBlock Text="AnalyticsInfo.VersionInfo.DeviceFamily" /> <TextBlock Text="Window.Current.Bounds.Height" /> <TextBlock Text="Window.Current.Bounds.Width" /> <TextBlock Text="GetForCurrentView().VisibleBounds.Height" /> <TextBlock Text="GetForCurrentView().VisibleBounds.Width" /> <ToggleButton Margin="10" Checked="ToggleButton_Checked" Content="FullScreen" Unchecked="ToggleButton_Unchecked" /> <Button x:Name="btnShowPopupWindowBounds" Click="btnShowPopupWindowBounds_Click" Content="ShowPopupWindowBounds" /> <Button x:Name="btnShowPopupVisibleBounds" Click="btnShowPopupVisibleBounds_Click" Content="ShowPopupVisibleBounds" /> </StackPanel> <StackPanel Grid.Column="1"> <TextBlock x:Name="txtDevice" Style="{StaticResource txtValueStyle}" /> <TextBlock x:Name="txtWindowHeight" Style="{StaticResource txtValueStyle}" /> <TextBlock x:Name="txtWindowWidth" Style="{StaticResource txtValueStyle}" /> <TextBlock x:Name="txtVisibleBoundsHeight" Style="{StaticResource txtValueStyle}" /> <TextBlock x:Name="txtVisibleBoundsWidth" Style="{StaticResource txtValueStyle}" /> </StackPanel> </Grid> </Viewbox> <Popup x:Name="popTest"> <Grid x:Name="grdPop" Background="AliceBlue" Tapped="grdPop_Tapped"> <ScrollViewer> <StackPanel> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="2" /> </StackPanel> </ScrollViewer> </Grid> </Popup> </Grid> </Page>
Raspberry Pi 2 Model B に Windows 10 IoT Core for Raspberry Pi 2 をインストールする
毎年、弊社では社内ハッカソンを行っているのですが、私はWindows系が本業なのでそれを生かしつつ、ちょっと新しいことをやりたいなと。
そして昨年のde:Codeの抽選で当たったラズパイが埋もれていたのでこいつを使うことにしました。
とりあえず環境構築を行いました。
(何を作るかはまた後日。。。)
諸々を購入
本体はあるものの、周辺機器が何もないので、社内ハッカソン経費で以下を購入
・無線LANアダプター(※後述しますが、これは使用しませんでした)
BUFFALO 11n対応 11g/b 無線LAN子機 親機-子機デュアルモード対応モデル WLI-UC-GNM2
- 出版社/メーカー: バッファロー
- 発売日: 2011/07/30
- メディア: Personal Computers
- 購入: 198人 クリック: 5,602回
- この商品を含むブログを見る
・SDカード
- 出版社/メーカー: トランセンド・ジャパン
- 発売日: 2015/10/02
- メディア: Personal Computers
- この商品を含むブログを見る
・ディスプレイ
・カメラ
Raspberry Pi Video Module Raspberry Pi Camera Board 775-7731
- 出版社/メーカー: Raspberry Pi
- メディア: 付属品
- この商品を含むブログ (1件) を見る
・色々入っているキット
Raspberry Pi電子工作エントリーキット(Premium)
- 出版社/メーカー: TechShare
- メディア: エレクトロニクス
- この商品を含むブログを見る
Raspberry Pi Model B+ / Pi2用 ヒートシンクセット
- 出版社/メーカー: TechShare
- メディア: エレクトロニクス
- この商品を含むブログを見る
・LEGO(本体ケースやカメラケースを自作しようかなと思い)
レゴ クラシック アイデアパーツ<エクストラセット> 10702
- 出版社/メーカー: レゴ
- 発売日: 2016/01/15
- メディア: おもちゃ&ホビー
- この商品を含むブログを見る
SDカードにWindows 10 IoT Core for Raspberry Pi 2をインストール
色々調べた結果、「raspberry pi windows10」でググると一番上にくる(2016/1/26時点)↓のサイトの様にPCでファイルをダウンロードして、イメージファイルをどうのこうの。。。とかは全く必要ありませんでした。
ascii.jp
Microsoftさんが、丁寧にまとめてくれていたので、こちらを参考にしました。
ms-iot.github.io
PCでこのサイトの真ん中へんの「Get the Windows 10 IoT Core Dashboard」をクリック
すると、IoT端末を管理するためのデスクトップアプリがPCにインストールされます。
インストール後、起動すると、、
え?勝手にやってくれる系?
すごい簡単そう。。。
んで、指示通りにSDカードをPCに接続し、インストール実行!
終わったけど、ちゃんとやってくれたのか不安を抱えながらラズパイにSDカードを接続して起動してみました。
ちなみにラズパイの起動は電源を挿すと起動します。
起動した!!
簡単過ぎ!!!
ネットワークに接続
インストールはできたけど、Windows 10 IoTはネットワークにつないでPCと通信ができないと何もできません。
※私も勘違いしていたのですが、「Windows」と銘打つからにはデスクトップがあって、エクスプローラーがあって、、とかと想像してましたが違います。
(そうなっていた方が「Windows」としての強み、他のOSとの差別化としてはいいと思うんですがね。。)
なので、ネットワークにつなぎます。
ここで無線LANアダプターの登場です。
「Raspberry Pi 無線LAN」とかでググるとたくさん出てきたので、(どうせ会社の金だし!と)あまり調べず購入したのですが、結論から言うと使えませんでした。
挿しても認識してくれません。
Raspbian OSだと大丈夫の様ですが、Windows 10 IoTでは
ms-iot.github.io
こちらに書いてある機器しかサポートしていないらしい。。。
そのため、なぜか会社にあったコイツ↓を使用してエセ無線LAN環境を構築しました。不幸中の幸いです。
これはちょっと高いですが、コンバーターとして使えるラズパイとLANケーブルでつなぐようなモノは探せばもっと安いのがあると思います。
- 出版社/メーカー: プラネックス
- 発売日: 2013/11/29
- メディア: Personal Computers
- この商品を含むブログ (1件) を見る
PCと同じネットワークに接続して、こちらに書いてある通りにPCからラズパイにアクセスします。
ms-iot.github.io
・ラズパイからIPアドレスを確認
・IPアドレス+「:8080」をブラウザでたたく
・ユーザーID:Administrator、パスワード:p@ssw0rdで接続
以上でラズパイの管理画面に接続できました。
めでたし、めでたし。
後日、作成したアプリとかをインストールしたいと思います。
※※※※※※※※※※※※※※※※※
2016/1/29 追記
カメラモジュールも使えませんでした...orz
Windows 10 Mobile でアプリケーションのフォルダーを参照したい
=================================================
追記:最新のバージョンでは下記手順はできなくなってます。
どうしよう。。。
=================================================
UWPの開発で ApplicationData.Current.LocalFolder(= ms-appdata:///local/) とかにログを出力したりするケースがあると思います。
ですが、Windows 10 Mobileの標準エクスプローラーでは大したところは見えません。
↓ このぐらいです。
検索しても見つけてくれません。
なので、どうにかしてログファイルをみたいな、と。
調べてみたところ、以下のサイトに行きつきました。
<参考サイト>
参考にして試行錯誤の末、なんとかできましたのでまとめときます。
もっとスマートな方法があったら教えてください。。。
1.PCでCドライブ直下のショートカットを作成する
なんでやねん。
なんでMobileってゆーのにいきなりPCが登場するんじゃい。
と突っ込みを入れたくなりますが、そこはこらえてください。
- Cドライブを右クリック
- ショートカットの作成
2.作成したショートカットをMobileに移動する
参考サイトの通り、実機でやるとUSBで簡単なのですが、今回はエミュレーターでの手順を記載しておきます。
- エミュレーターのメニューから≫を選択
- SD Card タブを選択
- ショートカットを置いた適当なフォルダーを指定
- Insert SD Card を選択
- Mobile 標準のエクスプローラーを起動する
- SDCARD が生まれているので選択
- 作成したショートカットがある
これで、Windows 10 Mobile のCドライブ直下を参照することができました。
3.アプリケーションのフォルダーを見つける
あとは簡単じゃーん。と思いの方もいるかもしれません。
そう思っていた時期が私にもありました。
答えから言うと、インストールしたパッケージたちは
C:\Data\Users\DefApps\AppData\Packages
にあります。
では見てみましょう。
- Cドライブ直下
- Data フォルダ
- Users フォルダ
- DefApps フォルダ
- AppData フォルダ
はい、空ですー!
隠しフォルダなのでしょうかね。
ということで・・・
- DefApps フォルダに戻って検索ボタン
- 「Package」と検索するとヒット!!
- お目当てのアプリのパッケージ名を選択
LocalStateがありましたよー!!
あとはふつうに中に入っているログファイルでもなんでも見れる!!
こんな面倒なことしないといけないのでしょうか。。。
ひとまずよかった。
Windows 10 × Visual Studio 2015 でAndroid実機デバッグ(Xamarin)
すでに、色んな方がサイトで公開してますが、自分用にまとめ。
- 端末の設定
- PC側に端末のドライバーをインストール
- PC側での接続確認
- Visual Studioからの起動
端末の設定
ここは簡単なので割愛します。
①端末の開発者オプションを有効にし、USBデバッグを許可にする
PC側に端末のドライバーをインストール
ここは結構手こずりました。
①Google USB Driverのインストール
Android SDK ManagerからGoogle USB Driverを指定してインストール。
%USERPROFILE%\AppData\Local\Android\android-sdk\extras\google\usb_driver
もしくは
C:\Program Files (x86)\Android\android-sdk\extras\google\usb_driver
<編集内容>
メモしたハードウェアIDを以下の対応する箇所に入れて
「Google.NTx86」、「Google.NTamd64」両方に追加する。
;機種名のコメント
%SingleAdbInterface% = USB_Install, USB\VID_[端末のVID]&PID_[端末のVID]
%CompositeAdbInterface% = USB_Install, USB\VID_[端末のVID]&PID_[端末のVID]&MI_01
※デバイスマネージャーからコピーしたのをそのままだと余計な(REVなんとかとか)がついてるから対応する箇所だけ抜き出す。
③PCに端末のドライバーをインストール
ここまでで準備ができたと思いきや、まだデバイスマネージャーからのドライバーのインストールができない。
Windows 8ぐらいから未署名のドライバーのインストールが簡単にできなくなったらしい。
※色んなサイトにはテストモードにするとかありましたが、不要なようです。
- 設定から起動オプションを指定する用の再起動を行う
- オプションから「トラブルシューティング」を選択
- 「詳細オプション」を選択
- 「スタートアップ設定」を選択
- 「ドライバー署名の強制を無効にする」を行いたいので、数字の7を押下する
- 再起動後にデバイスマネージャーから対象の機種を選択し、「ドライバーの更新」を選択
- Andoroid SDKの場所を指定し、インストールを実行
完了です!!やったー!!
PC側での接続確認
adbコマンドでちゃんと接続確認できているか確認をします。
adb devices
で
XXXXXXXX device
みたいに表示されていればOKです。
最初、deviceの箇所が「unauthorized」になっていましたが、実機に以下の確認メッセージが出ていたのに気づいていませんでした。。。
これをOKで本当にOKです!
Visual Studioからの起動
とうとう大詰め。
もう後は簡単です。
Visual Studio 2015を起動してXamarinのソリューションを開いてデバッグ先を先ほどの実機に指定して実行。
ドキドキ。
やったーーーーー!
今日はここまで。
UWP用のパッケージ作成時注意事項
はまった。
Visual Studio 2015でUWPアプリを作成しようとしたらうまくいかなかった。
①ビルド構成の問題
Windows 8.1時代のアプリをUWP対応させたから、この問題が発生した模様。
ストア申請用のパッケージを作成する際に顕在化。
(ビルドはできる。)
UWP用のアプリはDebugとReleaseでパッケージ化の仕組みが違うらしい。
参考 ↓
普通に新規でUWPのアプリを作成してビルド構成を別で追加したい場合は、Releaseからコピー作成すれば問題ないのだが、
1.Windows 8.1用アプリ時代にReleaseからコピーしてビルド構成作成
↓
2.Windows10用アプリ(UWP)にマイグレーション
だと、1.で作成したビルド構成には「.NET ネイティブ ツール チェーンでコンパイルする」のチェックが入っていなかった。
ってことでチェックつけたら解決。
②マニフェストで参照しているファイル 'XXXX.dll' がペイロードに含まれていません。
はい、謎のエラー。
これは単純にVisual StudioのUWPツールのバグのようです。
ここの通りにUWPツールのKBを当てたら解決。