2012年10月13日土曜日

Distributed Genetic Programming Framework

The Distributed Genetic Programming Framework (DGPF) is a scalable Java environment for heuristic, simulation-based search algorithms of any kind and Genetic Algorithms in special. We use the broad foundation of a search algorithms layer to provide a Genetic Programming system which is able to create Turing-complete code.

The main focus of our project is put on the automated creation of programs that should drive sensor networks. Such programs are instantiated on many automata which are able to communicate with each other wirelessly in an unreliable manner. Therefore, network simulators able to simulate whole networks of such automata are used. By doing so, we hope to be able to create emergent behaviors and self*-properties in large scale distributed systems.

Our system is not bound to Genetic Programming, nor even bound to Genetic Algorithms at all. You can easily implement other search algorithms (like Simulated Annealing or such and such) and use the distribution utilities to distribute them over a network. In the near future we will implement many of these algorithms ourselves and provide them here.

While the system can run on a single computer, one of its main strengths is its distribution-ability. Different search algorithms using different distribution mechanisms can easily implemented. You can find versatile implementations of Genetic Algorithms driven by a Genetic Engine in the Genetic Algorithms layer.

We support four different types of distribution of computational load for our genetic algorithms:
1. local: The whole population runs local, no tasks are distributed.
2. peer-to-peer / island hopping: Big virtual populations can be created if peer-to-peer nodes cooperate in a network.
3. client-server/master-slave: A genetic engine (client/master) uses different servers/slaves to perform the work of reproducing and evaluating individuals. This way, even populations of complicated-to-evaluated individuals can be handled in reasonable time.
4. p2p/cs-hybrid: P2P-networks of genetic engines using the client-server distribution approach can co-operate (event with pure p2p-genetic engines).

Other search algorithms can simple be implemented too - we've currently added Hill Climbing. Since the distribution tools we use are unified, the Hill Climbing based searches can be distributed in the same way than the Genetic Algorithms. Moreover, bothe search algorithms can interact and form a heterogeneous search. Another nice fact is, that each search algorithm implemented in the framework will automatically come equipped with an auto-adaptive, configurable Tabu Search backend improving problem space examination.

This Open-Source research project is licensed under LGPL, a license even more liberate than the GPL.

You might experience problems when compiling our project. This is due to an incompatibility of the Eclipse 3.1.1 compiler to Sun's JavaC compiler regarding Generics (introduced in Java 1.5/ J2SE 5.0). We cannot resolve this issue since this problem is not originated in our project. Therefore, the project currently can only be compiled with Eclipse.
Learn more about Eclipse 3.1.1 and its installation 
here.
Learn more about the incompatibility problem in our 
newsfeed or in the regarding Sun Developer Network Thread
.

Linux Foundation to offer signed solution for UEFI Secure Boot conundrum

Microsoft is demanding that systems with the "Designed for Windows 8" badge include a UEFI firmware feature called "Secure Boot" that will only boot software that has been signed with a particular cryptographic certificate. Although Microsoft's stipulations require also that x86/x64 systems provide an option to disable Secure Boot, Linux users are concerned that this will make it harder for them to boot non-Microsoft operating systems.

The Linux Foundation has announced plans to provide a general purpose solution suitable for use by Linux and other non-Microsoft operating systems. The group has produced a minimal bootloader that won't boot any operating system directly. Instead, it will transfer control to any other bootloader—signed or unsigned—so that that can boot an operating system.

On the face of it, this bootloader could be used to circumvent the security of Secure Boot. The entire point of Secure Boot is that it doesn't allow unsigned (and potentially malicious) code to be run before the operating system is started. To address this, the Linux Foundation bootloader will present its own splash screen and require user input before it actually boots. In this way, it can't be silently installed and used to hand control to a rootkit without the user's knowledge.

The Linux Foundation's bootloader is not the only solution for the Secure Boot conundrum. Technically skilled users will be able to add their own trusted certificates to the computer's firmware, and some major Linux distributions including Fedora, SUSE, and Ubuntu intend to provide their own solution to the problem.

However, the Linux Foundation's work is still useful, as it provides a solution that will be suitable for minor distributions, those unable or unwilling to acquire a signature for their bootloader, and anyone developing their own boot system.

明示的InterntをPendingIntentを経由して使う

今回のようなケースでは、受信側のクラスが指定されるので、明示的Intentで書く必要があります。

でも、それだけではなくて、生成したIntentをそのままアラームやボタンに定義はできません。

アラームやボタンにインテントを仕掛けるには、PendingIntentへ組み込んで、後で打ち出し処理が

出来るようにしてやる必要があります。

花火に例えるとIntent打ち上げ用の打ち上げ筒=PendingIntent、アラーム=発火装置と考えれば

いいでしょうか。

下記の例ではアラームにセットするためにPendingIntentを使用していますが、AppWidgetProviderの

上に定義したボタン等からIntentを飛ばす際にもこのPendigIntentを使用する必要があります。

実際の使い方は

Uri uri = Uri.parse("http://google.com");

Intent intent = new Intent(Intent.ACTION_VIEW, uri);

PendingIntent sender = PendingIntent.getBroadcast(ctx, 0, intent, 0);

AlarmManager am = (AlarmManager)(ctx.getSystemService(ALARM_SERVICE));

Calendar cal = Calendar.getInstance();

cal.setTimeInMillis(currentTime);

cal.set(Calendar.MINUTE, 5);

am.set(AlarmManager.RTC_WAKEUP,cal.aTimerInMillis,sender);

※やっぱり嘘入りでした。_wakeupが付いていると、消費電力対策になりません。イベント発生時に強制的に起動してしまいます。

違っていたらミクのソース見て後で直します。

2012年10月11日木曜日

[android] Context Menuを作ってみる

コンテキストメニューは、ビューを長押しした時にポップアップされるアレのことです。

Windowsだと右クリックで出てくるヤツですね。

やることは以下の通り。

registerForContextMenu() でビューを登録
onCreateContextMenu() をオーバーライドしてコンテキストメニューを作成
onContextItemSelected() をオーバーライドしてコンテキストメニュー選択時の動作を記述

01 public class SampleActivity extends Activity {
02
03 /** リストビューに表示するアイテム. */
04 private List<String> list;
05
06 @Override
07 public void onCreate(Bundle savedInstanceState) {
08 super.onCreate(savedInstanceState);
09 setContentView(R.layout.main);
10
11 // リストビューに表示するリストを作成
12 list = new ArrayList<String>();
13 list.add("Test 001");
14 list.add("Test 002");
15 list.add("Test 003");
16 list.add("Test 004");
17 list.add("Test 005");
18
19 // アダプタを作成
20 ListAdapter adapter = new ArrayAdapter<String>(
21 this,
22 android.R.layout.simple_list_item_1,
23 list
24 );
25
26 // リストビューにアダプタを設定
27 ListView listView = (ListView) findViewById(R.id.ListView);
28 listView.setAdapter(adapter);
29
30 // コンテキストメニューのためにリストビューを登録
31 registerForContextMenu(listView);
32 }
33
34 @Override
35 public void onCreateContextMenu(
36 ContextMenu menu,
37 View v,
38 ContextMenuInfo menuInfo) {
39
40 // コンテキストメニューを作る
41 menu.setHeaderTitle("たいとる");
42 menu.add("めにゅ?1");
43 menu.add("めにゅ?2");
44 menu.add("めにゅ?3");
45
46 super.onCreateContextMenu(menu, v, menuInfo);
47 }
48
49 @Override
50 public boolean onContextItemSelected(MenuItem item) {
51 // 選択されたヤツをテキストビューに設定する
52 TextView textView = (TextView) findViewById(R.id.TextView);
53 textView.setText("selected: " + item.getTitle());
54
55 return super.onContextItemSelected(item);
56 }
57 }

ListViewでContextMenuを実装する

ListViewをContextMenuに設定する場合を書いときます。

Androidのメニューには大きく2つあります。

OptionMenuとContextMenuとですが、Androidアプリはこれらのメニューを実装するための手続きが異なります。

OptionMenuはAndroid端末のメニューボタンを押した時に動作するメニューのこと、

ContextMenuは画面上のあるコンポーネントを長押しした時に動作するメニューのことです。

使い分けですが、

アプリケーション全体に関わる機能はOptionMenu、

選択した要素の補助的な機能はContextMenuで実装するのが望ましい」

ガイドラインに書いてあります。

Windowsの通常使うアプリケーションで言うと、

OptionMenuはウインドウ上部のメニューバー、

ContextMenuは右クリックしたときのメニューに相当するんじゃないかと勝手に考えます。

さて、今日のお題は以下のListViewのある要素に対するContextMenuを実装することです。

f:id:ats337:20110222004256p:image

上記はListViewでJリーグの試合結果を表示しています。

任意のチームを長押しすることで、そのチームのサブメニューが表示されるイメージです。

それではコードを示します。

public class RankingListActivity extends Activity {      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          setContentView(R.layout.main);            // ランキングリストを取得          ArrayList list = (ArrayList) getIntent().getSerializableExtra("RANKING_LIST");          setRank(list);            // ListViewを生成          ListView listView = (ListView) findViewById(R.id.mainListView01);            // Adapterを生成          SimpleAdapter adapter = new SimpleAdapter(          		this,          		list,          		R.layout.ranking_item,          		new String[]{"rank", "teamName", "win", "lose", "draw", "point"},          		new int[]{R.id.rank, R.id.teamName, R.id.win, R.id.lose, R.id.draw, R.id.point});            // ListViewにアダプタを設定          listView.setAdapter(adapter);            // コンテキストメニュー登録          registerForContextMenu(listView);        }          /**       * コンテキストメニュー生成時処理       */      public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo info) {      	super.onCreateContextMenu(menu, view, info);      	AdapterContextMenuInfo adapterInfo = (AdapterContextMenuInfo) info;      	ListView listView = (ListView) view;      	Map rankingMap = (Map) listView.getItemAtPosition(adapterInfo.position);        	menu.setHeaderTitle((String) rankingMap.get("teamName"));      	menu.add("直近10試合");      	menu.add("年別成績");      }  }  

Activityを継承したRankingListActivityクラスが本画面を示します。

ランキングリストはチーム名、順位、勝ち点等の情報を含んだ

Mapオブジェクトを持つリストで、ListViewの1つの要素となります。

ContextMenuを実装するには、以下の2つを実装する必要があります。

ContextMenuの登録

registerForContextMenuメソッドを呼び出すことでContextMenuが使える状態になります。

引数はViewクラスのインスタンスを引き渡します。

コンテキストメニュー生成時の処理

onCreateContextMenuメソッドをオーバーライドする形で実装します。

ContextMenuオブジェクトのsetHeaderTitleでウインドウ上部のタイトルが、

addでメニューリスト部分のテキストを出力できます。

ListViewの場合は、押された要素の情報も欲しいでしょう。

押された要素の情報を取得するためには

ContextMenuInfoのインスタンスをAdapterContextMenuInfoでキャストし、

positionフィールドにアクセスすることで、押された要素のインデックスを取得することができます。

あとは、ViewをListViewにキャストして、getItemAtPositionで要素をもらってくるだけ。

ここがミソだったりします。

更に、ContextMenuのメニュー押下時の実装はまた今度の機会にでも・・・・・。

Show a context menu for long-clicks in an Android ListView

Source code for this blog post is available as a complete Eclipse project at
http://github.com/mikeplate/ListViewDemo (zip download link in upper right
corner).
An Activity with an expanding ListView and a docked TextView

If you have an activity that will only contain a single ListView control,
you can derive your activity from the ListActivity instead of Activity.
However, I think I might like to show some extra info below my ListView so I
chose to have a separate ListView object. My activity layout looks like
this:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<ListView
android:id="@+id/list"
android:layout_width="fill_parent"
android:layout_height="0px"
android:layout_weight="1"
/>
<TextView
android:id="@+id/footer"
android:layout_width="fill_parent"
android:layout_height="60dip"
android:text="@string/footer"
android:padding="4dip"
android:background="#FF666666"
/>
</LinearLayout>
And I need the layout for items in the ListView (listitem.xml):
<?xml version="1.0" encoding="utf-8"?>
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="24dip"
android:padding="8dip"
/>
Note a nice trick that I've used to get the TextView to "dock" at the
bottom with a definied height, and have the ListView automatically fill out
the rest of the height. This kind of thinking is important since Android
devices can have different resolutions. The trick is to set the
layout_height to zero pixels and the layout_weight to one (default is zero).
Not sure about the logic behind that, but it works!

In order to have something to put into my ListView, I created a few country
names in a string array as a resource and I sort that array before adding it
to the ListView with the ArrayAdapter object. (Check out source code link
above for this content.)
public class ListViewDemoActivity extends Activity {
private String[] Countries;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Countries = getResources().getStringArray(R.array.countries);
Arrays.sort(Countries);

ListView list = (ListView)findViewById(R.id.list);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
R.layout.listitem, Countries);
list.setAdapter(adapter);
registerForContextMenu(list);
}
}
Creating a ContextMenu in Android

When the user long-clicks, the event onCreateContextMenu is fired for the
control that the user is clicking. For me, that is the ListView control. But
since I don't want to write a custom ListView-derived class, I want to
catch that event in my activity. There does not seem to be any bubbling
going on. Events fired in a child control does not bubble up to the parent
if they are unhandled.
But obviously, the api designers have thought of this since there is a
special method for this situation. Call the registerForContextMenu in your
activity for this! This will actually make sure your overridden methods for
both onCreateContextMenu and onContextItemSelected is called for the
ListView-events as we'll see soon.
Next, we'll provide the implementation of onCreateContextMenu. Here I want
to ensure that the event comes from the ListView and if so, I want to
determine on which item in the ListView the user long-clicked.
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenuInfo menuInfo) {
if (v.getId()==R.id.list) {
AdapterView.AdapterContextMenuInfo info =
(AdapterView.AdapterContextMenuInfo)menuInfo;
menu.setHeaderTitle(Countries[info.position]);
String[] menuItems = getResources().getStringArray(R.array.menu);
for (int i = 0; i<menuItems.length; i++) {
menu.add(Menu.NONE, i, i, menuItems[i]);
}
}
}
As you can see, the argument of type ContextMenuInfo can actually change
depending on what type of control is sending the event. For ListViews, the
class you need to type cast into is AdapterView.AdapterContextMenuInfo. From
there I used the position, which in my case corresponds to the index into
the string-array. From the array I retrieve the string for that particular
item and use as title for the menu. Then you can of course add all the menu
commands you like. For the demo, I defined another string array as a
resource with the commands I want to add.
When creating the menu items with the add-call, I specify that I don't want
any grouping of the items (Menu.NONE) and that the order and id of the item
is the same (i). The last argument to add is the text to display for the
item.

Responding to selected MenuItem

If the user dismisses the context menu (for instance, by back button) you
don't need to do anything. But for catching the actual selection of one of
the items, you need to override onContextItemSelected.
@Override
public boolean onContextItemSelected(MenuItem item) {
AdapterView.AdapterContextMenuInfo info =
(AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
int menuItemIndex = item.getItemId();
String[] menuItems = getResources().getStringArray(R.array.menu);
String menuItemName = menuItems[menuItemIndex];
String listItemName = Countries[info.position];

TextView text = (TextView)findViewById(R.id.footer);
text.setText(String.format("Selected %s for item %s", menuItemName,
listItemName));
return true;
}
The MenuItem argument holds all information that you need. The
ContextMenuInfo object that got sent to onCreateContextMenu is still there
and still needs type casting. Or I guess you could have saved that info in
the activity between the calls, but I didn't.
The id of the menu item selected is the same as the index into the string
array of menu item texts for me. Instead of just outputting the menu command
name and the list item text in a TextView, you would most likely have a big
switch statement on menuItemIndex.
This was my first blog post and code demo for the Android platform. I hope
it won't be the last! The goal is to build upon this demo and/or other
demos in my investigations of the Android platform. Please let me know in
the comments if you have even better methods or code patterns that solves
problems like this.

タオソフトウェア、Andorid開発者向けに「プライバシーガイドライン」

 タオソフトウェアは10月9日、「アンドロイドスマートフォンプライバシーガイドライン by タオソフトウェア」と題するドキュメントを公開した。Androidのアプリケーション開発者を対象に、プライバシー面で配慮すべき事柄をまとめた文書で、Apache License2の下、無償で公開されている。

 この文書のベースとなっているのは、総務省の「スマートフォンを経由した利用者情報の取り扱いに関するWG(ワーキンググループ)」の最終取りまとめである「スマートフォン プライバシー イニシアティブ - 利用者情報の適正な取り扱いとリテラシー向上による新時代イノベーション」というドキュメントだ。利用者情報の利用目的が不明瞭で、十分な説明のないままスマートフォンに蓄積された情報を取得、活用するアプリが増加し、利用者の不安が高まっていることを背景にまとめられた。

 タオソフトウェアでは、スマートフォン全般をカバーしている上記の文書の中から、Androidのアプリ開発者に必要な事項をピックアップし、さらにAndroid特有の要件を追加して再構成。全8章、58ページの文書として公開した。実際の運用に役立つよう、「個別の同意」を取得するダイアログを実装する際のポイントや、プライバシーポリシーの記述方法、サンプルも含まれている。

 同社はこの文書によって、Androidアプリの開発者が、利用者が安心して利用できるアプリケーションを効率的に設計し、公開できるよう支援したいとしている。

Google、タブレット向けアプリの品質チェックリストを公開

 米Googleは10月8日、 Android搭載タブレット向けアプリの品質や機能をチェックできる開発者向けサイト「Tablet App Quality Checklist」を公開した。タブレットの特性を生かしたアプリの開発に役立ててもらう狙い。

 チェックリストでは、タブレット向けアプリに求められる重点項目として、大型画面に合わせたレイアウトの最適化、タブレットの画面領域の活用、タブレット画面のためにデザインされたアイコンなどの資産の活用といった項目を提示。Google Playで配信する前に、ユーザーの期待に応えられるアプリになっているかどうかを確認できる。

 各項目ではさらに具体的なタスクやベストプラクティスを箇条書きで紹介し、それぞれの内容について解説したページへのリンクも提供した。

 併せて開発者向けのケーススタディとして、「Mint」「Tiny Co」「Instapaper」といった人気アプリを例に取り、ヒットした背景や開発者の声を紹介するページも開設。また、Google+内のAndroid開発者向けページでも、アプリ開発のノウハウを紹介している。

2012年10月9日火曜日

Android ビルドバージョンの取得と判定:Build.VERSION

自身が使っているデバイスの Android バージョンは Build.VERSION クラスの Build.VERSION.SDK_INT から取得することができます。
(Build.VERSION.SDK で同じ値をString型で取得することができますが、こちらは非推奨(@Deprecated)となっています)

取得した Android バージョンは Build.VERSION_CODES クラスに定義されたビルドバージョンの定数値と比較することで、バージョンに応じた処理分岐を行うことができます。

API Reference: Build.VERSION, Build.VERSION_CODES

比較方法:
switch (Build.VERSION.SDK_INT) {
case Build.VERSION_CODES.BASE:
// Android 1.0 (API 1)
break;
case Build.VERSION_CODES.BASE_1_1:
// Android 1.1 (API 2)
break;
case Build.VERSION_CODES.CUPCAKE:
// Android 1.5 (API 3)
break;
case Build.VERSION_CODES.DONUT:
// Android 1.6 (API 4)
break;
case Build.VERSION_CODES.ECLAIR:
// Android 2.0 (API 5)
break;
case Build.VERSION_CODES.ECLAIR_0_1:
// Android 2.0.1 (API 6)
break;
case Build.VERSION_CODES.ECLAIR_MR1:
// Android 2.1 (API 7)
break;
case Build.VERSION_CODES.FROYO:
// Android 2.2 (API 8)
break;
case Build.VERSION_CODES.GINGERBREAD:
// Android 2.3 (API 9)
break;
case Build.VERSION_CODES.GINGERBREAD_MR1:
// Android 2.3.3 (API 10)
break;
case Build.VERSION_CODES.HONEYCOMB:
// Android 3.0 (API 11)
break;
case Build.VERSION_CODES.HONEYCOMB_MR1:
// Android 3.1 (API 12)
break;
case Build.VERSION_CODES.HONEYCOMB_MR2:
// Android 3.2 (API 13)
break;
case Build.VERSION_CODES.ICE_CREAM_SANDWICH:
// Android 4.0 (API 14)
break;
case Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1:
// Android 4.0.3 (API 15)
break;
case Build.VERSION_CODES.JELLY_BEAN:
// Android 4.1 (API 16)
break;
case Build.VERSION_CODES.CUR_DEVELOPMENT:
// 未リリースの開発用バージョン
break;
default:
break;
}
以上が2012/09/09時点の全バージョンになります。
一般販売されているのは Android 1.5 以降のため、以下の3つは考える必要はありません。
・Build.VERSION_CODES.BASE
・Build.VERSION_CODES.BASE_1_1
・Build.VERSION_CODES.CUR_DEVELOPMENT
(すでに 1.6 すら対応必要なさそうですが…)

これを書くまで気づかなかったけど、Androidのコードネームはアルファベット順だったんですね。
お菓子の名前を適当につけているだけだと思っていました。
今は「J」で次は「K」。Android 5.0 で「Key Lime Pie」みたい。
Android 'Key Lime Pie' comes after Jelly Bean

2012年10月8日月曜日

「広告費というのは、平凡な製品を作ったときに必要になるものだ」───。アマゾン・ドット・コムのジェフ・ベゾス最高経営責任者(CEO)は、株主総会でこんな冗談を言ったことがある。

あれから3年。アマゾンは現在、タブレット端末や電子書籍端末といったモバイル端末事業を積極的に進めているが、市場調査会社カンターによると、今年1─6月期のテレビ広告費は3400万ドル(約26億7000万円)に上り、その額はさらに増える見通しだ。

マーケティングに多額の資金が投じられる消費者向けテクノロジー事業では、製品が素晴らしいからといってシェアを勝ち取れるわけではない。

アップルを例に取ってみよう。類まれな技術力で業界に君臨する同社ですら、iPhone(アイフォーン)やiPad(アイパッド)には、これまで約15億ドルの広告費をかけている。

スマートフォンやタブレット端末メーカーのサムスン電子<005930.KS>、アマゾン、マイクロソフト、そしてその他の企業は、こぞってテレビCMや紙媒体などの広告に巨額の費用を投じている。

年末に向けたホリデー商戦を前に、市場での戦いは熾烈(しれつ)でクリエイティブなものになるだろう。

広告エージェント、ドロガ5の創設者デービッド・ドロガ氏は、「全ての企業が注目を集めようとしている」と話す。米ニューヨークとシカゴでは数カ月前、ビルの側壁に「surface(サーフェス)」と記した謎の落書きが現れた。マイクロソフトが発売を控える、新基本ソフト(OS)「ウィンドウズ8」搭載のタブレット端末「サーフェス」の広告の一環だろうが、それを広告だと同社が認めることはおそらくないだろう。

<目の敵にされるアップル>

ブラックベリーで知られるカナダの老舗メーカー、リサーチ・イン・モーション(RIM) は今夏、アップルにある「いたずら」を仕掛けた。シドニーのアップルストアに黒い大型バスを送り込み、列をつくる客らに向かって「目を覚ませ」と書かれたプラカードを掲げたのだ。

iPhoneやiPadで顧客を引きつけるアップルは、他社にとってねたみの対象だ。

サムスンも、アップルに忠誠を誓うファンたちをからかったテレビコマーシャルを製作し、「iPhone5を求めて店先に並ぶ人はだまされている」といった内容を放送した。ソーシャルメディアのモニター会社ブルーフィンによると、このCMはユーチューブで1600万回も再生され、ツイッター上では放送開始1週間で最もつぶやかれた話題となった。一方でiPhone5のCMは、再生回数が100万回にとどまっている。

サムスンはさらに攻勢を強める見通しだ。カンターの調べでは、サムスンはスマートフォン「ギャラクシー」のテレビ広告費を急増させており、1─6月期で8000万ドルを投入。すでに昨年の全広告費を上回っている。

広告代理店のBBDOノースアメリカでデジタル戦略を担当するマーク・ヒメルズバック氏は、製品の差別化を図るためには「顧客の興味をかきたて、人の心を動かすブランド戦略を展開していくことが重要だ」と指摘する。

<急増する広告費>

調査会社ニールセンによると、スマートフォンやタブレット端末に投じられる広告費は、ここ5年間で2倍、金額にして年間約6億5000万ドルまで急増した。

グーグル、マイクロソフト、アマゾン、サムスンはいずれも具体的な広告費に関してコメントを拒否している。

皮肉なのは、スマートフォンやタブレット端末といった「ニューメディア」の広告が、テレビや出版物といった従来からの「オールドメディア」に頼っているところだ。

デジタル戦略に詳しいマイケル・ウィンター氏によれば、昨年から今年の第2・四半期までのスマートフォンに関する広告は、6割がテレビを通したものだったという。紙媒体での広告は3割、ウェブ広告に至ってはわずか9%だった。

アマゾンは新型タブレット端末「キンドル・ファイアHD」のテレビCMで、あえて製品の詳細を伝えないことによって消費者の好奇心をあおる「ティーザー広告」と呼ばれる戦略を展開した。こうした努力は、いずれ利益として企業に返ってくるだろう。

ブランド調査会社ブランド・キーズのロバート・パシコフ社長は、アマゾンがオンラインショッピングだけではなく、端末機器とそこからアクセスできるコンテンツをPRする努力を重ね、勢いに乗っていると分析した。

<アップルが頼るメディアの力>

だが、ブランドイメージを変えるのは一筋縄ではいかない。例えば、グーグルはネット検索大手としては名高いが、モバイルコンピューティングの分野ではそうでもないとパシコフ氏は語る。

世間一般では、モバイルOSシェア首位の「アンドロイド」がグーグルの製品であるというイメージを持っている人は少なく、このことが同社のハードウエアビジネスの展開に障壁となる可能性もある。

パシコフ氏は、「スマートフォンやタブレット端末の話をする時にグーグルは話題に上がらない」と指摘。グーグルはテレビCMや紙媒体、それに自社の検索ページも使って、新型タブレット端末「ネクサス7」のプロモーションを続けている。

一方、RIMはこの「広告戦争」で苦しい戦いに直面している。

マーケティング責任者のフランク・ボールベン氏は、新OS「ブラックベリー10」搭載の新型スマートフォンについて、メディアなどへの発表は小出しにしていくと話す。発売までは顧客の狙いを定めたリアルタイム・マーケティングを増やし、「店頭販売が始まってから、通信キャリアとともにテレビや屋外での広告といったマーケティングを開始する」という。

これとは対照的に、アップルのテレビキャンペーンは現在進行中だ。同社のマーケティング部門トップを務めるフィル・シラー氏は、サムスンとの特許訴訟の法廷で、自社製品のうわさを広めるために初めに頼るのはメディアだと証言した。さらに、広告を本格的に展開するのは、当初の熱気が冷めてきた時だとも語った。

また、アップルはテレビや印刷物に加え、テレビ番組や映画の中で同社の製品を登場させて露出を高める「プロダクト・プレイスメント」にも多くの費用を割いている。

特許訴訟の資料によると、アップルはiPhoneシリーズに10億ドル、iPadシリーズに4億5700万ドルの広告費を投じてきた。これに対して、メディアの報道に費用は全くかかっていない。