My Photo

« October 2011 | Main | December 2011 »

November 29, 2011

Androidアプリ開発メモ046:スタイルとテーマ

スタイルとテーマ

Androidではアプリやビューに統一したフォーマットを適用するためにスタイルとテーマが用意されている。

スタイル
ビューに個々にセットするフォーマット属性のセット。レイアウトファイルで設定する。
テーマ
アプリケーション全体または個々のアクティビティにセットするフォーマット属性のセット。AndroidManifest.xmlで設定する。

用意されているスタイル(一部)

TextAppearance 文字色白。文字サイズは小と中の間。
TextAppearance.Inverse 文字色黒。
TextAppearance.Small 文字サイズ小。
TextAppearance.Mediaum 文字サイズ中。
TextAppearance.Large 文字サイズ大。

「○○.Inverse」というスタイルは「○○の文字色反転版」ってことか?

用意されているテーマ(一部)

Theme.Black 背景が黒。テーマを指定しない場合と同じ?
Theme.Light 背景が白。
Theme.Dialog ダイアログっぽくなる。
Theme.NoDisplay
Theme.NoTitleBar タイトルバーなし
Theme.Translucent 背景が透明。タイトルバー付き。
Theme.Translucent.NoTitleBar 背景が透明。タイトルバーなし。
Theme.Translucent.NoTitleBar.Fullscreen 背景が透明。タイトルバーなし。ステータスバーもなし。

Theme.NoDisplayはどのようなテーマなのか不明。onCreate()は呼ばれているが画面の変化は一切ない。アクティビティ上にあるテキストビューやボタンも表示されない。
Theme.Translucentの場合は背景は透明だけがアクティビティは実際には存在していて、そのために後ろにある画面(ホーム画面など)は操作できないが、Theme.NoDisplayでは表示されている画面を操作できるのでアクティビティが画面上には存在していないと思われる。またバックキーを押すと、しばらくすると「<アプリケーション名>は応答していません。」というエラーのダイアログが出る。

下のスクリーンショットは"Theme.Dialog"。 Theme_dialog

独自のスタイル・テーマの指定

独自のスタイル・テーマを定義して使うこともできる。
テーマの定義は /res/values/style.xml に記述する。
以下は独自スタイル・テーマの例。

<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="SpecialText" parent="@android:style/TextAppearance.Medium" >
    <item name="android:textSize">18sp</item>
    <item name="android:textColor">#FF00FF00</item>
  </style>

  <drawable name="translucent_background">#DDFF0000</drawable>
  <style name="Theme.TranslucentRed" parent="android:style/Theme.Translucent">
    <item name="android:windowBackground">@drawable/translucent_background</item>
  </style>
</resources> 

"SpecialText"は"TextAppearance.Medium"を継承したスタイルで文字色が緑。
"Theme.TranslucentRed"は"Theme.Translucent"を継承したテーマで背景が"translucent_background"という上の行で定義してあるdrawableである。

スタイルの指定

スタイルはレイアウトファイルでビューの要素にstyle属性を追加して設定する。 #android:style属性ではない。

style="@android:style/<標準で用意されているスタイルの名前>"
style="@style/<独自のスタイルの名前>"

テキストビューの文字サイズを中に設定する場合は以下のようになる。
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello"
    style="@android:style/TextAppearance.Medium" />

テーマの指定

テーマはAndroidManifest.xmlでapplication要素、activity要素にandroid:theme属性を設定する。
application要素の属性の場合はそのアプリケーション全体にテーマがセットされる。
activity要素の属性の場合はそのアクティビティにテーマがセットされる

android:theme="@android:style/<標準で用意されているテーマの名前>"
android:theme="@style/<独自のテーマの名前>"

アクティビティに対して設定する場合は以下のようになる。
<activity
    android:label="@string/app_name"
    android:name=".ThemeExample"
    android:theme="@android:style/Theme.Translucent" />

参考:
6.8 スタイルとテーマの適用 - ソフトウェア技術ドキュメントを勝手に翻訳
Androidアプリ全体で文字色や背景色を統一させる方法(Theme/テーマ) | mucchinのAndroid戦記
Androidメモ
[音量設定アプリ]第6回 アプリのデザイン(テーマ)を変更 | Android Techfirm Lab

「月刊ヒーローズ」はパチンコホールでも売ってる

セブンイレブン独占販売って聞いたけどパチンコホールでも売ってるんだそうだ。
小学館とパチンコメーカーが金を出しているそうで、人気作品が出たらパチンコの新機種に使うつもりらしい。へー。

創刊号は清水栄一×下口智裕の「ウルトラマン」が目玉だったみたいだけど、ラインバレルの連載に影響がでないのか心配。
ラインバレルの最新刊は作品世界の秘密の一旦が明らかになって盛り上がってきただけに、連載ペースがガクッと落ちたりしたら残念だ。


トラックバック先:小学館クリエイティブがフィールズと共同出資で「株式会社ヒーローズ」を設立、年末に青年月刊コミックスを刊行 - tx別館(適当ブログ)txbekkan

November 28, 2011

Androidアプリ開発メモ045:透明なActivity

サービスからダイアログを開くことができないかなと思って調べたが、できないらしい。代わりの方法として、透明なアクティビティを開いてそこからダイアログを開くことができる。

Activityを透明にするには、AndroidManifest.xmlのActivity要素に以下の属性を入れればよい。

android:theme="@android:style/Theme.Translucent.NoTitleBar"

これは、Activityに対してTheme.Translucent.NoTitleBarというテーマを適用するということである。
translucentという単語を調べると「[形]半透明の」とあるが、半透明ではなく透明になる^^;

参考:
androidのサービスからダイアログを表示する - SmartSlickの日記 Androidとか
Activityを透過する « Tech Booster

はてなダイアリーへのトラックバック

はてなダイアリーは

記事のURL=トラックバックURL

なんだそうだ。

はてなダイアリーガイド「はてなダイアリー以外のサイトからトラックとは - はてなキーワード

トラックバックしようと思ったけどトラックバックURLが書いていなくて戸惑った^^;

November 27, 2011

オリンピック予選 日本vsシリア

日本2-1シリア/U22詳細 - サッカー日本代表ニュース : nikkansports.com

大津いいね。本人も言ってるけどゴールに向かう姿勢がいい。
それにくらべて大迫と山田。シュート打てるのにパスしたり、判断がおかしい。
シュート打てば枠に行かないかGKの正面か。
山田がGKと1対1になったシーン、ふわっと浮かせれば1点だったのに思いっきり蹴って止められてるし。
最初から山田out山崎inの状態(東が真ん中で山崎が左)の方がいいじゃないかと思う。

第33節、新潟惨敗、磐田も惨敗

J's GOAL:試合詳細:2011 J1 第33節 ヴァンフォーレ甲府 3-0 アルビレックス新潟

試合見てないけど、もうなんていうか、がっかり。
ヨンチョル、高徳、大輔がいないとはいえ、相手もマイクがいないんだし、言い訳しようない。
監督は残留が決まってモチベーションがどうのこうの言っているが、残留決まったらあとは負けてもいいのんか?ちがうやろ?ふざんけんな!
フロントは今日の試合で川又をあきらめたよね?ね?ね?
早く戦力外通告してくれ。


J's GOAL:試合詳細:2011 J1 第33節 ヴィッセル神戸 3-1 ジュビロ磐田

前半早々、加賀がケガしちゃったのか。
この負けで賞金圏内は無理になったなーorz

Androidアプリ開発メモ044:AppWidget その5:ボタン押下時の動作の取り消し

RemoteViews#setOnClickPendingIntent()でセットしたボタンの動作を取り消すには、PendingIntent#cancel()を使う。
これが適切な方法なのかはわからないが、とりあえず一度セットした動作を下記のコードでとりえ消すことが出来る。

android.app.PendingIntentクラス
public void cancel()
現在アクティブなPendingIntentをキャンセルする。PendingIntentを所有している元のアプリケーションのみそれを取り消すことができる。。

/**
 * validがtrueの場合、ボタンが押されたらActivityを開くようにセットする。<br />
 * validがfalseの場合は、trueの時にセットした動作を取り消す。ボタンを押しても何も起きなくなる。
 */
void setEvent(Context context, int appWidgetId, RemoteViews views, boolean valid) {
  Intent intent = new Intent(context, com.example.sampleactivity.SampleActivity.class);
  intent.setAction(BUTTON_ACTION);
  intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
  PendingIntent pendingIntent = PendingIntent.getActivity(context, appWidgetId, intent, 0);
  if (!valid) {
    pendingIntent.cancel();
  }
  views.setOnClickPendingIntent(R.id.awButton, pendingIntent);
}

ラストエグザイル 銀翼のファム #7「Weak square」

アラウダの冒頭の意味ありげなシーンはなんだろう。
「白の遺産」という言葉、覚えておいたほうが良さそうだ。

あいかわらず戦闘シーンにリアリティがない。
アデス第3艦隊はこれ以上ないくらい有利な状況だったのに結構な数逃げられてる。司令官は無能なんじゃねえの?ヴェスパは搭乗者むき出しだから散弾撃たれてたら終わりだろうに。

November 26, 2011

FF11 メイジャン回避短剣キーラ+2完成

こつこつやっていたメイジャンの回避短剣。
No.1893[プラトイド300匹 風天候or風曜日]は最初はバフラウ段丘でやっていたが、ビックリするくらい風天候にならない。
それまでのNo.25,26,27,1104,1105はワジャームやバフラウでやって結構風天候になっていたが、なんかピタッと風が吹かなくなった。
あまりに天候が変わらないので、途中からグロウベルグに変更。バフラウよりは頻繁に風天候になる。
若木は練習相手にもならないだが大きい木は楽なので大きい木を倒していって、No.1893をクリア。キーラ+1に強化。
次のNo.2290は風の石印15個なので、すぐにクリアw
キーラ+2をゲット。

キーラ+2 (D43 隔190 Lv90~) AGI+9 回避+20

とりあえずここで止めた。
次のNo.2723も石印40個なのですぐにクリアできるが、キーラ+3になると装備レベルが95以上になるので、おいらのシーフ(LV93)では使えなくなる^^;

今後、シーフはこのキーラ+2とトワイライトナイフの二刀流で戦っていく。

November 25, 2011

Androidアプリ開発メモ043:Logcatにアプリのログが出なくなった

先日、いつものようにEclipseでコードを書いてAVDで実行していたら、アプリからのログがLogcatビューに出なくなった。
アプリ以外からのログは出ているのだが、アプリのコード中のandroid.util.Log.v()からのログだけ出ない。
意識して何か設定を変えたりした記憶がないのだが。
ググって情報を探したら、参考サイトに書いてあるようにコマンドプロンプトでadbのコマンドを打ったら直った。

C:\Program Files\Android\android-sdk\platform-tools>adb kill-server

C:\Program Files\Android\android-sdk\platform-tools>adb start-server
* daemon not running. starting it now on port 5037 *
* daemon started successfully *

C:\Program Files\Android\android-sdk\platform-tools>

参考:
My InfoBox: android logcatにログがいきなり表示されない
AIR Androidアプリ作成:Flash, Flex Hero | 1-7: adb kill-serverを実行すべきではないのか?

Androidアプリ開発メモ042:動画の再生 その2:VideoViewを使用した再生

VideoViewによるビデオの再生

VideoViewは動画再生のためのビューでSurfaceViewのサブクラス。

public void setMediaController(MediaController controller)
メディアコントローラをセットする。

android.widget.MediaControllerはデフォルトでは「再生/一時停止ボタン」、「巻き戻しボタン」、「早送りボタン」、「プログレススライダー」を持つ。

public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  
  // VideoViewの生成
  try {
    VideoView videoView = (VideoView)findViewById(R.id.videoView1);
    videoView.requestFocus();
    videoView.setMediaController(new MediaController(this));  // メディアコントロールを付ける
    
    // Rawリソースのファイル保存
    InputStream is = getResources().openRawResource(R.raw.sample);
    in2file(this, is, "sample.mp4");
    
    // ビデオの再生
    String path = getFilesDir() + "/sample.mp4";
    videoView.setVideoPath(path);
    videoView.start();
  } catch (Exception e) {
    Log.e("EXCEPTION", e.toString());
  }
}

参考:
動画を再生する方法 VideoView - [サンプルコード/Androidアプリ] ぺんたん info
VideoViewで動画を再生する « Tech Booster

November 24, 2011

Androidアプリ開発メモ041:動画の再生 その1:MediaPlayerを使用した再生

動画を再生する方法として、サウンドと同様にMediaPlayerを使う方法と簡単にVideoViewを使う方法がある。

MediaPlayerによるビデオの再生

オーディオの再生と同じようにMediaPlayerを使ってビデオを再生することができる。
MediaPlayerにデータソースをセットして再生するのは同じだが、動画再生の場合は加えてビデオを表示するビューとしてSurfaceViewを使い、MediaPlayerのインスタンスにsetDisplay()でSurfaceHolder.Callbackインタフェースをセットする必要がある。

android.media.MediaPlayerクラス
public void setDisplay(SurfaceHolder sh)
メディアのビデオ部分を表示するために使用するSurfaceHolderをセットする。

実装例。ただし、AVDではうまく再生されない。音は聞こえるのだが。
実機(Xperia ray)では映像・音ともに再生された。
package com.example.videoplayerexample;

import android.app.Activity;
import android.graphics.PixelFormat;

import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/**
 * MediaPlayerを使った動画再生
 */
public class VideoPlayerExample extends Activity
  implements SurfaceHolder.Callback {

  private SurfaceHolder holder;
  private SurfaceView surfaceView;
  private MediaPlayer mMediaPlayer = null;
  
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    
    getWindow().setFormat(PixelFormat.TRANSPARENT);  // これがどういう意味を持つのか、必要なのかどうかわからない。transparent[形]透明な
    surfaceView = (SurfaceView) findViewById(R.id.surfaceView1);
    holder = surfaceView.getHolder();
    holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    holder.addCallback(this);
  }

  /**
   * サーフェイス生成時に呼ばれる。
   */
  @Override
  public void surfaceCreated(SurfaceHolder paramSurfaceHolder) {
    try {
      String path = Environment.getExternalStorageDirectory().getPath() + "/DCIM/100ANDRO/MOV_0009.mp4";
      mMediaPlayer = MediaPlayer.create(this, Uri.parse(path));
      mMediaPlayer.setDisplay(holder);
      mMediaPlayer.start();
    } catch (Exception e) {
      android.util.Log.e("", e.toString());
    }
  }

  /**
   * サーフェイス変更時に呼ばれる。
   */
  @Override
  public void surfaceChanged(SurfaceHolder paramSurfaceHolder, int paramInt1,
    int paramInt2, int paramInt3) {
  }

  /**
   * サーフェイス破棄時に呼ばれる。
   */
  @Override
  public void surfaceDestroyed(SurfaceHolder paramSurfaceHolder) {
    if(mMediaPlayer != null){
      mMediaPlayer.release();
      mMediaPlayer = null;
    }
  }
}

参考:動画を再生する方法 MediaPlayer - [サンプルコード/Androidアプリ] ぺんたん info

November 22, 2011

UN-GO 因果論

昨日、川崎で見てきた。
映画館に行ったのは劇場版Zガンダム以来だw
当初は渋谷か六本木で見ようかと思ったが、川崎のほうが空いて見やすい席を取れそうだったので。
短い映画から特別料金1200円。

テレビの方で明かされていないことが色々わかる。
本編に出てないけどOPやEDに出てくるキャラのことがわかる。
テレビの方がつまらなければ
「金取って本編の補足かよ。ふざけんな!」
だけど、テレビの方が面白から
「金払ってでも知りたい。」
になる。
面白いってことは、最強だな。
疑問点を整理してからもう1回見たい。

ゆうきまさみ(だったっけ?)がtwitterで「テレビ11話+劇場版で終わらすのはもったいない」と言っていたが、原案はそんなに長い作品じゃないからそれくらいできれいに終わったほうがいいんじゃないかと。

以下、感想というかメモというか。ネタバレ含みます。


-----
・水泳のシーン、作画イマイチ。躍動感がない。BONESは作画がいいイメージあるんだけど。
・泉ちゃん、テレビの方より新十郎に優しい。劇場版の終わりからテレビ版の始まりまでの間に新十郎が海勝にたくさん楯突いたから新十郎のことを嫌いになったとか?第6話で矢島が新十郎のことを「海勝と敵対している」と言っている。
・新十郎の本当の名前って出てきたか?
・「真犯人撃たれて死ぬ」、間抜けだw
・行方知れずになった別天王、第6話のラストで小説家の後ろにいた。

Sleipnirのスクリプト

SleipnirにはVBスクリプトまたはJavaScriptを実行する機能があると最近知った。
便利さがイマイチわからないが、とりあえず入力した言葉のWikipediaのページを開くスクリプトを作って、ショートカットキーを登録するところまでやってみた。

  1. Sleipnirにプラグイン「UserAction Extension」を入れる。これでスクリプトをSleipnirのアクションとして登録することができるようになる。Sleipnirではアクションに対してキーボードショートカットを設定するので、このプラグインを入れていないとスクリプトを実行するのにメニューをたどっていく方法しかなくとても面倒くさい。
  2. 下記のスクリプトを作成し、<Sleipnirのフォルダ>/plugins/scripts に置く。
  3. Sleipnirを再起動する。
  4. 2のスクリプトがアクションに追加されているので、メニューの「ツール>Sleipnirオプション」でオプション設定のダイアログを開き、「ユーザーインタフェース>キーボード」でスクリプトにショートカットキーを割り当てる。

スクリプトは以下。

obj = new ActiveXObject("Sleipnir.API");
tmp = obj.InputBox("Please input word.", "");
obj.NewWindow("http://ja.wikipedia.org/wiki/" + tmp, true);
obj = null;tmp = null;

最後の行がどうして必要なのかよくわからないが、本に載っていたサンプルはだいたいこんな感じになっていたので真似してみた。

参考:タブブラウザ Sleipnir オンラインデータベース(Sleipnir.API リファレンス)

Sleipnir2カスタマイズテクニック―オリジナルスクリプトを作る Sleipnir2カスタマイズテクニック―オリジナルスクリプトを作る
佐藤 信正

毎日コミュニケーションズ 2005-12
売り上げランキング : 551586

Amazonで詳しく見る
by G-Tools

November 21, 2011

FF11 黒エンピリアン装束+2揃った

週末、ジュノで「だいじ提供者が総取りアビセアNMツアー」の募集があったので、「ウルハドシのだいじなものあります」と言って黒で参加した。

やったのはグラヴォイド2戦、キレイン、ウルハドシ、イッパパ、ドゥリン。
さっと終わってウルハドシから木行の小片3個ゲット。トータルで7個。
ジュノに戻ってGTペタソス+1を+2に強化した^^

GTペタソス+2 防29 INT+8 精霊魔法スキル+15 精霊魔法の詠唱時間-12% 敵対心-6 コンビネーション:コンサーブMP性能アップ Lv85~ 黒

これでゴエティア装束+2がそろった。
装備的にはどこに出しても恥ずかしくない黒だ。
中の人のスキルはアレだが^^;

さて、次は何するかな。
五行アイテム目当てのシャウトもめっきり減ったし、なんか目標が見つからない^^;

November 20, 2011

第32節、新潟残留決定、磐田金園2ゴール

J's GOAL:試合詳細:2011 J1 第32節 アルビレックス新潟 2-2 ガンバ大阪

BSで観戦。
引き分けで勝ち点1。J1残留決定^^
でも勝って決めたかったし、勝てた試合だったorz
2点差を追いつかれ、終了間際のチャンスでも決めれない。だから残留争いに巻き込まれる。

三門のミドルで先制。1年に1回くらいああいうシュート決めるよなー。三門はw
菊地はやっぱいい選手だねえ。CBでも明らかに千葉よりいい。

しかし昨日みたいな試合をなんで松本山雅戦でなんでできないのか。


's GOAL:試合詳細:2011 J1 第32節 ジュビロ磐田 2-1 ヴァンフォーレ甲府

金園が2ゴールで今シーズン12点。これでもベストヤングプレイヤー賞はダメなのかな。
#大卒新人は対象外?


山形-福岡は0-5で福岡大勝、最下位脱出。松浦がらしいドリブルシュートを決めた。
そんな松浦と岐阜にレンタル中の押谷がジュビロに復帰するとの報道があった。今年は山田と金園は大活躍だし、前の方は選手が過剰だと思うんだけど。
まさか前田流出を既に覚悟してる?
前の選手より左SBでしょう。補強は。


名古屋-横浜戦の俊輔のゴールを「汚い」とかって批判しているやつがいるけど、サッカーのルール知らないの?
インプレーなんだから蹴って当然でしょう。
それよか甲府のマイクの2枚目のイエローの方がずっと汚くないか。「出場停止が1試合で済むとは知らなかった」と言っているがちょっと信じられない。

November 19, 2011

Androidアプリ開発メモ040:サウンドファイルの再生

MediaPlayer

オーディオやビデオの再生にはandroid.media.MedirPlayerクラスを使用する。
インスタンスの生成#MediaPlayer#create()を使用する。

public static MediaPlayer create(Context context, int resid)
与えられたリソースIDのリソースをデータソースとしてMediaPlayerを生成する。成功の場合、prepare()は既に呼ばれており、再度呼んではならない。

public static MediaPlayer create(Context context, Uri uri)
与えられたリソースURIをデータソースとしてMediaPlayerを生成する。成功の場合、prepare()は既に呼ばれており、再度呼んではならない。

再生、停止、シーク、再生終了イベントのリスナの設定のメソッドは以下。

public void start()
再生を開始する。前に一時停止した場合は、一時停止した場所から再生を続ける。

public void stop()
再生を停止する。

public void seekTo(int msec)
シークする。

public void setOnCompletionListener(MediaPlayer.OnCompletionListener listener)
OnCompletionListenerを登録する。

MediaPlayer.OnCompletionListenerには以下のメソッドがある。

android.media.MediaPlayer.OnCompletionListenerインタフェース
public abstract void onCompletion(MediaPlayer mp)
再生がメディアソースの最後に達したときに呼ばれる。

リソースのサウンドファイルの再生

サウンドファイルはプロジェクトのres/rawフォルダに置く。

サウンドファイルがsample.mp3の場合、再生するコードの例。

player = MediaPlayer.create(getContext(), R.raw.sample);
player.seekTo(0);  // 再生開始位置を指定
player.start();
// player.setOnCompletionListener(this);  // 再生終了時

SDカードにあるサウンドファイルの再生

SDカードの直下にサウンドファイルsample.mp3がある場合、再生するコードの例。

String path = Environment.getExternalStorageDirectory().getPath() + "/tmp01.mp3";
player = MediaPlayer.create(getContext(), Uri.parse(path));
player.start();

URIを指定してのサウンドファイルの再生

"http://www.hogehoge.jp/sample.mp3"を再生するコードの例。

String path = "http://www.hogehoge.jp/sample.mp3";
player = MediaPlayer.create(getContext(), Uri.parse(path));
player.start();

参考:
MediaPlayerで音楽を再生する << Tech Booster
>> MediaPlayer Android はじめました。

November 18, 2011

清武代表、解任される

巨人、清武代表を解任 渡辺球団会長と対立 - スポーツ:asahi.com


清武氏に批判的な意見が思ったより多いな。特にテレビのニュースや大新聞は。
ナベツネを恐れているのかな。まあヤツの機嫌を損ねたらやっかいなことになりそうだんもんなあ。

日本シリーズ直前に会見を開いたことが批判される原因の1つになっているが、それはコーチ陣の生活を考えて少しでも早く契約を締結したかったからじゃないかな。
決まったものだと思っていたのに急に「あ、来シーズンのコーチの契約、なしになったから」と言われたら困るだろう。

今はっきりしているのは、ナベツネが
「俺に断りなしにコーチ人事いじくるとかありえるのかね。」
と嘘をついたということだ。清武氏への反論の中で来シーズンの体制について説明を受けていたことを認めている。
なのに新聞もテレビのニュースもこのことについて全く追求してない。

結局、マスコミは叩きやすい人を叩いているだけに見える。

November 17, 2011

Androidアプリ開発メモ039:TextView#getText()の戻り値はSerializableではない

勉強がてらに、アドエスのクイックメモを参考にAppWidgetを作っている。
TextView#getText()の戻り値(CharSequence)をArrayListに突っ込んで、それをシリアライズしてローカルファイルに保存しようとしたら例外発生。

CharSequence text = textView.getText();
memoList.add(text);

// メモのリストをシリアライズしてファイルに保存する。
FileOutputStream fos;
ObjectOutputStream oos = null;
try {
  fos = openFileOutput(FILE_NAME, MODE_PRIVATE);
  oos = new ObjectOutputStream(fos);
  oos.writeObject(memoList);  // 例外発生!
  oos.close();
} catch (IOException e) {
  e.printStackTrace();
} finally {
  if (oos != null) {
    try {
      oos.close();
    } catch (IOException e) {
    }
  }
}

TextView#getText()の戻り値はStringだろうと決め付けていたが、違った。getClass().getName()で調べたら
android.text.SpannableStringBuilder
というクラスだった。
で、これがSerializableではなかった。
TextView#getText()の戻り値をtoString()してからArrayListにadd()したら解決。

CharSequence text = textView.getText();
memoList.add(text.toString());

天皇杯、新潟はJFLに敗れる

第91回天皇杯 3回戦 新潟 0-1 松本:J's GOAL


ほぼベストメンバーでJFLに敗戦。BSの生中継で全国に恥を晒した。
2chの新潟スレは「ここですか?」の嵐かなw

前半は試合開始早々にルーズなマークでコーナーキックから先制点を許し、松本の激しいプレッシャーで完全ににペースを握られた。
後半は松本の選手たちに疲れが出てきて相手陣内でのプレーが多かったが、パスの精度が悪く効果的な攻撃が出来ない。結局、縦ポン跳ね返されるの繰り返し。
攻め手がなくて苦し紛れの縦ポンとか、これが本当にJ1チームかと思う。新潟にはケネディもマイクも前田もいないのにね。
ミシェウが厳しいマークで仕事が出来ないときこそ本間勲がなんとかすべきなのに、判断遅い、いいパスが出ない。同郷だから応援してるけど、さすがに昨日のプレーは擁護できんわ。
ゴール裏はブーイングしたのかな。それともこんな試合でも暖かく拍手したのか。


磐田はジェフに負けてヤンツーの退任が決まったが、さすがに「今後も黒崎監督でいいのか?」と思ってしまった。
今までは監督擁護派だったけど、昨日の試合は選手の質が低いからで済ませていいんだろうかと。
こんな試合見せられると「残り試合全敗もありうるかも」と思ってしまう。そして甲府が全勝したら。。。

J1の次節、ガンバ戦はまたBSで中継がある。
恥を雪ぐか、恥の上塗りになるか。
#まあ、JFLに負けること以上の恥はそうそうないけどw

November 16, 2011

2011年10月開始アニメ途中経過

見ている作品について、ここまでの感想とか雑感とか戯言とか。


バクマン。2
原作読んでないけど、安定したおもしろさ。

WORKING'!!
これまた安定したおもしろさ。
新キャラの声優が中村悠一と戸松遙か。声優が豪華だな。
WEBラジオ「YAMAKING'!!」が何げに面白い。というか広橋涼が面白い。

灼眼のシャナⅢ
まあ、そこそこ。1と2見たので、最後まで見るつもり。
原作は完結したのか。数が多いけど、読んでみたくなった。

HUNTER×HUNTER
原作がいいからそれなりに面白い。
でもだいぶ端折ってるな。ハンター試験の2次試験でたしかハンゾウがスシ作らなかったっけ?なんか1回でさらっと終わってるし。
2次試験の試験官役を平野綾がやってる。あんな醜聞が広まったのに、よく今まで通りに声の仕事してられるなあ。TVにも顔出しで出てたし。
まああれくらい面の皮が厚くないと厳しい芸能界ではやっていけないのかなw

Fate/Zero
作画が非常に良い。
前回は「普通に良い」くらいだったように思うけど、その前の回(セイバー、ランサー、ライダー、アーチャー、バーサーカーが出てきた回)までは超良かった。
ストーリーも虚淵さんだし、今期のアニメでは総合1位だと自分は思う。

UN-GO
そんな期待してなかったが、かなりいい。
監督と脚本がハガレンのアニメ1作目の人たち。ハガレンアニメ1作目は好きじゃなかったのであまり評価してなかったが、この作品で見直した。
ハガレンは原作がシリアスとギャグが絶妙のバランスを取っていたのに、アニメ1作目はシリアスな方に振り切ってしたまっていたので、「ハガレンのアニメ化としてはいかがなものか」と思った。
オリジナル作品でシリアスな話なら、このコンビは悪くない。
それと、あいなまさん、大人形態の因果の声はすごいな。見直した。男と同棲しながらドル売りを続けるのはどうかと思うがw

ペルソナ4
ゲームかなり忠実に再現しているらしい。ベルベットルームはイゴールの声を故 田の中勇の声をゲーム用ライブラリから持ってきてを使っているそうだ。日付が変わるときのアイキャッチも、「ああ、ペルソナっだ」と思った(ペルソナ4は未プレイだがペルソナ3ポータブルはやった)。
ゲームに忠実だと「アニメ見たらゲームのネタバレになってゲーム買わなくなるんじゃないか?」と思ったが、今のペースで1クールで終わる作品だとすれば、仲間が全員揃ってアニメ終了、続きはゲームでねって感じになるからいいのか。

ラストエグザイル 銀翼のファム
続編だが、GONZOの経営のせいで間が空き過ぎ^^;
OPが坂本真綾と聞いて前作の沖野俊太郎の歌のイメージがあったのでどうかなーと思っていたが、以外といい。作曲はSchool Food Punishument。UN-GOのOPのアーティストだ。今まで知らなかったけど、同時に2作品で使われるって事は今注目されてるアーティストなのかねー。
まあ、今のところはそこそこ面白い。


「Fate/Zwro」と「UN-GO」が他の作品より頭1つ抜けてる感じ。

就職活動停止中

最初に応募した2社に落ちて以来、動いていない。
#正確には1社落ちて、1社は採用がなくなった。

2社以外、特に「是非ここで働きたい!」って思うようなところがない。
まあそんな贅沢言える立場じゃないのはわかるが、なんかやる気が起きない。
はあ~、ダメ人間だなあ。

November 15, 2011

Androidアプリ開発メモ038:AppWidget その4:AppWidgetのボタンの識別

AppWidgetについての以前の記事:
Androidアプリ開発メモ034:AppWidget
Androidアプリ開発メモ035:AppWidget その2
Androidアプリ開発メモ036:AppWidget その3:設定用Activity

AppWidgetの記事というより、IntentまたはPendingIntentの記事かもしれない。

AppWidgetに複数のボタン(例:"Prev"ボタンと"Next"ボタン)があってどのボタンが押されかを識別するにはどうしたらいいか、以下のような方法を考えた。

  • AppWidgetProvider#onUpdate()か設定用Activityで、ボタンにセットするPendingIntentのIntentにputExtra()でボタン固有の情報を埋め込む。
  • ボタンを押して起動されたActivityでgetIntent().getStringExtra()で埋め込んだ情報を取り出し、押されたボタンを識別する。

ボタンを設定するコード。
Intent intent = new Intent(this, com.example.appwidgetexample.AppWidgetExampleConfigure.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(KEY_BUTTON, "Prev");
PendingIntent pendingIntent = PendingIntent.getActivity(this, appWidgetId, intent, 0);
views.setOnClickPendingIntent(R.id.awButton1, pendingIntent);

intent = new Intent(this, com.example.appwidgetexample.AppWidgetExampleConfigure.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(KEY_BUTTON, "Next");
pendingIntent = PendingIntent.getActivity(this, appWidgetId, intent, 0);
views.setOnClickPendingIntent(R.id.awButton2, pendingIntent);

ボタンを識別するコード
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
  String buttonText = extras.getString(KEY_BUTTON);
  if ("Prev".equasl(buttonText)) {
    // Prevボタンの場合のコード
  } else if ("Next".equals(buttonText)) {
    // Nextボタンの場合のコード
  }
}

しかしこれだと思ったような結果にならない。どちらのボタンを押しても extras.getString(key)が"Prev"を返す。
また、ボタンの設定のコードでgetActivity()の第4引数をPendingIntent.FLAG_UPDATE_CURRENTにすると、どちらのボタンを押しても extras.getString(key)が"Next"を返す。
#PendingIntent.FLAG_CANCEL_CURRENTにすると、先に設定したPrevボタンが反応しなくなった。

以下、はっきり言ってよくわからないのだが、上記のボタン設定コードではシステム側にはIntentかPendingIntentが同じものとみなされているようだ。getActivity()の第4引数が0の場合は同じものとみなされて後の設定は無視され、第4引数がFLAG_UPDATE_CURRENTの場合は同じものとみなされて後の設定内容でIntentかPendingIntentが更新されるっぽい。
解決法として、適当な値をsetAction()やsetType()で指定する。そうすると、それぞれのIntentかPendingIntentが違うものとみなされるのか、意図したような動きになる。
#setData()とかsetFlags()でも行けるかもしれないが、確認していない。

Intent intent = new Intent(this, com.example.appwidgetexample.AppWidgetExampleConfigure.class);
intent.setAction("PREV");  // 別なIntent(またはPendingIntent?)とみなされるようにActionをセット
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(KEY_BUTTON, "Prev");  // Action見ればボタンを判定できるから、これいらない
PendingIntent pendingIntent = PendingIntent.getActivity(this, appWidgetId, intent, 0);
views.setOnClickPendingIntent(R.id.awButton1, pendingIntent);

intent = new Intent(this, com.example.appwidgetexample.AppWidgetExampleConfigure.class);
intent.setAction("NEXT");  // 別なIntent(またはPendingIntent?)とみなされるようにActionをセット
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(KEY_BUTTON, "Next");  // Action見ればボタンを判定できるから、これいらない
pendingIntent = PendingIntent.getActivity(this, appWidgetId, intent, 0);
views.setOnClickPendingIntent(R.id.awButton2, pendingIntent);

参考記事:AlarmManagerに異なるintentと認識させる方法 | Android Techfirm Lab

再び、ダメ人間度チェック

昔の記事を見返していたら、ダメ人限度チェックをやったという記事があった。
今の自分はどれくらいダメなのか、7年の時を越えてダメ人間度チェックを再びやってみた。

----------
名無しさんのダメ人間度は、57pointです。

総評
【ダメ格付けAa:堕落進行中ダメ人間】                                                          『自分は平均レベルのダメ人間』との自覚は有ると思いますが....現実はかなりダメが進行しています、『まだまだ、自分よりもダメ人間が沢山いるからまだ大丈夫』と思ってるかもしれませんが、この状態ではアッという間に底割れして大暴落ダメ人間になる事は必須です・・・・・・・・・・・・一般人に戻れる確率は30%程度、まだ何とかなるレベルなので早期の対処・更正が必要です。もし戻りたいのなら、何も言わずに以下の事を実践してください。『規則正しい生活・人との交流・過度の妄想禁止・素直な心を持つ』かなり難しい事ですが、コレを乗り越えないと一般人への道は険しいです。ちなみに、このままダメ人間として堕落して行く事は簡単です、さっきの事の逆を実践すれば良いだけです、簡単だね。


名無しサンに送る、ダメ格言
「そのうち何とかなるだろう」
----------

7年前と同じ結果だw

November 14, 2011

Androidアプリ開発メモ037:marginとpadding

レイアウトファイルでのビューの余白の設定について。

android:layout_margin

自ビューと隣接するビューとの間隔を設定する。要するに外側の間隔の設定。

android:layout_margin
android:layout_marginTop
android:layout_marginBottom
android:layout_marginLeft
android:layout_marginRight

android:padding

自ビューの外枠と子ビューとの間隔を設定する。要は内側の間隔の設定。

android:padding
android:paddingTop
android:paddingBottom
android:paddingLeft
android:paddingRight

これらはある程度よりは小さくならない?ボタンのlayout_marginを0dpにしてもビュー同士がぴったりくっついてはくれない。paddingを0dpにしてもボタン内の文字とボタンの外枠の間隔はなくならない。

参考サイト:
[UI]マージン設定 - Androidon
[UI]padding設定 - Androidon
よく使うUIパーツのプロパティ - [レイアウト/Androidアプリ] ぺんたん info

eclipseでXMLファイルに出る警告の抑止

Androidアプリ開発においてレイアウトファイルやマニフェストファイルなどのXMLファイルをEclipseで開くと、右上のほうに黄色い警告の印?が出ていて、見てみると

文書に対する文法制約 (DTD または XML スキーマ) が検出されませんでした。

とある。
#Androidアプリ開発に限らない?
これは、XML宣言の後に "<!DOCTYPE configuration>"を入れてやれば出てこなくなるらしい。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration>
<tag1>
  <tag2 />
</tag1>

参考サイト:Eclipseの「DTDまたはXMLスキーマが検出されませんでした」警告を消す - penultimate diary

November 11, 2011

医者で嫌な思いをした

今日、いつも通っている医院で診察の時、医師に治療について意見した。
治療効果が上がってないように思えたので。
しかし、こちらが意見を全部言い終わる前に、医師はこちらの発言を遮るように
「それが普通です。」
と言った。それもなんか小馬鹿にしたような感じで言われた。
すげー感じ悪い。
いつもジジババで混雑しているから、いちいち患者の要望なんか聞いてられるかって感じなんだろうか。
もうその医院に定期的に通うのはやめた。
たまに薬をもらいに行くだけにしよう。

November 10, 2011

配列リテラル

intの配列を引数にするメソッドを呼ぶときに

method({ 123 });

と書いたらエラーになった。配列のリテラルってどう書くんだっけ?
#適当な勉強用のコードでの話で、リリース版のコードで引数に配列リテラル直書きとかはないと思うが。
宣言と同時に初期化する

int intArray[] = { 123 };

というのはコンパイル通るのになあ。
調べると、

method(new int[]{ 123 });

と書けばいいとのこと。
はー、すっかり忘れているなあ。

参考:Javaの配列リテラルは宣言時にしか使えないのか! - 徒然日記

November 09, 2011

Androidアプリ開発メモ036:AppWidget その3:設定用Activity

AppWidgetについての以前の記事:
Androidアプリ開発メモ034:AppWidget
Androidアプリ開発メモ035:AppWidget その2

設定用Activity

AppWidgetを貼り付けるときに設定画面を出すことが出来る。

  • 設定ファイルのandroid:configure(Androidアプリ開発メモ034参照)に、Activityのパッケージ名を含む完全なクラス名を書く。完全なクラス名で書くのは、このActivityがAppWidgetホストから起動されるからだろうか。
  • AndroidManifest.xmlにactivity要素を追加し、APPWIDGET_CONFIGUREアクションを受け取れるようにintenti-filter要素を追加する。

下記はAndroidManifest.xmlへの追記の例。
<activity android:name=".AppWidgetExampleConfigure">
  <intent-filter>
    <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
  </intent-filter>
</activity>

Activityのコードでは以下の事を行う。
  1. AppWidget IDをIntentから取得する。
  2. AppWidgetを設定する。
  3. AppWidgetManger#updateAppWidgetでAppWidgetを更新する。
  4. setResult()でRESULT_OKをActivityの起動元に返すようにして終了する
リファレンスには、設定用Activityを使う場合はAppWidgetが作成されたときにACTION_APPWIDGET_UPDATEがブロードキャストされない、つまりonUpdate()が呼ばれないとある。よって、上記3にあるようにupdateAppWidget()で画面を更新する。
しかし、AVD上で実行するとAppWidgetのホーム画面に貼り付けるとonUpdate()が呼ばれる。リファレンスの記述とAVDがどちらが正しのかは不明。
以下は設定アクティビティのエディットテキストに入力した文字を表示するAppWidgetの例。
package com.example.appwidgetexample;

import android.app.Activity;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RemoteViews;

/**
 * AppWidget設定用Activity
 */
public class AppWidgetExampleConfigure extends Activity
	implements View.OnClickListener {
	
	EditText editText1;
	int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		Log.v("TEST", "AppWidgetExampleConfigure#onCreate()");
		
		// Set the result to CANCELED.  This will cause the widget host to cancel
		// out of the widget placement if they press the back button.
		setResult(RESULT_CANCELED);
		
		setContentView(R.layout.configure);
		
		// AppWidget IDを取得する
		Intent intent = getIntent();
		Bundle extras = intent.getExtras();
		if (extras != null) {
			mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
			if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
				// AppWidget IDが不正
				Log.v("TEST", "AppWidgetExampleConfigure#onCreate():mAppWidgetId=" + mAppWidgetId + "(INVALID_APPWIDGET_ID)");
				finish();
			} else {
				Log.v("TEST", "AppWidgetExampleConfigure#onCreate():mAppWidgetId=" + mAppWidgetId);
				setupConfigureViews();
			}
		} else {
			Log.v("TEST", "AppWidgetExampleConfigure#onCreate():no extras");
			finish();
		}
	}

	/**
	 * OKボタン押下時の処理
	 */
	@Override
	public void onClick(View v) {
		Log.v("TEST", "AppWidgetExampleConfigure#onClick():mAppWidgetId=" + mAppWidgetId);
		
		RemoteViews views = new RemoteViews(this.getPackageName(), R.layout.appwidget);
		
		// AppWidgetのボタンの設定
		Intent intent = new Intent(this, com.example.appwidgetexample.AppWidgetExampleConfigure.class);
		intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
		PendingIntent pendingIntent = PendingIntent.getActivity(this, mAppWidgetId, intent, 0);	// 第2引数が大事
		views.setOnClickPendingIntent(R.id.awButton1, pendingIntent);
		
		// エディットテキストのテキストでAppWidgetを更新する
		CharSequence text = editText1.getText();
		views.setTextViewText(R.id.awTextView1, text);
//		views.setCharSequence(R.id.awTextView1, "setTextKeepState", text);	// setXXX()のテスト
//		views.setInt(R.id.editText1, "setTextColor", 0xffff00);	// setXXX()のテスト。これを実行するとAppWidgetは表示されない
		AppWidgetManager awm = AppWidgetManager.getInstance(this);
		awm.updateAppWidget(mAppWidgetId , views);
		
		// RESULT_OKをセットする
		Intent resultValue = new Intent();
		resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
		setResult(RESULT_OK, resultValue);
		finish();
	}
	
	/**
	 * 設定画面のビューの設定をする
	 */
	private void setupConfigureViews() {
		// TODO プリファレンスかローカルファイルか何かから表示するテキストを取ってきてエディットテキストにセットする
		editText1 = (EditText)findViewById(R.id.editText1);
		
		Button button1 = (Button)findViewById(R.id.button1);
		button1.setOnClickListener(this);
	}
}

onCreate()の始めで結果にRESULT_CANCELEDを設定している部分はApiDemosのExampleAppWidgetConfigure.javaから持ってきたコードで、設定アクティビティが完了する前にバックキーを押されたときにAppWidgetホストにキャンセルされたという通知するためとリファレンスには書かれている。しかし、AVD上ではRESULT_CANCELEDを設定する/しないによってバックキーを押したときの見た目上の動きは変わらない(どちらでもAppWidgetは貼り付けられない)。

onClick()中のAppWidgetManager#getActivity()は、AppWidgetを2個貼り付けた場合に第2、第4引数の組み合わせによって動作が変わってくる。

  • (0,0)の場合、以下の3パターン。
    1. 1個目をAppWidgetを貼り付ける。
    2. 1個目のAppWidgetのボタンで更新をかける。->1個目のAppWidgetが更新される。
    3. 2個目のAppWidgetを貼り付ける。
    4. 2個目のAppWidgetのボタンで更新をかける。->1個目のAppWidgetが更新される。

    1. 1個目をAppWidgetを貼り付ける。
    2. 2個目のAppWidgetを貼り付ける。
    3. 2個目のAppWidgetのボタンで更新をかける。->どちらのAppWigetも更新されない。
    4. 1個目のAppWidgetのボタンで更新をかける。->どちらのAppWigetも更新されない。

    1. 1個目をAppWidgetを貼り付ける。
    2. 2個目のAppWidgetを貼り付ける。
    3. 1個目のAppWidgetのボタンで更新をかける。->どちらのAppWigetも更新されない。
    4. 2個目のAppWidgetのボタンで更新をかける。->どちらのAppWigetも更新されない。
  • (0,PendingIntent.FLAG_CANCEL_CURRENT)の場合、2個目のAppWidgetを貼り付けると1個目のAppWidgetのボタンが反応しなくなる。2個目のAppWidgetのボタンから更新をかけると2個目のAppWidgetが更新される。
  • (0,PendingIntent.FLAG_UPDATE_CURRENT)の場合、どちらの更新ボタンで更新をかけても、2個目のAppWidgetが更新される。
  • (mAppWidgetId,PendingIntent.FLAG_CANCEL_CURRENT),(mAppWidgetId,PendingIntent.FLAG_UPDATE_CURRENT),(mAppWidgetId,0)の組み合わせでは、ボタンを押したAppWidgetが更新された。

前記事にも書いたが、getActivity(),getBroadcast(),getService()の第2引数は使用されている。同じアプリのAppWidgetを複数貼り付ける可能性がある場合は第2引数にAppWidget IDをセットすると良いようだ。参考サイト3を参照。

onClick()の中でコメントアウトしているRemoteviews#setCharSequence()について。

android.widget.RemoteViewsクラス
public void setCharSequence(int viewId, String methodName, CharSequence value)
このsetCharSequence()をはじめRemoteViewsクラスのsetInt()、setDouble()、setBoolean()といったsetXXX()("XXX"は型名)というメソッドは、第1引数viewIdで指定したビューの第2引数methodName指定した名前のメソッドを、第3引数valueを引数として渡して呼び出すメソッドである。
つまり上記の例ではコメントアウトを外せば「TextViewのsetTextKeepState(text)を呼ぶ」ということになる。
ビューのメソッドにはこれらのsetXXX()で呼び出せるものと呼び出せないものがある。
例えば上記のTextView#setTextKeepState()はsetCharSequence()で使えるが、TextView#setText()は使えない。
RemoteViews#setTextViewText()があるので、わざわざTextView#setText()をsetCharSequence()経由で呼び出さなくても用が足りるからではないかと思う。つまり、setXXX()で使えないビューのメソッドは、setXXX()を使わなくても済むようなメソッドがRemoteViewsに用意されているメソッドではないかと推測している。参考サイト4を参照。

参考サイト:
1.f. アプリウィジェット - ソフトウェア技術ドキュメントを勝手に翻訳
2.Y.A.M の 雑記帳: Android AppWidget
3.Y.A.M の 雑記帳: Android AppWidget の PendingIntent で putExtra するときの注意
4.RemotableViewMethod - 横浜デ部

November 08, 2011

Xperia rayにb-mobile Fair導入

日曜日にamazonで注文して今日届いた。
注文後、
「rayって普通のSIMでいいんだっけ?もしマイクロSIMだったら。。。」
って思ったけど、調べたらXperia rayは「スタンダードサイズSIM」って書いてあってホッとした^^;

パッケージを開けて、まず開通手続き。
「お客様の携帯電話で…」って取説に書いてあるがPHSでも問題なく出来た。

次にb-mobileのSIMをXperia rayにパイルダー・オン!
最後にAPNの設定をして保存しようとしたら、MCCとMNCというのも入力しろと怒られた。
はて?取説やb-mobileのサイトにはAPN、ユーザ名、パスワードの3つが載っている。しかしMCCやMNCという言葉はない。
ググって調べると、どうやらMCCは440、MNCは10で良いらしい。MCCは国、MNCはキャリアを識別するコードで、440は日本、10はドコモ。b-mobileはドコモのMVNOだもんな。

で、今度こそAPNの設定を保存、されない。あれ?
何回やってもエラーメッセージやワーニングが出るわけではないが、APN一覧に何も表示されない。
ネットで調べても解決策は見出せず、最後の手段として工場出荷状態に戻してからやり直そう、、、と思ったが、その前にSIMカードがきちんと挿さっているか確認てみた。前後逆に、端子の方が手前になって挿さっていた。。。
アホ過ぎる。30分無駄にしたorz

SIMカードを正しく挿して電源を入れると、APN一覧に先ほど入力したAPNが出ていた。
WiFiを切ってモバイルネットワーク設定の「データ通信を有効にする」にチェックを入れると、WEBサイトも見れる。Gmailも読める。
これでやっとWiFiないところでもいろいろ出来るようになった。

あとはAndroidにも対応した050plusを使えば通話も出来て完璧!と思ったが、契約するには携帯電話の電話番号(080か090で始まる電話番号)がいるらしい。
残念!

Androidアプリ開発メモ035:AppWidget その2

AppWidgetについての前記事:Androidアプリ開発メモ034:AppWidget

AppWidgetホスト

AppWidgetを保持できるコンポーネントをAppWidgetホストという。
普通はホームスクリーンだが、AppWidgetHostを使えば普通のアプリもApp Widget hostになれるようだ。

サービスの利用

リファレンスでは、AppWidgetの実装にサービスを利用することも検討するようにと書かれている。
理由は、AppWidgetProviderがブロードキャストレシーバなので、そのプロセスがずっと残るとは限らないから。
#AppWidget更新のブロードキャストインテントが投げられると、AppWidgetのブロードキャストレシーバをシステムが自動的に起動してくれる、とはなってないのか?
ApiDemosのExampleAppwidgetProviderはサービスを使ってないようだが、onUpdate()でサービスを起動する実装が例として挙げられている。

ここから、開発ガイドのサンプルコードに出てくるクラス・メソッドについて。

RemoteViews

AppWidgetは、AppWidgetProviderまたはAppWidgetProviderから起動したサービスとは異なるプロセスで動いている。異なるプロセス上のAppWidgetのビューを扱うにははRemoteViewsを使う。
"RemoteViews"と複数形になっているので、1個のビューではなく、レイアウトを含めたひとまとまりのビューの集合を扱うクラスなんだろう。
リファレンスのClass Overviewには以下のように書いてある。

そのクラスは、別のプロセスに表示できるビューの階層(hierarchy)を説明します(describe)。階層は、レイアウトのリソースファイルから膨らませ、そしてこのクラスでは、膨張した階層の内容を変更するためのいくつかの基本的な操作を提供しています。

レイアウトファイルに定義されている1つの画面のビューの集まりは階層構造しているから。hierarchyとはそのビューの集まりのことか。

android.widget.RemoteViewsクラス
public RemoteViews(String packageName, int layoutId)
指定したレイアウトファイルに含まれるビューを表示する新しいRemoteViewsオブジェクトを生成する。

public void setOnClickPendingIntent(int viewId, PendingIntent pendingIntent)
クリック時にIntentを発行するように指定する。
提供されたPendingIntentを起動するsetOnClickListener(android.view.View.OnClickListener)を呼び出すことに相当する。コレクション内の項目(例えばListView、StackViewなど)のオンクリックアクションを設定する場合は、このメソッドは動作しない。代わりに、setPendingIntentTemplate(int, PendingIntent)をsetOnClickFillInIntent(int, Intent)とあわせて使用する。

PendingIntent

PendingIntentを使うとタイミングを指定して(イベント発生時など)Intentを発行できる。Intentとターゲットアクション(startActivity()など)を組み合わせたラッパーとみなすことが出来る。
このクラスのインスタンスはgetActivity()、getBroadcast()、getService()で生成する。

android.app.PendingIntentクラス
public static PendingIntent getActivity(Context context, int requestCode, Intent intent, int flags)
Context.startActivity()の呼び出しのように、新しいアクティビティを開始するPendingIntentを取得する。アクティビティは、既存のアクティビティのコンテキストの外部で起動されるので、IntentでIntent.FLAG_ACTIVITY_NEW_TASK起動フラグを使用する必要があることに注意する必要がある。

public static PendingIntent getBroadcast(Context context, int requestCode, Intent intent, int flags)
Context.sendBroadcas()の呼び出しのように、ブロードキャストを実行するPendingIntentを取得する。

public static PendingIntent getService(Context context, int requestCode, Intent intent, int flags)
Context.startService()の呼び出しのように、サービスを開始するPendingIntentを取得する。

上記3個のメソッド第2引数requestCodeについて、リファレンスでは "currently not used" と書いてあるが、使用されているらしい。詳しくは参考サイト3を参照。

AppWidgetManager

AppWidgetの更新はAppWidgetManager#updateAppWdiget()を使う。

android.appwidget.AppWidgetManagerクラス
public static AppWidgetManager getInstance(Context context)
AppWidgetManagerのインスタンスを取得する。

public void updateAppWidget(ComponentName provider, RemoteViews views)
指定されたproviderのAppWidgetすべての画面を更新する。
引数:
  provider  AppWidgetのプロバイダのためのComponentName
  views  表示するRemoteViews

public void updateAppWidget(int[] appWidgetIds, RemoteViews views)
appWidgetIdsのAppWidgetの画面を更新する。

ComponentName

AppWidgetManager#updateAppWidget()の引数に使われているComponentNameは、利用可能な特定のアプリケーションコンポーネント(Activity,Service,BroadcastReceiver,ContentProvider) の識別子である。コンポーネントを識別する情報としてパッケージ名とパッケージ内のクラス名(ともに文字列)がカプセル化されている。

android.content.ComponentNameクラス
public ComponentName(String pkg, String cls)
新しいコンポーネント識別子を生成する。

参考サイト:
1.Android適当メモ : RemoteViewsの仕組み
2.Y.A.M の 雑記帳: Android AppWidget
3.Y.A.M の 雑記帳: Android AppWidget の PendingIntent で putExtra するときの注意
4.AppWidgetの作成(2) + PendingIntent << Tech Booster

November 06, 2011

FF11 ローグプーレーヌをゲット

シーフAF1足のクエ「候国の栄光」がガルレージュ要塞のイベント・NM戦でずっと止まっていた。
それで今週、2回ほどジュノ港で「門開けるの手伝ってくださいー」ってシャウトしたが、応えてくれる人はなし。
一人、「さっきのシャウト人集まらなかった?自分もシーフAF足欲しいんだけど」というtellはあったが。
それで今日、LSメンバーにお願いした。

面倒くさいクエである。1門の手前2カ所、門の奥で4カ所でイベントを見てからボムNM戦。一度外に出るとイベントがクリアされるので、過去から行っても出来ない。過去から門奥に行ってイベントを見て、門を通って門手前のイベントを見ても、NMを沸く場所が門奥なので1人だと門を通れないのでNMの沸く場所まで行けない。

テクテク歩いて全部のイベントを見終わり、NMを湧かした。が、即自爆。アイテム手に入らず、なんでやねんorz
WEBで調べたら、
1.???を調べる。
2.すぐに逃げる。
3.NMが湧いてから魔法以外の遠隔攻撃で釣る。
という手順が必要とのこと。
10分待って、再度NMを湧かし、手順どおりに弓で遠隔攻撃して戦闘開始。
LV90以上ならソロで勝てるかと思ったが、思いっきり死にましたorz
自分はシーフだったのだが敵の攻撃をほとんど避けられない。きちんとした装備してきたのに。
そして攻撃力が高い。一発で100とか200とかHPを持っていかれる上にバーサクも使ってくる。
ソロでやるなら忍/踊か踊/忍じゃないと厳しそうだ。蝉は必要。自分なら忍も踊もカンストしてないから、シ/忍で、ハイポたくさんもっていくしかない。まあ、もう2度と戦うことはないけどw
門開けを手伝ってくれたLSメンバーにレイズをもらい、同じくLSメンバーの忍さんが倒してくれた。
シャンデリアの灰を入手。

マウラで灰を渡し、ウィンでナナー・ミーゴに会ってクリア、と思ったら、まだオルデール鍾乳洞を通ってその奥まで行かないと行けないと言われた。
本当に面倒くさいクエだ。
ラテーヌ高原で最後のイベントを見てローグプーレーヌをゲット。
やーっと手に入った。面倒なクエの報酬だけあって、とんずら+30秒は非常に有用だ^^

November 05, 2011

第31節、新潟完敗また潟った、磐田は快勝

J's GOAL:試合詳細:2011 J1 第31節 柏レイソル 4-0 アルビレックス新潟

首位のチームと下位のチームの実力差がそのまま、いやそれ以上にで出た。
新潟はミシェウが出場停止なので柏のブラジル人対策も兼ねて4-3-3に変更。小林慶行がアンカーで、その前に本間と菊地。しかしJ'sGOALの試合レポートによると柏はそれをわかっていてちゃんと選手に対策を指示していたようだ。
いつもと違うことやるならちゃんと情報管理しようよ。これから何をやるか新聞に書かれちゃしょうがないだろう。

負けたこと以上に腹立つのはまた「90+1分」に失点していること。全く改善が見られない。
ミシェウが戻っても名古屋とガンバには同じような結果だろうなあ。


J's GOAL:試合詳細:2011 J1 第31節 浦和レッズ 0-3 ジュビロ磐田

ロドリゴソウトが復帰し、前田2得点、山崎1得点。
#前田の3年連続得点王は厳しいな。ケネディとハーフナーが17点だから。
しかし浦和が悪すぎるな。エスクデロと原口がドリブルでただ突っ込んでくるだけ。
マルシオがベンチにも入ってないけどケガなのか。それとも単にベンチ外なのか。もし使わねえなら新潟に返してくれ。


山形は神戸に負けてJ2降格決定。一番近いJ1チームが落ちて残念だ。
小林監督を悪く言う人がいるが、そりゃ酷だろう。むしろあの戦力でよく3年間J1で保ったと思う。
これで小林監督がやめて、牧内が監督に昇格とか牧内が推薦する監督が就任とかなら、山形は当分J1に戻れなくなる。
牧内を切って小林監督を慰留すべき。


新潟は情けない試合をしたが甲府は負けたので、甲府は残り3試合全勝しかなくなった。甲府はこれ以上ない崖っぷち。
新潟は勝ち点1足せば残留がほぼ確定だが、これから2試合、オリンピック予選で高徳と大輔がいない。
磐田が頑張れ。新潟を助けてくれ^^;

November 03, 2011

へこむ1日だった

昨日は本当に嫌なことばかりの1日だった。

朝から腰が痛かった。
起きる前、布団の中にいる段階で痛い。それも今まで感じたことのない痛み。
今までは腰から足にかけて鈍い痛みだったが、昨日のは腰の奥の方に鋭い痛みがした。
椎間板ヘルニアが悪化してるのかなあ。

その後、路上で知らない人に怒鳴られた。
まあ、俺が悪いのだが。
でも、同じような事をしている人はたくさんいるのに怒鳴られているのを見たことはない。
俺の顔は弱そうな、怒鳴っても反撃されなそうに見える顔なんだろうな。

さいごに就職活動がダメだった。
応募していた2社のうち、1社は応募して速攻で「残念ながら…」ってメールが来たが、もう1社は応答がないので意を決して直接電話した。で、ダメだった。
返事がないってことはダメなんだろうなと思っていた。はっきりしたのでこれはかえってスッキリしたかな。

やる気が90%くらい減った。
FF11やって現実逃避中w

November 02, 2011

Androidアプリ開発メモ034:AppWidget

AppWidgetとは

AppWidgetはホームスクリーンに貼り付けられて常駐する小さいアプリケーション。フルスクリーン表示はできないらしい。

必要なのは以下。

  • レイアウトファイル
  • 設定ファイル
  • AppWidgetProviderを継承したクラス
  • AndroidManifest.xmlへAppWidgetの宣言を書く。

レイアウトファイルは使用できるレイアウトが以下のFrameLayout,LinearLayout,RelativeLayoutの3つのみで、使用できるウィジェットも限定されるが、それ以外は通常のアプリケーションと同じ。

設定ファイル

res/xmlフォルダにappwidget-provider要素1個だけがあるXMLファイルを作る。その属性で設定をする。

android:minHeight,android:minWidthはAppWidgetのサイズを指定する。サイズは決められたセル単位となる。
値は使うセルの数で下記の計算をしてdp(dip)単位で指定する。

  (セルの数 * 74) - 2

android:updatePeriodMillisは更新間隔をミリ秒単位で指定する。0とした場合は自動更新しない。
最小値は1800000(30分)で、それ以下の場合を設定した場合は1800000に繰り上げられる。

android:initialLayoutはレイアウトファイルを指定する。レイアウトファイルが"res/layout/appwidget.xml"の場合は、"@layout/appwidget"と指定する。

android:configureはAppWidget設定用アクティビティのクラス名を指定する。これはオプション。

<?xml version="1.0" encoding="UTF-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/appwidget"
    android:minHeight="72dp"
    android:minWidth="146dp"
    android:updatePeriodMillis="0"
    android:configure="com.example.appwidgetexample.AppWidgetExampleConfigure" >
</appwidget-provider>

AppWidgetProvider

android.appwidget.AppWidgetProviderクラスを継承し、以下のメソッドを必要に応じてオーバーライドしてブロードキャストレシーバを作成する。

public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
AppWidget更新時に呼ばれる。

public void onDeleted(Context context, int[] appWidgetIds)
AppWidget削除されると毎回呼ばれる。

public void onEnabled(Context context)
AppWidgetのインスタンスが始めて作成されたときに呼ばれる。

public void onDisabled(Context context)
AppWidgetがすべて削除されたときに呼ばれる。


AVDで同じAppWidgetを2個ホームスクリーンに貼り付けた場合、貼り付けるときにはそれぞれ1回ずつonUpdate()が呼ばれてそのときのappWidgetIds.lengthは1だが、自動更新(updatePeriodMillis)の時にonUpdate()が1回だけ呼ばれてappWidgetIds=2である。しかし、AppWidgetを1個削除しても次のouUpdate()の呼び出しでappWidgetIds=2である。なんか変な感じがする。

上記のメソッド全部をオーバーライドする必要はなく、例えば表示が変わるだけでリソースの取得・解放が必要なければonUpdate()だけオーバーライドすればよい。

AppWidgetProvider#onReceive()の実装は、ブロードキャストをフィルタし上記のメソッドを適切に呼び出している(ACTION_APPWIDGET_UPDATEのIntentを受信した場合にonUpdate()を呼ぶ、など)ので、通常はこのメソッドをオーバーライドする必要はない。

以下、リファレンスのClass Overviewの訳(一部)
public class AppWidgetProvider extends BroadcastReceiver
クラスの概観
AppWidgetプロバイダの実装を補助する便利なクラス。AppWidgetProviderでできるすべてのものは、いつものBroadcastReceiverでできる。AppWidgetProviderは単に、onReceive(Context,Intent)で受信されたIntentからの関連するフィールドをパースし、受信した追加のものとともにフックメソッドを呼ぶだけである。

AppWidgetの宣言

AndroidManifest.xmlにAppWidgetの宣言を追記する。
<receiver
  android:name=".AppWidgetExample"
  android:label="@string/app_name">
  <intent-filter>
    <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
  </intent-filter>
  <meta-data
    android:name="android.appwidget.provider"
    android:resource="@xml/appwidget_provider_info" />
</receiver>

intent-filter要素ではactionがAPPWIDGET_UPDATEのブロードキャストインテントを受信できるようにしている。必要に応じて他のブロードキャストインテントも受信できるようにする。

meta-data要素のandroid:name属性はメタデータの名前を指定する。AppWidgetの設定の場合は"android.appwidget.provider"とする。

android:resource属性の値はAppWidgetの設定ファイルのファイル名(この場合は"appwidget_provider_info.xml")を指定する。

参考:
f. アプリウィジェット - ソフトウェア技術ドキュメントを勝手に翻訳
AppWidgetの作成(1) << Tech Booster
ウィジェットの作り方 | テックファーム
Y.A.M の 雑記帳: Android AppWidget
Android適当メモ : RemoteViewsの仕組み
Android1.6ではandroid:updatePeriodMillisの最小値は1800000: 雪羽の発火後忘失

FF11 スラッグNMに2連敗

2連敗してしまったorz

2回ともこんな感じ。
特殊技を受ける->ヒーリングワルツを使う->攻撃を多く受ける->ケアルワルツのリキャストがまだ->ケアルワルツが使えるようになったので使う->ちょうどウォタガかウォタジャの詠唱が始まる->Vフラリッシュが間に合わずorミスして魔法を受けて死亡

勝ったときは雷曜日だったのかなあ。今回は火曜日だったが。
次やるときは曜日を気にして、あとメロー17号ロケットでも装備してみるか。

« October 2011 | Main | December 2011 »

May 2017
Sun Mon Tue Wed Thu Fri Sat
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
無料ブログはココログ

日本blog村

  • にほんブログ村 IT技術ブログへ
  • にほんブログ村 アニメブログへ
  • にほんブログ村 サッカーブログ アルビレックス新潟へ

好きな音楽家

メモ

XI-Prof