0
FlashAir Android App
Development
Sep. 18 2013
Yuki Anzai
uPhyca Inc.
Steps

• Access the FlashAir
• Display a list of files stored on the
FlashAir

• Display thumbnail images
• Download image...
Set up a Project
•

[File] - [New] - [Android Application Project]

•

Application Name: FlashAirSample

•

Project Name: FlashAirSample

•...
Access the FlashAir
Access the FlashAir #1

•

Connect your Android device to the FlashAir's
wireless network.

•

Create a shortcut to open t...
res/menu/main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_wifi_se...
MainActivity.java
public class MainActivity extends Activity {
...
@Override
public boolean onCreateOptionsMenu(Menu menu)...
Access the FlashAir #2

•

Since the FlashAir uses HTTP, your app will require
android.permission.INTERNET.

•
•

Default ...
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/and...
Access the FlashAir #3
•
•

Use a library project
FlashAirDev

•
•
•
•

https://github.com/yanzm/FlashAirDev
git clone htt...
Access FlashAir #4
•
•

Add the FlashAirDev library project
[Android] - [Library] - [Add]

•

Select FlashAirDev
Access FlashAir #5

•
•
•
•

To get the number of files in a folder:
Use http://flashair/command.cgi?op=101&DIR=[path]
The...
res/layout/activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http:...
res/menu/main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_reload"...
MainActivity.java
public class MainActivity extends Activity {
...
@Override
public boolean onOptionsItemSelected(MenuItem...
MainActivity.java
public class MainActivity extends Activity {
...
private void getFileCount(final String dir) {
new Async...
FlashAirUtils.java

Get the number of files

public class FlashAirUtils {
public static final String BASE = "http://flasha...
Utils.java

For HTTP Access

public class Utils {
public static String accessToFlashAir(String uri) throws IOException {
U...
Utils.java

For HTTP Access

public class Utils {
...
private static String inputStreamToString(InputStream stream)
throws...
Display a list of files stored
on the FlashAir
Display a list of files #1
•
•
•

Get a list of the DCIM folder

•

<directory>,<file name>,<file
size>,<attribute>,<date>...
Display a list of files #2

•
•
•
•
•
•
•
•

The file's size is in bytes
Attribute is a 16-bit integer
Bit 5 : Archive
Bit...
Display a list of files #3
•

Date is also a 16-bit integer

•
•
•
•

Bit 15-9 : A value based on 0 as a 1980
Bit 8-5 : Mo...
FlashAirFileInfo.java

Class for a file information

public class FlashAirFileInfo {
public FlashAirFileInfo(String info, ...
FlashAirFileInfo.java
...

Class for a file information

mDir = dir;
int year = ((date >> 9) & 0x0000007f) + 1980;
int mon...
FlashAirFileInfo.java
...
public
public
public
public
public
public

static
static
static
static
static
static

final
fina...
FlashAirUtils.java

Get a file information

public class FlashAirUtils {
...
public static List<FlashAirFileInfo> getFileL...
FlashAirUtils.java
...
} catch (IOException e) {
e.printStackTrace();
}
}

return null;

Get a file information
res/layout/activity_main.xml

Add ListView

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xml...
MainActivity.java
public class MainActivity extends Activity {
...
@Override
public boolean onOptionsItemSelected(MenuItem...
MainActivity.java

Set a file list to ListView

public class MainActivity extends Activity {
...
private void getFileList(...
Display thumbnail of
images
Display thumbnails #1
•
•
•
•

To get thumbnails from image files:

•

Thumbnail images are defined by EXIF standard, and ...
Display thumbnails #2
•
•

Display the thumbnails in a ListView
Use Volley!

•
•

A network processing library for Android...
Display thumbnails #3

•

NetworkImagView of Vollay

•
•

<com.android.volley.toolbox.NetworkImageView>
setImageUrl(String...
Display thumbnails #4
•

Volley is a library project, so we need to add it.

•

git clone
https://android.googlesource.com...
Display thumbnails #5
•
•

Open Properties for FlashAirSample
[Android] - [Library] - [Add]

•

Select volley

If Volley i...
res/layout/list_row.xml

Layout for list

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schem...
MainActivity.java

Prepare Volley

public class MainActivity extends Activity {
private RequestQueue mQueue;
private Image...
MainActivity.java

Prepare Volley

...
public class BitmapCache implements ImageCache {
private LruCache<String, Bitmap> m...
MainActivity.java

Expand Adapter for list

public class MainActivity extends Activity {
...
public class FileListAdapter ...
MainActivity.java

Set URL at NetworkImageView

...
NetworkImageView niv = (NetworkImageView) convertView
.findViewById(R....
FlashAirUtils.java
public class FlashAirUtils {
public static final String BASE = "http://flashair/";
public static final ...
Download images
Download images #1

•
•
•
•

To get an image file
Use http://flashair/[path]
e.g. http://flashair/DCIM/IMG_xxx.jpg
Use Dow...
Download images #2

•

Using DownloadManager

•
•

Create a download request with Request request = new
DownloadManager.Re...
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/and...
MainActivity.java

Set Listener in list

public class MainActivity extends Activity implements OnItemClickListener {
...
p...
MainActivity.java

Set Listener in list

public class MainActivity extends Activity implements OnItemClickListener {
...
@...
MainActivity.java
...
private void openDownloadedFile(String filePath) {
MediaScannerConnection.scanFile(this, new String[...
MainActivity.java
...
@Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter(
Down...
MainActivity.java
...
BroadcastReceiver receiver = new BroadcastReceiver() {

}

@Override
public void onReceive(Context c...
FlashAir Android App Development
FlashAir Android App Development
FlashAir Android App Development
Upcoming SlideShare
Loading in...5
×

FlashAir Android App Development

14,731

Published on

This slides were used for the FlashAir x Android App Development Workshop held in Tokyo. The APIs, development tutorials, and Q&A forum for FlashAir Android App Development are now available for free on "FlashAir Developers" > https://flashair-developers.com

Published in: Technology, Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
14,731
On Slideshare
0
From Embeds
0
Number of Embeds
12
Actions
Shares
0
Downloads
31
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide
  • {}
  • Transcript of "FlashAir Android App Development"

    1. 1. FlashAir Android App Development Sep. 18 2013 Yuki Anzai uPhyca Inc.
    2. 2. Steps • Access the FlashAir • Display a list of files stored on the FlashAir • Display thumbnail images • Download images
    3. 3. Set up a Project
    4. 4. • [File] - [New] - [Android Application Project] • Application Name: FlashAirSample • Project Name: FlashAirSample • Package Name: com.example.flashairsample • Mininum Required SDK: API 9 • Use default settings for everything else
    5. 5. Access the FlashAir
    6. 6. Access the FlashAir #1 • Connect your Android device to the FlashAir's wireless network. • Create a shortcut to open the WiFi configuration window.
    7. 7. 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>
    8. 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); }
    9. 9. Access the FlashAir #2 • Since the FlashAir uses HTTP, your app will require android.permission.INTERNET. • • Default SSID: flashair_xxxxx Default Password: 12345678
    10. 10. 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>
    11. 11. Access the FlashAir #3 • • Use a library project 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: • Set FlashAirDev folder
    12. 12. Access FlashAir #4 • • Add the FlashAirDev library project [Android] - [Library] - [Add] • Select FlashAirDev
    13. 13. Access FlashAir #5 • • • • To get the number of files in a folder: Use http://flashair/command.cgi?op=101&DIR=[path] The number of files will be returned See: https://www.flashairdevelopers.com/ja/documents/api/commandcgi/#101
    14. 14. 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>
    15. 15. 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>
    16. 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. 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. 18. FlashAirUtils.java Get the number of files 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. 19. Utils.java For HTTP Access 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; ...
    20. 20. Utils.java For HTTP Access 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(); } } ...
    21. 21. Display a list of files stored on the FlashAir
    22. 22. Display a list of files #1 • • • Get a list of the DCIM folder • <directory>,<file name>,<file size>,<attribute>,<date>,and <time> are returned. • • e.g. /DCIM,100__TSB,0,16,9944,129 Use: http://flashair/command.cgi?op=100&DIR=[path] See: https://www.flashairdevelopers.com/ja/documents/api/commandcgi/#100 NOTE: A comma could be returned as part of a filename.
    23. 23. Display a list of files #2 • • • • • • • • The file's size is in bytes Attribute is a 16-bit integer Bit 5 : Archive Bit 4 : Directly Bit 3 : Volume Bit 2 : System file Bit 1 : Hidden file Bit 0 : Read only
    24. 24. Display a list of files #3 • Date is also a 16-bit integer • • • • Bit 15-9 : A value based on 0 as a 1980 Bit 8-5 : Month from 1 to 12 Bit 4-0 : Day from 1 to 31 So is the Timestamp • • • Bit 15-11 : Hour Bit 10-5 : Minute Bit 4-0 : Second/2
    25. 25. FlashAirFileInfo.java Class for a file information 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. 26. FlashAirFileInfo.java ... Class for a file information 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 public public public public ... String mDir; String mFileName; String mSize; int mAttribute; Calendar mCalendar;
    27. 27. FlashAirFileInfo.java ... public public public public public public static static static static static static final final final final final final int int int int int int Class for a file information ATTR_MASK_ARCHIVE = 0x00000020; ATTR_MASK_DIRECTORY = 0x00000010; ATTR_MASK_VOLUME = 0x00000008; ATTR_MASK_SYSTEM_FILE = 0x00000004; ATTR_MASK_HIDDEN_FILE = 0x00000002; 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. 28. FlashAirUtils.java Get a file information 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;
    29. 29. FlashAirUtils.java ... } catch (IOException e) { e.printStackTrace(); } } return null; Get a file information
    30. 30. res/layout/activity_main.xml Add ListView <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>
    31. 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); } ... } Get a file list
    32. 32. MainActivity.java Set a file list to ListView 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); }
    33. 33. Display thumbnail of images
    34. 34. Display thumbnails #1 • • • • To get thumbnails from image files: • Thumbnail images are defined by EXIF standard, and are only available in JPEG format • If a file is not JPEG or no thumbnails are defined, a 404 error is returned Use http://flashair/thumbnail.cgi?[path] e.g. http://flashair/thumbnail.cgi?/DCIM/IMG_xxx.jpg See: https://www.flashairdevelopers.com/ja/documents/api/thumbnailcgi/
    35. 35. Display thumbnails #2 • • Display the thumbnails in a ListView Use Volley! • • A network processing library for Android • http://y-anz-m.blogspot.jp/2013/05/google-io-2013android-volley-easy-fast.html • NetworkImageView is available https://android.googlesource.com/platform/frameworks/v olley/ • NetworkImageView is an ImageView with communication processing
    36. 36. Display thumbnails #3 • NetworkImagView of Vollay • • <com.android.volley.toolbox.NetworkImageView> setImageUrl(String url, ImageLoader loader)
    37. 37. Display thumbnails #4 • Volley is a library project, so we need to add it. • git clone https://android.googlesource.com/platform/frameworks/vo lley • [File] - [Import] - [Android] - [Existing Android Code Into Workspace] • Select root directory: • Set volley folder
    38. 38. Display thumbnails #5 • • Open Properties for FlashAirSample [Android] - [Library] - [Add] • Select volley If Volley is not appear on the list, make sure Is Library od Volley project is checked!
    39. 39. res/layout/list_row.xml Layout for list <?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>
    40. 40. MainActivity.java Prepare Volley 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()); } ...
    41. 41. MainActivity.java Prepare Volley ... 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); }
    42. 42. MainActivity.java Expand Adapter for list 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); ...
    43. 43. MainActivity.java Set URL at NetworkImageView ... 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;
    44. 44. 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; } } ...
    45. 45. Download images
    46. 46. Download images #1 • • • • To get an image file Use http://flashair/[path] e.g. http://flashair/DCIM/IMG_xxx.jpg Use DownloadManager • http://developer.android.com/reference/android/app/Dow nloadManager.html
    47. 47. Download images #2 • Using DownloadManager • • Create a download request with Request request = new DownloadManager.Request(uri) • • Get an instance with getSystemService(Context.DOWNLOAD_SERVICE) Add the request with downloadManager.enqueue(request) To save image to your device, you will need android.permission.WRITE_EXTERNAL_STORAGE.
    48. 48. 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>
    49. 49. MainActivity.java Set Listener in list 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();
    50. 50. MainActivity.java Set Listener in list 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());
    51. 51. 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); } ...
    52. 52. 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); } ...
    53. 53. 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()); } } };
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×