• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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.android.fmradio.dialogs;
18 
19 import android.app.Activity;
20 import android.app.AlertDialog;
21 import android.app.Dialog;
22 import android.app.DialogFragment;
23 import android.content.DialogInterface;
24 import android.os.Bundle;
25 import android.text.Editable;
26 import android.text.TextWatcher;
27 import android.view.View;
28 import android.view.View.OnClickListener;
29 import android.view.WindowManager;
30 import android.widget.Button;
31 import android.widget.EditText;
32 import android.widget.Toast;
33 
34 import com.android.fmradio.FmRecorder;
35 import com.android.fmradio.FmService;
36 import com.android.fmradio.R;
37 
38 import java.io.File;
39 
40 /**
41  * The dialog fragment for save recording file
42  */
43 public class FmSaveDialog extends DialogFragment {
44     private static final String TAG = "FmSaveDialog";
45 
46     // save recording file button
47     private Button mButtonSave = null;
48     // discard recording file button
49     private Button mButtonDiscard = null;
50     // rename recording file edit text
51     private EditText mRecordingNameEditText = null;
52     // recording file default name
53     private String mDefaultRecordingName = null;
54     // recording file to save name
55     private String mRecordingNameToSave = null;
56     private OnRecordingDialogClickListener mListener = null;
57 
58     // The default filename need't to check whether exist
59     private boolean mIsNeedCheckFilenameExist = false;
60     // record sd card path when start recording
61     private String mRecordingSdcard = null;
62 
63     private String mRecordingFileName = null;
64 
65     private String mTempRecordingName = null;
66 
67     /**
68      * FM record dialog fragment, because fragment manager need empty
69      * constructor to instantiated this dialog fragment when configuration
70      * change
71      */
FmSaveDialog()72     public FmSaveDialog() {
73     }
74 
75     /**
76      * FM record dialog fragment according name, should pass value recording
77      * file name
78      *
79      * @param defaultName The default file name in FileSystem
80      * @param recordingName The name in the dialog for show and save
81      */
FmSaveDialog(String sdcard, String defaultName, String recordingName)82     public FmSaveDialog(String sdcard, String defaultName, String recordingName) {
83         mRecordingSdcard = sdcard;
84         mTempRecordingName = defaultName + FmRecorder.RECORDING_FILE_EXTENSION;
85         mDefaultRecordingName = recordingName;
86         mRecordingNameToSave = recordingName;
87     }
88 
89     @Override
onAttach(Activity activity)90     public void onAttach(Activity activity) {
91         super.onAttach(activity);
92         try {
93             mListener = (OnRecordingDialogClickListener) activity;
94         } catch (ClassCastException e) {
95             e.printStackTrace();
96         }
97     }
98 
99     @Override
onCreateDialog(Bundle savedInstanceState)100     public Dialog onCreateDialog(Bundle savedInstanceState) {
101         if (savedInstanceState != null) {
102             mRecordingNameToSave = savedInstanceState.getString("record_file_name");
103             mDefaultRecordingName = savedInstanceState.getString("record_default_name");
104             mRecordingSdcard = FmService.getRecordingSdcard();
105         }
106         setStyle(STYLE_NO_TITLE, 0);
107         View view =  getActivity().getLayoutInflater().inflate(R.layout.save_dialog, null);
108         mButtonSave = (Button) view.findViewById(R.id.save_dialog_button_save);
109         mButtonSave.setOnClickListener(mButtonOnClickListener);
110 
111         mButtonDiscard = (Button) view.findViewById(R.id.save_dialog_button_discard);
112         mButtonDiscard.setOnClickListener(mButtonOnClickListener);
113 
114         // Set the recording edit text
115         mRecordingNameEditText = (EditText) view.findViewById(R.id.save_dialog_edittext);
116         AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()).setView(view);
117         return builder.create();
118     }
119 
120     @Override
onDismiss(DialogInterface dialog)121     public void onDismiss(DialogInterface dialog) {
122         super.onDismiss(dialog);
123         if (mListener != null) {
124             mListener.onRecordingDialogClick(mRecordingFileName);
125             mListener = null;
126         }
127     }
128 
129     /**
130      * Set the dialog edit text and other attribute
131      */
132     @Override
onResume()133     public void onResume() {
134         super.onResume();
135         // have define in fm_recorder_dialog.xml length at most
136         // 250(maxFileLength - suffixLength)
137         if (mDefaultRecordingName != null) {
138             if (null != mRecordingNameToSave) {
139                 // this case just for,fragment recreate
140                 mRecordingNameEditText.setText(mRecordingNameToSave);
141                 if ("".equals(mRecordingNameToSave)) {
142                     mButtonSave.setEnabled(false);
143                 }
144             } else {
145                 mRecordingNameEditText.setText(mDefaultRecordingName);
146             }
147         }
148 
149         mRecordingNameEditText.requestFocus();
150         setTextChangedCallback();
151         Dialog dialog = getDialog();
152         dialog.setCanceledOnTouchOutside(false);
153         dialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE
154                         | WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
155     }
156 
157     @Override
onSaveInstanceState(Bundle outState)158     public void onSaveInstanceState(Bundle outState) {
159         outState.putString("record_file_name", mRecordingNameToSave);
160         outState.putString("record_default_name", mDefaultRecordingName);
161         super.onSaveInstanceState(outState);
162     }
163 
164     /**
165      * This method register callback and set filter to Edit, in order to make
166      * sure that user input is legal. The input can't be illegal filename and
167      * can't be too long.
168      */
setTextChangedCallback()169     private void setTextChangedCallback() {
170         mRecordingNameEditText.addTextChangedListener(new TextWatcher() {
171             // not use, so don't need to implement it
172             @Override
173             public void afterTextChanged(Editable arg0) {
174             }
175 
176             // not use, so don't need to implement it
177             @Override
178             public void beforeTextChanged(CharSequence s, int start, int count, int after) {
179             }
180 
181             /**
182              * check user input whether include invalid character
183              */
184             @Override
185             public void onTextChanged(CharSequence s, int start, int before, int count) {
186                 // Filename changed, so we should check the new filename is
187                 // whether exist.
188                 mIsNeedCheckFilenameExist = true;
189                 String recordName = s.toString().trim();
190                 // Characters not allowed by file system
191                 if (recordName.length() <= 0
192                         || recordName.startsWith(".")
193                         || recordName.matches(".*[/\\\\:*?\"<>|\t].*")) {
194                     mButtonSave.setEnabled(false);
195                 } else {
196                     mButtonSave.setEnabled(true);
197                 }
198 
199                 mRecordingNameToSave = mRecordingNameEditText.getText().toString().trim();
200             }
201         });
202     }
203 
204     private OnClickListener mButtonOnClickListener = new OnClickListener() {
205         /**
206          * Define the button operation
207          */
208         @Override
209         public void onClick(View v) {
210 
211             File recordingFolderPath = new File(mRecordingSdcard, "FM Recording");
212 
213             switch (v.getId()) {
214                 case R.id.save_dialog_button_save:
215                 String msg = null;
216                 // Check the recording name whether exist
217                 mRecordingNameToSave = mRecordingNameEditText.getText().toString().trim();
218                 File recordingFileToSave = new File(recordingFolderPath, mRecordingNameToSave
219                                 + FmRecorder.RECORDING_FILE_EXTENSION);
220 
221                 if (mRecordingNameToSave.equals(mDefaultRecordingName)) {
222                     mIsNeedCheckFilenameExist = false;
223                 } else {
224                     mIsNeedCheckFilenameExist = true;
225                 }
226 
227                 if (recordingFileToSave.exists() && mIsNeedCheckFilenameExist) {
228                     // show a toast notification if can't renaming a file/folder
229                     // to the same name
230                     msg = mRecordingNameEditText.getText().toString() + " "
231                             + getActivity().getResources().getString(R.string.already_exists);
232                     Toast.makeText(getActivity(), msg, Toast.LENGTH_SHORT).show();
233                 } else {
234                     mRecordingFileName = mRecordingNameToSave;
235                     dismissAllowingStateLoss();
236                 }
237                 break;
238 
239                 case R.id.save_dialog_button_discard:
240                     dismissAllowingStateLoss();
241                     // here need delete discarded recording file
242                     File needToDelete = new File(recordingFolderPath, mTempRecordingName);
243                     if (needToDelete.exists()) {
244                         needToDelete.delete();
245                     }
246                     break;
247 
248                 default:
249                     break;
250             }
251         }
252     };
253 
254     /**
255      * The listener for click Save or Discard
256      */
257     public interface OnRecordingDialogClickListener {
258         /**
259          * Record dialog click callback
260          *
261          * @param recordingName The user input recording name
262          */
onRecordingDialogClick(String recordingName)263         void onRecordingDialogClick(String recordingName);
264     }
265 }
266