SlideShare ist ein Scribd-Unternehmen logo
1 von 56
Downloaden Sie, um offline zu lesen
FlashAir対応
Androidアプリ開発
2013年9月18日
あんざいゆき (株式会社ウフィカ)
Steps
• FlashAirにアクセスする
• FlashAirに保存されているファイルの一覧を表
示する
• FlashAirに保存されている画像ファイルのサム
ネイルを表示する
• FlashAirに保存されている画像ファイルをダウ
ンロードする
プロジェクトの用意
• [File] - [New] - [Android Application Project]
• Application Name: FlashAirSample
• Project Name: FlashAirSample
• Package Name: com.example.flashairsample
• Mininum Required SDK:API 9
• 以降はすべてデフォルト設定
FlashAirにアクセスする
FlashAirにアクセスする(1)
• FlashAirにアクセスするには、Androidデバイス
がFlashAirのアクセスポイントに接続している必
要があります
• 設定アプリのWiFi接続画面を開くメニューを用意
しましょう
res/menu/main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_wifi_settings"
android:showAsAction="never"
android:title="@string/action_wifi_settings"/>
</menu>
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
...
<string name="action_wifi_settings">WiFi Settings</string>
</resources>
MainActivity.java
public class MainActivity extends Activity {
...
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
switch (itemId) {
case R.id.action_wifi_settings:
Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
}
FlashAirにアクセスする(2)
• FlashAirにはHTTPでアクセスするため、アプリ
にはInternetパーミッションが必要です
• デフォルト SSID: flashair_xxxxx
• デフォルト Pass: 12345678
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.flashairsample"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET"/>
...
</manifest>
FlashAirにアクセスする(3)
• ライブラリプロジェクトを利用する
• FlashAirDev
• https://github.com/yanzm/FlashAirDev
• git clone https://github.com/yanzm/FlashAirDev.git
• [File] - [Import] - [Android] - [Existing Android Code
Into Workspace]
• Select root directory:
• FlashAirDevフォルダを指定
FlashAirにアクセスする(4)
• FlashAirSampleのプロパティを開く
• [Android] - [Library] - [Add]
• FlashAirDev を選択
FlashAirにアクセスする(5)
• フォルダ内のファイル数を取得する
• http://flashair/command.cgi?op=101&DIR=[path]
• https://www.flashair-developers.com/ja/
documents/api/commandcgi/#101
• レスポンスはファイル数(数字)
res/layout/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"
...
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
</RelativeLayout>
res/menu/main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_reload"
android:showAsAction="ifRoom"
android:title="@string/action_reload"/>
...
</menu>
res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
...
<string name="action_reload">Reload</string>
<string name="image_count_format">%1$d images</string>
</resources>
MainActivity.java
public class MainActivity extends Activity {
...
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
switch (itemId) {
...
case R.id.action_reload:
String dir = "/DCIM";
getFileCount(dir);
return true;
}
return super.onOptionsItemSelected(item);
}
...
}
MainActivity.java
public class MainActivity extends Activity {
...
private void getFileCount(final String dir) {
new AsyncTask<Void, Void, Integer>() {
@Override
protected Integer doInBackground(Void... params) {
return FlashAirUtils.getFileCount(dir);
}
@Override
protected void onPostExecute(Integer result) {
TextView tv = (TextView) findViewById(R.id.textView1);
tv.setText(getString(R.string.image_count_format, result));
}
}.execute();
}
}
FlashAirUtils.java
public class FlashAirUtils {
public static final String BASE = "http://flashair/";
public static final String COMMAND = BASE + "command.cgi?";
public static final String FILE_COUNT = COMMAND + "op=101&DIR=";
public static int getFileCount(String dir) {
try {
String result = Utils.accessToFlashAir(FILE_COUNT + dir);
return Integer.parseInt(result);
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return -1;
}
...
}
ファイル数取得
Utils.java
public class Utils {
public static String accessToFlashAir(String uri) throws IOException {
URL url = new URL(uri);
HttpURLConnection urlConnection
= (HttpURLConnection) url.openConnection();
String result = null;
try {
InputStream in
= new BufferedInputStream(urlConnection.getInputStream());
result = inputStreamToString(in);
in.close();
} finally {
urlConnection.disconnect();
}
return result;
}
...
}
HTTPアクセス用
Utils.java
public class Utils {
...
private static String inputStreamToString(InputStream stream)
throws IOException {
Reader reader = new InputStreamReader(stream, "UTF-8");
StringBuilder sb = new StringBuilder();
char[] buffer = new char[1024];
int num;
while (0 < (num = reader.read(buffer))) {
sb.append(buffer, 0, num);
}
return sb.toString();
}
...
}
HTTPアクセス用
FlashAirに保存されている
ファイルの一覧を表示する
ファイルの一覧を表示する(1)
• DCIMフォルダ内のファイル一覧を取得する
• http://flashair/command.cgi?op=100&DIR=[path]
• https://www.flashair-developers.com/ja/
documents/api/commandcgi/#100
• レスポンスは<ディレクトリ>,<ファイル名>,<ファイル
サイズ>,<属性>,<日付>,<時間>
• 例)/DCIM,100__TSB,0,16,9944,129
• ファイル名やディレクトリ名に,が入ってる場合もあり
うる!
ファイルの一覧を表示する(2)
• ファイルサイズはバイト単位
• 属性は16ビット整数の10進数表記
• ビット5 : アーカイブ
• ビット4 : ディレクトリ
• ビット3 : ボリューム
• ビット2 : システムファイル
• ビット1 : 隠しファイル
• ビット0 : 読み取り専用
ファイルの一覧を表示する(3)
• 日付は16ビット整数の10進数表記
• ビット15-9 : 1980年を0とした値
• ビット8-5 : 月(1∼12)
• ビット4-0 : 日(1∼31)
• 時刻は16ビット整数の10進数表記
• ビット15-11 : 時
• ビット10-5 : 分
• ビット4-0 : 秒/2
FlashAirFileInfo.java
public class FlashAirFileInfo {
public FlashAirFileInfo(String info, String dir) {
int start;
int end;
start = info.lastIndexOf(",");
int time = Integer.parseInt(info.substring(start + 1).trim());
end = start;
start = info.lastIndexOf(",", end - 1);
int date = Integer.parseInt(info.substring(start + 1, end).trim());
end = start;
start = info.lastIndexOf(",", end - 1);
mAttribute = Integer.parseInt(info.substring(start + 1, end).trim());
end = start;
start = info.lastIndexOf(",", end - 1);
mSize = info.substring(start + 1, end);
end = start;
start = info.indexOf(",", dir.length());
mFileName = info.substring(start + 1, end);
...
ファイル情報用のクラス
FlashAirFileInfo.java
...
mDir = dir;
int year = ((date >> 9) & 0x0000007f) + 1980;
int month = (date >> 5) & 0x0000000f - 1;
int day = (date) & 0x0000001f;
int hourOfDay = (time >> 11) & 0x0000001f;
int minute = (time >> 5) & 0x0000003f;
int second = ((time) & 0x0000001f) * 2;
mCalendar = Calendar.getInstance();
mCalendar.set(year, month, day, hourOfDay, minute, second);
}
public String mDir;
public String mFileName;
public String mSize;
public int mAttribute;
public Calendar mCalendar;
...
ファイル情報用のクラス
FlashAirFileInfo.java
...
public static final int ATTR_MASK_ARCHIVE = 0x00000020;
public static final int ATTR_MASK_DIRECTORY = 0x00000010;
public static final int ATTR_MASK_VOLUME = 0x00000008;
public static final int ATTR_MASK_SYSTEM_FILE = 0x00000004;
public static final int ATTR_MASK_HIDDEN_FILE = 0x00000002;
public static final int ATTR_MASK_READ_ONLY = 0x00000001;
public boolean isDirectory() {
return (mAttribute & ATTR_MASK_DIRECTORY) > 0;
}
@Override
public String toString() {
return "DIR=" + mDir + " FILENAME=" + mFileName + " SIZE=" + mSize
+ " ATTRIBUTE=" + mAttribute + " DATE="
+ DateFormat.format("yyyy-MM-dd kk:mm:ss", mCalendar);
}
}
ファイル情報用のクラス
FlashAirUtils.java
public class FlashAirUtils {
...
public static List<FlashAirFileInfo> getFileList(String dir) {
try {
String result = Utils.accessToFlashAir(FILE_LIST + dir);
if (TextUtils.isEmpty(result)) {
return null;
}
ArrayList<FlashAirFileInfo> list = new ArrayList<FlashAirFileInfo>();
for (String line : result.split("n")) {
if (TextUtils.isEmpty(line)) {
continue;
}
if (line.split(",").length < 6) {
continue;
}
FlashAirFileInfo info = new FlashAirFileInfo(line, dir);
list.add(info);
}
return list;
...
ファイル情報取得
FlashAirUtils.java
...
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
ファイル情報取得
res/layout/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"
...
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/textView1" />
</RelativeLayout>
一覧用ListView追加
MainActivity.java
public class MainActivity extends Activity {
...
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int itemId = item.getItemId();
switch (itemId) {
...
case R.id.action_reload:
String dir = "/DCIM";
getFileCount(dir);
getFileList(dir);
return true;
}
return super.onOptionsItemSelected(item);
}
...
}
ファイル一覧取得
MainActivity.java
public class MainActivity extends Activity {
...
private void getFileList(final String dir) {
new AsyncTask<Void, Void, List<FlashAirFileInfo>>() {
@Override
protected List<FlashAirFileInfo> doInBackground(Void... params) {
return FlashAirUtils.getFileList(dir);
}
@Override
protected void onPostExecute(List<FlashAirFileInfo> result) {
ListView lv = (ListView) findViewById(R.id.listView1);
lv.setAdapter(new FileListAdapter(MainActivity.this, result));
}
}.execute();
}
public class FileListAdapter extends ArrayAdapter<FlashAirFileInfo> {
public FileListAdapter(Context context, List<FlashAirFileInfo> data) {
super(context, android.R.layout.simple_list_item_1, data);
}
}
}
ファイル一覧をListViewにセット
FlashAirに保存されている
画像ファイルのサムネイル
を表示する
サムネイルを表示する(1)
• 画像ファイルのサムネイルを取得する
• http://flashair/thumbnail.cgi?[path]
• 例)http://flashair/thumbnail.cgi?/DCIM/IMG_xxx.jpg
• https://www.flashair-developers.com/ja/documents/
api/thumbnailcgi/
• EXIF規格で定められているサムネイル画像
• JPEG(image/jpeg)形式
• JPEGでない場合、EXIF規格で定められたサムネイル画像
がない場合、404 Not Found が返る
サムネイルを表示する(2)
• ListViewにサムネイルを表示する
• Volleyを利用する
• Androidのネットワーク処理用のライブラリ
• https://android.googlesource.com/platform/
frameworks/volley/
• http://y-anz-m.blogspot.jp/2013/05/google-
io-2013-android-volley-easy-fast.html
• 通信処理が組み込まれた ImageView である
NetworkImageView が用意されている
サムネイルを表示する(3)
• VolleyのNetworkImagView
• <com.android.volley.toolbox.NetworkImageView>
• setImageUrl(String url, ImageLoader loader)
• Volleyはライブラリプロジェクト
• git clone https://android.googlesource.com/
platform/frameworks/volley
• [File] - [Import] - [Android] - [Existing Android Code
Into Workspace]
• Select root directory:
• volleyフォルダを指定
サムネイルを表示する(4)
• FlashAirSampleのプロパティを開く
• [Android] - [Library] - [Add]
• volley を選択
サムネイルを表示する(5)
Volleyが選択肢に出てこない場合は、
VolleyプロジェクトのIs Libraryに
チェックが付いてることを確認
res/layout/list_row.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
<com.android.volley.toolbox.NetworkImageView
android:id="@+id/imageView1"
android:layout_width="100dp"
android:layout_height="80dp"
android:src="@drawable/ic_launcher" />
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Medium Text"
android:textAppearance="?android:attr/textAppearanceMedium" />
</LinearLayout>
リスト用レイアウト
MainActivity.java
public class MainActivity extends Activity {
private RequestQueue mQueue;
private ImageLoader mImageLoader;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mQueue = Volley.newRequestQueue(getApplicationContext());
mImageLoader = new ImageLoader(mQueue, new BitmapCache());
}
...
Volleyの準備
MainActivity.java
...
public class BitmapCache implements ImageCache {
private LruCache<String, Bitmap> mCache;
public BitmapCache() {
int maxSize = 5 * 1024 * 1024; // 5MB
mCache = new LruCache<String, Bitmap>(maxSize) {
@Override
protected int sizeOf(String key, Bitmap value) {
return value.getRowBytes() * value.getHeight();
}
};
}
@Override
public Bitmap getBitmap(String url) {
return mCache.get(url);
}
@Override
public void putBitmap(String url, Bitmap bitmap) {
mCache.put(url, bitmap);
}
}
Volleyの準備
MainActivity.java
public class MainActivity extends Activity {
...
public class FileListAdapter extends ArrayAdapter<FlashAirFileInfo> {
LayoutInflater mInflater;
public FileListAdapter(Context context, List<FlashAirFileInfo> data) {
super(context, 0, data);
mInflater = LayoutInflater.from(context);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if (convertView == null) {
convertView = mInflater.inflate(R.layout.list_row, parent, false);
}
FlashAirFileInfo item = getItem(position);
TextView tv = (TextView) convertView.findViewById(R.id.textView1);
tv.setText(item.mFileName);
...
リスト用Adapterを拡張
MainActivity.java
...
NetworkImageView niv = (NetworkImageView) convertView
.findViewById(R.id.imageView1);
if (item.mFileName.endsWith(".jpg") ||
item.mFileName.endsWith(".jpeg")) {
niv.setImageUrl(
FlashAirUtils.getThumbnailUrl(item.mDir, item.mFileName),
mImageLoader);
} else {
niv.setImageUrl(null, mImageLoader);
}
return convertView;
}
}
}
NetworkImageViewにURLをセット
FlashAirUtils.java
public class FlashAirUtils {
public static final String BASE = "http://flashair/";
public static final String THUMBNAIL = BASE + "thumbnail.cgi?";
public static String getThumbnailUrl(String dir, String fileName) {
return THUMBNAIL + dir + "/" + fileName;
}
...
}
FlashAirに保存されている画像
ファイルをダウンロードする
画像をダウンロードする(1)
• 画像ファイルを取得する
• http://flashair/[path]
• 例)http://flashair/DCIM/IMG_xxx.jpg
• DownloadManager を利用する
• http://developer.android.com/reference/android/
app/DownloadManager.html
画像をダウンロードする(2)
• DownloadManager
• getSystemService(Context.DOWNLOAD_SERVICE) でイ
ンスタンスを取得
• Request request = new DownloadManager.Request(uri)
でダウンロードリクエストを作成
• downloadManager.enqueue(request) でダウンロードリク
エストを追加
• SDカードにダウンロードする場合はパーミッションが必要
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.flashairsample"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
MainActivity.java
public class MainActivity extends Activity implements OnItemClickListener {
...
private void getFileList(final String dir) {
new AsyncTask<Void, Void, List<FlashAirFileInfo>>() {
@Override
protected List<FlashAirFileInfo> doInBackground(Void... params) {
return FlashAirUtils.getFileList(dir);
}
@Override
protected void onPostExecute(List<FlashAirFileInfo> result) {
ListView lv = (ListView) findViewById(R.id.listView1);
lv.setAdapter(new FileListAdapter(MainActivity.this, result));
lv.setOnItemClickListener(MainActivity.this);
}
}.execute();
}
...
リストにリスナーをセット
MainActivity.java
public class MainActivity extends Activity implements OnItemClickListener {
...
@Override
public void onItemClick(AdapterView<?> adapter, View v, int position,
long l) {
FlashAirFileInfo info = (FlashAirFileInfo) adapter
.getItemAtPosition(position);
File path = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File file = new File(path, info.mFileName);
if (!file.exists()) {
startDownload(info);
return;
}
openDownloadedFile(file.toString());
}
...
リストにリスナーをセット
MainActivity.java
...
private void openDownloadedFile(String filePath) {
MediaScannerConnection.scanFile(this, new String[] { filePath }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(uri);
startActivity(intent);
}
});
}
private void startDownload(FlashAirFileInfo info) {
Uri uri = FlashAirUtils.getFileUri(info.mDir, info.mFileName);
DownloadManager manager =
(DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(uri);
request.allowScanningByMediaScanner();
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DCIM,
info.mFileName);
manager.enqueue(request);
}
...
MainActivity.java
...
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE);
registerReceiver(receiver, filter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(receiver);
}
...
MainActivity.java
...
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if (id > 0) {
DownloadManager manager =
(DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
Uri fileUri = manager.getUriForDownloadedFile(id);
openDownloadedFile(fileUri.getPath());
}
}
};
}
FlashAir x Androidアプリ開発ワークショップ コーディングパート

Weitere ähnliche Inhalte

Andere mochten auch

Andere mochten auch (7)

Infra: Kubernetes and GKE, Network
Infra: Kubernetes and GKE, NetworkInfra: Kubernetes and GKE, Network
Infra: Kubernetes and GKE, Network
 
開発ビギナーだけじゃない!インフラエンジニア & マネージャー にも知ってほしいテスト自動化と品質管理
開発ビギナーだけじゃない!インフラエンジニア & マネージャー にも知ってほしいテスト自動化と品質管理開発ビギナーだけじゃない!インフラエンジニア & マネージャー にも知ってほしいテスト自動化と品質管理
開発ビギナーだけじゃない!インフラエンジニア & マネージャー にも知ってほしいテスト自動化と品質管理
 
Xamarin 紹介:Windows Phone / iOS / Android アプリ同時開発のススメ 2015/8/20 版
Xamarin 紹介:Windows Phone / iOS / Android アプリ同時開発のススメ 2015/8/20 版Xamarin 紹介:Windows Phone / iOS / Android アプリ同時開発のススメ 2015/8/20 版
Xamarin 紹介:Windows Phone / iOS / Android アプリ同時開発のススメ 2015/8/20 版
 
リクルートにおけるVDI導入 ~働き方変革とセキュリティ向上の両立を目指して~
リクルートにおけるVDI導入 ~働き方変革とセキュリティ向上の両立を目指して~リクルートにおけるVDI導入 ~働き方変革とセキュリティ向上の両立を目指して~
リクルートにおけるVDI導入 ~働き方変革とセキュリティ向上の両立を目指して~
 
事業成長にコミットするエンジニア組織への道のり
事業成長にコミットするエンジニア組織への道のり事業成長にコミットするエンジニア組織への道のり
事業成長にコミットするエンジニア組織への道のり
 
プロトタイプで終わらせない死の谷を超える機械学習プロジェクトの進め方 #MLCT4
プロトタイプで終わらせない死の谷を超える機械学習プロジェクトの進め方 #MLCT4プロトタイプで終わらせない死の谷を超える機械学習プロジェクトの進め方 #MLCT4
プロトタイプで終わらせない死の谷を超える機械学習プロジェクトの進め方 #MLCT4
 
「はじめてでもわかる RandomForest 入門-集団学習による分類・予測 -」 -第7回データマイニング+WEB勉強会@東京
「はじめてでもわかる RandomForest 入門-集団学習による分類・予測 -」 -第7回データマイニング+WEB勉強会@東京「はじめてでもわかる RandomForest 入門-集団学習による分類・予測 -」 -第7回データマイニング+WEB勉強会@東京
「はじめてでもわかる RandomForest 入門-集団学習による分類・予測 -」 -第7回データマイニング+WEB勉強会@東京
 

Mehr von FlashAirデベロッパーズ

Mehr von FlashAirデベロッパーズ (8)

Terminal share of FlashAir W-04
Terminal share of FlashAir W-04Terminal share of FlashAir W-04
Terminal share of FlashAir W-04
 
[FlashAir Developers Summit] FlashAirの紹介
[FlashAir Developers Summit] FlashAirの紹介[FlashAir Developers Summit] FlashAirの紹介
[FlashAir Developers Summit] FlashAirの紹介
 
FlashAir IoT Hubで計測値・イメージをアップロード!
FlashAir IoT Hubで計測値・イメージをアップロード!FlashAir IoT Hubで計測値・イメージをアップロード!
FlashAir IoT Hubで計測値・イメージをアップロード!
 
TOSHIBAxGUGEN FlashAirハッカソン-FlashAirでなに作る?
TOSHIBAxGUGEN FlashAirハッカソン-FlashAirでなに作る?TOSHIBAxGUGEN FlashAirハッカソン-FlashAirでなに作る?
TOSHIBAxGUGEN FlashAirハッカソン-FlashAirでなに作る?
 
[Maker Faire Tokyo 2014] FlashAirは超ミニマイコン! ひろがる電子工作コミュニティ
[Maker Faire Tokyo 2014] FlashAirは超ミニマイコン!ひろがる電子工作コミュニティ[Maker Faire Tokyo 2014] FlashAirは超ミニマイコン!ひろがる電子工作コミュニティ
[Maker Faire Tokyo 2014] FlashAirは超ミニマイコン! ひろがる電子工作コミュニティ
 
SDカードで無線Lチカ? FlashAirは超ミニマイコン!★Arduino用シールド(基板)配布中
SDカードで無線Lチカ?FlashAirは超ミニマイコン!★Arduino用シールド(基板)配布中SDカードで無線Lチカ?FlashAirは超ミニマイコン!★Arduino用シールド(基板)配布中
SDカードで無線Lチカ? FlashAirは超ミニマイコン!★Arduino用シールド(基板)配布中
 
SDカードで無線LチカFlashAirは超ミニマイコンアイデアコンテストも実施中
SDカードで無線LチカFlashAirは超ミニマイコンアイデアコンテストも実施中SDカードで無線LチカFlashAirは超ミニマイコンアイデアコンテストも実施中
SDカードで無線LチカFlashAirは超ミニマイコンアイデアコンテストも実施中
 
FlashAirの組み込み機器応用事例@OSC2014 Tokyo/Spring
FlashAirの組み込み機器応用事例@OSC2014 Tokyo/SpringFlashAirの組み込み機器応用事例@OSC2014 Tokyo/Spring
FlashAirの組み込み機器応用事例@OSC2014 Tokyo/Spring
 

Kürzlich hochgeladen

Kürzlich hochgeladen (11)

論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 

FlashAir x Androidアプリ開発ワークショップ コーディングパート