Home | History | Annotate | Download | only in content
      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
     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
    122     protected void onDestroy() {
    123         super.onDestroy();
    124         stopWatchingExternalStorage();
    125     }
    126 
    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 
    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 
    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 
    173     void stopWatchingExternalStorage() {
    174         unregisterReceiver(mExternalStorageReceiver);
    175     }
    176  // END_INCLUDE(monitor_storage)
    177 
    178  // BEGIN_INCLUDE(public_picture)
    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 
    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 
    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)
    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 
    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 
    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)
    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 
    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          if (file != null) {
    343              file.delete();
    344          }
    345      }
    346 
    347      boolean hasExternalStoragePrivateFile() {
    348          // Get path for the file on external storage.  If external
    349          // storage is not currently mounted this will fail.
    350          File file = new File(getExternalFilesDir(null), "DemoFile.jpg");
    351          if (file != null) {
    352              return file.exists();
    353          }
    354          return false;
    355      }
    356  // END_INCLUDE(private_file)
    357 
    358     Item createStorageControls(CharSequence label, File path,
    359             View.OnClickListener createClick,
    360             View.OnClickListener deleteClick) {
    361         LayoutInflater inflater = (LayoutInflater)getSystemService(LAYOUT_INFLATER_SERVICE);
    362         Item item = new Item();
    363         item.mRoot = inflater.inflate(R.layout.external_storage_item, null);
    364         TextView tv = (TextView)item.mRoot.findViewById(R.id.label);
    365         tv.setText(label);
    366         if (path != null) {
    367             tv = (TextView)item.mRoot.findViewById(R.id.path);
    368             tv.setText(path.toString());
    369         }
    370         item.mCreate = (Button)item.mRoot.findViewById(R.id.create);
    371         item.mCreate.setOnClickListener(createClick);
    372         item.mDelete = (Button)item.mRoot.findViewById(R.id.delete);
    373         item.mDelete.setOnClickListener(deleteClick);
    374         return item;
    375     }
    376 }
    377