PreferenceActivity に LinearLayout を追加する

今となっては, PreferenceFragment に変わられ deprecated となっているが簡単に設定画面が作れる.

ネットで調べると, 面倒なのが多かった気がしたので貼っておく.

settings.xml をレイアウトとして作る.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="fill_parent"
    android:layout_width="fill_parent"
    android:orientation="vertical">
    <LinearLayout
        android:id="@+id/main"
        android:layout_width="fill_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/admob">
        <ListView
            android:id="@android:id/list"
            android:layout_width="fill_parent"
            android:layout_height="match_parent"
            />
    </LinearLayout>
    <LinearLayout
        android:id="@+id/admob"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:orientation="vertical"
        android:layout_alignParentBottom="true"
        />
</RelativeLayout>

読み込み側 PreferenceActivity を親にもつ子.

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.settings);
    ...

これで, けりがつく.

Preference や PreferenceScreen を作らなくてよい.

ミソは id の記述と

       <ListView
            android:id="@android:id/list"
            android:layout_width="fill_parent"
            android:layout_height="match_parent"
            />

PreferenceActivity は ListActivity を親に持つということ.

java.lang.Object
   +	android.content.Context
 	   +	android.content.ContextWrapper
 	 	   +	android.view.ContextThemeWrapper
 	 	 	   +	android.app.Activity
 	 	 	 	   +	android.app.ListActivity
 	 	 	 	 	   +	android.preference.PreferenceActivity

RelaytiveLayout は必須.

PreferenceActivity | Android Developers

Androidの座標

座標を使ってみるとわけわかめ
いくつかの座標系があるような。

座標の取得の方法

getLeft(),getRight()で座標取得する - duyojiぶろぐ 

Y.A.M の 雑記帳: Android View の位置を取得する 

タッチイベント(TouchEvent)を取得するには - 逆引きAndroid入門 


琴線探査: Androidでグローバル座標系でのViewのRectを得るには? 

Androidでは、基本的にはウィジェットを配置する位置を座標で自由に指定する事ができない。
ウィジェットの位置は、各レイアウトによって決められたルールに従って、配置される事になる。

レイアウト(1)-ウィジェット(Viewクラス)の幅と高さと位置 - 愚鈍人 

まとめ

画面サイズの取得

WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);  
Display disp = wm.getDefaultDisplay();  
width = disp.getWidth();  
height = disp.getHeight();  

viewの位置取得

TextView view = (TextView)this.findViewById(R.id.textview);
int[] location = new int[2];
view.getLocationOnScreen(location);

CursorLoader

startManagingCursor() が deprecate というので

Android3.0以降、非推奨ということで。
SQLiteの利用に使いたいのだができれば ContentProvider は使わずにやりたい、
と雰囲気では思いながら調べる。

CursorLoader | Android Developers http://developer.android.com/reference/android/content/CursorLoader.html

AsyncTaskLoaderを継承しているので非同期な処理を行えるのだろう。

使い方をみてみる

よくわからないままいろいろ眺める。

Android:Loaderについてメモ | 自転車で通勤しましょ♪ブログ 

SimpleCursorLoader という公開されているクラスを使っている。

  • Loaderのロードは、ActivityのonCreateか、FragmentのonActivityCreatedで行なう。
  • DBヘルバーは利用する。loadInBackground() 内で。
  • callback 的に使う。
  • fragment で使うと良い。

Content Providers and Content Resolvers | Android Design Patterns 

Life Before Loaders (part 1) | Android Design Patterns 

android - How does CursorLoader with LoaderManager know to send the cursor to a CursorAdapter? - Stack Overflow 

  • ListAdapter と使う。
  • API Demo の ノートが参考になる。他にも、どこかでみた。

5. Notepad チュートリアル - ソフトウェア技術ドキュメントを勝手に翻訳 

git clone からの eclipse プロジェクト登録

とりあえずメモ。
[File]-[import]-[Git]-[Project from Git] からうまくできなかったので。

手順

1. clone を ~/tmp/ 以下に取得。
2. そのファイル群から新規プロジェクト登録。

[File]-[import]-[Android]-[Exsiting Android Code Into ...]

3. プロジェクト名にメインアクティビティ名が余分につくのでリネーム

[Refector]-[Rename]

4. Git Repositoroes ウィンドウから、git 登録ファイルを実ファイルごと消す。
5. パッケージエクスプローラ上からgit commitしてgit登録下に。

こういうものなのだろうか

編集するファイルリソースをリポジトリ配下に置くのは、筋ではないのか。
ちなみに、上記[Project From Git]で吐かれるエラーはこんな。

eclipse - "Invalid project description", importing from GIT repo problem - Stack Overflow 


なんかソース以外をPUSHしてるような。。。

SDカードのディレクトリ・パス

それなりの記述(Environment.getExternalStorageDirectory)でマルチにいけると思ったのだが、国内機種を中心にいろいろある。

SDカードパスまとめ - hidecheckの日記 

環境変数に持ってるらしい。

System.getenv("EXTERNAL_STORAGE_ALL")で取得結果です。
/mnt/sdcard:/mnt/usbdisk:/mnt/ext_card
System.getenv("EXTERNAL_ALT_STORAGE");
・EXTERNAL_STORAGE
・SECOND_VOLUME_STORAGE
・THIRD_VOLUME_STORAGE
・EXTERNAL_ALT_STORAGE
環境変数についてはSO-03DにはEXTERNAL_STORAGE_ALLというのがあ り、
/mnt/sdcard:/mnt/usbdisk:/mnt/sdcard/external_sd
というのが取れるらしいというのはわかりました。

Xperia acro HDのSDカードのパスを取得する方法 - Google グループ 

どうも国産中心らしいが。

F-05D      /mnt/sdcard/external_sd/
IS12S       /mnt/ext_card/
ISW11M    /mnt/sdcard-ext/
N-04D      /mnt/sdcard/external_sd/
T-01D      /mnt/sdcard/external_sd/
SC-02C    /mnt/sdcard/external_sd/
SO-03D    /mnt/sdcard/external_sd/
ISW11F     /mnt/sdcard/external_sd/
F-08D       /mnt/sdcard/external_sd/
SC-02B     /mnt/sdcard/external_sd/
ISW11SC    /mnt/sdcard/external_sd/
SC-03D     /mnt/sdcard/external_sd/
N50GT_A    /mnt/storage/sdcard/

パス別に並べるとこれくらいか。

/mnt/sdcard/external_sd/
/mnt/ext_card/
/mnt/sdcard-ext/
/mnt/storage/sdcard/

環境変数名が端末によって違うので困る。

こんな雰囲気だったり。

/sdcard       → 内蔵ストレージ
/sdcard/external_sd → SDカード(外部ストレージ)

スマホ初心者注意!Androidのバックアップに潜む罠 | ガジェット速報 

実際のSDカードのパスを調べるのはどうすべきか。

android - Find an external SD card location - Stack Overflow 

簡単に以下でチェックしながらやってみますか。

 File.exists(), File.isDirectory(), and File.canWrite().

機種別にSDカード内ディレクトリもOSとしては認識している。

Environment | Android Developers 

ダウンロードディレクトリに対しては以下で取得できる?

File pathExternalPublicDir = 
    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
// Downloadフォルダーのパス
String dir = pathExternalPublicDir.getPath();

Android:フォルダパスを動的に取得 - りりーの幸せ日記 

マニュアルによいコードがある。

public static File getExternalStoragePublicDirectory (String type)
Since: API Level 8
特別のタイプのファイルを置くためにトップレベルの公の外部記憶装置ディレクトリーを得てください。
これはユーザが典型的には自分のファイルを置き管理する場所です。したがって、あなたは、それらのファイルを消さないか自分の構成の邪魔にならないことを保証するために、ここで何を置くかに注意するべきです。
Here is an example of typical code to manipulate a picture on the public external storage:
void createExternalStoragePublicPicture() {
    // Create a path where we will place our picture in the user's
    // public pictures directory.  Note that you should be careful about
    // what you place here, since the user often manages these files.  For
    // pictures and other media owned by the application, consider
    // Context.getExternalMediaDir().
    // 私たちがユーザの公開画像ディレクトリーに写真を置くところで、パスを作成してください。
    // ユーザがこれらのファイルをしばしば管理するので、ここで何を置くかに注意するべきであることに注意してください。
    //適用によって所有された絵および他のメディアについては、Context.getExternalMediaDir()を考慮してください。

    File path = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    File file = new File(path, "DemoPicture.jpg");

    try {
        // Make sure the Pictures directory exists.
        path.mkdirs();

        // Very simple code to copy a picture from the application's
        // resource into the external file.  Note that this code does
        // no error checking, and assumes the picture is small (does not
        // try to copy it in chunks).  Note that if external storage is
        // not currently mounted this will silently fail.
        InputStream is = getResources().openRawResource(R.drawable.balloons);
        OutputStream os = new FileOutputStream(file);
        byte[] data = new byte[is.available()];
        is.read(data);
        os.write(data);
        is.close();
        os.close();

        // Tell the media scanner about the new file so that it is
        // immediately available to the user.
        MediaScannerConnection.scanFile(this,
                new String[] { file.toString() }, null,
                new MediaScannerConnection.OnScanCompletedListener() {
            public void onScanCompleted(String path, Uri uri) {
                Log.i("ExternalStorage", "Scanned " + path + ":");
                Log.i("ExternalStorage", "-> uri=" + uri);
            }
        });
    } catch (IOException e) {
        // Unable to create file, likely because external storage is
        // not currently mounted.
        Log.w("ExternalStorage", "Error writing " + file, e);
    }
}

void deleteExternalStoragePublicPicture() {
    // Create a path where we will place our picture in the user's
    // public pictures directory and delete the file.  If external
    // storage is not currently mounted this will fail.
    File path = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    File file = new File(path, "DemoPicture.jpg");
    file.delete();
}

boolean hasExternalStoragePublicPicture() {
    // Create a path where we will place our picture in the user's
    // public pictures directory and check if the file exists.  If
    // external storage is not currently mounted this will think the
    // picture doesn't exist.
    File path = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    File file = new File(path, "DemoPicture.jpg");
    return file.exists();
}

Environment | Android Developers 

このサンプリのように保存した画像はほかアプリから使えるようにに反映させておくとよい。

MediaScannerConnectionを使って画像をギャラリーに反映させる « Tech Booster 

けど、最終的には、環境変数を元に書き込みチャレンジするしか、という。

SDカード 内部と外部

内部SDカードと外部SDカードを持つ機種もある。
GALAXY S2の場合は、本体ストレージの一部を内部SDカードして扱います。
内部SDカードは、“/sdcard”になります。
また、通常のmicroSDカードを外部SDカードとして扱います。
外部SDカードは、“/sdcard/external_sd”になります。

spモードメールの絵文字は、デフォルトでは内部SDカードの“Download”フォルダに保存されます。
この“Download”フォルダの下にアプリのマイファイルで種類毎にフィルダを作成し、
絵文字を保存(移動)すればいいと思います。

価格.com - 『SDカードとマイファイル』 サムスン GALAXY S II LTE SC-03D docomo [Dark Gray] のクチコミ掲示板 

内部SDカードを優先にしたほうがSPモードアプリとの連携がよい。

SDカードの画像をギャラリーに反映させる

ダウンロードした画像がギャラリーにすぐに反映されない。
SDカード上の画像はDB内にインデックス化され保存される。
タイミングはSDカードがマウントされたとき。

MediaScan | Android Wiki for Developers 

Uri uri = Uri.parse("file://" + Environment.getExternalStorageDirectory());
Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED, uri);
sendBroadcast(intent);