Android ListViewでなんちゃってフィルター

ListViewでフィルターぽい処理をしてみました。
フィルタするデータのレイアウトを非表示にするパターンなのでデータの再読み込みは発生しません。
もしかしたら、デフォルトでフィルタ機能があるかもしれませんが・・・

MainActivity

public class MainActivity extends Activity {

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // filterButton
        ((Button)findViewById(R.id.filterButton)).setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                String keyword = ((EditText)findViewById(R.id.keywordText)).getText().toString();
                ListView listView = (ListView)findViewById(R.id.listView);
                AppAdapter appAdapter = ((AppAdapter)listView.getAdapter()); //adapter取得
                appAdapter.setFilter(keyword); // filter設定
                appAdapter.notifyDataSetInvalidated();	// listView更新
                listView.setSelectionAfterHeaderView(); // listViewのTOPに移動
                // ソフトキーボード消す
                InputMethodManager inputMethodManager = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
                inputMethodManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
            }
        });
        // データ取得
        new AppTask(getApplicationContext(), (ListView)findViewById(R.id.listView)).execute();
    }

    class AppTask extends AsyncTask<Void, Void, List<ApplicationInfo>> {

        private Context context;
        private ListView listView;

        public AppTask(Context context, ListView listView) {
            this.context = context;
            this.listView = listView;
        }

        @Override
        protected void onPreExecute() {
            // progress表示
        }

        @Override
        protected List<ApplicationInfo> doInBackground(Void... params) {
            // アプリ情報を取得
            PackageManager pm = getPackageManager();
            return pm.getInstalledApplications(BIND_AUTO_CREATE);
        }

        @Override
        protected void onPostExecute(List<ApplicationInfo> appList) {
            // progress非表示
            AppAdapter appAdapter = new AppAdapter(context, appList);
            listView.setAdapter(appAdapter);
        }
    }

}


adapter

public class AppAdapter extends ArrayAdapter<ApplicationInfo>{

    private Context context;
    private LayoutInflater inflater;
    private String keyword; // フィルタ用キーワード

    public AppAdapter(Context context, List<ApplicationInfo> items) {
        super(context, 0, items);
        this.context = context;
        inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        keyword = "";
    }

    public View getView(final int position, View convertView, ViewGroup parent) {
        Holder holder = null;
        View view = convertView;
        if (view == null) {
            view = inflater.inflate(R.layout.item, null);
            RelativeLayout mainLayout = (RelativeLayout)view.findViewById(R.id.mainLayout);
            ImageView iconImage = (ImageView)view.findViewById(R.id.iconImage);
            TextView nameText = (TextView)view.findViewById(R.id.nameText);
            holder = new Holder(mainLayout, iconImage, nameText);
            view.setTag(holder);
        } else {
            holder = (Holder)view.getTag();
        }

        ApplicationInfo appInfo = getItem(position);
        if (appInfo != null) {
            try {
                // アプリ名
                String name = appInfo.loadLabel(context.getPackageManager()).toString();
                holder.nameText.setText(name);
                // アイコン
                holder.iconImage.setImageDrawable(null); // クリア
                holder.iconImage.setTag(name);				// 非同期だとアイコンが一致しないため
                // フィルタ処理
                if (TextUtils.isEmpty(keyword)) {
                    // フィルタなし
                    holder.mainLayout.setVisibility(View.VISIBLE);
                    new BitmapTask(holder.iconImage).execute(appInfo);	//非同期
                } else if (name.toLowerCase().indexOf(keyword.toLowerCase()) >= 0) {
                    // 一致していれば表示
                    holder.mainLayout.setVisibility(View.VISIBLE);
                    new BitmapTask(holder.iconImage).execute(appInfo);	//非同期
                } else {
                    // 不一致なのでlayout非表示
                    holder.mainLayout.setVisibility(View.GONE);
                }
            } catch (Exception e) {
            }
        }
        return view;
    }

    /**
     * フィルタする文字列設定
     * @param keyword
     */
    public void setFilter(String keyword) {
        this.keyword = keyword;
    }

    static class Holder {
        RelativeLayout mainLayout;
        ImageView iconImage;
        TextView nameText;
        Holder(RelativeLayout mainLayout, ImageView iconImage, TextView nameText) {
            this.mainLayout = mainLayout;
            this.iconImage = iconImage;
            this.nameText = nameText;
        }
    }

    // アイコン取得
    class BitmapTask extends AsyncTask<Object, Void, Drawable> {

        private ImageView iconImage;
        private String tag;

        public BitmapTask(ImageView iconImage) {
            this.iconImage = iconImage;
            tag = iconImage.getTag().toString();
        }

        @Override
        protected void onPreExecute() {}

        @Override
        protected Drawable doInBackground(Object... params) {
            // 本来ならHashMap等にキャッシュとして保持して再利用
            try {
                ApplicationInfo appInfo = (ApplicationInfo)params[0];
                return appInfo.loadIcon(context.getPackageManager());
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        protected void onPostExecute(Drawable icon) {
            if (tag.equals(iconImage.getTag().toString())) {
                // tagが一致したらセット
                iconImage.setImageDrawable(icon);
            }
        }
    }
}


main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <LinearLayout android:layout_height="wrap_content" android:id="@+id/linearLayout1" android:layout_width="fill_parent">
        <EditText android:layout_height="wrap_content" android:id="@+id/keywordText" android:layout_width="fill_parent" android:layout_weight="1"></EditText>
        <Button android:layout_height="wrap_content" android:id="@+id/filterButton" android:text="filter" android:layout_width="wrap_content"></Button>
    </LinearLayout>
<ListView android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/listView" android:divider="#00000000"></ListView>
</LinearLayout>


item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:id="@+id/layout" android:layout_height="wrap_content" android:orientation="vertical">
    <!-- フィルタ時はこのRelativeLayoutを非表示 -->
    <RelativeLayout android:layout_height="wrap_content" android:layout_width="fill_parent" android:id="@+id/mainLayout">
        <LinearLayout android:layout_height="fill_parent" android:layout_width="wrap_content" android:id="@+id/item_layout">
            <ImageView android:id="@+id/iconImage" android:layout_height="72px" android:layout_gravity="center_vertical" android:layout_width="72px"></ImageView>
            <TextView android:id="@+id/nameText" android:text="TextView" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_width="fill_parent"></TextView>
        </LinearLayout>
        <!-- 擬似的にラインを引いているが、画像などできれいなラインにしたほうがいいかも -->
        <ImageView android:id="@+id/lineImage" android:background="#ffffff" android:layout_width="fill_parent" android:layout_below="@+id/iconImage" android:layout_alignParentBottom="true" android:layout_height="1px"></ImageView>
    </RelativeLayout>
<!-- このダミーがないと非表示の時にレイアウトがつぶれる -->
<View android:id="@+id/dummy" android:layout_width="wrap_content" android:layout_height="1px"></View>
</LinearLayout>

Androidアプリ 漢字Check 50,000ダウンロード達成

友人のiPhoneアプリからの移植ですが、Android版の漢字Checkが50,000ダウンロード達成しました。
まさにツールという感じのシンプルアプリですが、場面によっては重宝するかと思います。
今後ともよろしくお願いいたします。

https://market.android.com/details?id=it.kakeru.kanji_check

AndroidでAdMobとAdMakerの切り替え

AdMakerのSDKもバージョンが上がって、広告の成否が判断できるようになってました。
優先度を設定して表示するサンプル。
・AdMobのSDKは4.1.1
・AdMakerのSDKは1.1

広告クラス

public class ComAd {

    private static final int STATE_OK   = 1;    // 成功
    private static final int STATE_EXEC = 0;    // 実行中
    private static final int STATE_NG   = -1;   // 失敗

    private Activity activuty;
    private RelativeLayout adLayout;
    private AdView adMob;
    private libAdMaker adMaker;

    private boolean priorityAdMobFlg;    // AdMob優先フラグ
    private int stateAdMob;              // AdMob状態
    private int stateAdMaker;            // AdMaker状態

    /**
     *
     * @param activuty
     */
    public ComAd(Activity activity, RelativeLayout adLayout) {
        this.activuty = activity;
        this.adLayout = adLayout;
        this.adLayout.setVisibility(LinearLayout.INVISIBLE);

        if (Locale.getDefault().equals(Locale.JAPAN)
        || Locale.getDefault().equals(Locale.JAPANESE)) {
            // 日本のみAdMaker優先とか
            priorityAdMobFlg = false;
        } else {
            priorityAdMobFlg = true;
        }
    }

    // 広告取得
    public void loadAd() {
        // 実行中に設定
        stateAdMob = STATE_EXEC;
        stateAdMaker = STATE_EXEC;
        // 実行
        loadAdMob();
        loadAdMaker();
    }

    // AdMob取得
    private void loadAdMob() {
        adMob = new AdView(activuty, AdSize.BANNER, "xxxxxxx");
        adLayout.addView(adMob);
        adMob.loadAd(new AdRequest());
        adMob.setAdListener(new AdListener() {
            public void onReceiveAd(Ad arg0) {
                // 成功
                stateAdMob = STATE_OK;
                setAd();
            }
            public void onFailedToReceiveAd(Ad arg0, ErrorCode arg1) {
                // 失敗
                stateAdMob = STATE_NG;
                setAd();
            }
            public void onPresentScreen(Ad arg0) {}
            public void onLeaveApplication(Ad arg0) {}
            public void onDismissScreen(Ad arg0) {}
        });
    }

    // AdMaker取得
    private void loadAdMaker() {
        LayoutParams lp = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
        adMaker = new libAdMaker(activuty);
        adMaker.setLayoutParams(lp);
        adMaker.setBackgroundColor(Color.WHITE);
        adLayout.addView(adMaker);
        adMaker.siteId = "XXX";    // siteId
        adMaker.zoneId = "XXXX";   // zoneId
        adMaker.setUrl("http://images.ad-maker.info/apps/xxxx.html"); // URL
        adMaker.start();
        adMaker.setAdMakerListener(new AdMakerListener() {
            public void onReceiveAdMaker() {
                // 成功
                stateAdMaker = STATE_OK;
                setAd();
            }
            public void onFailedToReceiveAdMaker(String arg0) {
                // 失敗
                stateAdMaker = STATE_NG;
                setAd();
            }
        });
    }

    // Ad
    private void setAd() {
        // メモのためif分は分かりやすく記述
        // ここのif分を変更すれば、先に表示された広告を優先で表示等にできる
        if (stateAdMob == STATE_OK && priorityAdMobFlg) {
            //AdMobかつAdMob優先ならAdMob表示(AdMaker処理は待たない)
            setAdMob();
            return;
        }
        if (stateAdMaker == STATE_OK && !priorityAdMobFlg) {
            //AdMakerかつAdMob優先ではないならAdMaker表示(AdMob処理は待たない)
            setAdMaker();
            return;
        }
        if (stateAdMob == STATE_OK && stateAdMaker == STATE_NG) {
            //adMobのみ成功
            setAdMob();
            return;
        }
        if (stateAdMob == STATE_NG && stateAdMaker == STATE_OK) {
            //adMakerのみ成功
            setAdMaker();
            return;
        }
        if (stateAdMob == STATE_NG && stateAdMaker == STATE_NG) {
            // 両方失敗ならやりなおし
            loadAd();
        }
    }

    // AdMob
    private void setAdMob() {
        // AdMob表示
        adLayout.setVisibility(LinearLayout.VISIBLE);
        adMob.setVisibility(AdView.VISIBLE);
        // AdMaker非表示
        adMaker.setVisibility(AdView.GONE);
        adMaker.stop();
    }

    // AdMaker
    private void setAdMaker() {
        // AdMaker表示
        adLayout.setVisibility(LinearLayout.VISIBLE);
        adMaker.setVisibility(AdView.VISIBLE);
        // AdMob非表示
        adMob.setVisibility(AdView.GONE);
        adMob.stopLoading();
    }
}

呼び出し元ActivityのOnCreateあたりで

    //広告表示
    new ComAd(this, (RelativeLayout)findViewById(R.id.ad_layout)).loadAd();

呼び出し元Activityのレイアウトの上部か下部に

<RelativeLayout android:id="@+id/ad_layout" android:layout_width="fill_parent" android:layout_height="50dp"></RelativeLayout>

AndroidManifestに以下を忘れずに

        <activity android:name="com.google.ads.AdActivity" android:configChanges="orientation|keyboard|keyboardHidden"></activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

AndroidでTwitter4jを使用した、OAuth認証と認証解除

OAuth認証のサンプルはよく見かけるのですが、解除がなかったのでメモ。
(正しいかどうかは不明です・・・)

以下、ソース(エラー処理とか省く)

定数

public final class Const {
    public static final String CONSUMER_KEY       = "xxxxx";
    public static final String CONSUMER_SECRET    = "xxxxx";
    public static final String OAUTH_CALLBACK_URL = "myapp://callback"; // コールバック
    public static final String OAUTH_VERIFIER     = "oauth_verifier";
    public static final String OAUTH_URL          = "oauth_url";
    public static final String OAUTH_CHECK_TEXT   = "https://api.twitter.com/oauth/authorize"; // Twitterのウェブサイトで認証or解除をしたかの確認文字列
}

認証開始のActivity

public class OAuthActivity extends Activity {

    private Twitter twitter = null;
    private RequestToken requestToken = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.oauth);
        // button
        Button oauthButton = (Button)findViewById(R.id.oauth_button);
        oauthButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View view) {
                doOAuth();
            }
        });
        setView();
    }

    // 画面処理
    private void setView(){
        TextView nameText = (TextView)findViewById(R.id.nameTextView);
        ImageView iconImage = (ImageView)findViewById(R.id.iconImageView);
        Button oauthButton = (Button)findViewById(R.id.oauth_button);
        OAuth oAuth = loadOAuth();
        if (oAuth.isEmpty()) {
            oauthButton.setText("アプリ認証");
            nameText.setText("");
            iconImage.setImageBitmap(null);
        } else {
            oauthButton.setText("アプリ認証解除");
            nameText.setText(oAuth.name);
            new ImageTask(iconImage).execute(oAuth.imageUrl); // Twitterアイコン読み込み
        }
    }

    // Twitter認証
    private void doOAuth() {
        ConfigurationBuilder confbuilder  = new ConfigurationBuilder();
        confbuilder.setOAuthConsumerKey(CONSUMER_KEY).setOAuthConsumerSecret(CONSUMER_SECRET);
        twitter = new TwitterFactory(confbuilder.build()).getInstance();
        try {
            requestToken = twitter.getOAuthRequestToken(OAUTH_CALLBACK_URL);
        } catch (TwitterException e) {
            // エラー
        }
        // ブラウザ起動
        Intent intent = new Intent(this, OAuthWebActivity.class);
        intent.putExtra(OAUTH_URL, requestToken.getAuthorizationURL());
        startActivityForResult(intent, 0);
    }

    // ブラウザからの戻り
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);
        // キャンセル
        if (resultCode == RESULT_CANCELED) {
            Toast.makeText(this, "キャンセル", Toast.LENGTH_LONG).show();
            return;
        }
        // 認証or認証解除
        if (resultCode == RESULT_OK){
            String verifier = intent.getExtras().getString(OAUTH_VERIFIER);
            if (!TextUtils.isEmpty(verifier)) {
                // verifierがあれば認証
                try {
                    AccessToken accessToken = twitter.getOAuthAccessToken(requestToken, verifier);
                    // user取得
                    User user = twitter.verifyCredentials();
                    saveOAuth(new OAuth(user.getScreenName(), user.getProfileImageURL().toString(), accessToken.getToken(), accessToken.getTokenSecret()));
                    setView();
                    Toast.makeText(this, "認証OK", Toast.LENGTH_LONG).show();
                } catch (TwitterException e) {
                    // エラー
                }
            } else {
                // 認証解除
                if (!loadOAuth().isEmpty()) {
                    Toast.makeText(this, "認証解除", Toast.LENGTH_LONG).show();
                    saveOAuth(new OAuth()); // OAuthクリア
                }
            }
        }
    }

    // icon取得
    class ImageTask extends AsyncTask<String, Void, Bitmap> {

        private ImageView iconView;

        public ImageTask(ImageView iconView) {
            this.iconView = iconView;
        }

        @Override
        protected void onPreExecute() { // progress表示 }

        @Override
        protected Bitmap doInBackground(String... params) {
            try {
                String url = params[0].toString();
                URL imageUrl = new URL(url);
                Bitmap bitmap = BitmapFactory.decodeStream(imageUrl.openStream());
                return bitmap;
            } catch (Exception e) {
                return null;
            }
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            // progress非表示
            iconView.setImageBitmap(bitmap);
        }
    }

    // OAuthの保存と取得はPreference用の別クラス等に実装がよい
    // OAuth保存
    private void saveOAuth(OAuth oAuth) {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        Editor editor = prefs.edit();
        editor.putString(OAuth.NAME, oAuth.name);
        editor.putString(OAuth.IMAGE_URL, oAuth.imageUrl);
        editor.putString(OAuth.TOKEN, oAuth.token);
        editor.putString(OAuth.TOKEN_SECRET, oAuth.tokenSecret);
        editor.commit();
    }

    // OAuth取得
    private OAuth loadOAuth() {
        SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        return new OAuth(prefs.getString(OAuth.NAME, ""),
                         prefs.getString(OAuth.IMAGE_URL, ""),
                         prefs.getString(OAuth.TOKEN, ""),
                         prefs.getString(OAuth.TOKEN_SECRET, ""));
    }
}

認証ブラウザActivity

public class OAuthWebActivity extends Activity {

    private boolean checkFlg = false;

    protected void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        // layout
        setContentView(R.layout.oauth_web);
        // webview
        WebView webView = (WebView)findViewById(R.id.oauth_web_view);
        webView.getSettings().setJavaScriptEnabled(true); // JavaScript有効
        webView.setScrollBarStyle(WebView.SCROLLBARS_INSIDE_OVERLAY); // スクロールバー設定
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageStarted(WebView view, String url, Bitmap favicon) {
                // ページ読み込み開始
                super.onPageStarted(view, url, favicon);
                if (url.startsWith(OAUTH_CALLBACK_URL)) {
                    Uri uri = Uri.parse(url);
                    // verifier取り出し
                    String oauthVerifier = uri.getQueryParameter(OAUTH_VERIFIER);
                    Intent intent = getIntent();
                    intent.putExtra(OAUTH_VERIFIER, oauthVerifier);
                    if (checkFlg) {
                        // 認証or認証解除
                        setResult(RESULT_OK, intent);
                    } else {
                        // キャンセルの場合
                        setResult(RESULT_CANCELED, null);
                    }
                    finish();
                }
            }
            // ページ読み込み終了
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                // 認証or認証解除をしたか確認
                checkFlg |= url.equals(OAUTH_CHECK_TEXT);
            }
        });
        // ページ読み込み
        webView.loadUrl(getIntent().getExtras().getString(OAUTH_URL));
    }
}

OAuth保持Entity

public class OAuth {

    public static final String NAME = "oauth_name";
    public static final String IMAGE_URL = "oauth_image_url";
    public static final String TOKEN = "oauth_token";
    public static final String TOKEN_SECRET = "oauth_token_secret";

    public String name;
    public String imageUrl;
    public String token;
    public String tokenSecret;

    public OAuth() {
        this.name = "";
        this.imageUrl = "";
        this.token = "";
        this.tokenSecret = "";
    }

    public OAuth(String name, String imageUrl, String token, String tokenSecret) {
        this.name = name;
        this.imageUrl = imageUrl;
        this.token = token;
        this.tokenSecret = tokenSecret;
    }

    public boolean isEmpty() {
        return TextUtils.isEmpty(name);
    }
}


レイアウト:R.layout.oauth_web

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:id="@+id/main_layout">
<Button android:layout_width="wrap_content" android:id="@+id/oauth_button" android:layout_height="wrap_content"></Button>
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:id="@+id/nameTextView"></TextView>
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/iconImageView"></ImageView>
</LinearLayout>


レイアウト:R.layout.oauth_web

<?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:id="@+id/oauth_web_layout">
    <android.webkit.WebView android:layout_width="fill_parent"
                            android:layout_height="fill_parent"
                            android:id="@+id/oauth_web_view">
    </android.webkit.WebView>
</LinearLayout>

AndroidManifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="me.undigital.test" android:versionCode="1" android:versionName="1.0">
    <uses-sdk android:minSdkVersion="4" />
    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name="OAuthActivity" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name="OAuthWebActivity" android:label="@string/app_name">
        </activity>
    </application>
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

wwwtter

wwwtterという、Twitter関連のアプリをAndroidMarketへリリースしました。
Twitterでつぶやかれている、WEBページをランキング形式でリアルタイムにチェックできるアプリです。
ランキングからWEBページへの遷移とそのWEBページに対してのツイートも簡単にできます。
TwitterのStreamingAPIを使用してサーバーで集計してます。

宣伝もしてないので、スタートダッシュは大失敗な感じですが・・・気長にメンテナンスとかしていきます。
無料ですので、よかったら使ってみてください。


https://market.android.com/details?id=me.undigital.wwwtter

けっこうAndroidアプリのノウハウも溜まったので、アプリ開発のメモを少しづつアップしていこうかと思っています。

GalaxySをAndroid2.3にアップデートしてみた

準備
SamsungのサイトからKiesをダウンロードしてインストール
 http://jp.samsungmobile.com/pc/lineup/SC-02Bdownload.html
 Windowsのみ・・・Macな方はドコモに行ったら期間限定らしいですがアップデートしてくれるらしいです。
Android端末のUSB設定をSamsung Kiesモードに変更する(設定>無線とネットワーク>USB設定)
 ここでプチはまりモード・・・
 
 デバックモードのままでは「デバイスSamsung Kies(PC Studio)モードで接続してください。」と
 表示が出てPCが認識してくれません。
 まあ、SamsungのサイトにUSBモード変更が記載されていたので、よく説明を読まないと・・・

更新
Android端末が認識されたらファームウェアのアップデートと出るのでポチる
 男らしく!?バックアップはさくっとキャンセルしたので、更新時間は5〜6分程度。
 最後に「USBを抜いて端末を再起動してください」的なメッセージがでましたが、どうみても端末の画面は
 まだアップデートの真っ最中で、ここでUSB抜いたら危険な予感がw
 迷っていたら、USBを繋いだままでも問題なく端末再起動されて無事完了しました。
 

まあ、アップデート後は少し早くなった気もしますが、プラシーボ効果かも。

ListView等の高さや幅を動的に変更する方法

AndroidのListView等はメソッドにsetHeight(int)等がありません。
アプリ開発で動的に変更する必要があったので調査してみました。

ListView listView = (ListView)findViewById(R.id.list_view);
listView.getLayoutParams().width = 100;
listView.getLayoutParams().height = 100;
listView.requestLayout();

ListViewからLayoutParamsを取得して、そこに高さや幅をセット。
最後にrequestLayoutを呼び出して設定を反映。

もっといい方法があるかもしれないけど、お約束の実現できたのでOKと・・・