2012年8月31日金曜日

ヤフオクで売ってるボードでADKをやってみる

ボードの情報
http://mybd.sitemix.jp/pic_24FJ64GB002_2.html

回路図(必要な所だけ)


後は、 PIC24FJ64GB002でAndroid Accessory:ADK
の記事を参考に進める。


試す場合は自己責任でお願いします。
パソコンやアンドロイド端末が壊れる可能性があります。

PIC24FJ64GB002でAndroid Accessory:ADK

手元にある部品だけでとりあえず回路を組んでみました。
動作確認

参考にしたサイト:
side2(サイドツー)PIC24FJ64GB002でADKを試す(その2)
PIC24FJ64GB002のADK開発環境
第4回名古屋Android勉強会資料

試す場合は自己責任でお願いします。
パソコンやアンドロイド端末が壊れる可能性があります。

1.まず、pickit2でPIC24FJ64GB002にプログラムを書き込むのに必要な回路だけ組む
pickit3は持っていないのでpickit2を使ってPICkit 2 Programmer で書き込んだ。
書き込むプログラムはPIC24FJ64GB002でADKを試す(その2)でダウンロード出来るHexファイル

2.残りの回路を組む。

3.Android端末にアプリをインストールする。
Play ストアでMicrochipを検索してBasic Accessory Demoをインストールする。
Basic Accessory Demo

4.PICとAndroidを繋げて動作確認

参考
pickit2 で書き込めるリストが下記のアドレスで紹介されている。
http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName=en027813
PPIC24FJ64GB002もICkit 2 Programmer Application v2.61で書き込めるようです。

2012年8月20日月曜日

データベースの作成:sqlite

SQLiteOpenHelper クラスを使わないでデータベースの作成

import android.os.Bundle;
import android.app.Activity;
import android.content.ContentValues;
import android.database.sqlite.SQLiteDatabase;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //データベース作成
        SQLiteDatabase db;
        
        db = openOrCreateDatabase( "TestData.db" , SQLiteDatabase.CREATE_IF_NECESSARY , null );
        
        //テーブル作成
        String sql = "CREATE TABLE IF NOT EXISTS table_name (" 
          + "id INTEGER PRIMARY KEY AUTOINCREMENT,"
          + "name TEXT);";
  
        db.execSQL(sql);

        //レコードの追加
        ContentValues val = new ContentValues();
        val.put( "name", "sakkura" );
        db.insert( "table_name", null, val );
        
        db.close();

    }

}


2012年8月16日木曜日

TextView・一行表示・横スクロール

TextView で一行で表示される文字数を超えると自動的に改行される。


一行に制限する。
android:singleLine="true"


横スクロールさせる

<LinearLayout 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"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ellipsize="marquee"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:marqueeRepeatLimit="marquee_forever"
        android:scrollHorizontally="true"
        android:singleLine="true"
        android:text="ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ" />

        <TextView
        android:id="@+id/textView2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:ellipsize="marquee"
        android:focusable="true"
        android:focusableInTouchMode="true"
        android:marqueeRepeatLimit="marquee_forever"
        android:scrollHorizontally="true"
        android:singleLine="true"
        android:text="ABCDEFGHIJKLMNOPQRSTUVWXYZ" />

</LinearLayout>

はみ出さない場合は、スクロールしない






2012年8月15日水曜日

ARROWS X F-10D 関連情報

Android携帯をやっと手に入れました。
最先端の高速クアッドコアCPU搭載 All in oneハイスペック防水スマートフォンという事でいろいろ調べて、F-10Dを選びました。

Android携帯端末ソフトウェア開発者向けサポート情報
docomo NEXT series ARROWS X F-10D

ディスプレイ・サイズ約 4.6インチ
赤外線通信対応IrSimpleTM/IrSSTMには非対応です。
Bluetooth®通信Bluetooth® 4.0
GPSオートGPS/海外GPS対応
モーションセンサー取扱説明書 34p
電子コンパス取扱説明書 129p
温度センサー取扱説明書 24p
湿度センサー取扱説明書 24p
RGBセンサー取扱説明書 24p
近接センサー取扱説明書 24p
FMトランスミッタ取扱説明書 24p
指紋センサー取扱説明書 24p
この表は、私が勝手に作りました。正確さは無保証

F-10D ADB用USBドライバ

サービス・機能とスペックを見ても書いてないセンサーや機能があるので、
お客様サポートの説明書をダウンロードして調べないと分からない。

センサーの名前も
モーションセンサーと加速度センサーは同じなのか?
電子コンパス(デジタルコンパス)とジャイロセンサー、地磁気センサーは同じなのか?
近接センサーとRGBセンサーの違いなど未確認です。

2012年8月9日木曜日

ソースコードの整形の設定・改行位置:Eclipse

ウインドウ->設定
Java->コードスタイル->フォーマッター

編集をクリックする。

折り返し タブを選択して
プレビュー・ウインドウの行の幅の設定 の部分を変更する。

2012年8月8日水曜日

Threadの利用方法:Java標準

Threadを利用しない場合



時間の掛かる処理終了後に画面が表示される。

import android.os.Bundle;
import android.app.Activity;
import android.widget.Toast;

public class MainActivity extends Activity {

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

  waitTime();// 時間のかかる処理

  Toast.makeText(this, "時間の掛かる処理終了後に実行されるはず", Toast.LENGTH_LONG).show();

 }

 private void waitTime() {
  // TODO 自動生成されたメソッド・スタブ
  try {
   Thread.sleep(10 * 1000);
  } catch (InterruptedException e) {
   // TODO 自動生成された catch ブロック
   e.printStackTrace();
  }
 }

}

Java標準のThreadを利用した並列処理を使った場合
時間の掛かる処理終了前に画面が表示される

import android.os.Bundle;
import android.app.Activity;
import android.widget.Toast;

public class MainActivity extends Activity {

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

  new Thread(new Runnable() {
   public void run() {
    // TODO Auto-generated method stub
    waitTime();// 時間のかかる処理
   }
  }).start();

  Toast.makeText(this, "時間の掛かる処理終了前に表示されるはず", Toast.LENGTH_LONG).show();

 }

 private void waitTime() {
  // TODO 自動生成されたメソッド・スタブ
  try {
   Thread.sleep(10 * 1000);
  } catch (InterruptedException e) {
   // TODO 自動生成された catch ブロック
   e.printStackTrace();
  }
 }

}

UI操作を行う場合 Handler を使う



時間の掛かる処理からデータを受け取ってUIを操作している。

import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

 private TextView textView;

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

  textView = (TextView) findViewById(R.id.textView1);
  
  final Handler handler = new Handler();
  
  new Thread(new Runnable() {
   public void run() {
    // TODO Auto-generated method stub
    
    final int num = waitTime();//時間のかかる処理
    
    handler.post(new Runnable() {
     public void run() {
      //int num = waitTime();// ここに置いたら別スレッドにならない
      textView.setText("UIを変更::" + num);
     }
    });
   }

  }).start();

  Toast.makeText(this, "これが先に実行されるはず", Toast.LENGTH_LONG).show();

 }

 private int waitTime() {
  // TODO 自動生成されたメソッド・スタブ
  try {
   Thread.sleep(10 * 1000);//10秒待つ
   
  } catch (InterruptedException e) {
   // TODO 自動生成された catch ブロック
   e.printStackTrace();
  }
  return 2012;
 }

}


NanoHTTPD を使ってみる2:indexファイルの利用

SDカードにindex.htmlがある場合

import java.io.File;
import java.io.IOException;
import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {
 private MyHTTPD server;

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

 @Override
 protected void onResume() {
  super.onResume();

  //File am = new File("/data/data/com.example.servertest/lib/", "");//
 File am = new File("/mnt/sdcard/", "");//

  try {
   server = new MyHTTPD(8080, am);
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

 @Override
 protected void onPause() {
  super.onPause();
  if (server != null)
   server.stop();
 }

 private class MyHTTPD extends NanoHTTPD {

  public MyHTTPD(int port, File wwwroot) throws IOException {
   super(port, wwwroot);
   // TODO 自動生成されたコンストラクター・スタブ
  }
 }
}




2012年8月3日金曜日

ボタンス・タイルのカスタマイズ


<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content">

    <!-- フォーカスされていない -->
    <!-- ボタンが押されていない -->
    <item android:state_focused="false"
        android:state_pressed="false">
    <layer-list>
            <item><shape xmlns:android="http://schemas.android.com/apk/res/android"
                android:shape="rectangle">
                    <gradient android:angle="270"
                        android:startColor="#000000"
                        android:centerColor="#ffffff"
                        android:endColor="#000000"
                        android:type="linear" />

                    <corners android:radius="4dip" />

                    <stroke android:width="1dip"
                        android:color="#ffffff" />
                    <padding android:top="5dip"
                        android:bottom="5dip"/>
                </shape></item>
        </layer-list></item>

    <!-- フォーカスされていない -->
    <!-- ボタンが押されている -->
    <item android:state_focused="false"
        android:state_pressed="true"><layer-list>
            <item><shape xmlns:android="http://schemas.android.com/apk/res/android"
                android:shape="rectangle">
                    <gradient android:angle="270"
                        android:startColor="#ffffff"
                        android:centerColor="#000000"
                        android:endColor="#ffffff"
                        android:type="linear" />

                    <corners android:radius="4dip" />

                    <stroke android:width="1dip"
                        android:color="#ffffff" />
                </shape></item>
        </layer-list></item>

    <!-- フォーカスされた -->
    <!-- ボタンが押されていない -->
    <item android:state_focused="true"
        android:state_pressed="false"><layer-list>
            <item><shape xmlns:android="http://schemas.android.com/apk/res/android"
                android:shape="rectangle">
                    <gradient android:angle="270"
                        android:startColor="#000000"
                        android:centerColor="#ffffff"
                        android:endColor="#000000"
                        android:type="linear" />

                    <corners android:radius="4dip" />

                    <stroke android:width="1dip"
                        android:color="#FF6600" />
                </shape></item>
        </layer-list></item>

    <!-- フォーカスされた -->
    <!-- ボタンが押されている -->
    <item android:state_focused="true"
        android:state_pressed="true"><layer-list>
            <item><shape xmlns:android="http://schemas.android.com/apk/res/android"
                android:shape="rectangle">
                    <gradient android:angle="270"
                        android:startColor="#ffffff"
                        android:centerColor="#000000"
                        android:endColor="#ffffff"
                        android:type="linear" />

                    <corners android:radius="4dip" />

                    <stroke android:width="1dip"
                        android:color="#CC6600" />
                </shape></item>
        </layer-list></item>

</selector>

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">

    <style name="button" >
        <item name="android:layout_marginTop">1dip</item>
  <item name="android:layout_marginBottom">1dip</item>
    </style>

</resources>

<?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:orientation="vertical" ><Button
        android:id="@+id/button1"
        style="@style/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@layout/mybutton"
        android:text="Button" />

    <Button
        android:id="@+id/button2"
        style="@style/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="@layout/mybutton"
        android:text="Button" />

</LinearLayout>

Android で NanoHTTPD を使ってみる

android に webサーバ機能を追加

NanoHTTPD の情報
http://elonen.iki.fi/code/nanohttpd/

とりあえずやってみる

package com.example.servertest;

import java.io.File;
import java.io.IOException;
import java.util.Properties;

import android.app.Activity;
import android.os.Bundle;

public class MainActivity extends Activity {
 private MyHTTPD server;
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
 }

 @Override
 protected void onResume() {
  super.onResume();

  try {
   server = new MyHTTPD(8080, null);
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

 @Override
 protected void onPause() {
  super.onPause();
  if (server != null)
   server.stop();
 }

 private class MyHTTPD extends NanoHTTPD {


  public MyHTTPD(int port, File wwwroot) throws IOException {
   super(port, wwwroot);
   // TODO 自動生成されたコンストラクター・スタブ
  }

  @Override
  public Response serve(String uri, String method, Properties header,
    Properties parms, Properties files) {
   System.out.println(method + " '" + uri + "' ");
   String msg = "<html><body><h1>Hello server</h1>\n";
   msg += "</body></html>\n";
   return new NanoHTTPD.Response(HTTP_OK, MIME_HTML, msg);
  }
 }
}

マニフェストファイルの設定
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>

ダウンロードしてきた NanoHTTPD.java を同じパッケージ内に置く
実機にインストールしてアプリを実行する。

ブラウザでandroidのアドレスにアクセスする。


カメラ映像をPCに転送するアプリ

Androidでカメラ画像を転送するアプリでソースコードが公開されているもの
sipdroid
http://code.google.com/p/sipdroid/

ipcamera-for-android
http://code.google.com/p/ipcamera-for-android/

spydroid-ipcamera
http://code.google.com/p/spydroid-ipcamera/

SmartLab HTML5 Camera and Android


HTML5 Camera and Android とipcamera-for-android がシンプルで分かりやすい。


2012年8月2日木曜日

インターネット上の動画ファイルを再生:VideoView


import android.net.Uri;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.MediaController;
import android.widget.VideoView;

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        VideoView videoView = (VideoView)findViewById(R.id.videoView1);
        videoView.setMediaController(new MediaController(this));
        
        String LINK = "http://www.xxx.jp/xxx/xxx.mp4";
        
        Uri uri=Uri.parse(LINK);

        VideoView video=(VideoView)findViewById(R.id.videoView1);
        video.setVideoURI(uri);
        video.start();

    }

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

AVDでは再生は出来るが画質が悪い、
実機ではうまく再生できている様です。

android SDK Tools 20.0.1 で不具合

android SDK Tools を 20.0.1 にアップグレードしたらいろいろ不具合が出た。

LogCatがおかしい
ビューを作成できませんでした: プラグイン "com.android.ide.eclipse.ddms" は、クラス "com.android.ide.eclipse.ddms.views.LogCatView" をインスタンス化できませんでした。

プロジェクトが作成できない。
必要なパッケージがインストール出来ない。

eclipse フォルダの eclipse.exe -clean.cmd をダブルクリックで起動すればなおりました。



2012年8月1日水曜日

カウントダウンタイマーでシングルタップとダブルタップの判定



import android.app.Activity;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.widget.LinearLayout;

public class CountdownTimerActivity extends Activity {
    /** Called when the activity is first created. */
 private boolean mTimerRunning = false;
 private boolean doubleTapFlag = false;
 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        LinearLayout listView = (LinearLayout) findViewById(R.id.LinearLayout1);
        
        //ダブルタップの間隔取得
        final int doubleTime = ViewConfiguration.getDoubleTapTimeout();

  listView.setOnTouchListener(new View.OnTouchListener() {
   
   public boolean onTouch(View v, MotionEvent event) {
    Log.i("TAG", "タップされた");

    // 二重起動を防止する
    if (!mTimerRunning) {
     mTimerRunning = true;
     // カウントダウンする
     new CountDownTimer(doubleTime, 1) {
      // カウントダウン処理
      public void onTick(long millisUntilFinished) {
     }
      // カウントが0になった時の処理
      public void onFinish() {
       if( doubleTapFlag ){
        Log.v("LOG", "ダブルタップ");
        doubleTapFlag = false;
       }else{
        Log.i("LOG", "シングルタップ");
       }
       
       mTimerRunning = false;
      }
     }.start();
    }else{
     //ダブルタップ
     doubleTapFlag = true;
    }
    return false;
   }
  });
 }
}

ダブルタップを単に取得したいなら、GestureDetectorクラスで簡単に取得できます。

中華タブレットでwifiデバック

eee pc を使ってwifiデバッグ でもいろいろ苦労したけど、
中華タブレットはもっと苦労した。

結局、USBケーブルを接続した状態で、
adb connect 192.168.24.xx を打てば接続は出来る。