Skip to content

Most visited

Recently visited

navigation
AutoBackupForApps / src / 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
 * <p/>
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
 * <p/>
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<CharSequence> 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<CharSequence> 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 fil