├── .google └── packaging.yaml ├── Application ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── example │ │ └── android │ │ └── autobackupsample │ │ ├── AddFileActivity.java │ │ ├── MainActivity.java │ │ ├── MainActivityFragment.java │ │ └── Utils.java │ └── res │ ├── drawable-hdpi │ └── tile.9.png │ ├── layout │ ├── activity_main.xml │ ├── add_file.xml │ ├── file_list_item.xml │ └── fragment_main.xml │ ├── menu │ └── menu_main.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-sw600dp │ ├── template-dimens.xml │ └── template-styles.xml │ ├── values-v11 │ └── template-styles.xml │ ├── values-v21 │ ├── base-colors.xml │ └── base-template-styles.xml │ ├── values-w820dp │ └── dimens.xml │ ├── values │ ├── base-strings.xml │ ├── dimens.xml │ ├── strings.xml │ ├── template-dimens.xml │ └── template-styles.xml │ └── xml │ └── backup.xml ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── screenshots ├── ic_launcher.png └── main.png └── settings.gradle /.google/packaging.yaml: -------------------------------------------------------------------------------- 1 | 2 | # GOOGLE SAMPLE PACKAGING DATA 3 | # 4 | # This file is used by Google as part of our samples packaging process. 5 | # End users may safely ignore this file. It has no relevance to other systems. 6 | --- 7 | status: PUBLISEHD 8 | technologies: [Android] 9 | categories: [Content] 10 | languages: [Java] 11 | solutions: [Mobile] 12 | github: android-Automatic Backup 13 | level: INTERMEDIATE 14 | icon: screenshots/icon-web.png 15 | apiRefs: 16 | - android:android.app.Backup 17 | license: apache2 18 | -------------------------------------------------------------------------------- /Application/build.gradle: -------------------------------------------------------------------------------- 1 | 2 | buildscript { 3 | repositories { 4 | jcenter() 5 | google() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:3.0.1' 10 | } 11 | } 12 | 13 | apply plugin: 'com.android.application' 14 | 15 | repositories { 16 | jcenter() 17 | google() 18 | } 19 | 20 | dependencies { 21 | compile "com.android.support:support-v4:27.0.2" 22 | compile "com.android.support:support-v13:27.0.2" 23 | compile "com.android.support:cardview-v7:27.0.2" 24 | compile "com.android.support:appcompat-v7:27.0.2" 25 | } 26 | 27 | // The sample build uses multiple directories to 28 | // keep boilerplate and common code separate from 29 | // the main sample code. 30 | List dirs = [ 31 | 'main', // main sample code; look here for the interesting stuff. 32 | 'common', // components that are reused by multiple samples 33 | 'template'] // boilerplate code that is generated by the sample template process 34 | 35 | android { 36 | compileSdkVersion 27 37 | 38 | buildToolsVersion "27.0.2" 39 | 40 | defaultConfig { 41 | minSdkVersion 23 42 | targetSdkVersion 27 43 | } 44 | 45 | compileOptions { 46 | sourceCompatibility JavaVersion.VERSION_1_7 47 | targetCompatibility JavaVersion.VERSION_1_7 48 | } 49 | 50 | sourceSets { 51 | main { 52 | dirs.each { dir -> 53 | java.srcDirs "src/${dir}/java" 54 | res.srcDirs "src/${dir}/res" 55 | } 56 | } 57 | androidTest.setRoot('tests') 58 | androidTest.java.srcDirs = ['tests/src'] 59 | 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /Application/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 18 | 19 | 25 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /Application/src/main/java/com/example/android/autobackupsample/AddFileActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 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.autobackupsample; 18 | 19 | import android.app.Activity; 20 | import android.content.Context; 21 | import android.os.Bundle; 22 | import android.text.TextUtils; 23 | import android.util.Log; 24 | import android.view.Gravity; 25 | import android.view.View; 26 | import android.widget.AdapterView; 27 | import android.widget.ArrayAdapter; 28 | import android.widget.EditText; 29 | import android.widget.Spinner; 30 | import android.widget.Toast; 31 | 32 | import com.example.android.autobackupsample.MainActivityFragment; 33 | 34 | import java.io.BufferedOutputStream; 35 | import java.io.File; 36 | import java.io.FileOutputStream; 37 | 38 | /** 39 | * The purpose of AddFileActivity activity is to create a data file based on the 40 | * file name and size parameters specified as an Intent external parameters or with the 41 | * activity UI. 42 | *

43 | * The optional intent parameters are 44 | * {@link com.example.android.autobackupsample.AddFileActivity#FILE_NAME} and 45 | * {@link com.example.android.autobackupsample.AddFileActivity#FILE_SIZE_IN_BYTES}. 46 | * {@link com.example.android.autobackupsample.AddFileActivity#FILE_STORAGE}. 47 | *

48 | * The activity will return an 49 | * {@link com.example.android.autobackupsample.MainActivityFragment#ADD_FILE_RESULT_ERROR} 50 | * if intent parameters are specified incorrectly or it will display Toast messages to the user 51 | * if those parameters are specified via the activity UI. 52 | */ 53 | public class AddFileActivity extends Activity { 54 | 55 | private static final String TAG = "AutoBackupSample"; 56 | 57 | /** 58 | * The intent parameter that specifies a file name. The file name must be unique for the 59 | * application internal directory. 60 | */ 61 | public static final String FILE_NAME = "file_name"; 62 | 63 | /** 64 | * The intent parameter that specifies a file size in bytes. The size must be a number 65 | * larger or equal to 0. 66 | */ 67 | public static final String FILE_SIZE_IN_BYTES = "file_size_in_bytes"; 68 | 69 | /** 70 | * The file storage is an optional parameter. It should be one of these: 71 | * "INTERNAL", "EXTERNAL", "DONOTBACKUP". The default option is "INTERNAL". 72 | */ 73 | public static final String FILE_STORAGE = "file_storage"; 74 | 75 | /** 76 | * A file size multiplier. It is used to calculate the total number of bytes to be added 77 | * to the file. 78 | */ 79 | private int mSizeMultiplier = 1; 80 | 81 | /** 82 | * Defines File Storage options. 83 | */ 84 | private static enum FileStorage { 85 | INTERNAL, 86 | EXTERNAL, 87 | DONOTBACKUP; 88 | } 89 | 90 | /** 91 | * Contains a selected by a user file storage option. 92 | */ 93 | private FileStorage mFileStorage = FileStorage.INTERNAL; 94 | 95 | @Override 96 | public void onCreate(Bundle savedInstanceState) { 97 | super.onCreate(savedInstanceState); 98 | setContentView(R.layout.add_file); 99 | initFileSizeSpinner(); 100 | initFileStorageSpinner(); 101 | } 102 | 103 | @Override 104 | protected void onResume() { 105 | super.onResume(); 106 | // If an intent has extra parameters, create the file and finish the activity. 107 | if (getIntent().hasExtra(FILE_NAME) && getIntent().hasExtra(FILE_SIZE_IN_BYTES)) { 108 | String fileName = getIntent().getStringExtra(FILE_NAME); 109 | String sizeInBytesParamValue = getIntent().getStringExtra(FILE_SIZE_IN_BYTES); 110 | String fileStorageParamValue = FileStorage.INTERNAL.toString(); 111 | 112 | if (getIntent().hasExtra(FILE_STORAGE)) { 113 | fileStorageParamValue = getIntent().getStringExtra(FILE_STORAGE); 114 | } 115 | 116 | if (TextUtils.isEmpty(fileName) || 117 | isFileExists(fileName) || 118 | !isSizeValid(sizeInBytesParamValue) || 119 | !isFileStorageParamValid(fileStorageParamValue)) { 120 | setResult(MainActivityFragment.ADD_FILE_RESULT_ERROR); 121 | finish(); 122 | return; 123 | } 124 | 125 | mFileStorage = FileStorage.valueOf(fileStorageParamValue); 126 | 127 | if (mFileStorage == FileStorage.EXTERNAL && !Utils.isExternalStorageAvailable()) { 128 | setResult(MainActivityFragment.ADD_FILE_RESULT_ERROR); 129 | finish(); 130 | return; 131 | } 132 | 133 | createFileWithRandomDataAndFinishActivity(fileName, mFileStorage, 134 | sizeInBytesParamValue); 135 | } 136 | } 137 | 138 | /** 139 | * A handler function for a Create File button click event. 140 | * 141 | * @param view a reference to the Create File button view. 142 | */ 143 | public void onCreateFileButtonClick(View view) { 144 | EditText fileNameEditText = (EditText) findViewById(R.id.file_name); 145 | EditText fileSizeEditText = (EditText) findViewById(R.id.file_size); 146 | String fileName = fileNameEditText.getText().toString(); 147 | String fileSizeEditTextValue = fileSizeEditText.getText().toString(); 148 | 149 | if (TextUtils.isEmpty(fileName) || isFileExists(fileName)) { 150 | Toast toast = Toast.makeText(this, getText(R.string.file_exists), Toast.LENGTH_LONG); 151 | toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0); 152 | toast.show(); 153 | return; 154 | } 155 | 156 | if (!isSizeValid(fileSizeEditTextValue)) { 157 | Toast toast = Toast.makeText(this, getText(R.string.file_size_is_invalid), 158 | Toast.LENGTH_LONG); 159 | toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0); 160 | toast.show(); 161 | return; 162 | } 163 | 164 | long fileSize = Integer.parseInt(fileSizeEditTextValue) * mSizeMultiplier; 165 | 166 | if (mFileStorage == FileStorage.EXTERNAL && !Utils.isExternalStorageAvailable()) { 167 | Toast toast = Toast.makeText(this, 168 | getText(R.string.external_storage_unavailable), Toast.LENGTH_LONG); 169 | toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0); 170 | toast.show(); 171 | return; 172 | } 173 | 174 | createFileWithRandomDataAndFinishActivity(fileName, mFileStorage, String.valueOf(fileSize)); 175 | } 176 | 177 | private void initFileSizeSpinner() { 178 | Spinner spinner = (Spinner) findViewById(R.id.file_size_spinner); 179 | final ArrayAdapter adapter = 180 | ArrayAdapter.createFromResource(this, R.array.file_size_array, 181 | android.R.layout.simple_spinner_item); 182 | adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 183 | spinner.setAdapter(adapter); 184 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 185 | @Override 186 | public void onItemSelected(AdapterView parent, View view, int position, long id) { 187 | String sizeMeasure = adapter.getItem(position).toString(); 188 | mSizeMultiplier = (int) Math.pow(1024, position); 189 | if (Log.isLoggable(TAG, Log.DEBUG)) { 190 | Log.d(TAG, String.format("Selected: %s, %d", sizeMeasure, 191 | mSizeMultiplier)); 192 | } 193 | } 194 | 195 | @Override 196 | public void onNothingSelected(AdapterView parent) { 197 | 198 | } 199 | }); 200 | } 201 | 202 | private void initFileStorageSpinner() { 203 | Spinner spinner = (Spinner) findViewById(R.id.storage_spinner); 204 | final ArrayAdapter adapter = 205 | ArrayAdapter.createFromResource(this, R.array.file_storage_array, 206 | android.R.layout.simple_spinner_item); 207 | adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); 208 | spinner.setAdapter(adapter); 209 | spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { 210 | @Override 211 | public void onItemSelected(AdapterView parent, View view, int position, long id) { 212 | mFileStorage = FileStorage.values()[position]; 213 | } 214 | 215 | @Override 216 | public void onNothingSelected(AdapterView parent) { 217 | 218 | } 219 | }); 220 | } 221 | 222 | private void createFileWithRandomDataAndFinishActivity(String fileName, FileStorage storage, 223 | String sizeInBytes) { 224 | long size = Long.valueOf(sizeInBytes); 225 | File file = null; 226 | FileOutputStream out = null; 227 | BufferedOutputStream bufOut = null; 228 | try { 229 | switch (storage) { 230 | case INTERNAL: 231 | file = getInternalFile(fileName); 232 | out = openFileOutput(file.getName(), Context.MODE_PRIVATE); 233 | break; 234 | case EXTERNAL: 235 | assert Utils.isExternalStorageAvailable() : 236 | "The external storage is not available"; 237 | File externalAppDir = getExternalFilesDir(null); 238 | file = new File(externalAppDir, fileName); 239 | out = new FileOutputStream(file); 240 | break; 241 | case DONOTBACKUP: 242 | file = new File(getNoBackupFilesDir(), fileName); 243 | out = new FileOutputStream(file); 244 | break; 245 | } 246 | 247 | if (file == null || out == null) { 248 | Log.d(TAG, "Unable to create file output stream"); 249 | // Returning back to the caller activity. 250 | setResult(MainActivityFragment.ADD_FILE_RESULT_ERROR); 251 | finish(); 252 | return; 253 | } 254 | 255 | bufOut = new BufferedOutputStream(out); 256 | for (int i = 0; i < size; i++) { 257 | byte b = (byte) (255 * Math.random()); 258 | bufOut.write(b); 259 | } 260 | 261 | String message = String.format("File created: %s, size: %s bytes", 262 | file.getAbsolutePath(), sizeInBytes); 263 | 264 | Toast toast = Toast.makeText(this, message, Toast.LENGTH_LONG); 265 | toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0); 266 | toast.show(); 267 | Log.d(TAG, message); 268 | 269 | // Returning back to the caller activity. 270 | setResult(MainActivityFragment.ADD_FILE_RESULT_SUCCESS); 271 | finish(); 272 | } catch (Exception e) { 273 | Log.e(TAG, e.getMessage(), e); 274 | // Returning back to the caller activity. 275 | setResult(MainActivityFragment.ADD_FILE_RESULT_ERROR); 276 | finish(); 277 | } finally { 278 | if (bufOut != null) { 279 | try { 280 | bufOut.close(); 281 | } catch (Exception e) { 282 | // Ignore. 283 | } 284 | } 285 | } 286 | } 287 | 288 | private boolean isFileExists(String fileName) { 289 | File file = getInternalFile(fileName); 290 | if (file.exists()) { 291 | if (Log.isLoggable(TAG, Log.DEBUG)) { 292 | Log.d(TAG, "This file exists: " + file.getName()); 293 | } 294 | return true; 295 | } 296 | return false; 297 | } 298 | 299 | private boolean isSizeValid(String sizeInBytesParamValue) { 300 | long sizeInBytes = 0; 301 | try { 302 | sizeInBytes = Long.valueOf(sizeInBytesParamValue); 303 | } catch (NumberFormatException e) { 304 | if (Log.isLoggable(TAG, Log.DEBUG)) { 305 | Log.d(TAG, "Invalid file size: " + sizeInBytesParamValue); 306 | } 307 | return false; 308 | } 309 | 310 | // Validate file size value. It should be 0 or a positive number. 311 | if (sizeInBytes < 0) { 312 | if (Log.isLoggable(TAG, Log.DEBUG)) { 313 | Log.d(TAG, "Invalid file size: " + sizeInBytes); 314 | } 315 | return false; 316 | } 317 | return true; 318 | } 319 | 320 | private boolean isFileStorageParamValid(String fileStorage) { 321 | try { 322 | mFileStorage = FileStorage.valueOf(fileStorage); 323 | } catch (IllegalArgumentException e) { 324 | if (Log.isLoggable(TAG, Log.DEBUG)) { 325 | Log.d(TAG, "Invalid file storage: " + fileStorage); 326 | } 327 | return false; 328 | } 329 | return true; 330 | } 331 | 332 | private File getInternalFile(String fileName) { 333 | File internalAppDir = getFilesDir(); 334 | return new File(internalAppDir, fileName); 335 | } 336 | 337 | } -------------------------------------------------------------------------------- /Application/src/main/java/com/example/android/autobackupsample/MainActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 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.autobackupsample; 18 | 19 | import android.app.Activity; 20 | import android.os.Bundle; 21 | import android.view.Menu; 22 | import android.view.MenuItem; 23 | 24 | 25 | public class MainActivity extends Activity { 26 | 27 | @Override 28 | protected void onCreate(Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.activity_main); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Application/src/main/java/com/example/android/autobackupsample/MainActivityFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 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.autobackupsample; 18 | 19 | import android.app.Fragment; 20 | import android.content.Intent; 21 | import android.os.Bundle; 22 | import android.os.Environment; 23 | import android.util.Log; 24 | import android.view.LayoutInflater; 25 | import android.view.Menu; 26 | import android.view.MenuInflater; 27 | import android.view.MenuItem; 28 | import android.view.View; 29 | import android.view.ViewGroup; 30 | import android.widget.ArrayAdapter; 31 | import android.widget.ListView; 32 | import android.widget.TextView; 33 | 34 | import java.io.File; 35 | import java.text.NumberFormat; 36 | import java.util.ArrayList; 37 | 38 | 39 | /** 40 | * A placeholder fragment containing a simple view. 41 | */ 42 | public class MainActivityFragment extends Fragment { 43 | 44 | private static final String TAG = "AutoBackupSample"; 45 | public static final int ADD_FILE_REQUEST = 1; 46 | public static final int ADD_FILE_RESULT_SUCCESS = 101; 47 | public static final int ADD_FILE_RESULT_ERROR = 102; 48 | 49 | private ArrayAdapter mFilesArrayAdapter; 50 | private ArrayList mFiles; 51 | 52 | public MainActivityFragment() { 53 | } 54 | 55 | @Override 56 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 57 | Bundle savedInstanceState) { 58 | setHasOptionsMenu(true); 59 | return inflater.inflate(R.layout.fragment_main, container, false); 60 | } 61 | 62 | @Override 63 | public void onActivityResult(int requestCode, int resultCode, Intent data) { 64 | super.onActivityResult(requestCode, resultCode, data); 65 | 66 | if (requestCode == ADD_FILE_REQUEST && resultCode == ADD_FILE_RESULT_SUCCESS) { 67 | updateListOfFiles(); 68 | } 69 | } 70 | 71 | @Override 72 | public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 73 | // Inflate the menu; this adds items to the action bar if it is present. 74 | inflater.inflate(R.menu.menu_main, menu); 75 | super.onCreateOptionsMenu(menu, inflater); 76 | } 77 | 78 | @Override 79 | public boolean onOptionsItemSelected(MenuItem item) { 80 | // Handle action bar item clicks here. The action bar will 81 | // automatically handle clicks on the Home/Up button, so long 82 | // as you specify a parent activity in AndroidManifest.xml. 83 | int id = item.getItemId(); 84 | 85 | //noinspection SimplifiableIfStatement 86 | if (id == R.id.action_settings) { 87 | return true; 88 | } else if (id == R.id.action_add_file) { 89 | Intent addFileIntent = new Intent(getActivity(), AddFileActivity.class); 90 | startActivityForResult(addFileIntent, ADD_FILE_REQUEST); 91 | return true; 92 | } 93 | 94 | return super.onOptionsItemSelected(item); 95 | } 96 | 97 | @Override 98 | public void onResume() { 99 | super.onResume(); 100 | if (mFilesArrayAdapter == null) { 101 | mFiles = createListOfFiles(); 102 | mFilesArrayAdapter = new ArrayAdapter(getActivity(), 103 | R.layout.file_list_item, mFiles) { 104 | 105 | @Override 106 | public View getView(int position, View convertView, ViewGroup parent) { 107 | LayoutInflater inflater = LayoutInflater.from(getContext()); 108 | View itemView = inflater.inflate(R.layout.file_list_item, parent, false); 109 | TextView fileNameView = (TextView) itemView.findViewById(R.id.file_name); 110 | String fileName = getItem(position).getAbsolutePath(); 111 | fileNameView.setText(fileName); 112 | TextView fileSize = (TextView) itemView.findViewById(R.id.file_size); 113 | String fileSizeInBytes = NumberFormat.getInstance() 114 | .format(getItem(position).length()); 115 | fileSize.setText(fileSizeInBytes); 116 | return itemView; 117 | } 118 | }; 119 | updateListOfFiles(); 120 | ListView filesListView = (ListView) getView().findViewById(R.id.file_list); 121 | filesListView.setAdapter(mFilesArrayAdapter); 122 | } 123 | } 124 | 125 | private ArrayList createListOfFiles() { 126 | ArrayList listOfFiles = new ArrayList(); 127 | addFilesToList(listOfFiles, getActivity().getFilesDir()); 128 | if (Utils.isExternalStorageAvailable()) { 129 | addFilesToList(listOfFiles, getActivity().getExternalFilesDir(null)); 130 | } 131 | addFilesToList(listOfFiles, getActivity().getNoBackupFilesDir()); 132 | return listOfFiles; 133 | } 134 | 135 | private void addFilesToList(ArrayList listOfFiles, File dir) { 136 | File[] files = dir.listFiles(); 137 | for (File file: files) { 138 | listOfFiles.add(file); 139 | } 140 | } 141 | 142 | public void updateListOfFiles() { 143 | TextView emptyFileListMessage = 144 | (TextView) getView().findViewById(R.id.empty_file_list_message); 145 | mFiles = createListOfFiles(); 146 | if (mFilesArrayAdapter.getCount() > 0) { 147 | mFilesArrayAdapter.clear(); 148 | } 149 | for (File file: mFiles) { 150 | mFilesArrayAdapter.add(file); 151 | } 152 | // Display a message instructing to add files if no files found. 153 | if (mFiles.size() == 0) { 154 | emptyFileListMessage.setVisibility(View.VISIBLE); 155 | } else { 156 | emptyFileListMessage.setVisibility(View.GONE); 157 | } 158 | } 159 | } 160 | 161 | -------------------------------------------------------------------------------- /Application/src/main/java/com/example/android/autobackupsample/Utils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 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.autobackupsample; 18 | 19 | import android.os.Environment; 20 | import android.util.Log; 21 | 22 | /** 23 | * Utility methods for the app. 24 | */ 25 | public class Utils { 26 | 27 | private static final String TAG = "AutoBackupSample"; 28 | 29 | public static boolean isExternalStorageAvailable() { 30 | String state = Environment.getExternalStorageState(); 31 | if (!Environment.MEDIA_MOUNTED.equals(state)) { 32 | Log.d(TAG, "The external storage is not available."); 33 | return false; 34 | } 35 | return true; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Application/src/main/res/drawable-hdpi/tile.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/googlearchive/android-AutoBackupForApps/5b7eee01d71c250a5edf6956df4a7d8fce285075/Application/src/main/res/drawable-hdpi/tile.9.png -------------------------------------------------------------------------------- /Application/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 21 | -------------------------------------------------------------------------------- /Application/src/main/res/layout/add_file.xml: -------------------------------------------------------------------------------- 1 | 2 | 16 | 20 | 21 | 25 | 26 | 27 | 37 | 38 | 46 | 47 | 48 | 57 | 58 | 67 | 68 | 77 | 78 | 79 | 90 | 91 | 98 | 99 |