2011年7月18日月曜日

ListView の画像に ContactBadge を表示する

ListView に表示している画像がクリックされたら ContactBadge を表示させる。OnItemClickListener ではクリックされた位置がわからないので、OnTouchListener で一度受けて座標情報を保存し、OnItemClickListener でレンジをチェックして処理を分ける。以下の例では画像の表示エリアが左側なので、その右端で判定している。

  mListView.setOnItemClickListener(new OnItemClickListener() {
   @Override
   public void onItemClick(AdapterView arg0, View arg1,
     int position, long arg3) {
    ImageView iv = (ImageView) arg1.findViewById(R.id.photo);
    int right = iv.getRight();
    if (mListPosX <= right) {
     Contact contact = mAdapter.getItem(position).getContact();
     Uri uri = ContactsContract.Contacts.getLookupUri(contact.getContactId(),
       contact.getLookupKey());
     ContactsContract.QuickContact.showQuickContact(mContext, iv , uri,
       ContactsContract.QuickContact.MODE_SMALL,  null);
     mContactBadge = true;
    } else {
     Intent intent = new Intent(MainActivity.this,
       ContactActivity.class);
     intent.putExtra(ContactActivity.INTENT_CONTACT, mAdapter
       .getItem(position).getContact().getContactId());
     startActivity(intent);
    }
   }
  });
  
  mListView.setOnTouchListener(new OnTouchListener() {

   @Override
   public boolean onTouch(View v, MotionEvent event) {
    mListPosX = (int) event.getX();
    return false;
   }
   
  });

2011年7月1日金曜日

DialogPreference で summary を設定

DialogPreference を継承したクラスで summary を起動時にセットするときに、そのコンストラクタで getPersistedValue しても設定が読めない。ちょっと探してみた限りは明確な答えが見つからなかったけど、onAttachedToActivity() で設定を読むようにしたらちゃんと読めた。

 @Override
 protected void onAttachedToActivity() {
  AppInfo info = getSetting(); // この中で getPersistedString() してる
  if (info == null) {
   setSummary(mContext.getString(R.string.no_pref));
  } else {
   setSummary(info.mLabel);
  }
 }

その他ハマってしまったのは、onDialogClosed で superクラス呼ばないと設定が保存されないこと。

2011年6月15日水曜日

アプリから画像の選択Intentをもらう

画像をピックするIntent呼び出しに反応するには、AndroidManifest.xml に以下を追加する。

            <intent-filter>
                <action android:name="android.intent.action.GET_CONTENT" />
                <category android:name="android.intent.category.OPENABLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="image/*" />
            </intent-filter>

ただし、アプリによってはこれで受け取れない。例えば Seesmic の「添付ファイルを選択」に反応するためには、以下を追加する必要がある。

            <intent-filter>
                <action android:name="android.intent.action.PICK" />
                <category android:name="android.intent.category.OPENABLE" />
                <category android:name="android.intent.category.DEFAULT" />
                <data android:mimeType="image/*" />
            </intent-filter>





2011年6月5日日曜日

Xperia で GregorianCalendar に年月日をセット

Xperiaでカレンダーに値をセットしてゲットすると値がずれることがある。例えば 1995/6/5 を new GregorianCalendar(1995, 6 - 1, 5) として、Calendar.DATE をgetすると 4 が返ってくる。ちょっと調べてみたら、1976/5/3 から 2000/9/17 の期間はずれる。1942年あたりもずれる。同じコードをエミュレータで実行してみるとずれない。DATEをセットする前にゲットするとずれない。

GregorianCalendar calendar = new GregorianCalendar();
   calendar.set(Calendar.YEAR, year);
   calendar.set(Calendar.MONTH, month - 1);
   // Xperiaで日にちがずれる。
   calendar.get(Calendar.DATE);
   calendar.set(Calendar.DATE, day);

2011年5月21日土曜日

ウィジェットが動かなくなっちゃう問題

ウィジェットが気がつくと動かなくなってしまう問題は、端末の縦横が変わると発生することがわかった。

対処は、Orientation changeをキャッチして、PendingIntentを再設定して、RemoteViewを書き直す。書き直しはやらなくていいかも。
リンクの例では正しく動作しない。oldOrientation が newConfigと同じになる。
 public static class UpdateService extends Service {

  private List mIdList;
  private int mOrientation;
  
  @Override
  public void onStart(Intent intent, int startId) {
   Bundle extras = intent.getExtras();
   int id = AppWidgetManager.INVALID_APPWIDGET_ID;
   if (extras != null) {
    id = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
      AppWidgetManager.INVALID_APPWIDGET_ID);
   }
   if (id == AppWidgetManager.INVALID_APPWIDGET_ID) {
    return;
   }
   
   if (mIdList == null) {
    mIdList = new ArrayList();
   }
   mIdList.add(id);
   
   AppWidgetManager manager = AppWidgetManager.getInstance(this);
            
            updateWidget(mContext, manager, id);
  }
  
        @Override
        public void onConfigurationChanged(Configuration newConfig)
        {
            if(newConfig.orientation != mOrientation) {
             mOrientation = newConfig.orientation;
                AppWidgetManager manager = AppWidgetManager.getInstance(this);
                for (int id : mIdList) {
                 updateWidget(mContext, manager, id);
                }
            }
        }
  
  @Override
  public IBinder onBind(Intent arg0) {
   // TODO Auto-generated method stub
   return null;
  }
  
 }
Manifestでandroid.permission.CHANGE_CONFIGURATION も必要

2011年5月8日日曜日

ExpandableListViewの長押し

ExpandableListViewでは、アイテムの長押しを setOnLongClickListenerで設定できない。
コンテクストメニューを使って実現する。

こんな感じで設定しておく。
mExpandableListView
    .setOnCreateContextMenuListener(new OnCreateContextMenuListener() {

     @Override
     public void onCreateContextMenu(ContextMenu menu, View v,
       ContextMenuInfo menuInfo) {

      ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo) menuInfo;
      int type = ExpandableListView
        .getPackedPositionType(info.packedPosition);
      int groupPosition = ExpandableListView
        .getPackedPositionGroup(info.packedPosition);
      int childPosition = ExpandableListView
        .getPackedPositionChild(info.packedPosition);
      // Only create a context menu for child items
      if (type == 1) {

       // Array created earlier when we built the
       // expandable list
       Contact contact = (Contact) mAdapter.getChild(
         groupPosition, childPosition);
       menu.setHeaderTitle(contact.getName());
       menu.add(0, MENU_EDIT, 0, "Edit birthday");
       menu.add(0, MENU_DELETE, 1, "Delete birthday");
      }
     }

    });

メニューが選ばれたらそれを実行。
public boolean onContextItemSelected(MenuItem menuItem) {
  ExpandableListContextMenuInfo info = (ExpandableListContextMenuInfo) menuItem
    .getMenuInfo();
  int groupPos = 0, childPos = 0;
  int type = ExpandableListView
    .getPackedPositionType(info.packedPosition);
  if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {
   groupPos = ExpandableListView
     .getPackedPositionGroup(info.packedPosition);
   childPos = ExpandableListView
     .getPackedPositionChild(info.packedPosition);
  }

  Contact contact = (Contact) mAdapter.getChild(groupPos, childPos);
  switch (menuItem.getItemId()) {
  case MENU_EDIT:
   dateDialog(contact, contact.getBirthday());
   return true;
  case MENU_DELETE:
   deleteBirthday(contact);
  default:
   return super.onContextItemSelected(menuItem);
  }
 }

2011年5月5日木曜日

コード表示

http://www.kuribo.info/2008/06/blogger-syntax-highlighter.html
を参考にして、コード表示できるようにした。ここで紹介されている導入方法はFirefoxでは動作しない。IEタブで開くと導入することができた。
最初よくわからなくて、いろいろやってたらコード表示を1個しか書いていないにもかかわらず2個表示されるようになった。1個だけ表示するように戻す方法がわからなかったので、そのブログを廃棄!して別のブログを作成したw。
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}