Android エミュレータのSDカードにファイルを配置する

まずエミュレータにSDカードを作成します。
エクリプスのメニューより「ウィンドウ」→「AVDマネージャー」を選択します。
開いたダイアログよりSDカードを作成するエミュレータを選択し「編集」ボタンをクリックします。

SDカードに512MのSDカードを作成しました。
「AVDの編集」をクリックしダイアログを終了します。

SDカードが作成できたら「開始」ボタンでエミュレータを起動します。

エミュレータが起動したらエクリプスのメニューより「ウィンドウ」→「パースペクティブを開く」→「その他」→「DDMS」を選択します。 「ファイル・エクスプローラ」タブにsdcardが見えていると思います。

私のエミュレータではmntフォルダの下にsdcardが有りました。
最初はトップ階層のsdcardだと思って「なんでフォルダじゃないんだろう」なんて悩んでしまいました。
情報列の「mnt/sdcard」の意味がわからなかった・・・

右上の「pull a file」ボタンと[push a file」ボタンでSDカードにファイルを配置したり取り出したりできます。
私の環境では日本語名のファイルは「push a file」ボタンで配置できませんでした。
DDMSでファイルを配置できない場合は、コマンドプロンプトから以下のコマンドを入力します。

※ファイルを配置するには
>adb push C:\Sample.txt /sdcard/
adb push <PCにあるファイル> <デバイスのフォルダ>

※ファイルを取り出すには
adb pull <デバイスファイル名> <PCのファイル名>

Android TabActivityとTabHostを使用してTab画面を表示する

2012/11/19 追記
TabHostを使用する方法はAndroid 3.0 以降は非推奨となりました。
TabHostを使用せずにタブ画面を表示する方法はコチラ
Android ActionBarとFragmentを使用してTab画面を表示する(Android 4.0以上)
Android ActionBarとFragmentを使用してTab画面を表示する(Android 2.x)



むかし2年程前にタブメニューについて調べたんです。コレ→「Android タブ画面を表示する
今回タブを使おうと思って昔の記事を読んでみたんですが・・・全然わかんないわぁ(;´д`)
自分で読んでも何を書いてるのかわかんないのに、二人の人が役にたったとリアクションしてくれてます。ゴメンナサイ

結局、私の役にはたたなかったので、ほかの人のブログを参考にしました。
自分の調べた事をメモるブログなのに意味ないしっ(>_<)

気を取り直して、再度調べた事をまとめておきます。

タブメニューを作成するにはTabHostウィジェットを使用します。
ActivityにTabHostを配置し、ActivityのonCreate()でTabHostにタブを追加します。
各タブをクリックしたときに表示するコンテンツですが、以下の3通りがあるようです。
  1. TabHostを配置したアクティビティに定義したViewを表示する。
  2. 他のアクティビティを表示する
  3. layoutファイルに定義したViewを表示する

TabHostを配置したアクティビティに定義したViewを表示する

ActivityにTabHostを配置します。

アウトラインを見ると以下のようになっていると思います。
TabHost(id/tabhost)
 |--LinearLayout
    |--TabWidget(id/tabs)
      |--FrameLayout(id/tabcontent)
        |--LinearLayout(id/tabs1)
        |--LinearLayout(id/tabs2)
        |--LinearLayout(id/tabs3)

注意点は以下の3点です。
  • TabHostはidがtabhostであること。
  • TabWidgetはidがtabsであること。
  • FrameLayoutはidがtabcontentであること。

3つのLinearLayout(idがtab1,tab2,tab3)が各タブをクリックしたときに表示されるコンテンツになります。
タブを4つにしたければLinearLayoutをもう一つ追加します。

それでは各LinearLayoutに適当にウイジェットを配置します。
何か方法があるのかもしれませんが、2つめ以降のLinearLayoutをGraphicalLayoutでデザイン作成できないのが不便です。
アウトラインに追加し、XMLを編集していくしかないのですかね(´д`)

今回は各LinearLayoutにTextViewを1つずつ配置しました。

activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TabHost
        android:id="@android:id/tabhost"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true" >

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" >

            <TabWidget
                android:id="@android:id/tabs"
                android:layout_width="match_parent"
                android:layout_height="wrap_content" >
            </TabWidget>

            <FrameLayout
                android:id="@android:id/tabcontent"
                android:layout_width="match_parent"
                android:layout_height="match_parent" >

                <LinearLayout
                    android:id="@+id/tab1"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" >

                    <TextView
                        android:id="@+id/textView1"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Tabページ1" />

                </LinearLayout>

                <LinearLayout
                    android:id="@+id/tab2"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" >

                    <TextView
                        android:id="@+id/textView2"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Tabページ2" />

                </LinearLayout>

                <LinearLayout
                    android:id="@+id/tab3"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent" >

                    <TextView
                        android:id="@+id/textView3"
                        android:layout_width="wrap_content"
                        android:layout_height="wrap_content"
                        android:text="Tabページ3" />

                </LinearLayout>

            </FrameLayout>
        </LinearLayout>
    </TabHost>

</RelativeLayout>

タブ部分に表示するテキストをres/values/strings.xmlに定義します。
<resources>
    :
    :
    <string name="tab1">ページ1</string>
    <string name="tab2">ページ2</string>
    <string name="tab3">ページ3</string>
</resources>

ActivityはTabActivityを継承して作成し、onCreate()でTabHostに各タブを追加していきます。
TabSpec#setIndicator()でタブ部分の文字を指定します。
TabSpec#setContent()でタブをクリックした時に表示するViewのidを指定します。
ここではactivity_main.xmlにある3つのLinearLayoutのidです。

MainActivity.java
public class MainActivity extends TabActivity {
        
    private static final String TAB[] = {"tab1", "tab2","tab3" };   
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //TabHostオブジェクト取得   
        TabHost tabhost = getTabHost();
        //Tab1設定   
        TabSpec tab1 = tabhost.newTabSpec(TAB[0]);   
        tab1.setIndicator(this.getResources().getString(R.string.tab1));       
        tab1.setContent(R.id.tab1);
        tabhost.addTab(tab1);       
        //Tab2設定   
        TabSpec tab2 = tabhost.newTabSpec(TAB[1]);   
        tab2.setIndicator(this.getResources().getString(R.string.tab2));      
        tab2.setContent(R.id.tab2);
        tabhost.addTab(tab2);   
        //Tab3設定   
        TabSpec tab3 = tabhost.newTabSpec(TAB[2]);   
        tab3.setIndicator(this.getResources().getString(R.string.tab3));      
        tab3.setContent(R.id.tab3);
        tabhost.addTab(tab3);       
        //初期表示するタブ   
        tabhost.setCurrentTab(0);  
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    } 

}

他のアクティビティを表示する

次はタブをクリックした時に表示するコンテンツにActivityを指定する方法です。

まずTabHostを配置したメインとなるアクティビティを1つ作成します。
そしてタブをクリックした時に表示するアクティビティをタブの数だけ作成します。

つまりタブが3つある画面であれば4つのアクティビティを作成することになります。

各タブのコンテンツとなるアクティビティ「Tab1Activity.java」、「Tab2Activity.java」、「Tab3Activity.java」を作成します。
各アクティビティには、それぞれの違いがわかるように適当にウィジェットを配置しておきます。

次にメインとなるActivityを作成します。
こちらは「TabHostを配置したアクティビティに定義したViewを表示する」で作成したMainActivity.javaとほぼ同じです。
違いは、TabSpec#setContent()でアクティビティを指定します。

MainActivity.java
public class MainActivity extends TabActivity {
        
    private static final String TAB[] = {"tab1", "tab2","tab3" };   
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //TabHostオブジェクト取得   
        TabHost tabhost = getTabHost();
        //Tab1設定   
        TabSpec tab1 = tabhost.newTabSpec(TAB[0]);   
        tab1.setIndicator(this.getResources().getString(R.string.tab1));       
        tab1.setContent(new Intent().setClass(this, Tab1Activity.class));
        tabhost.addTab(tab1);       
        //Tab2設定   
        TabSpec tab2 = tabhost.newTabSpec(TAB[1]);   
        tab2.setIndicator(this.getResources().getString(R.string.tab2));      
        tab2.setContent(new Intent().setClass(this, Tab2Activity.class));
        tabhost.addTab(tab2);   
        //Tab3設定   
        TabSpec tab3 = tabhost.newTabSpec(TAB[2]);   
        tab3.setIndicator(this.getResources().getString(R.string.tab3));      
        tab3.setContent(new Intent().setClass(this, Tab3Activity.class));
        tabhost.addTab(tab3);       
        //初期表示するタブ
        tabhost.setCurrentTab(0);  
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    } 

}
この方法はアクティビティがいっぱいになるのがイヤだな・・・

layoutファイルに定義したViewを表示する

最後にTabをクリックした時に表示するコンテンツに、res/layoutに作成したファイルを表示する方法です。
これが一番よいのではと思っています。

res/layoutを右クリックし「新規」→「その他」→「Android XML レイアウト・ファイル」を選択し
「tab1.xml」、「tab2.xml」、「tab3.xml」を作成します。

ルート要素はLinearLayoutにし、それぞれの違いがわかるように適当にウィジェットを配置しておきます。

次にメインとなるActivityを作成します。
こちらは「TabHostを配置したアクティビティに定義したViewを表示する」で作成したMainActivity.javaとほぼ同じです。
違いは、TabSpec#setContent()でTabContentFactoryインターフェースを実装したクラスを指定します。
TabContentFactoryのcreateTabContent()メソッドで先ほど作成したレイアウトファイルを返すようにします。
MainActivity.java
public class MainActivity extends TabActivity {
        
    private static final String TAB[] = {"tab1", "tab2","tab3" };   
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //タブに表示するViewをlayoutより取得する
        LayoutInflater layout = LayoutInflater.from(MainActivity.this); 
        final View viewTab1 = layout.inflate(R.layout.tab1, null);
        final View viewTab2 = layout.inflate(R.layout.tab2, null);
        final View viewTab3 = layout.inflate(R.layout.tab3, null);
        //TabHostオブジェクト取得   
        TabHost tabhost = getTabHost();
        //Tab1設定   
        TabSpec tab1 = tabhost.newTabSpec(TAB[0]);   
        tab1.setIndicator(this.getResources().getString(R.string.tab1));       
        tab1.setContent(new TabHost.TabContentFactory (){
            public View createTabContent(String tag) {return viewTab1;}
        });
        tabhost.addTab(tab1);       
        //Tab2設定   
        TabSpec tab2 = tabhost.newTabSpec(TAB[1]);   
        tab2.setIndicator(this.getResources().getString(R.string.tab2));      
        tab2.setContent(new TabHost.TabContentFactory (){
            public View createTabContent(String tag) {return viewTab2;}
        });
        tabhost.addTab(tab2);  
        //Tab3設定   
        TabSpec tab3 = tabhost.newTabSpec(TAB[2]);   
        tab3.setIndicator(this.getResources().getString(R.string.tab3));      
        tab3.setContent(new TabHost.TabContentFactory (){
            public View createTabContent(String tag) {return viewTab3;}
        });
        tabhost.addTab(tab3);  
        //初期表示するタブ   
        tabhost.setCurrentTab(0);  
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    } 

}


今回はちゃんとまとめられたと思うっ( *`ω´)

Android AlertDialogに画像を表示する

以前のAndroid AlertDialogを表示する の「独自のレイアウトを表示する」方法を利用してAlertDialogに画像を表示します。

画像の用意


まずAlertDialogに配置する画像を用意します。
画像はファイルエクスプローラーから\res\drawableフォルダに直接配置します。
drawableフォルダがなければ作成してください。
Androidは .png ( 推奨 )、.jpg ( 容認 )、.gif ( 非推奨 ) の 3つのフォーマットのビットマップをサポートします。
Eclipseが画像を自動で認識して、プロジェクトエクスプローラのres/drawableにそれぞれの画像が表示されます。
画像が読み込まれない場合、メニュー「プロジェクト」→「クリーン」を行ってください。

リソースファイルの用意


AlertDialogのメッセージの文字色を白色にしたいので、色リソースを定義します。
Eclipseのプロジェクトエクスプローラのres/valuesを右クリックし「新規」→「その他」→「Android XML 値ファイル」を選択します。
ファイル名を「color」としルート要素に「resources」を選択します。
白色を定義します。
res/values/color.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
     <color name="white">#FFFFFF</color>
</resources>

レイアウトファイルの用意


Eclipseのプロジェクトエクスプローラのres/layoutを右クリックし「新規」→「その他」→「Android XML レイアウト・ファイル」を選択します。
ファイル名を「alert」としルート要素に「LinearLayout」を選択しました。

レイアウトファイルには
画像を表示するためのImageViewとメッセージを表示するためのTextViewを配置します。
TextViewのTextColorは先ほど作成した色リソースの白を指定します。
色リソースがEclipseに認識されない場合はプロジェクトのクリーンを行ってください。
res/layout/alert.xml
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content" >
     <ImageView
          android:id="@+id/imageAlertIcon"
          android:layout_width="60dp"
          android:layout_height="60dp" />
     <TextView
          android:id="@+id/lblMessage"
          android:layout_width="258dp"
          android:layout_height="match_parent"
          android:text="TextView"
          android:textColor="@color/white" />

</LinearLayout>

AlertDialogを表示するクラスの用意


AlertDialogを表示するクラスAlertHelperクラスを作成します。(ここら辺はおこのみで)
レイアウトファイルの用意で作成したalertレイアウトを取得し
ImageViewに画像を、TextViewにメッセージを表示します。
public class AlertHelper {
    
    /**
     * 警告メッセージを表示します。
     * @param context
     * @param message
     * @param listenerOK
     */
    public static void showWarning(Context context,String message,DialogInterface.OnClickListener listenerOK){
        LayoutInflater inflater = LayoutInflater.from(context);
        final View view = inflater.inflate(R.layout.alert,null);
        ImageView imgAlertIcon = (ImageView)view.findViewById(R.id.imageAlertIcon);
        imgAlertIcon.setImageResource(R.drawable.warning);
        TextView lblMessage = (TextView)view.findViewById(R.id.lblMessage);
        lblMessage.setText(message);
        AlertDialog.Builder alert = new AlertDialog.Builder(context);        
        alert.setPositiveButton("OK",listenerOK);
        alert.setView(view);
        alert.show();    
    }
    
    /**
     * エラーメッセージを表示します。
     * @param context
     * @param message
     * @param listenerOK
     */
    public static void showError(Context context,String message,DialogInterface.OnClickListener listenerOK){
        LayoutInflater inflater = LayoutInflater.from(context);
        final View view = inflater.inflate(R.layout.alert,null);
        ImageView imgAlertIcon = (ImageView)view.findViewById(R.id.imageAlertIcon);
        imgAlertIcon.setImageResource(R.drawable.error);
        TextView lblMessage = (TextView)view.findViewById(R.id.lblMessage);
        lblMessage.setText(message);
        AlertDialog.Builder alert = new AlertDialog.Builder(context);        
        alert.setPositiveButton("OK",listenerOK);
        alert.setView(view);
        alert.show();    
    }
    
    /**
     * 情報メッセージを表示します。
     * @param context
     * @param message
     * @param listenerOK
     */
    public static void showInformation(Context context,String message,DialogInterface.OnClickListener listenerOK){
        LayoutInflater inflater = LayoutInflater.from(context);
        final View view = inflater.inflate(R.layout.alert,null);
        ImageView imgAlertIcon = (ImageView)view.findViewById(R.id.imageAlertIcon);
        imgAlertIcon.setImageResource(R.drawable.information);
        TextView lblMessage = (TextView)view.findViewById(R.id.lblMessage);
        lblMessage.setText(message);
        AlertDialog.Builder alert = new AlertDialog.Builder(context);        
        alert.setPositiveButton("OK",listenerOK);
        alert.setView(view);
        alert.show();    
    }
    
    /**
     * 質問メッセージを表示します。
     * @param context
     * @param message
     * @param listenerOK
     */
    public static void showQuestion(Context context,String message,DialogInterface.OnClickListener listenerYes,DialogInterface.OnClickListener listenerNo){
        LayoutInflater inflater = LayoutInflater.from(context);
        final View view = inflater.inflate(R.layout.alert,null);
        ImageView imgAlertIcon = (ImageView)view.findViewById(R.id.imageAlertIcon);
        imgAlertIcon.setImageResource(R.drawable.question);
        TextView lblMessage = (TextView)view.findViewById(R.id.lblMessage);
        lblMessage.setText(message);
        AlertDialog.Builder alert = new AlertDialog.Builder(context);     
        alert.setPositiveButton("YES",listenerYes);
        alert.setNegativeButton("NO", listenerNo);
        alert.setView(view);
        alert.show();    
    }
}

質問メッセージを表示してみます。
public class MainActivity extends Activity {
     public void button1Click(View view) {
         OnClickListener listenerYes = new OnClickListener(){
            public void onClick(DialogInterface dialog, int which) {
                Toast.makeText(MainActivity.this, "Yes", Toast.LENGTH_LONG).show();
            }
         };
        AlertHelper.showQuestion(this, "質問メッセージです。", listenerYes , null);
     }
}

Android SDカードに配置したデータベースにアクセスする

SDカードに配置したデータベースにアクセスするには

マニフェストファイルにSD カードのコンテンツの変更/削除の権限を与える設定を行います。


SQLiteOpenHelperを継承したクラスのデータベース名にSDカードのデータベースパスを指定します。
public class DatabaseHelperTest extends SQLiteOpenHelper {

    /* データベース名 */  
    //private final static String DB_NAME = "HelloAndroid.db";  
    private final static String DB_NAME = Environment.getExternalStorageDirectory() + "/HelloAndroid.db"; 
    /* データベースのバージョン */  
    private final static int DB_VER = 1;   
    
    /*  
     * コンストラクタ  
      */  
    public DatabaseHelperTest(Context context) {   
        super(context, DB_NAME, null, DB_VER);   
    }   

    @Override
    public void onCreate(SQLiteDatabase db) {
        // TODO 自動生成されたメソッド・スタブ
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        // TODO 自動生成されたメソッド・スタブ
    }

}
あとは従来通りにsqlを発行すればOKです。

Android SDカードに配置したデータベースをデータベースフォルダにコピーする

SDカードに配置したSQLiteデータベースをデータベースフォルダにコピーします。
public class MainActivity extends Activity {

    public void button1Click(View view){
        try {
            final String DB_NAME = "HelloAndroid.db";
            //既存データベースを削除
            this.deleteDatabase(DB_NAME);
            //コピー元パス(SDカード)
            String pathFrom = Environment.getExternalStorageDirectory().getPath() + "/" + DB_NAME;
            //コピー先パス(データベースフォルダ)
            String pathTo = this.getDatabasePath(DB_NAME).getPath();
            //コピー
            FileInputStream fis = new FileInputStream(pathFrom);
            FileChannel channelFrom = fis.getChannel();    
            FileOutputStream fos = new FileOutputStream(pathTo);
            FileChannel channeTo = fos.getChannel();
            try {
                channelFrom.transferTo(0, channelFrom.size(), channeTo);
            } finally {
                fis.close();
                channelFrom.close();
                fos.close();
                channeTo.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
DatabaseHelperのonCreateでやれば良いと思う。

Android SDカードのファイルを読み書きする

実機で実行している場合、「マウント」をOFFします。
(SDカードに書き込みできず、マウントOFFに気づくのに小一時間゜・(ノД`)・゜・)

マニフェストファイルにSD カードのコンテンツの変更/削除の権限を与える設定を行います。
※SDカードから読み込むだけなら必要ありません。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

SDカードは端末によりパスが異なるのでgetExternalStorageDirectory()メソッドでパスを取得します。
String sdPath = Environment.getExternalStorageDirectory().getPath();

あとは普通のファイル入出力と同じです。

SDカードに書き込み
public void button1Click(View view) {
    try {
        //SDカードフォルダのパス
        String sdPath = Environment.getExternalStorageDirectory().getPath();
        //作成するファイル名
        String fileName = "/Hello.txt";
        //書き込み
        BufferedWriter bw = null;
        try {
            FileWriter fw = new FileWriter(sdPath + fileName);
            bw = new BufferedWriter(fw);
            bw.write("ハロー");
        } finally {
            bw.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

SDカードに書き込み
public void button2Click(View view) {
    try {
        //SDカードフォルダのパス
        String sdPath = Environment.getExternalStorageDirectory().getPath();
        //読み込むァイル名
        String fileName = "/Hello.txt";
        //読み込み
        BufferedReader br = null;
        try {
            FileReader fr = new FileReader(sdPath + fileName);
            br = new BufferedReader(fr);
            StringBuilder sb = new StringBuilder();   
            String str;   
            while((str = br.readLine()) != null){   
                sb.append(str +"\r\n");   
            }
            Toast.makeText(this, sb.toString(), Toast.LENGTH_LONG).show();
        } finally {
            br.close();
        }
    }catch (Exception e){
        e.printStackTrace();
    }
    
}

.NET OracleデータベースのデータをSQLiteデータベースに移送する

前回、VisualStudioでSQLiteを使用できるようにしました。
.NET VisualStudioでSQLiteを使用する

今回は既存のOracleデータベースの選択したテーブルから、SQLiteにテーブルを作成しデータを移送するコードです。
データ移送がメンドイので作りました。自分用のメモです。

画面を表示するとリストボックスにOracleデータベースのテーブル一覧が表示されます。
SQLiteDB選択ボタンでデータを移送するSQLiteデータベースを選択してください。
データ移送ボタンで処理を実行します。

Imports System.Data.Common

Public Class FrmOracleToSqlite

    Private Const CONNECTION_STRING_PC As String = "user id=xxxxx;password=xxxxx;data source=xxxxx"
    Private Const PROVIDER_NAME_PC As String = "System.Data.OracleClient"

    Private _ConnectionStringAndroid As String = "data source={0}"
    Private Const PROVIDER_NAME_ANDROID As String = "System.Data.SQLite"

    Private Sub Form_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        SetTableNameList()
    End Sub

    Private Sub cmdSelectDb_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles cmdSelectDb.Click
        Using dialog As New OpenFileDialog
            If dialog.ShowDialog() = Windows.Forms.DialogResult.OK Then
                Me._ConnectionStringAndroid = String.Format(Me._ConnectionStringAndroid, dialog.FileName)
                Me.lblDbNm.Text = Me._ConnectionStringAndroid
            End If
        End Using
    End Sub
   
    Private Sub cmdExec_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdExec.Click
        If Me.lstTableName.CheckedItems.Count = 0 Then
            MessageBox.Show("テーブルを選択して下さい。")
            Return
        End If
        System.Windows.Forms.Cursor.Current = Cursors.WaitCursor
        For Each sTableName As String In Me.lstTableName.CheckedItems
            CreateTableForAndroid(sTableName)
        Next
        MessageBox.Show("終了~!")
    End Sub

    '-----Private-----

    Private Sub SetTableNameList()
        Dim factory As DbProviderFactory = DbProviderFactories.GetFactory(PROVIDER_NAME_PC)
        Dim tbl As New DataTable
        Using cnn As DbConnection = factory.CreateConnection()
            cnn.ConnectionString = CONNECTION_STRING_PC
            cnn.Open()
            Try
                Using cmd As DbCommand = cnn.CreateCommand
                    cmd.CommandText = "select table_name from user_tables order by table_name"
                    Using adp As DbDataAdapter = factory.CreateDataAdapter
                        adp.SelectCommand = cmd
                        adp.Fill(tbl)
                    End Using
                End Using
            Finally
                cnn.Close()
            End Try
        End Using 'cnn

        For idx As Integer = 0 To tbl.Rows.Count - 1
            Me.lstTableName.Items.Add(tbl.Rows(idx).Item(0).ToString, False)
        Next
    End Sub
    

    Private Sub CreateTableForAndroid(ByVal sTableName As String)
        Dim factoryPC As DbProviderFactory = DbProviderFactories.GetFactory(PROVIDER_NAME_PC)
        Dim factoryAD As DbProviderFactory = DbProviderFactories.GetFactory(PROVIDER_NAME_ANDROID)

        'PC側テーブル情報を取得
        Dim tblSchema As New DataTable
        Dim tblPKey As New DataTable
        Using cnn As DbConnection = factoryPC.CreateConnection()
            cnn.ConnectionString = CONNECTION_STRING_PC
            cnn.Open()
            Try
                Using adp As DbDataAdapter = factoryPC.CreateDataAdapter
                    '--列情報
                    Using cmd As DbCommand = cnn.CreateCommand
                        adp.SelectCommand = cmd
                        Dim sbSql As New System.Text.StringBuilder
                        With sbSql
                            .AppendLine("select")
                            .AppendLine("   C.Column_Name")
                            .AppendLine("   ,C.Data_type")
                            .AppendLine("   ,C.Data_precision")
                            .AppendLine("   ,C.Data_scale")
                            .AppendLine("   ,C.Nullable")
                            .AppendLine("FROM USER_TAB_COLUMNS C")
                            .AppendLine("   INNER JOIN USER_TABLES T ON")
                            .AppendLine("       C.Table_Name = T.Table_Name")
                            .AppendLine("WHERE")
                            .AppendLine("   T.Table_Name='" & sTableName & "'")
                        End With
                        cmd.CommandText = sbSql.ToString
                        adp.Fill(tblSchema)
                    End Using
                    '--主キー情報
                    Using cmd As DbCommand = cnn.CreateCommand
                        adp.SelectCommand = cmd
                        Dim sbSql As New System.Text.StringBuilder
                        With sbSql
                            .AppendLine("SELECT")
                            .AppendLine("   B.COLUMN_NAME AS COL_NAME")
                            .AppendLine("FROM USER_CONSTRAINTS A")
                            .AppendLine("   LEFT JOIN USER_CONS_COLUMNS B ON")
                            .AppendLine("       B.TABLE_NAME = A.TABLE_NAME")
                            .AppendLine("       AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME")
                            .AppendLine("WHERE")
                            .AppendLine("   B.TABLE_NAME = '" & sTableName & "'")
                            .AppendLine("   AND A.CONSTRAINT_TYPE = 'P'")
                        End With
                        cmd.CommandText = sbSql.ToString
                        adp.Fill(tblPKey)
                    End Using
                End Using
            Finally
                cnn.Close()
            End Try
        End Using 'cnn

        'Android側にテーブル作成
        '--Drop文作成
        Dim sSqlDrop As String = "DROP TABLE " & sTableName
        '--主キーリスト作成
        Dim lstPKey As New List(Of String)
        For Each r As DataRow In tblPKey.Rows
            lstPKey.Add(r.Item("COL_NAME").ToString)
        Next
        '--Create文作成
        Dim sqlCreate As New System.Text.StringBuilder
        With sqlCreate
            .AppendLine("CREATE TABLE " & sTableName & "(")
            For idx As Integer = 0 To tblSchema.Rows.Count - 1
                If idx <> 0 Then
                    .Append(",")
                End If
                .Append(tblSchema.Rows(idx).Item("Column_Name").ToString)
                Select Case tblSchema.Rows(idx).Item("Data_type").ToString
                    Case "VARCHAR2", "DATE"
                        .Append("   TEXT")
                    Case "NUMBER"
                        If CInt(tblSchema.Rows(idx).Item("data_scale")) = 0 Then
                            .Append("   NUMBER")
                        Else
                            .Append("   REAL")
                        End If
                End Select
                If tblSchema.Rows(idx).Item("Nullable").ToString = "N" Then
                    .Append("   NOT NULL")
                End If
                .AppendLine("")
            Next
            sqlCreate.AppendLine(",PRIMARY KEY (" & String.Join(",", lstPKey.ToArray) & ")")
            sqlCreate.AppendLine(")")
        End With
        '--テーブル作成
        Using cnn As DbConnection = factoryAD.CreateConnection()
            cnn.ConnectionString = Me._ConnectionStringAndroid
            cnn.Open()
            Try
                Using adp As DbDataAdapter = factoryAD.CreateDataAdapter
                    Using cmd As DbCommand = cnn.CreateCommand
                        cmd.CommandText = sSqlDrop
                        Try
                            cmd.ExecuteNonQuery()
                        Catch ex As Exception
                            '何もしない
                        End Try

                        cmd.CommandText = sqlCreate.ToString
                        cmd.ExecuteNonQuery()
                    End Using
                End Using

            Finally
                cnn.Close()
            End Try
        End Using 'cnn

        'データ移送
        Const DATA_CNT As Integer = 100
        Dim iSt As Integer = 0
        Dim iEd As Integer = iSt + DATA_CNT - 1
        '--PC側データのSELECT文の作成
        Dim sqlSelect As New System.Text.StringBuilder
        With sqlSelect
            .AppendLine("SELECT TMPTABLE2.* FROM")
            .AppendLine(String.Format("(SELECT ROWNUM AS ROW_NUM, {0}.* FROM {0} ) TMPTABLE2", sTableName))
            .AppendLine("WHERE ROW_NUM >= :ROW_NUM_Sta")
            .AppendLine("AND   ROW_NUM <= :ROW_NUM_End")
        End With
        Dim cmdSelect As DbCommand = factoryPC.CreateCommand
        cmdSelect.CommandText = sqlSelect.ToString
        Dim pSt As DbParameter = factoryPC.CreateParameter
        pSt.ParameterName = "ROW_NUM_Sta"
        cmdSelect.Parameters.Add(pSt)
        Dim pEd As DbParameter = factoryPC.CreateParameter
        pEd.ParameterName = "ROW_NUM_End"
        cmdSelect.Parameters.Add(pEd)
        '--Android側のInsert文の作成
        Dim lstColNm As New List(Of String)
        Dim lstPrmmNm As New List(Of String)
        For Each row As DataRow In tblSchema.Rows
            lstColNm.Add(row.Item("Column_Name").ToString)
            lstPrmmNm.Add("@" & row.Item("Column_Name").ToString)
        Next
        Dim sqlInsert As New System.Text.StringBuilder
        With sqlInsert
            .AppendLine("INSERT INTO " & sTableName & "(")
            .AppendLine(String.Join(","c, lstColNm.ToArray))
            .AppendLine(")VALUES(")
            .AppendLine(String.Join(","c, lstPrmmNm.ToArray))
            .AppendLine(")")
        End With
        Dim cmdInsert As DbCommand = factoryAD.CreateCommand
        cmdInsert.CommandText = sqlInsert.ToString
        For Each colnm As String In lstColNm
            Dim prm As DbParameter = factoryAD.CreateParameter
            prm.ParameterName = colnm
            prm.SourceColumn = colnm
            prm.SourceVersion = DataRowVersion.Current
            cmdInsert.Parameters.Add(prm)
        Next
        '--データをSelectしInsertをDATA_CNT件づつ繰り返す
        Using cnnPC As DbConnection = factoryPC.CreateConnection()
            cnnPC.ConnectionString = CONNECTION_STRING_PC
            cnnPC.Open()
            Try
                Using cnnAd As DbConnection = factoryAD.CreateConnection()
                    cnnAd.ConnectionString = Me._ConnectionStringAndroid
                    cnnAd.Open()
                    Try
                        cmdSelect.Connection = cnnPC
                        cmdInsert.Connection = cnnAd
                        Do
                            '----Select実行
                            Dim tblSelect As New DataTable
                            Using adp As DbDataAdapter = factoryPC.CreateDataAdapter
                                adp.SelectCommand = cmdSelect
                                cmdSelect.Parameters(pSt.ParameterName).Value = iSt
                                cmdSelect.Parameters(pEd.ParameterName).Value = iEd
                                adp.Fill(tblSelect)
                            End Using
                            If tblSelect.Rows.Count = 0 Then
                                Exit Do
                            End If
                            '----取得したデータの行状態を追加にする
                            For Each row As DataRow In tblSelect.Rows
                                row.SetAdded()
                            Next
                            '----Insert実行
                            Using adp As DbDataAdapter = factoryAD.CreateDataAdapter
                                adp.InsertCommand = cmdInsert
                                adp.Update(tblSelect)
                            End Using
                            '----インクリメント
                            iSt = iEd + 1
                            iEd = iSt + DATA_CNT - 1
                        Loop

                    Finally
                        cnnAd.Close()
                    End Try
                End Using 'cnnAd
            Finally
                cnnPC.Close()
            End Try
        End Using 'cnnPC
    End Sub

End Class