2014年5月6日火曜日

Tomcat + My SQL on Windows 初歩の初歩

My SQLインスール for Windows

世の中にはXAMPPという便利なツールがあるみたいですが、上記ですでにTomcatインストールしている ので、My SQLだけ単独でインストールします。ちなみに以下がXAMPPのサイト

https://www.apachefriends.org/jp/index.html

My SQLをインストールします。以下のサイトが参考になりますが、インストールの ところはかなり変わっています。

http://www.kkaneko.com/rinkou/mysql/mysqlinstall.html

Oracle eDelivery とかでMy SQLでSearchしてからインストールしなくてはいけません。 "MySQL Installer 5.6.18.0 Package"をダウンロードしましょう。

ダウンロードしたZIPを回答して、インストーラーを起動します。

途中にLogin/Password聞かれるところでなぜかエラーになるけどそのままインストール を続けます。

インストールが終わるとWindowsのプログラムにCommand Line Clientというのができる のでそれで操作できます

http://www.kkaneko.com/rinkou/mysql/command.html
mysql->mysql> CREATE DATABASE testdb DEFAULT CHARACTER SET cp932 COLLATE cp932_japanese_ci;
mysql> use testdb;
mysql> CREATE TABLE commodity (
    ->           type INTEGER primary key not null,
    ->           name VARCHAR(32) not null,
    ->           price INTEGER );
mysql> INSERT INTO commodity VALUES( 1, 'apple', 50 );
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO commodity VALUES( 2, 'orange', 20 );
Query OK, 1 row affected (0.00 sec)

mysql> INSERT INTO commodity VALUES( 3, 'strawberry', 100 );
Query OK, 1 row affected (0.00 sec)

mysql> SELECT * FROM commodity;
+------+------------+-------+
| type | name       | price |
+------+------------+-------+
|    1 | apple      |    50 |
|    2 | orange     |    20 |
|    3 | strawberry |   100 |
+------+------------+-------+
3 rows in set (0.00 sec)

ServletとMySQLの接続

Databaseと接続するためにはコネクタをインストールする必要があります。 コネクタはそれぞれにデータベースによって異なります。ここでは、以下の ページより、My SQLのコネクタをインストールしてください。

http://www-jp.mysql.com/products/connector/
1. JDBC Driver for MySQL (Connector/J)を選択
2. platform independentを選択
3. mysql-connector-java-5.1.30.zipをダウンロード
4. 解凍したフォルダを適当な場所に置く C:\Program Files\Java\mysql-connector-java-5.1.30
5.jarファイルをTomcatのフォルダに置く C:\hoge\apache-tomcat-7.0.53\lib

Servletを以下のように記述すれば、先ほどのCommodityからデータを取得する ことが可能。

@WebServlet("/HelloMySQL")
public class HelloMySQL extends HttpServlet {
 private static final long serialVersionUID = 1L;

 final private static String DBNAME = "testdb"; // Database Name
 
 final private static String USER = "XXXXX"; // user name for DB.
 
 final private static String PASS = "XXXXX"; // password for DB.
 
 final private static String JDBCDriver = "com.mysql.jdbc.Driver";
 
 final private static String DBURL = "jdbc:mysql://localhost/" + DBNAME;

 /**
  * @see HttpServlet#HttpServlet()
  */
 public HelloMySQL() {
  super();
  // TODO Auto-generated constructor stub
 }

 /**
  * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
  *      response)
  */
 protected void doGet(HttpServletRequest request,
   HttpServletResponse response) throws ServletException, IOException {
  // TODO Auto-generated method stub
  Connection conn = connect();
  if (conn != null) {
   Statement stmt = null;
   ResultSet rs = null;
   try {
    conn.setReadOnly(true);
    stmt = conn.createStatement();
    rs = stmt.executeQuery("select * from commodity");
    String resString = "commodity: ";
    while (rs.next()) {
     resString += rs.getString("name") + ", ";
    }
    response.getWriter().write(resString);
   } catch (SQLException e) {
    e.printStackTrace();
   } finally {
    if (rs != null) {
     try {
      rs.close();
     } catch (SQLException e) {
      e.printStackTrace();
     }
    }
    if (stmt != null) {
     try {
      stmt.close();
     } catch (SQLException e) {
      e.printStackTrace();
     }
    }
    disconnect(conn);
   }
  } else {
   response.getWriter().write("Hello, My SQL not connected!");
  }
 }
 
 private Connection connect() {
  Connection conn = null;
  try {
   Class.forName(JDBCDriver).newInstance();
   System.setProperty("jdbc.driver",JDBCDriver);
  }
  catch (Exception e) {
   e.printStackTrace();
   return null;
  }
  
  try {
   conn = DriverManager.getConnection(DBURL, USER, PASS);
  } catch (SQLException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
   return null;
  }
  return conn;  
 }
 
 private void disconnect(Connection conn) {
  try {
   conn.close();
  } catch (SQLException e) {
   e.printStackTrace();
  }
 }

2014年2月23日日曜日

AWS Android SDK

AWSのAndroid SDKを使ってみたので、少し記述しておきます。

まずAndroidから使うためには、ACCESS KEYを取得する必要が
あります。ACCESS KEYを取得するには、IAMというサービスで
ユーザを作ることで可能となります。














ここでユーザを作成した時に、必要なパーミッションを追加して下さい。
今回は、S3に読み書きしたいので、"AmazonS3FullAccess"を使いました。

ACCESS KEYを使った後はAmazonのSDKを取得するのですが、
これはAmazonのサイトから取得して下さい。

http://aws.amazon.com/jp/sdkforandroid/

アプリ側にはJarを追加するだけです。

今回は、新しく追加されたTransferManagerについて記述しておきます。
TransferManagerはS3の操作でよくやる、UploadとDownloadを簡単に
やってくれるものです。

http://docs.aws.amazon.com/AWSAndroidSDK/latest/javadoc/

例えば以下のコードでDownloadが可能です。

public void download(final String bucketName, final String key, final String path,
    final long size) {
    Runnable task = new Runnable() {
        @Override
        public void run() {
            try {
                File file = new File(path);
                Download download = mTransferManager.download(bucketName, key, file);
                TransferProgressListener progressListener = new TransferProgressListener(
                mNotifier, size);
                download.addProgressListener(progressListener);
                download.waitForCompletion();
                download.removeProgressListener(progressListener);
                mNotifier.notifyDownloaded(path);
            } catch (Exception e) {
                mNotifier.notifyError(e.getMessage());
            }
        }
    };
    mExecutor.submit(task);
}
}

2014年1月3日金曜日

Facebookアプリ作成の初歩ではまったこと

AWS EC2を使ってFacebookアプリを作りました。ここでのFacebookアプリとは
AWS EC2にWeb Appを作成し、そのWeb AppをFacebookアプリとして登録
するという一般的なものです。

自分以外のアカウントでは動作しないという状況になったので、その時に問題
の原因をシェアします。

原因は、Sandbox Modeにあります。Defaultでは、これになっていることがある
ので要注意です。Sandbox Modeの場合はFacebook Developerでないとアプリ
を動作させれないようです。Sandbox Modeを無効にしておく必要があります。


Sandobox Modeを無効にするとFacebookアプリはHTTPSで接続する必要
があります。(最近そうなったらしい。でも普通に考えればそりゃそうだよね)

Amazon EC2 ApacheでHTTPSをセットアップを以下のようにしたのでメモ
代わりに書いておきます。ただ、以下の内容は、事前にApacheを立ち上げた
後の作業です。

1. EC2のConsoleで、現在のインスタンスにわりあてているSecurity Groupに
HTTPSを足してください


2. EC2の既存のインスタンスにログインして、mod_sslをインストール

# sudo yum install mod_ssl

3. サーバーの秘密鍵の作成

# cd /etc/pki/tls/certs
# sudo make server.key
# sudo openssl rsa -in server.key -out server.key

4. サーバー証明書の作成

# sudo make server.crt
# sudo mv /etc/pki/tls/certs/server.key /etc/pki/tls/private

5. /etc/httpd/conf.d/ssl.conf で <Virtual Host> と </Virtual Host> の間に以下を記述。
以下のように書き換えます。

#SSLCertificateFile /etc/pki/tls/certs/localhost.crt SSLCertificateFile /etc/pki/tls/certs/server.crt

#SSLCertificateKeyFile /etc/pki/tls/private/localhost.key SSLCertificateKeyFile /etc/pki/tls/private/server.key


$sudo service httpd restart

って感じで、HTTPSにしたら普通にアプリがみんなの環境で動作するようになりました(祝)

2014年1月1日水曜日

Amazon EC2のインスタンス上げた後にすること

自分のためのメモ

1. Private Keyを適当なところに置く

2. chmod 600 xxx.pem

3. ssh configに以下を書いておく。AmazonのDNSのはいろいろあるからワイルドカード使っておくと便利

Host *.compute.amazonaws.com
User ec2-user
Port 22
IdentityFile ~/.ssh/xxxx.pem

3. ssh xxxx.compute.amazonaws.com でログイン

4. sudo yum -y install httpd

5. sudo service httpd start

6. sudo yum -y install emacs





2011年12月31日土曜日

Android Compatibility PackageでFragmentを楽しむ

Android 3.0より低いバージョンでFragmentを利用する場合は、Android Compatibility
Packageをインストールする必要があります。Android Compatibility Packageは
SDK Managerからインストールすることが可能です。

android-sdk-windows\extras\android\compatibility
以下にファイルが作成されていれば、インストールされています。


1. Android Projectを作成します
2. android-support-v4.jarファイルを適当なところにコピーします
 - android-sdk-windows\extras\android\compatibility\v4にあります
- 例えばlibsフォルダを作成してその下にコピーするなど
3. Eclipseでjarにパスを通します
- プロジェクト名-> Property -> Java Build Path -> Add JARs

<サンプルコード>

試しに、Fragmentのサンプルの簡易版を動かしてみて、Android2.3の
Xperiaで動作することが確認できました。ICSが出る前に先行して開発が
進められそうで便利そうです。

基本のサンプルは、以下のページにあるものをAndroid Compatibility
Packageにあわせて修正したものです。

package jp.gr.java.conf.ulexite.fragmenttest;

import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.ListFragment;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class TitlesFragment extends ListFragment {
private int mCurCheckPosition = 0;
private static final String[] mTitles = {"Title1", "Title2", "Title3", "Title4",
"Title5", "Title6", "Title7", "Title8"};

@Override
public void onActivityCreated(Bundle savedState) {
super.onActivityCreated(savedState);

ArrayAdapter titlesArray = new ArrayAdapter(getActivity(),
R.layout.title, mTitles);
setListAdapter(titlesArray);

if (savedState != null) {
mCurCheckPosition = savedState.getInt("curChoice", 0);
}

getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE);
showDetails(mCurCheckPosition);
}

@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putInt("curChoice", mCurCheckPosition);
}

@Override
public void onListItemClick(ListView l, View v, int pos, long id) {
showDetails(pos);
}

private void showDetails(int index) {
mCurCheckPosition = index;

getListView().setItemChecked(index, true);

// Check what fragment is shown, replace if needed.
DetailsFragment details = (DetailsFragment)
getFragmentManager().findFragmentById(R.id.details);
if (details == null || details.getShownIndex() != index) {
// Make new fragment to show this selection.
details = DetailsFragment.newInstance(index);

// Execute a transaction, replacing any existing
// fragment with this one inside the frame.
FragmentTransaction ft
= getFragmentManager().beginTransaction();
ft.replace(R.id.details, details);
ft.setTransition(
FragmentTransaction.TRANSIT_FRAGMENT_FADE);
ft.commit();
}
}
}

2011年11月17日木曜日

git --numstat

gitのnumstatがとても便利です。numstatはソースコードの変更行数を出してくれるので、リポジトリの変更がどの程度行われたのか、また、どのファイルが特に変更されたのかなどをざっと見る時にとても便利です。

簡単な使い方としては、git logと組みわせる方法があります。

$ git log --numstat

以下のようなログが出ます。
(https://android.googlesource.com/platform/frameworks/base のログの一つです)

commit 2237e1e7b636651f0ed1efacefa8aaccb21433ca
Author: Eric Fischer
Date: Wed Nov 2 15:14:43 2011 -0700

Import revised translations. DO NOT MERGE
Change-Id: I2f073cc6d62d757ba4e6565a0c7974ca9cecba4c

1 1 core/res/res/values-en-rGB/strings.xml
1 1 core/res/res/values-ru/strings.xml
5 5 core/res/res/values-sw/strings.xml
24 24 core/res/res/values-uk/strings.xml
2 2 packages/BackupRestoreConfirmation/res/values-sw/strings.xml
2 2 packages/SystemUI/res/values-af/strings.xml
1 1 packages/SystemUI/res/values-ru/strings.xml
8 8 packages/SystemUI/res/values-sw/strings.xml
1 1 packages/SystemUI/res/values-uk/strings.xml

この場合だとリソースのみの変更であることが一目でわかります。

またdiffとの組み合わせも便利です。

$ git diff android-2.2_r1 android-2.3.1_r1 --numstat

99 64 Android.mk
21 1 CleanSpec.mk
418795 0 api/9.xml
24489 1485 api/current.xml
0 31 awt/Android.mk
0 1354 awt/com/android/internal/awt/AndroidGraphics2D.java
0 96 awt/com/android/internal/awt/AndroidGraphicsConfiguration.java
0 87 awt/com/android/internal/awt/AndroidGraphicsFactory.java
0 274 awt/com/android/internal/awt/AndroidImageDecoder.java
0 536 awt/com/android/internal/awt/AndroidJavaBlitter.java
0 75 awt/com/android/internal/awt/AndroidNativeEventQueue.java
0 88 awt/com/android/internal/awt/AndroidWTK.java
0 52 awt/com/android/internal/awt/AwtFactory.java
0 66 awt/com/android/internal/awt/ImageOutputStreamWrapper.java
0 681 awt/java/awt/AWTEvent.java
0 47 awt/java/awt/AWTException.java
0 712 awt/java/awt/AWTKeyStroke.java
0 47 awt/java/awt/AWTListenerList.java
0 61 awt/java/awt/AWTPermission.java
0 39 awt/java/awt/ActiveEvent.java
0 166 awt/java/awt/Adjustable.java
0 352 awt/java/awt/AlphaComposite.java
0 2443 awt/java/awt/BasicStroke.java
0 195 awt/java/awt/BufferCapabilities.java
0 990 awt/java/awt/Color.java



2011年10月25日火曜日

【Android】 KeyEventの発行

KeyEventの発行についてまとめておきます。

KeyEventですが、基本的にIWindowManagerにあるinjectKeyEventを呼び出すことで
可能なのですが、残念ながら公開されているインターフェースではなく、リフレクションを
使う方法でしか呼び出しができません。

そこでいろいろ調べていたのですが、Instrumentationクラスを用いることで可能なことが
分かりました。

http://developer.android.com/reference/android/app/Instrumentation.html

InstrumentationクラスにあるsendKeySyncイベントなどを発行することで可能となります。

ただ、上記のAPIは、UIスレッドでは呼び出し不可能なので、別スレッドを作成して、そこから
呼び出す必要があります。以下、適当なコードですけどサンプルを載せておきます。

以下の手順で動作確認できます。

1. Musicをならす
2. 以下のアプリを起動
3. Buttonを押すと、Musicが停止したり、再開したりさせれます。(Play-Pauseキーなので)

全面のActivityにまずKeyEventが発行され、その後、IntentでMusic側に流れている
ことが確認できます。
public class SandBoxActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Button b = (Button) this.findViewById(R.id.button1);
b.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
KeyEventSender sender = new KeyEventSender();
sender.execute(null);
}
});
}

public boolean onKeyDown(int keyCode, KeyEvent event) {
android.util.Log.d("TEMPORARY", "keyCode = " + keyCode);
return super.onKeyDown(keyCode, event);
}

private class KeyEventSender extends AsyncTask {
@Override
protected Object doInBackground(Object... params) {
Instrumentation ist = new Instrumentation();
ist.sendKeyDownUpSync(KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE);
return null;
}
}
}