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