Mais conteúdo relacionado Mais de FlashAirデベロッパーズ (8) FlashAir x Androidアプリ開発ワークショップ コーディングパート4. • [File] - [New] - [Android Application Project]
• Application Name: FlashAirSample
• Project Name: FlashAirSample
• Package Name: com.example.flashairsample
• Mininum Required SDK:API 9
• 以降はすべてデフォルト設定
8. 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);
}
}
11. 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フォルダを指定
16. 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);
}
...
}
17. 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();
}
}
18. 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;
}
...
}
ファイル数取得
19. 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アクセス用
20. 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アクセス用
22. ファイルの一覧を表示する(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
• ファイル名やディレクトリ名に,が入ってる場合もあり
うる!
25. 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);
...
ファイル情報用のクラス
26. 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;
...
ファイル情報用のクラス
27. 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);
}
}
ファイル情報用のクラス
28. 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;
...
ファイル情報取得
31. 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);
}
...
}
ファイル一覧取得
32. 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にセット
36. サムネイルを表示する(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 が用意されている
38. • Volleyはライブラリプロジェクト
• git clone https://android.googlesource.com/
platform/frameworks/volley
• [File] - [Import] - [Android] - [Existing Android Code
Into Workspace]
• Select root directory:
• volleyフォルダを指定
サムネイルを表示する(4)
40. 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>
リスト用レイアウト
41. 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の準備
42. 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の準備
43. 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を拡張
44. 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をセット
45. 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;
}
...
}
50. 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>
51. 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();
}
...
リストにリスナーをセット
52. 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());
}
...
リストにリスナーをセット
53. 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);
}
...
54. 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);
}
...
55. 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());
}
}
};
}