ライブ壁紙開発時にUSBケーブルを接続しないと起動しない問題

問題というほどでもなかった。Androidのライブ壁紙作成のお話。

ライブ壁紙をステップ実行してデバッグするためにwaitForDebuggerを書いたのはいいのだけど、それを忘れてデバッグ用じゃない端末にインストールすると、一向にライブ壁紙を選択した後の「ライブ壁紙を読み込み中…」から進まない。

開発用端末でUSBケーブルを繋いでいると先に進めてしまうので、isDebuggerConnectedメソッドで分岐するようにしました。

public class MyWallpaperService extends WallpaperService {

	private final Handler handler = new Handler();

	@Override
	public Engine onCreateEngine() {
		if (android.os.Debug.isDebuggerConnected() // ここでデバッガが繋がっているか判定
				&& MyApplication.isDebuggable()) { // こっちはmanifestのdebuggableを読む実装
			android.os.Debug.waitForDebugger();    // デバッガ待機
		}
		return new MyEngine();
	}

	// do something ...

}


Androidで地磁気センサーの値が取れない問題

いや、取れないわけじゃないですけどね。SensorManager.SENSOR_STATUS_UNRELIABLEにハマった…

駄猫の備忘録: 久々にセンサーを使ってみた

XPERIA rayで方位が取れない問題があったので、調べていたところaccuracyのチェックでメソッドを抜けていたことが判明…完全に見落としてた。

	@Override
	public void onSensorChanged(SensorEvent event) {

		if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) {
			return;
		}

		switch (event.sensor.getType()) {
		case Sensor.TYPE_MAGNETIC_FIELD:
			magneticValues = event.values.clone(); // ■ここに来ない
			break;
		case Sensor.TYPE_ACCELEROMETER:
			accelerometerValues = event.values.clone();
			break;
		}

		// do something ...

	}

GALAXY Sでも方向が取れないと報告があったので多分これでしょう。

キャリブレーションすればいいのかな…


Heap updates are NOT ENABLED for this client

How to enable Heap updates on my android client – Stack Overflow

EclipseのDDMSでAndroid実機端末のヒープを見る方法のメモ。

heap1

heap2

デバイスビューの緑の筒みたいなアイコンをクリックします。

heap3

これでヒープが見られるようになります。

heap4


CoreException: Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resource-plugin:2.4.3

Eclipse 3.7(Indigo)で、m2eをインストールしてTwitter4jをインポートしたあと、pom.xmlで

CoreException: Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resource-plugin:2.4.3

というエラーが表示されてビルドできないという現象がありました。

m2eの再インストールとか色々試したのですが、以下の情報で解決できました。

De GIS, Programación y Otros Demonios: Maven Error: Could not calculate build plan

Windowsのユーザーフォルダにある.m2\repositoryフォルダの中から、「.lastUpdated」という拡張子がついたファイルを検索します。

ファイルが見つかったら、それを削除します。

Eclipseのプロジェクトエクスプローラー上から、プロジェクトを選択して、右クリック、Maven→Update Project Configuration…を選択、プロジェクトを選択してOKを押すだけです。


MavenのプロジェクトをEclipseにインポートする

環境はWindows7+Eclipse 3.7(Indigo)。

以前、m2eclipseと呼ばれていたプロジェクトは正式にEclipseのプロジェクトに取り込まれて、今はm2eとしてEclipseのレポジトリからインストールできます。

Webで検索すると、sonatypeのサイトにリンクしている、情報が古いエントリが多く出てくるので注意。

メニューのHelp→Install New Software…で、Work withに「Indigo – http://download.eclipse.org/releases/indigo」を選択。

「type filter text」の欄に「maven」と入力すれば「m2e」が表示されます。「m2e – Maven Integration for Eclipse    1.0.0.20110607-2117」にチェックを入れて、先に進めばインストールできます。

実際にMavenのプロジェクトを取り込むときは、メニューのFile→Import→Maven→Existing Maven Projectsを選択して、「Root Directory」の欄にpom.xmlのあるディレクトリを指定すればProjectsのリストが表示されます。


Symfonyの機能テストでclickを使わずにmultipartのファイルPOSTをする方法

Symfony 1.4で実装したAPIのFunctionalテストをする際に、ファイルをPOSTする方法に迷ったので調べました。

ファイルのアップロードテストは、通常のWebサイトであれば、

$browser->
    get('/upload')->
    click('Upload', array('form' => array(
        'file1' => sfConfig::get('sf_test_dir').'/datas/test01.jpg',
    )))
;

みたいに書くのですが、テストしたいアプリケーションはAPIなので、GETするページはありません。

sfBrowserBase::clickを参考にして、こんな感じで実装しました。

まずはテスト本体。test/functional/api/hogeActionsTest.php

<?php

include(dirname(__FILE__).'/../../bootstrap/functional.php');

$browser = new MyTestFunctional(new myBrowser());
$browser->loadData();

$browser->
    info('JPEGファイルをアップロードできる')->
    setUploadFile('file1', sfConfig::get('sf_test_dir').'/datas/test01.jpg')->
    post('/upload', array('title' => 'hoge'))->
    
    with('response')->begin()->
        isStatusCode(200)->
    end()->
;

次にmyBrowserを定義します。lib/test/myBrowser.class.php

<?php

class myBrowser extends sfBrowser
{

    public function setUploadFile($key, $filename)
    {
        if (is_readable($filename))
        {
          $fileError = UPLOAD_ERR_OK;
          $fileSize = filesize($filename);
        }
        else
        {
          $fileError = UPLOAD_ERR_NO_FILE;
          $fileSize = 0;
        }
        
        $this->parseArgumentAsArray($key, array(
            'name' => basename($filename),
            'type' => '',
            'tmp_name' => $filename,
            'error' => $fileError,
            'size' => $fileSize,
        ),
        $this->files);
    }

}

sfBrowserBaseクラスのfilesに対して配列でファイルの情報を書き込むと、POST直前に$_FILESに書きこんでくれます。

で、あとはMyでmyBrowser::setUploadFileを呼び出すだけです。lib/test/MyTestFunctional.class.php

<?php

class MyTestFunctional extends sfTestFunctional
{
    public function loadData()
    {
        $doctrine = Doctrine_Manager::getInstance()->getCurrentConnection()->getDbh();
        $doctrine->query('SET FOREIGN_KEY_CHECKS = 0');
        $doctrine->query('TRUNCATE TABLE uploads');
        $doctrine->query('SET FOREIGN_KEY_CHECKS = 1');
        unset($doctrine);
        
        Doctrine::loadData(sfConfig::get('sf_test_dir').'/fixtures/');
        return $this;
    }

    public function setUploadFile($key, $filename)
    {
        $this->browser->setUploadFile($key, $filename);
        
        return $this;
    }
}

こうやってsetUploadFile(…)->post(…)と呼び出せばOKです。

sfBrowserBase::callされるたびにfilesの中身はクリアされます。


SSDのデータを完全消去する

SSDを廃棄したり、人に譲るときなど、データを完全に削除したい場合があります。

HDDで使われるディスク消去ツールは、HDDの特性に合わせて作られているので、SSDで実行した場合に、限られた書き込み回数を無駄に消費することになるので使えません。

Intelから提供されているSSD Toolboxを使うと、簡単にデータを削除できます。

ダウンロード・センター Intel® Solid State Drive Toolbox

Windows 7,Windows Vista,Windows XPで使えます。


ArduinoとEthernetシールドとDHCPとDNS

以前書いた Arduino DHCP Libraryを使ってみる : blog.loadlimit – digital matter – で使ったライブラリが、最近のIDEで使えなくなったということで、他のライブラリを見つけました。

gkaindl.com → software → arduino ethernet

前述のDHCP Libraryをベースに改良されたもので、機能も拡張されています。

ダウンロード後、解凍して、中身のフォルダをArduinoのlibrariesフォルダにコピーします。

あとはただただソースを書くだけ。

DHCPの更新処理とかを自動でやってくれるmaintain()が便利です。こんな感じのコードになりました。
#if defined(ARDUINO) && ARDUINO > 18
#include <SPI.h>
#endif
#include <Ethernet.h>
#include <EthernetDHCP.h>
#include <EthernetDNS.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };

const char* hostName = "sample.com";

void setup()
{
  delay(100);
  Serial.begin(9600);

  EthernetDHCP.begin(mac);
}

void loop()
{
  EthernetDHCP.maintain();
  
  const byte* dnsAddr = EthernetDHCP.dnsIpAddress();
  EthernetDNS.setDNSServer(dnsAddr);
  
  static bool isDnsResolved = false;
  static byte remoteAddr[4];
  
  if (!isDnsResolved) {
    
    DNSError err = EthernetDNS.sendDNSQuery(hostName);
    
    if (DNSSuccess == err) {
      do {
        err = EthernetDNS.pollDNSReply(remoteAddr);
        
        if (DNSTryLater == err) {
          delay(20);
          Serial.print(".");
        }
      } while (DNSTryLater == err);
    }
    
    if (DNSSuccess == err) {
      isDnsResolved = true;
    }
    
  }
  
  if (isDnsResolved) {
    
    Client client(remoteAddr, 80);
    
    Serial.println("connecting...");
    
    if (client.connect()) {
      Serial.println("connected");
      
      client.println("GET / HTTP/1.0");
      client.println();
      
      // 返事が戻ってくるまで待機
      do {
        if (client.available()) {
          char c = client.read();
          // ここで何かする
        }
        if (!client.connected()) {
          Serial.println();
          Serial.println("disconnecting.");
          client.stop();
          break;
        }
      } while (true);
    }
    else {
      Serial.println("connection failed");
      delay(2000);
    }
    
  }
}

DNSの更新は見ていないのでDDNS環境のサーバを長時間監視する場合はそれなりの処理が必要です。

それと、イーサネットシールドがPCに接続していない場合にIPを取れない問題は、新しいバージョンのイーサネットシールドでは修正されていたようです。

スイッチサイエンス/商品詳細 Arduino イーサネットシールド

古いバージョンを使っている人は、下記のサイトに対策が載っていました。自分もコンデンサひとつとダイオードひとつ追加してみたら正常に動作するようになりました。

Arduino Ethernet Shieldのパワーオンリセット: PS3とLinux、電子工作も


AndroidアプリからFacebookアプリに画像をキャプション付きで投稿する

Androidにて、ActivityからFacebookにギャラリーの画像をシェアする際に、画像の説明であるキャプションを指定する方法がわからなかったので調べました。

結論としてはIntent.EXTRA_TITLEを指定すれば良いようです。

TwitterやメールではIntent.EXTRA_TEXTとかなので、そのままだとFacebookアプリには反映されません。

String text = "Some caption...";
Uri path = Uri.parse("content://media/external/images/media/1"); // Gallery's URI etc.

Intent intent = new Intent(Intent.ACTION_SEND);

// キャプション
intent.putExtra(Intent.EXTRA_TITLE, text);

// 添付ファイル
intent.setType("image/jpeg");
intent.putExtra(Intent.EXTRA_STREAM, path);

intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(Intent.createChooser(intent, getString(R.string.post_facebook)));

追記 2012/09/20

Facebookのプラットフォームにより、Intentでテキストを追加することができなくなったそうです。
Bug – Android Intent Sharing is Broken – Facebook開発者


sfFlickrPluginのRequest failed.に対処する

symfony 1.4にて、Flickrから画像を取得して使いたかったので、sfFlickrPluginを使ってみました。

sfFlickrPluginのインストール方法はこちらのサイトを参考にチェックアウトできます。

symfonyでFlickrを使用するためのPluginまとめ – Layer8 Reference

基本的には手動によるセットアップです。
plugins/に展開します。
自分はエクスポートしました。

$ cd plugins/
$ svn export http://svn.symfony-project.com/plugins/sfFlickrPlugin

キーに関してはさきほどのサイトを参考に。

あとは

config/ProjectConfiguration.class.php

に、enablePluginsを追加すればOKです。

  public function setup()
  {
    $this->enablePlugins('sfDoctrinePlugin');
    $this->enablePlugins('sfFlickrPlugin');
  }

で、セットアップ完了。

ここから表題の話。

グループから写真を取得したい場合はgetGroupPhotoListを使います。

が、getGroupPhotoListを実行すると、

Request failed. The requested URL returned error: 413

というエラーで停止。

plugins/sfFlickrPlugin/lib/vendor/Phlickrを最新に差し替えることで解決します。

Phlickrはこちらにあります。

Phlickr | Download Phlickr software for free at SourceForge.net

Phlickrの最新版は0.2.8だったので、丸ごと上書きします。

ファイル一式とFramework、TextUiディレクトリも上書き

それ以外のディレクトリは調べてないのでわからないですが、まぁ、置いておけば良いのでは。

Testsは、いらない雰囲気。

これで正常に動くようになりました。

あと、桁あふれの問題があるので、

PhlickrのbuildImgUrlでPhoto IDが桁あふれ : blog.loadlimit – digital matter –

を参考にして修正してください。