1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.example.android.apis.content;
18 
19 //Need the following import to get access to the app resources, since this
20 //class is in a sub-package.
21 import com.example.android.apis.R;
22 
23 import android.app.Activity;
24 import android.content.BroadcastReceiver;
25 import android.content.Context;
26 import android.content.Intent;
27 import android.content.IntentFilter;
28 import android.media.MediaScannerConnection;
29 import android.net.Uri;
30 import android.os.Bundle;
31 import android.os.Environment;
32 import android.util.Log;
33 import android.view.LayoutInflater;
34 import android.view.View;
35 import android.view.ViewGroup;
36 import android.widget.Button;
37 import android.widget.TextView;
38 
39 import java.io.File;
40 import java.io.FileOutputStream;
41 import java.io.IOException;
42 import java.io.InputStream;
43 import java.io.OutputStream;
44 
45 
46 /**
47 * Demonstration of styled text resources.
48 */
49 public class ExternalStorage extends Activity {
50     ViewGroup mLayout;
51 
52     static class Item {
53         View mRoot;
54         Button mCreate;
55         Button mDelete;
56     }
57 
58     Item mExternalStoragePublicPicture;
59     Item mExternalStoragePrivatePicture;
60     Item mExternalStoragePrivateFile;
61 
62     @Override
onCreate(Bundle savedInstanceState)63     protected void onCreate(Bundle savedInstanceState) {
64         super.onCreate(savedInstanceState);
65 
66         setContentView(R.layout.external_storage);
67         mLayout = (ViewGroup)findViewById(R.id.layout);
68         mExternalStoragePublicPicture = createStorageControls(
69                 "Picture: getExternalStoragePublicDirectory",
70                 Environment.getExternalStoragePublicDirectory(
71                         Environment.DIRECTORY_PICTURES),
72                 new View.OnClickListener() {
73                     public void onClick(View v) {
74                         createExternalStoragePublicPicture();
75                         updateExternalStorageState();
76                     }
77                 },
78                 new View.OnClickListener() {
79                     public void onClick(View v) {
80                         deleteExternalStoragePublicPicture();
81                         updateExternalStorageState();
82                     }
83                 });
84         mLayout.addView(mExternalStoragePublicPicture.mRoot);
85         mExternalStoragePrivatePicture = createStorageControls(
86                 "Picture getExternalFilesDir",
87                 getExternalFilesDir(Environment.DIRECTORY_PICTURES),
88                 new View.OnClickListener() {
89                     public void onClick(View v) {
90                         createExternalStoragePrivatePicture();
91                         updateExternalStorageState();
92                     }
93                 },
94                 new View.OnClickListener() {
95                     public void onClick(View v) {
96                         deleteExternalStoragePrivatePicture();
97                         updateExternalStorageState();
98                     }
99                 });
100         mLayout.addView(mExternalStoragePrivatePicture.mRoot);
101         mExternalStoragePrivateFile = createStorageControls(
102                 "File getExternalFilesDir",
103                 getExternalFilesDir(null),
104                 new View.OnClickListener() {
105                     public void onClick(View v) {
106                         createExternalStoragePrivateFile();
107                         updateExternalStorageState();
108                     }
109                 },
110                 new View.OnClickListener() {
111                     public void onClick(View v) {
112                         deleteExternalStoragePrivateFile();
113                         updateExternalStorageState();
114                     }
115                 });
116         mLayout.addView(mExternalStoragePrivateFile.mRoot);
117 
118         startWatchingExternalStorage();
119     }
120 
121     @Override
onDestroy()122     protected void onDestroy() {
123         super.onDestroy();
124         stopWatchingExternalStorage();
125     }
126 
handleExternalStorageState(boolean available, boolean writeable)127     void handleExternalStorageState(boolean available, boolean writeable) {
128         boolean has = hasExternalStoragePublicPicture();
129         mExternalStoragePublicPicture.mCreate.setEnabled(writeable && !has);
130         mExternalStoragePublicPicture.mDelete.setEnabled(writeable && has);
131         has = hasExternalStoragePrivatePicture();
132         mExternalStoragePrivatePicture.mCreate.setEnabled(writeable && !has);
133         mExternalStoragePrivatePicture.mDelete.setEnabled(writeable && has);
134         has = hasExternalStoragePrivateFile();
135         mExternalStoragePrivateFile.mCreate.setEnabled(writeable && !has);
136         mExternalStoragePrivateFile.mDelete.setEnabled(writeable && has);
137     }
138 
139 // BEGIN_INCLUDE(monitor_storage)
140     BroadcastReceiver mExternalStorageReceiver;
141     boolean mExternalStorageAvailable = false;
142     boolean mExternalStorageWriteable = false;
143 
updateExternalStorageState()144     void updateExternalStorageState() {
145         String state = Environment.getExternalStorageState();
146         if (Environment.MEDIA_MOUNTED.equals(state)) {
147             mExternalStorageAvailable = mExternalStorageWriteable = true;
148         } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
149             mExternalStorageAvailable = true;
150             mExternalStorageWriteable = false;
151         } else {
152             mExternalStorageAvailable = mExternalStorageWriteable = false;
153         }
154         handleExternalStorageState(mExternalStorageAvailable,
155                 mExternalStorageWriteable);
156     }
157 
startWatchingExternalStorage()158     void startWatchingExternalStorage() {
159         mExternalStorageReceiver = new BroadcastReceiver() {
160             @Override
161             public void onReceive(Context context, Intent intent) {
162                 Log.i("test", "Storage: " + intent.getData());
163                 updateExternalStorageState();
164             }
165         };
166         IntentFilter filter = new IntentFilter();
167         filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
168         filter.addAction(Intent.ACTION_MEDIA_REMOVED);
169         registerReceiver(mExternalStorageReceiver, filter);
170         updateExternalStorageState();
171     }
172 
stopWatchingExternalStorage()173     void stopWatchingExternalStorage() {
174         unregisterReceiver(mExternalStorageReceiver);
175     }
176  // END_INCLUDE(monitor_storage)
177 
178  // BEGIN_INCLUDE(public_picture)
createExternalStoragePublicPicture()179     void createExternalStoragePublicPicture() {
180         // Create a path where we will place our picture in the user's
181         // public pictures directory.  Note that you should be careful about
182         // what you place here, since the user often manages these files.  For
183         // pictures and other media owned by the application, consider
184         // Context.getExternalMediaDir().
185         File path = Environment.getExternalStoragePublicDirectory(
186                 Environment.DIRECTORY_PICTURES);
187         File file = new File(path, "DemoPicture.jpg");
188 
189         try {
190             // Make sure the Pictures directory exists.
191             path.mkdirs();
192 
193             // Very simple code to copy a picture from the application's
194             // resource into the external file.  Note that this code does
195             // no error checking, and assumes the picture is small (does not
196             // try to copy it in chunks).  Note that if external storage is
197             // not currently mounted this will silently fail.
198             InputStream is = getResources().openRawResource(R.drawable.balloons);
199             OutputStream os = new FileOutputStream(file);
200             byte[] data = new byte[is.available()];
201             is.read(data);
202             os.write(data);
203             is.close();
204             os.close();
205 
206             // Tell the media scanner about the new file so that it is
207             // immediately available to the user.
208             MediaScannerConnection.scanFile(this,
209                     new String[] { file.toString() }, null,
210                     new MediaScannerConnection.OnScanCompletedListener() {
211                 public void onScanCompleted(String path, Uri uri) {
212                     Log.i("ExternalStorage", "Scanned " + path + ":");
213                     Log.i("ExternalStorage", "-> uri=" + uri);
214                 }
215             });
216         } catch (IOException e) {
217             // Unable to create file, likely because external storage is
218             // not currently mounted.
219             Log.w("ExternalStorage", "Error writing " + file, e);
220         }
221     }
222 
deleteExternalStoragePublicPicture()223     void deleteExternalStoragePublicPicture() {
224         // Create a path where we will place our picture in the user's
225         // public pictures directory and delete the file.  If external
226         // storage is not currently mounted this will fail.
227         File path = Environment.getExternalStoragePublicDirectory(
228                 Environment.DIRECTORY_PICTURES);
229         File file = new File(path, "DemoPicture.jpg");
230         file.delete();
231     }
232 
hasExternalStoragePublicPicture()233     boolean hasExternalStoragePublicPicture() {
234         // Create a path where we will place our picture in the user's
235         // public pictures directory and check if the file exists.  If
236         // external storage is not currently mounted this will think the
237         // picture doesn't exist.
238         File path = Environment.getExternalStoragePublicDirectory(
239                 Environment.DIRECTORY_PICTURES);
240         File file = new File(path, "DemoPicture.jpg");
241         return file.exists();
242     }
243 // END_INCLUDE(public_picture)
244 
245 // BEGIN_INCLUDE(private_picture)
createExternalStoragePrivatePicture()246     void createExternalStoragePrivatePicture() {
247         // Create a path where we will place our picture in our own private
248         // pictures directory.  Note that we don't really need to place a
249         // picture in DIRECTORY_PICTURES, since the media scanner will see
250         // all media in these directories; this may be useful with other
251         // media types such as DIRECTORY_MUSIC however to help it classify
252         // your media for display to the user.
253         File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
254         File file = new File(path, "DemoPicture.jpg");
255 
256         try {
257             // Very simple code to copy a picture from the application's
258             // resource into the external file.  Note that this code does
259             // no error checking, and assumes the picture is small (does not
260             // try to copy it in chunks).  Note that if external storage is
261             // not currently mounted this will silently fail.
262             InputStream is = getResources().openRawResource(R.drawable.balloons);
263             OutputStream os = new FileOutputStream(file);
264             byte[] data = new byte[is.available()];
265             is.read(data);
266             os.write(data);
267             is.close();
268             os.close();
269 
270             // Tell the media scanner about the new file so that it is
271             // immediately available to the user.
272             MediaScannerConnection.scanFile(this,
273                     new String[] { file.toString() }, null,
274                     new MediaScannerConnection.OnScanCompletedListener() {
275                 public void onScanCompleted(String path, Uri uri) {
276                     Log.i("ExternalStorage", "Scanned " + path + ":");
277                     Log.i("ExternalStorage", "-> uri=" + uri);
278                 }
279             });
280         } catch (IOException e) {
281             // Unable to create file, likely because external storage is
282             // not currently mounted.
283             Log.w("ExternalStorage", "Error writing " + file, e);
284         }
285     }
286 
deleteExternalStoragePrivatePicture()287     void deleteExternalStoragePrivatePicture() {
288         // Create a path where we will place our picture in the user's
289         // public pictures directory and delete the file.  If external
290         // storage is not currently mounted this will fail.
291         File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
292         if (path != null) {
293             File file = new File(path, "DemoPicture.jpg");
294             file.delete();
295         }
296     }
297 
hasExternalStoragePrivatePicture()298     boolean hasExternalStoragePrivatePicture() {
299         // Create a path where we will place our picture in the user's
300         // public pictures directory and check if the file exists.  If
301         // external storage is not currently mounted this will think the
302         // picture doesn't exist.
303         File path = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
304         if (path != null) {
305             File file = new File(path, "DemoPicture.jpg");
306             return file.exists();
307         }
308         return false;
309     }
310 // END_INCLUDE(private_picture)
311 
312 // BEGIN_INCLUDE(private_file)
createExternalStoragePrivateFile()313      void createExternalStoragePrivateFile() {
314          // Create a path where we will place our private file on external
315          // storage.
316          File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
317 
318          try {
319              // Very simple code to copy a picture from the application's
320              // resource into the external file.  Note that this code does
321              // no error checking, and assumes the picture is small (does not
322              // try to copy it in chunks).  Note that if external storage is
323              // not currently mounted this will silently fail.
324              InputStream is = getResources().openRawResource(R.drawable.balloons);
325              OutputStream os = new FileOutputStream(file);
326              byte[] data = new byte[is.available()];
327              is.read(data);
328              os.write(data);
329              is.close();
330              os.close();
331          } catch (IOException e) {
332              // Unable to create file, likely because external storage is
333              // not currently mounted.
334              Log.w("ExternalStorage", "Error writing " + file, e);
335          }
336      }
337 
deleteExternalStoragePrivateFile()338      void deleteExternalStoragePrivateFile() {
339          // Get path for the file on external storage.  If external
340          // storage is not currently mounted this will fail.
341          File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
342          file.delete();
343      }
344 
hasExternalStoragePrivateFile()345      boolean hasExternalStoragePrivateFile() {
346          // Get path for the file on external storage.  If external
347          // storage is not currently mounted this will fail.
348          File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
349          return file.exists();
350      }
351  // END_INCLUDE(private_file)
352 
createStorageControls(CharSequence label, File path, View.OnClickListener createClick, View.OnClickListener deleteClick)353     Item createStorageControls(CharSequence label, File path,
354             View.OnClickListener createClick,
355             View.OnClickListener deleteClick) {
356         LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
357         Item item = new Item();
358         item.mRoot = inflater.inflate(R.layout.external_storage_item, null);
359         TextView tv = (TextView)item.mRoot.findViewById(R.id.label);
360         tv.setText(label);
361         if (path != null) {
362             tv = (TextView)item.mRoot.findViewById(R.id.path);
363             tv.setText(path.toString());
364         }
365         item.mCreate = (Button)item.mRoot.findViewById(R.id.create);
366         item.mCreate.setOnClickListener(createClick);
367         item.mDelete = (Button)item.mRoot.findViewById(R.id.delete);
368         item.mDelete.setOnClickListener(deleteClick);
369         return item;
370     }
371 }
372