Xamarin.Forms : Androidのアプリ名を変えたい
以前に,アプリのアイコン下に表示される名称を変更しました.
しかし,インストールしたアプリの情報を表示させると,表示されるのはプロジェクト名です.
ここに表示される文字列はどこで変更できるのか.
AndroidManifest.xmlに記載するandroid:labelについて。shun1adhocblog.wordpress.com
こちらの記事を読むと,以前に私がアプリ名の変更と思っていたのはアイコンに表示されるラベルの変更でした.
アプリケーション名をへんこうするには,AndroidManifest.xml
の以下の部分を変更する必要があります.
<application android:label="XFMyDecode2020.Android" android:icon="@mipmap/ic_launcher"></application>
このapplication
要素のandroid:label
属性に指定した文字列がアプリ名として使用されます.
ここを以下のようにします.
<application android:label="@string/app_name" android:icon="@mipmap/ic_launcher"></application>
@string/app_name
はResources/values/Strings.xml
でアプリ名の文字列(My de:code 2020)を割り当てています.
実行し,アプリの情報を確認すると以下のように指定したアプリ名が表示されました.
Android Studioのアップデート
File -> Settings
を開く.
左側のメニューからAppearance & Behavior -> System Settings -> Updates
を選択する.
Automatically check updates for
にチェックがついていること.これで,普段から使っていればアップデートの通知が表示されると思う.
チャンネルを選択する.Stable Channel
でOk.
Check Now
ボタンを押すと,アップデートの有無をチェックにいく.
アップデートがある場合,以下のようなアップデートの情報が表示される.
手っ取り早くここでUpdate and Restart
を選んでアップデートする.
以前のバージョンの設定を引き継ぐ場合は,以下のダイアログで選択する.
以前のバージョンのAndroid Studioを削除するか訊かれるので,不要な場合はチェックをつける.
これでアップデートは完了.
System.Text.Jsonでコメント付きJSONをデシリアライズ
System.Text.json issue with comments · Issue #30743 · dotnet/runtime · GitHub
例えば以下のようなコメント付きのJSONがあったとする.
{ //Comment "FirstName": "太郎", /* this is comment */ "LastName": "田中"//コメントだよ! }
これのデシリアライズを試みます.
まず,これに対応するクラスを用意しておきます.
public class SampleData { public string FirstName { get; set; } public string LastName { get; set; } }
そして,以下のようにSystem.Text.Jsonを使ってデシリアライズします.
SampleData sampleData = System.Text.Json.JsonSerializer.Deserialize<SampleData>(jsonString);
例外となります.
コメント付きのJSONをデシリアライズするには以下のように,JsonSerializerOptions
を使ってコメントを無視するように指定します.
JsonSerializerOptions options = new JsonSerializerOptions
{
ReadCommentHandling = JsonCommentHandling.Skip
};
SampleData sampleData = System.Text.Json.JsonSerializer.Deserialize<SampleData>(jsonString, options);
デシリアライズに成功します.以下はデシリアライズ後にFirstName
を出力しています.
ソースコード
App Centerを通じてXamarin.Formsで作ったAndroidアプリをストアに公開する
Googleデベロッパー登録する
外部ツールからのAPIアクセスを許可する
App CenterからGoogle Play Storeにアプリを公開するために,Googl Play StoreのAPIを外部ツールが利用できるようにする必要があります.
まずはGoogle Play Consoleにログインします.
左側に設定
という項目があるのでそれを選択します.
次にデベロッパーアカウント > APIアクセス
を選択します.
新しいプロジェクトを作成
ボタンを押します.
自分のGoogle Play ConsoleとリンクしたAPIプロジェクトが自動で作成されます.
一番下にサービスアカウント
という項目があるので,サービスアカウントを作成
ボタンを押します.
サービスアカウント作成
ダイアログが表示されます.
これは作成の手順が示されているだけですので,まず手順1のGoogle API コンソール
へのリンクをクリックします.
Google Cloud Platformのページが開きます.
上部に+ サービスアカウントを作成
を押します.
サービスアカウントの作成
ページが開きます.
以下のようにサービス名(任意)をつけて,作成
ボタンを押します.
次のステップでは権限を設定します. ロール
にオーナー
を選んで続行
ボタンを押します.
次のステップはそのまま完了
を押します.
一番最初のページに戻ってきます.リストに作成したサービスアカウントが追加されています.
キーID
の項目が「キーがありません」となっているので,キーを作成します.
操作
の項目にあるアイコンをクリックして表示されるメニューから鍵を作成
を選びます.
秘密鍵の作成
ダイアログが開きます.
鍵をJSONファイルでダウンロードしますが,注意書きにもあるようにこのファイルは再発行できないので紛失しないように気をつけます.
キーのタイプにJSON
を選択し,作成
ボタンを押すとダウンロードされます.
ファイルを保管してGoogle Cloud Platformを閉じます.
Google Play Consoleに戻ると,以下のようにサービスアカウントがリストに追加されているので,アクセスを許可
ボタンを押します.
権限などの情報が表示されます.ここではこのままユーザーを追加
を押します.
Google Play Console側の手順はこれで完了?
App CenterでGoogle Play Connectionを作成する
App Centerの対象のアプリのページで,左側のメニューからDistribute > Stores
を選択すると,以下のようなページが表示されます.
Connect to store
ボタンを押します.
以下のように公開先の選択肢が表示されるので,Google Play
を選択します.
次のステップではサービスアカウントを作成したときにダウンロードした秘密鍵のJSONファイルをアップロードします.
最後のステップではGoogle Play Storeに公開されているアプリを指定します.
指定にはAndroidアプリのパッケージ名(例:com.harusoft.XFMyDecode2020)を指定します.
しかし,指定したアプリがPlay Storeに見つからない,と言われます.
App Centerはすでにストアにあるアプリのアップデートだけができる,とのことです.
App Center can only upload new versions to existing apps that are already published on to Google Play.
初回は手動でGoogle Play Storeに公開する必要があります.
Google Play Consoleでアプリを登録する
(長くなったのでこちらに移動.) shuhelohelo.hatenablog.com
追記)2020/10/9の夜にアプリがストアに公開されました.申請したのが10/6日だったので大体3日間かかりました.
公開されるとメールが届くので気長に待ちましょう.
Google Play Consoleでは以下のようにステータスが「公開中」に変わります.
App CenterでGoogle Play Connectionを作成する(続き)
まだ公開はされていませんが,ストアにアプリの情報が入ったのでGoogle Play Connectionを作成できるようになりました.
中断していた手順を再開し,ストアに公開したアプリのパッケージ名を入力します.
Connectionが作成され,以下のように表示されます.
App CenterのDistribute -> Stores -> Production
を選択すると,この時点では以下のように「何もないよ」という表示がされます.
App Centerで自動デプロイからストアへ
さて,現時点でmaster
とdevelop
という2つのブランチがあり,ストアにはmasterブランチの内容でアプリを公開してあります.
申請してから公開されるまでの3日間で,ちょっとした修正があり,その修正はdevelopブランチで行いました.
このdevelopブランチの修正をmasterブランチにマージして,その際にストアに自動的にアップロードされるようにしたいと思います. 製品を自動アップロードするのが正しいのかはおいておいて.
上の画面でmasterブランチの🔧
アイコンをクリックして設定画面を開きます.
Distribute builds
の項目でリリース先をStore
にします.
Select destination
というドロップダウンリストがあるので,Production
を選択します.
Release noteの項目を必要であれば記入し,Save
ボタンを押します.
それでは,Githubのほうでdevelopをmasterにマージします.
App Centerのほうでmasterブランチのビルドがはじまりました.
ビルドが完了したあと,Google Play Consoleをみてみると,以下のようにアップデートを処理しています
となりました.
どうやらうまくいったようです.
数日後に処理が完了したらきっとまたメールが来ると思います.
Visual Studio拡張機能(VSIX)をVisual Studio Marketplaceに公開する
前回,Generic Hostを使ったXamarin.FormsプロジェクトのテンプレートをVisual Studio拡張機能として作りました.
今回は,これをVisual Studio Marketplaceに公開したいと思います.
Visual Studio Marketplaceを開きます.
Microsoftアカウントでログインします.
サイト右上のPublish extensions
をクリックします.
Create Publisher
というページが開くので,Marketplaceに公開される自身の情報を入力します.
ページの一番下にCreate
ボタンがあるので,押します.
管理ページが開きます.
画面中央の+ New extension
を押すと,ドロップダウンリストが表示されるので,Visual Studio
を選択します.
拡張機能をアップロードします.
Continue
ボタンを押します.
ワーニングが出てしまった.パスが長すぎるという...
ワーニングだからとりあえずそのままにして,Basic Information
を入力していきます.
Internal name
は拡張機能のURLに使用されるものです.
項目に一通り入力したら,一番下のSave & Upload
をクリックします.
以下のように最初の管理画面のリストに拡張機能が追加されます.
Version
の項目がVerifying
になっていますが,しばらくするとチェックマークに変わります.
今回について言えば,1分もしないうちにステータスが変わりました.
早速リンクをクリックして,この拡張機能のページに移動してみます.
ストアに並べられていることが確認できました.
MarketplaceでのURLは以下のとおりです.
Xamarin.Forms with Generic host Template - Visual Studio Marketplace
しかし,現在の状態はprivate
であり,検索などではひっかからない状態です.これをpublic
にして誰もが見つけられるようにします.
この公開ステータスを変更するには,若干わかりづらいのですが拡張機能名の右側に・・・
のメニューアイコンがあり,それをクリックすると表示されるメニューの中にあります.
このMake Public
をクリックするとストアに公開されます.
さっそく検索してみると,以下のように検索結果に表示されます.
補足
これはJames Montemagnoさんがブログでしょうかいされていたもので,Xamarin.FormsでGeneric hostを使うことでASP.NET Coreと同じDIやロギングの仕組みを使うことができるというものです.
実際に手を動かしたときの記録は以下の一連の記事に書きました.
これを毎回手動でセットアップするのが手間だな,ということでテンプレート化しました.
それをMarketplaceで公開する,というのが今回の記事の目的でした.
VSIXプロジェクトテンプレートを作る
以前にASP.NET Core(Generic Host)のDIの仕組みをXamarin.Formsで利用する手順を書きました.
しかし,毎回この手順を行うのは苦痛なので,プロジェクトのテンプレートを作成したいと思います.
Xamarin.Formsは通常,複数プロジェクト(共有プロジェクト,Android,iOS,UWPなど)からなります.
複数プロジェクトのテンプレートを作成するには以下の公式ドキュメントの「既存のソリューションから複数プロジェクトのテンプレートを作成する」に従います.
雛形となるソリューションを作成する
作成したものがこちらになります.これが「既存のソリューション」に当たります
各プラットフォームのプロジェクトをテンプレートとしてエクスポートする
各プラットフォームのプロジェクトそれぞれについて「Project -> Export Template...」します.
Export Template Wizard
が開くので,作成するテンプレートの種類にはProject template
を選択し,エクスポート対象のプロジェクトを下のドロップダウンリストから選択してNext
ボタンを押します.
次の画面ではテンプレート名などの情報を入力します.
テンプレート名,説明,アイコン,出力先などを指定できますが,ここでは基本デフォルトのままで,一つだけAutomatically import the template into Visual Studio
のチェックを外してFinish
ボタンを押します.
これがついていると,プロジェクトをエクスポートすると同時にVisual Studioにテンプレートとして追加されてしまうためです.
今回はまだVisual Studioに追加されてほしくないので,チェックを外しておきます.
これを各プラットフォームの分だけ行います.今回は共有プロジェクト
,Android
,iOS
の3つです.
出力先はデフォルトでは%USERPROFILE%\Documents\Visual Studio {バージョン:2019とか2017}\My Exported Templates
です.
テンプレートファイルを解凍する
zip形式で出力された各テンプレートファイルですが,これをそれぞれ解凍します.
解凍されてできたフォルダごと,適当なフォルダに移動させます.私はデスクトップに「XFAspNetCoreDITemplate」という名前のフォルダを作って,そこに3つのフォルダを移動させました.
.vstemplate
ファイルを作成する
各テンプレートのフォルダを置いたフォルダに.vstemplate
という拡張子のファイルを作成します.
空のテキストファイルを作成して名前を変更して作ればOkです.
ここではXFAspNetCoreDITemplate.vstemplate
という名前にしました.中身はまだ空です.
vstemplateファイルの中身を書く
vstemplateファイルにはXMLで以下のように書きます.
<VSTemplate Version="3.0.0" xmlns="http://schemas.microsoft.com/developer/vstemplate/2005" Type="ProjectGroup"> <TemplateData> <Name>Xamarin.Forms with ASP.NET Core DI (.NET Standard 2.1)</Name> <Description>Xamarin.Forms with ASP.NET Core DI template.</Description> <ProjectType>CSharp</ProjectType> <Icon></Icon> <DefaultName>XFAppAspDI</DefaultName> <ProvideDefaultName>true</ProvideDefaultName> </TemplateData> <TemplateContent PreferedSolusionConfigration="Debug|Any CPU"> <ProjectCollection> <ProjectTemplateLink ProjectName="$safeprojectname$" CopyParameters="true"> XFAspNetCoreDITemplate\MyTemplate.vstemplate </ProjectTemplateLink> <ProjectTemplateLink ProjectName="$safeprojectname$.Android" CopyParameters="true"> XFAspNetCoreDITemplate.Android\MyTemplate.vstemplate </ProjectTemplateLink> <ProjectTemplateLink ProjectName="$safeprojectname$.iOS" CopyParameters="true"> XFAspNetCoreDITemplate.iOS\MyTemplate.vstemplate </ProjectTemplateLink> </ProjectCollection> </TemplateContent> </VSTemplate>
vstemplateファイル内で各プロジェクトの名前なども指定するのですが,実際に使うときはプロジェクトの名前はユーザーが作成時に入力するソリューション名が使用されるようにしなければなりません.
それをどうするかというと,田淵さんのサンプルにあるように$safeprojectname$
という変数(テンプレートパラメータ)を使います.
テンプレートパラメータに関する公式ドキュメントはこちら.
これで,アプリ作成時に指定したソリューション名に合わせて{ソリューション名}.Android
,{ソリューション名}.iOS
のように各プラットフォームのプロジェクト名がつけられます.
が,プロジェクトの中ではソリューション名が変わらないままです.
例えば,Android,iOSの各プロジェクトから共有コードのプロジェクトを参照しているのですが,その参照先のプロジェクト名が変更されないため,以下のように参照エラーになります.これではいけません.
各プロジェクトの中でソリューション名に指定された文字列を使うためにはここでも先程と同じようにテンプレートパラメータ
を使用します.
どのようなテンプレートパラメータを使用するかというと$ext_safeprojectname
というパラメータです.
Android,iOSの各プロジェクトの.csproj
ファイルの中で,プロジェクトの参照情報の記述があるので,それを以下のように変更します.
<ItemGroup> <ProjectReference Include="..\XFAspNetCoreDITemplate\XFAspNetCoreDITemplate.csproj"> <Project>{7DD7EBB5-8DCB-428D-A7B2-FE93EE1EFC89}</Project> <Name>XFAspNetCoreDITemplate</Name> </ProjectReference> </ItemGroup>
↓
<ItemGroup> <ProjectReference Include="..\$ext_safeprojectname$\$ext_safeprojectname$.csproj"> <Project>{7DD7EBB5-8DCB-428D-A7B2-FE93EE1EFC89}</Project> <Name>$ext_safeprojectname$</Name> </ProjectReference> </ItemGroup>
あともう一点,変更箇所がありました.基本的にはAndroidもiOSも同じです.
<PropertyGroup> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <ProjectGuid>{$guid1$}</ProjectGuid> <ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> <TemplateGuid>{c9e5eea5-ca05-42a1-839b-61506e0a37df}</TemplateGuid> <OutputType>Library</OutputType> <RootNamespace>$ext_safeprojectname$</RootNamespace> <AssemblyName>$ext_safeprojectname$.Android</AssemblyName>
ピックアップすると以下の箇所です.
<ProjectGuid>{$guid1$}</ProjectGuid>
<RootNamespace>$ext_safeprojectname$</RootNamespace>
<AssemblyName>$ext_safeprojectname$.Android</AssemblyName>
以上のように修正して保存します.
フォルダとvstemplateファイルをzip形式に圧縮する
以下のようにフォルダとファイルを選択してzipにします.
テンプレートフォルダに配置
以下のフォルダに先程作成したzipファイルを配置します.
%USERPROFILE%\Documents\Visual Studio 2019\Templates\ProjectTemplates
これで準備完了です.
Visual Studioを閉じてから再び起動します.
試してみる.
プロジェクトの新規作成でテンプレートを検索すると,以下のように先程作成したテンプレートが見つかります.
デフォルトのプロジェクト名も指定したとおりになっています.
ソースコード
テンプレートのもとにしたプロジェクト
テンプレート(zip前)
これをzipで固めると,プロジェクトテンプレートになります.
テンプレートの公開
作成したテンプレートを他の端末や,多くの人に使ってもらいたい場合,テンプレートを拡張機能として公開すると便利でしょう.
その場合は以下の手順を行います.
VSIXファイルを作成する
VSIXプロジェクトを作成するのですが,VSIXプロジェクトを作成するにはVisual Studio SDK
をインストールしておく必要があるので,インストールします.
Visual Studio SDKのインストール
インストールはVisual Studio Installer
からVisual Studio extension development
というワークロードを選択することでインストールされます.
約3GBあるので,インストールの完了を気長に待ちます.
VSIXプロジェクトの作成
Visual Studio SDKのインストールが完了したら,Visual Studioを起動してC#
のEmpty VSIX Project
を新規作成します.
プロジェクト名はこのようにしました.
テンプレートファイル(zip)をプロジェクトに追加する
ソリューションエクスプローラでVSIXプロジェクトを右クリックしてコンテキストメニューからAdd -> Existing Item
を選択します.
ファイル選択ダイアログが開くのでファイルの種類をAll Files
にして,先程出力したテンプレートファイル(zip)を選択します.
ソリューションエクスプローラ上で,追加したテンプレートファイルを右クリックしてコンテキストメニューからProperty
を選択し,Copy to Output Directory
の項目にCopy always
を指定します.
source.extension.vsixmanifestを編集する
VSIXプロジェクトの中にsource.extension.vsixmanifest
というファイルがあるので,ダブルクリックしてデザイナを開きます.
デザイナではMetadata
のページで以下のように入力します.
次にAssets
のページでNew
ボタンを押します.
以下のウィンドウが表示されるので以下のように各項目を指定します.
Type
にはMicrosoft.VisualStudio.ProjectTemplate
を指定.Source
はFile on filesystem
を指定.Path
にテンプレートファイル(zip)を指定します.
OK
ボタンを押します.
すると,ソリューションには以下のようにフォルダが作成され,その中にテンプレートファイルがインポートされます.
VSIXプロジェクトをビルドする
ビルドすると,VSIXプロジェクト内のbin\Debug(またはRelease)
フォルダ内に以下のような.vsix
ファイルが生成されます.
拡張機能としてテンプレートをインストールする
この中のvsixファイルをダブルクリックするとインストールが始まります.
インストールが完了したらVisual Studioを起動します.
プロジェクト新規作成でテンプレートを検索すると,以下のようにインストールしたテンプレートが見つかります.
20200715追記
Releaseビルドしたvsixファイルをインストールしようとすると,以下のようにサインがない,と言われてインストールできないことがあります.
App CenterのAnalyticsを使う.
www.slideshare.net
アプリケーションの利用状況やクラッシュ
App Center SDKの導入
App Centerの各アプリケーションのトップに表示されるGetting Startedにもあるように以下の2ステップで導入できます.
- Nugetからパッケージのインストール
以下の3つのパッケージをインストールする.
次のパッケージはTurnip Trackerではインストールされていたが,用途がよくわからない.
App Centerに登録したアプリケーションのOverview
には大切な情報が書いてある.
ここにGetting Started
という情報があって,そこにはApp.xaml.csのOnStartメソッドに以下のように書けとある.
Xamarin.NativeとXamarin.Formsで書き方が異なるので注意.
androidの********
の部分にはGUIDが書かれているのだが,これ,ただのサンプルコードではなく,このGUIDを使わないとApp Center SDKから情報が送られないようだ.
AppCenter.Start("android=**************************;" + "uwp={Your UWP App secret here};" + "ios={Your iOS App secret here}", typeof(Analytics), typeof(Crashes));
てっきりこれは記述例だと思っていたので,適当な文字列を使用したらまったくApp Centerにデータが送られてこないので困った.
App Centerでは1つのアプリでもプラットフォームごとに登録していくのだが,おそらく各プラットフォームのGetting Started
にそのプラットフォーム用のGUIDの情報が表示されるのだろうと思う.
さて,Start
メソッドについて.
1つ目の引数はApp Secret
とある.
2つ目以降は使用するServiceで,例えばCrashesとAnalyticsを使うのであれば上記のように列挙する.
今回はOnStartメソッドに以下のように書いた.
各プラットフォームごとのApp Secretは同じ文字列を使ってはいけない,とのこと.
protected override void OnStart() { string android = this._config["AppCenter_AppSecret_Android"]; string ios = this._config["AppCenter_AppSecret_iOS"]; string uwp = this._config["AppCenter_AppSecret_UWP"]; AppCenter.Start($"android={android};" + $"uwp={uwp};" + $"ios={ios}", typeof(Analytics), typeof(Crashes)); }
appsettings.jsonに記載された情報を取得して使用する.このあたりの仕組については以前に書いた記事を参考にする.
機密情報はApp Centerの環境変数に設定しておき,コード内には記述しないようにしている. App Centerのビルドスクリプトで機密情報を差し込み,ビルドしている.
使ってみる
ユーザーの行動をトラッキングしたい箇所で,「名前」と必要に応じて「任意の情報」をDictionary形式で付加する.
Analytics.TrackEvent("OpenBrowser", new Dictionary<string, string> { ["sessionId"] = SessionInfo.SessionID, ["uri"] = uri, });
そして実行してみると,それぞれTrackEvent
メソッドを挿入した箇所を処理が通ると,App CenterのAnalytics
にデータが表示される.
オフラインの場合
10MBまでローカルストレージに保存する.
10MBを超えたら古いものから削除していく.
オンラインになったときに50個一気に送るか,3秒ごとに送信する?