2010年10月29日金曜日

RingerVolume と Media Volume のコントロール

悩みました。

本体の音量コントロールキーでは、

android.media.MediaPlayerで再生している場合は、
MediaVolume が操作されるのですが、

止まっている間や、android.media.MediaPlayerで再生していない場合は、Ringer Volumeが操作されます。

で、これをすべて「Media Volume」に寄せたかったのですが、寄せ方がわかりませんでした。

どうやら、Activityの onCreate 内で以下のおまじないを実行すると、
画面表示中に、ずっと「Media Volume」が操作対象となります。

setVolumeControlStream(AudioManager.STREAM_MUSIC);

やっと探しました。

2010年10月26日火曜日

Android アプリで設定音量を取得&再生音量に設定する。

アプリでシステムの着信音量設定を取得して、効果音をその設定音量に合わせるには、以下のとおり。

使用パッケージはandroid.media.AudioManagerとandroid.media.SoundPool。
soundpool.playと同時に音量を設定することもできるし、事前にsoundpool.setVolumeすることもできる。

package jp.mediba.android.testapp;

import java.util.List;
import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;

public class Out extends Activity {

 SoundPool soundPool;
 int[] sounds = new int[1];
 
 public void onCreate(Bundle savedInstanceState) {
     
  super.onCreate(savedInstanceState);
  setContentView(R.layout.out);

  int[] sounds = new int[1];
  SoundPool soundPool;
  soundPool = new SoundPool(1, AudioManager.STREAM_RING, 0);
  sounds[0] = soundPool.load(this, R.raw.omikuji_bar, 1);

  AudioManager audio = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
  int ringVol = audio.getStreamVolume(AudioManager.STREAM_RING);
  soundPool.play(sounds[0], (float)ringVol, (float)ringVol, 0, 0, 1.0F);
 }
}

2010年10月19日火曜日

XCodeとInterfaceBuilderで10分でモックアプリを作る方法(2)

全部で5回の予定です。
おそらく5回書き終わってからでないとあまり意味のない記事になっちゃいました…。
でも頑張ります。


プロジェクトの作成

View-Basedの一番シンプルなアプリをテンプレートから作成します。


これでiPhoneアプリをまず一つ作成します。





プロジェクトを保存し、シミュレーターを使って起動してみると、
Viewがひとつだけあるグレーの画面がひとつだけあるアプリが出来ます。

とりあえずの動作確認は、緑色の<ビルドと実行>をおすと、シミュレーターで確認できます。



NavigationTestViewController.xib が、このアプリの最初のViewです。
これを上の画面遷移の、「タイトル」とします。

部品を埋めていきます。
画面遷移にはボタンを使うことにします。

NavigationTestViewController.xibをダブルクリックするとInterfaceBuilderが立ち上がります。
これに遷移用のボタンを3つ作成してください。
ボタンをDrag & Drop 出来上がったボタンに分かりやすいように名前をつけました。



これを他の画面についても繰り返していきます。

画面の部品配置用のファイルを追加して、からボタンを配置していきます。

タイトル画面:NavigationTestViewController.xib
メイン画面:MainViewController.xib
結果画面:ResultViewController.xib
ヘルプ画面:HelpViewController.xib
設定画面:HelpViewController.xib


こんな感じ。
nibファイルの作成
View-Controllerのsubclass



メイン画面:MainViewController.xib
をダブルクリックして、IBを立ち上げボタンを配置します。

メイン画面なので、「結果に進む」だけのボタンだけ配置します。
(戻れないけどまあいいかと。)



というかんじで、以下の3つについても、命名規則をあわせて、同じ手順で作ります。

結果画面:ResultViewController.xib
ヘルプ画面:HelpViewController.xib
設定画面:SettingViewController.xib

全部作り終わると、画面ファイルはこんな感じです。




この状態で、GUIの準備はできました。
あとは、それぞれのボタンと、動作Actionを関連付けていきます。









ここからは、しばらくInterfaceBuilderの作業になります。

一度、すべてのxibファイルを閉じて、タイトル画面である、NavigationTestViewController.xibをダブルクリックして、表示します。

このファイルに「ボタンを押すと別画面に遷移する」という動作を関連付けましょう。
ここから出てくるファイルは、以下の3つです。

NavigationTestViewController.xib これは InterfaceBuilderでゴニョゴニョするだけ。

NavigationTestViewController.m これには、methodを追加します。
NavigationTestViewController.h これには、methodの定義だけを追加します。

じゃっそういうことでこれは明日やりますか。

2010年10月18日月曜日

XCodeとInterfaceBuilderで10分でモックアプリを作る方法(1)

iPhone App 開発者としては、初心者のmarcovです。

AppleのiOS関連の開発ツールには、プログラムを書くIDEであるXcodeとGUIを作成するInterfaceBuilder(以下IB)が、付属しています。

また、簡単にアプリを作るためのフォーマットも用意されており、XCodeでiPhoneアプリのテンプレートを選ぶと、取りあえず動くものが出来るのですが、これでは全く物足りません。

普通のゲームのようなアプリを作るときは、メニュー画面とゲーム画面、加えて設定画面、ヘルプ画面の最低でも4つ程の画面は必要だと思われますが、これらを作るときに、Xcodeの新規作成のプロジェクトでは、帯に短しタスキに長しです。

というわけで、画面が4つだけあるような、アプリを作って画面遷移だけしてみます。
これだけできていると、デザイナーから上がってきた、アプリをモックとして、動かすことができるので非常に便利です。また、WEBのライトウェイトプログラマーである自分としても、とりあえずの画面遷移が出来ていると作るターゲットがだいたい決まっているように見えて気分で気にも楽ですね。


全部で5回の予定です。
おそらく5回書き終わってからでないとあまり意味のない記事になっちゃいました…。
でも頑張ります。


今回はこんなアプリを作成します。



タイトル画面から、遷移してそれぞれもどってくるタイプです。
メインと、結果のページに付いては、一方向に流れてタイトルに戻ります。

続きはまた明日。

2010年10月6日水曜日

Android開発 - SQLiteでの日付型データ保存

現在開発中のアプリにおいて、SQLiteデータベースにデータの更新日時を保存したいのですが、
下記のように標準のSQLiteDatabaseライブラリのインサートメソッドを使うと、

ContentValuesvalues = new ContentValues();
values.put("datetime", "datetime('now', 'localtime')");
db.insert("tablename", null, values);

 datetime('now', 'localtime')がそのまま文字列として保存されてしまいます。
(SQLiteには日付のデータ型は存在しないためdatetimeカラムはTEXT型

おそらくライブラリがString型の変数に対して " " で囲ってSQLを発行するためと思われます。

 回避策として、

String sql  =  "INSERT INTO tablename" +
                       "(datetime) " +
                       "VALUES(datetime('now', 'localtime'));";
db.execSQL(sql);

といった形で直接SQLを記述して実行するとうまくいきました。

なんだか納得行かないのでメモ書き。

2010年10月4日月曜日

Android開発 - フェードインアニメーション

アプリケーション起動時にタイトルロゴをフェードインさせるページの実装方法です。


黒一色の画面から白バックのロゴ画像がフェードインします。

アニメーションの定義方法はこちらを参考にしました。
http://android.roof-balcony.com/resource/animation/

■res/anim/にアニメーション定義のXMLファイルを作成。



    android:duration="3000" 
    android:fromAlpha="0.0"
    android:toAlpha="1.0"
    android:interpolator="@android:anim/decelerate_interpolator"
    />


■レイアウトのXMLファイルは以下のとおりです。


android:id="@+id/MainLayout"
android:orientation="vertical"
android:layout_width="320dp"
android:layout_height="455dp"
android:background="#FFFFFF"
>


android:id="@+id/ImageLogo" 
android:src="@drawable/******" 
android:layout_gravity="center" 
android:layout_marginTop="180dp"
android:layout_width="272dp" 
android:layout_height="76dp" 
>

今回はLinearLayoutごとフェードインさせます。

■Javaファイルの記述

package ***********************************;

import android.app.Activity;
import android.os.Bundle;
import android.content.Intent;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.LinearLayout;

public class **** extends Activity implements AnimationListener{

private Animation fadeIn;
private LinearLayout mainLayout;
private Intent intent;

@Override
public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);
setContentView(R.layout.****);

mainLayout = (LinearLayout)findViewById(R.id.MainLayout);

fadeIn = AnimationUtils.loadAnimation(this, R.anim.****);
fadeIn.setAnimationListener(this);
mainLayout.setAnimation(fadeIn);
}

@Override
public void onAnimationEnd(Animation animation) {

// フェードイン完了後次の画面へ
if (animation == fadeIn) {
intent = new Intent(this, ****.class);
startActivity(intent);
finish();
}

}

@Override
public void onAnimationRepeat(Animation animation) {

}

@Override
public void onAnimationStart(Animation animation) {

}
}

onCreate()時にレイアウトとアニメーションのXMLを指定し、setAnimationListenerにセットします。
対象のアニメーションが終了したときにonAnimationEnd()がコールされ、次のアクティビティに移動します。

このアクティビティをManifestファイルで起動アクティビティに指定すると、

起動 -> 画像のフェードイン表示 -> メイン画面(メニュー画面など)

といったよく見る流れの実装が可能です。

一旦アプリを中断し、再開した場合に再度ロゴアニメーションが表示されるのは鬱陶しいので
次のアクティビティを呼び出した後finish()をかけています。

画面遷移のアニメーションについてはXMLのみで実装する方法もあるらしいので、いずれ調査したいと思います。