Windows Phoneアプリケーション開発入門

第34回 Mangoで追加されたSaveRingtoneTaskを使って着信音を登録してみよう!

この記事を読むのに必要な時間:およそ 3 分

リソースファイルを分離ストレージへ保存する

一般的なアプリケーションでSaveRingtoneTaskを使用するケースを考えた場合,アプリケーション内のリソースを着信音に登録するようなケースはほぼなく,インターネット上の楽曲ファイルをダウンロードしてきて着信音に登録することがほとんどだと思いますので,分離ストレージから着信音を設定できるようにします。

まず,アプリケーションリソースとして持っているMP3ファイルを分離ストレージに保存します。

なんらかのストリームから分離ストレージへの保存処理自体は連載第29回ストリームを分離ストレージのファイルに書き出す処理のものを流用しています。

Application.GetResourceStreamメソッドでURIを指定して,楽曲データのリソースを取り出します。取り出したリソースのストリームから,IsolatedStorageFileを使って分離ストレージへの書き出しを行っております。

// アプリケーションリソースファイルを分離ストレージへ保存する
private void SaveFileTo(string fileName)
{
    var resourceStream = Application.GetResourceStream(new Uri(fileName, UriKind.Relative));

    var store = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication();
    // 以前に作成したファイルが残っている場合は削除する
    if (store.FileExists(fileName))
    {
        store.DeleteFile(fileName);
    }

    // 読み込んだストリームを分離ストレージのファイルに書き出す
    using (var strm = store.CreateFile(fileName))
    using (var reader = new System.IO.BinaryReader(resourceStream.Stream))
    {
        var bytes = new byte[256 * 1024];
        while (true)
        {
            int read = reader.Read(bytes, 0, bytes.Length);
            if (read <= 0) break;
            strm.Write(bytes, 0, read);
        }
    }

    store.Dispose();
}
' アプリケーションリソースファイルを分離ストレージへ保存する
Private Sub SaveFileTo(fileName As String)
    Dim resourceStream = Application.GetResourceStream(New Uri(fileName, UriKind.Relative))

    Dim store = System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication()
    ' 以前に作成したファイルが残っている場合は削除する
    If store.FileExists(fileName) Then
        store.DeleteFile(fileName)
    End If

    ' 読み込んだストリームを分離ストレージのファイルに書き出す
    Using strm = store.CreateFile(fileName)
        Using reader = New System.IO.BinaryReader(resourceStream.Stream)
            Dim bytes = New Byte(256 * 1024 - 1) {}
            While True
                Dim read As Integer = reader.Read(bytes, 0, bytes.Length)
                If read <= 0 Then
                    Exit While
                End If
                strm.Write(bytes, 0, read)
            End While
        End Using
    End Using

    store.Dispose()
End Sub

SaveFileToメソッドにリソース名(例えばsample.mp3)を渡すと,アプリケーションそのものからリソースを取得して,分離ストレージへ同じリソース名で保存を行うことができるようになりました。

SaveRingtoneTaskを使って着信音を登録する

先ほどアプリケーションリソースを分離ストレージへ保存するメソッドを作りました。ボタンをタップされたのをトリガーにして着信音を登録してみましょう。MainPage.xamlに適当なボタンを配置して,Clickイベントにイベントハンドラを設定します。

<Button Content="SaveRingtone" Height="89" HorizontalAlignment="Left" Margin="6,322,0,0" x:Name="btnSaveRingtone" VerticalAlignment="Top" Width="444" Click="btnSaveRingtone_Click" />

ボタンがタップされると,btnSaveRingtone_Clickメソッドが呼び出され,SaveFileToメソッドを使ってリソースを分離ストレージへ保存します。あとは分離ストレージへ保存したMP3ファイルのパスを設定するだけなのですが,ほかのChooserと同じでShowメソッドを呼ぶ前にいくつかのプロパティを設定しておくことができます。

DisplayNameプロパティを設定すると,Showメソッドで呼び出される登録画面の初期表示の着信音名を決めておくことができます。またほかのアプリケーションから使わせなくするために,登録した着信音をDRM保護したい場合は,SaveRingtoneTaskのIsShareableプロパティにfalseを設定します。下記の例ではtrueを設定しています。

最後にSourceプロパティへ分離ストレージに保存したファイルパスを「isostore:/」というスキーマを使用して指定しています。http:// のようにスラッシュを2つ付けないように気を付けてください。

今回使用するSaveRingtoneTaskを始め,登録や取得が完了した時点でCompletedイベントを発行するChooserは非同期で動作します。下記のサンプルコードでは,非同期処理を簡単に制御できるようにReactive Extention(Rx)というフレームワークを使用します。

Reactive Extentionを使うには,Microsoft.Phone.ReactiveとSystem.Observableを参照しておく必要がありますので,ソリューションエクスプローラーから参照を追加を行っておいてください。

private void btnSaveRingtone_Click(object sender, RoutedEventArgs e)
{
    // アプリケーションリソースのMP3ファイルを分離ストレージに保存する
    SaveFileTo("sample.mp3"); 

    var saveRingToneTask = new SaveRingtoneTask();
    saveRingToneTask.DisplayName = "JUMP ON!";
    saveRingToneTask.IsShareable = true;
    saveRingToneTask.Source = new Uri("isostore:/sample.mp3");

    Observable.FromEvent<TaskEventArgs>(
        h => saveRingToneTask.Completed += h,
        h => saveRingToneTask.Completed -= h)
        .Subscribe(ex =>
        {
            // 着信音の保存に成功
            if (ex.EventArgs.TaskResult == TaskResult.OK)
                MessageBox.Show("Save Success!");
        });
    saveRingToneTask.Show();
}
Private Sub btnSaveRingtone_Click(sender As Object, e As RoutedEventArgs)

    ' アプリケーションリソースのMP3ファイルを分離ストレージに保存する
    SaveFileTo("sample.mp3")

    Dim saveRingToneTask = New SaveRingtoneTask()
    saveRingToneTask.DisplayName = "JUMP ON!" 
    saveRingToneTask.IsShareable = True
    saveRingToneTask.Source = New Uri("isostore:/sample.mp3")

    Observable.FromEvent(Of TaskEventArgs)(
        Sub(h) AddHandler saveRingToneTask.Completed, h,
        Sub(h) RemoveHandler saveRingToneTask.Completed, h) _
    .Subscribe(Sub(ex)
                   ' 着信音の保存に成功
                   If ex.EventArgs.TaskResult = TaskResult.OK Then
                       MessageBox.Show("Save Success!")
                   End If
               End Sub)
    saveRingToneTask.Show()
End Sub

上記のコードが正しく実行されると,Save ringtone画面が表示されます。ここでシステムに登録する名前を設定して,アプリケーションバーのチェックボタンをタップすると,着信音の登録は完了です。

画像

Windows Phone Emulatorでは,settings(設定アプリ)「ringtones + sounds」の項目が表示されません。以降は,サンプルアプリケーションを実機にデプロイしたものを使用して確認したいと思います。画質が良くありませんがご了承ください。

一番上に表示されている項目「ringtones+sounds」を選択します。

画像

いくつか設定項目がありますが「Ringtone」を選択します。写真上では画面中央の「Pure」が選択されている項目です。

画像

Customの項目に,先ほど設定した名前で着信音が登録されているのを確認してください。⁠JUMP ON!」の左側にある再生ボタンをタップして,きちんと曲が再生されれば成功です。

画像

登録した着信音を削除したい場合は,アイテムを長押しすると「delete」が表示されます。そのまま選択しましょう。

さいごに

2011年8月10日より「Windows Phone 評価端末プログラム」が開始されます。具体的な情報は現段階では公開されておりませんが,Windows Phone Developer Dayに参加されて応募用紙を提出された方を対象に8月10日より申し込みが可能になるようです。

この評価端末プログラムは,世界で始めてWindows Phone 7.5端末の発売される日本独自のプログラムとなっているようです。日本市場でのWindows Phoneの普及に本気で力を注がれているのが感じられます。

以上で今回は終わりです。ありがとうございました。

著者プロフィール

和田健司(わだけんじ)

1982年10月12日生まれ。大阪で働くプログラマ。Microsoft MVP for Device Application Development(Jul 2010 - Jun 2011)。Windows Mobileに傾倒し今に至る。Windows Mobile向けのTipsを書いています。iPhoneアプリ開発を始めました。嫌いな食べ物はカレー。

URL: http://ch3cooh.jp/
Blog: http://d.hatena.ne.jp/ch3cooh393/