Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 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; |
| 18 | |
| 19 | import android.app.Activity; |
| 20 | import android.app.FragmentManager; |
| 21 | import android.app.Notification; |
| 22 | import android.app.Notification.Builder; |
| 23 | import android.app.PendingIntent; |
| 24 | import android.content.ComponentName; |
| 25 | import android.content.ContentResolver; |
| 26 | import android.content.ContentUris; |
| 27 | import android.content.Context; |
| 28 | import android.content.Intent; |
| 29 | import android.content.ServiceConnection; |
| 30 | import android.database.ContentObserver; |
| 31 | import android.database.Cursor; |
| 32 | import android.graphics.Bitmap; |
| 33 | import android.net.Uri; |
| 34 | import android.os.Bundle; |
| 35 | import android.os.Handler; |
| 36 | import android.os.Message; |
| 37 | import android.text.TextUtils; |
| 38 | import android.util.Log; |
| 39 | import android.view.View; |
| 40 | import android.widget.Button; |
| 41 | import android.widget.TextView; |
| 42 | import android.widget.Toast; |
| 43 | |
| 44 | import com.android.fmradio.FmStation.Station; |
| 45 | import com.android.fmradio.dialogs.FmSaveDialog; |
| 46 | import com.android.fmradio.views.FmVisualizerView; |
| 47 | |
| 48 | import java.io.File; |
| 49 | import java.text.SimpleDateFormat; |
| 50 | import java.util.Date; |
| 51 | import java.util.Locale; |
| 52 | |
| 53 | /** |
| 54 | * This class interact with user, FM recording function. |
| 55 | */ |
| 56 | public class FmRecordActivity extends Activity implements |
| 57 | FmSaveDialog.OnRecordingDialogClickListener { |
Benson Huang | 8303243 | 2014-12-25 16:35:27 +0800 | [diff] [blame] | 58 | private static final String TAG = "FmRecordActivity"; |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 59 | |
Benson Huang | 8303243 | 2014-12-25 16:35:27 +0800 | [diff] [blame] | 60 | private static final String FM_STOP_RECORDING = "fmradio.stop.recording"; |
| 61 | private static final String FM_ENTER_RECORD_SCREEN = "fmradio.enter.record.screen"; |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 62 | private static final String TAG_SAVE_RECORDINGD = "SaveRecording"; |
| 63 | private static final int MSG_UPDATE_NOTIFICATION = 1000; |
Benson Huang | ec7335d | 2014-12-24 14:58:24 +0800 | [diff] [blame] | 64 | private static final int TIME_BASE = 60; |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 65 | private Context mContext; |
| 66 | private TextView mMintues; |
| 67 | private TextView mSeconds; |
| 68 | private TextView mFrequency; |
| 69 | private View mStationInfoLayout; |
| 70 | private TextView mStationName; |
| 71 | private TextView mRadioText; |
| 72 | private Button mStopRecordButton; |
| 73 | private FmVisualizerView mPlayIndicator; |
| 74 | private FmService mService = null; |
| 75 | private FragmentManager mFragmentManager; |
| 76 | private boolean mIsInBackground = false; |
| 77 | private int mRecordState = FmRecorder.STATE_INVALID; |
| 78 | private int mCurrentStation = FmUtils.DEFAULT_STATION; |
| 79 | private Notification.Builder mNotificationBuilder = null; |
| 80 | |
| 81 | @Override |
| 82 | protected void onCreate(Bundle savedInstanceState) { |
| 83 | super.onCreate(savedInstanceState); |
| 84 | Log.d(TAG, "onCreate"); |
| 85 | mContext = getApplicationContext(); |
| 86 | mFragmentManager = getFragmentManager(); |
| 87 | setContentView(R.layout.fm_record_activity); |
| 88 | |
| 89 | mMintues = (TextView) findViewById(R.id.minutes); |
| 90 | mSeconds = (TextView) findViewById(R.id.seconds); |
| 91 | |
| 92 | mFrequency = (TextView) findViewById(R.id.frequency); |
| 93 | mStationInfoLayout = findViewById(R.id.station_name_rt); |
| 94 | mStationName = (TextView) findViewById(R.id.station_name); |
| 95 | mRadioText = (TextView) findViewById(R.id.radio_text); |
| 96 | |
| 97 | mStopRecordButton = (Button) findViewById(R.id.btn_stop_record); |
| 98 | mStopRecordButton.setEnabled(false); |
| 99 | mStopRecordButton.setOnClickListener(new View.OnClickListener() { |
| 100 | @Override |
| 101 | public void onClick(View v) { |
| 102 | // Stop recording and wait service notify stop record state to show dialog |
| 103 | mService.stopRecordingAsync(); |
| 104 | } |
| 105 | }); |
| 106 | |
| 107 | mPlayIndicator = (FmVisualizerView) findViewById(R.id.fm_play_indicator); |
| 108 | |
| 109 | if (savedInstanceState != null) { |
| 110 | mCurrentStation = savedInstanceState.getInt(FmStation.CURRENT_STATION); |
| 111 | mRecordState = savedInstanceState.getInt("last_record_state"); |
| 112 | } else { |
| 113 | Intent intent = getIntent(); |
| 114 | mCurrentStation = intent.getIntExtra(FmStation.CURRENT_STATION, |
| 115 | FmUtils.DEFAULT_STATION); |
| 116 | mRecordState = intent.getIntExtra("last_record_state", FmRecorder.STATE_INVALID); |
| 117 | } |
| 118 | bindService(new Intent(this, FmService.class), mServiceConnection, |
| 119 | Context.BIND_AUTO_CREATE); |
| 120 | updateUi(); |
| 121 | } |
| 122 | |
| 123 | private void updateUi() { |
| 124 | // TODO it's on UI thread, change to sub thread |
| 125 | ContentResolver resolver = mContext.getContentResolver(); |
| 126 | mFrequency.setText("FM " + FmUtils.formatStation(mCurrentStation)); |
| 127 | Cursor cursor = null; |
| 128 | try { |
| 129 | cursor = resolver.query( |
| 130 | Station.CONTENT_URI, |
| 131 | FmStation.COLUMNS, |
| 132 | Station.FREQUENCY + "=?", |
| 133 | new String[] { String.valueOf(mCurrentStation) }, |
| 134 | null); |
| 135 | if (cursor != null && cursor.moveToFirst()) { |
| 136 | // If the station name does not exist, show program service(PS) instead |
| 137 | String stationName = cursor.getString(cursor.getColumnIndex(Station.STATION_NAME)); |
| 138 | if (TextUtils.isEmpty(stationName)) { |
| 139 | stationName = cursor.getString(cursor.getColumnIndex(Station.PROGRAM_SERVICE)); |
| 140 | } |
| 141 | String radioText = cursor.getString(cursor.getColumnIndex(Station.RADIO_TEXT)); |
| 142 | mStationName.setText(stationName); |
| 143 | mRadioText.setText(radioText); |
| 144 | int id = cursor.getInt(cursor.getColumnIndex(Station._ID)); |
| 145 | resolver.registerContentObserver( |
| 146 | ContentUris.withAppendedId(Station.CONTENT_URI, id), false, |
| 147 | mContentObserver); |
| 148 | // If no station name and no radio text, hide the view |
| 149 | if ((!TextUtils.isEmpty(stationName)) |
| 150 | || (!TextUtils.isEmpty(radioText))) { |
| 151 | mStationInfoLayout.setVisibility(View.VISIBLE); |
| 152 | } else { |
| 153 | mStationInfoLayout.setVisibility(View.GONE); |
| 154 | } |
| 155 | Log.d(TAG, "updateUi, frequency = " + mCurrentStation + ", stationName = " |
| 156 | + stationName + ", radioText = " + radioText); |
| 157 | } |
| 158 | } finally { |
| 159 | if (cursor != null) { |
| 160 | cursor.close(); |
| 161 | } |
| 162 | } |
| 163 | } |
| 164 | |
Benson Huang | ff42d62 | 2014-12-15 17:31:17 +0800 | [diff] [blame] | 165 | private void updateRecordingNotification(long recordTime) { |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 166 | if (mNotificationBuilder == null) { |
Benson Huang | 8303243 | 2014-12-25 16:35:27 +0800 | [diff] [blame] | 167 | Intent intent = new Intent(FM_STOP_RECORDING); |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 168 | intent.setClass(mContext, FmRecordActivity.class); |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 169 | intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
| 170 | PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0, intent, |
| 171 | PendingIntent.FLAG_UPDATE_CURRENT); |
| 172 | |
| 173 | Bitmap largeIcon = FmUtils.createNotificationLargeIcon(mContext, |
| 174 | FmUtils.formatStation(mCurrentStation)); |
| 175 | mNotificationBuilder = new Builder(this) |
| 176 | .setContentText(getText(R.string.record_notification_message)) |
| 177 | .setShowWhen(false) |
| 178 | .setAutoCancel(true) |
| 179 | .setSmallIcon(R.drawable.ic_launcher) |
| 180 | .setLargeIcon(largeIcon) |
| 181 | .addAction(R.drawable.btn_fm_rec_stop_enabled, getText(R.string.stop_record), |
| 182 | pendingIntent); |
Benson Huang | ff42d62 | 2014-12-15 17:31:17 +0800 | [diff] [blame] | 183 | |
Benson Huang | 8303243 | 2014-12-25 16:35:27 +0800 | [diff] [blame] | 184 | Intent cIntent = new Intent(FM_ENTER_RECORD_SCREEN); |
Benson Huang | ff42d62 | 2014-12-15 17:31:17 +0800 | [diff] [blame] | 185 | cIntent.setClass(mContext, FmRecordActivity.class); |
| 186 | cIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
| 187 | PendingIntent contentPendingIntent = PendingIntent.getActivity(mContext, 0, cIntent, |
| 188 | PendingIntent.FLAG_UPDATE_CURRENT); |
| 189 | mNotificationBuilder.setContentIntent(contentPendingIntent); |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 190 | } |
| 191 | // Format record time to show on title |
| 192 | Date date = new Date(recordTime); |
| 193 | SimpleDateFormat simpleDateFormat = new SimpleDateFormat("mm:ss", Locale.ENGLISH); |
| 194 | String time = simpleDateFormat.format(date); |
| 195 | |
| 196 | mNotificationBuilder.setContentTitle(time); |
| 197 | if (mService != null) { |
| 198 | mService.showRecordingNotification(mNotificationBuilder.build()); |
| 199 | } |
| 200 | } |
| 201 | |
| 202 | @Override |
| 203 | public void onNewIntent(Intent intent) { |
Benson Huang | 8303243 | 2014-12-25 16:35:27 +0800 | [diff] [blame] | 204 | if (intent != null && intent.getAction() != null) { |
| 205 | String action = intent.getAction(); |
| 206 | if (FM_STOP_RECORDING.equals(action)) { |
| 207 | // If click stop button in notification, need to stop recording |
| 208 | if (mService != null && !isStopRecording()) { |
| 209 | mService.stopRecordingAsync(); |
| 210 | } |
| 211 | } else if (FM_ENTER_RECORD_SCREEN.equals(action)) { |
| 212 | // Just enter record screen, do nothing |
| 213 | } |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 214 | } |
| 215 | } |
| 216 | |
| 217 | @Override |
| 218 | protected void onResume() { |
| 219 | super.onResume(); |
| 220 | mIsInBackground = false; |
Benson Huang | 3dfd9a9 | 2014-12-22 11:09:27 +0800 | [diff] [blame] | 221 | if (null != mService) { |
| 222 | mService.setFmRecordActivityForeground(true); |
| 223 | } |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 224 | // Show save dialog if record has stopped and never show it before. |
| 225 | if (isStopRecording() && !isSaveDialogShown()) { |
| 226 | showSaveDialog(); |
| 227 | } |
| 228 | // Trigger to refreshing timer text if still in record |
| 229 | if (!isStopRecording()) { |
Benson Huang | ec7335d | 2014-12-24 14:58:24 +0800 | [diff] [blame] | 230 | mHandler.removeMessages(FmListener.MSGID_REFRESH); |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 231 | mHandler.sendEmptyMessage(FmListener.MSGID_REFRESH); |
| 232 | } |
| 233 | // Clear notification, it only need show when in background |
| 234 | removeNotification(); |
| 235 | } |
| 236 | |
| 237 | @Override |
| 238 | protected void onPause() { |
| 239 | super.onPause(); |
| 240 | mIsInBackground = true; |
Benson Huang | 3dfd9a9 | 2014-12-22 11:09:27 +0800 | [diff] [blame] | 241 | if (null != mService) { |
| 242 | mService.setFmRecordActivityForeground(false); |
| 243 | } |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 244 | // Stop refreshing timer text |
| 245 | mHandler.removeMessages(FmListener.MSGID_REFRESH); |
| 246 | // Show notification when switch to background |
| 247 | showNotification(); |
| 248 | } |
| 249 | |
| 250 | private void showNotification() { |
| 251 | // If have stopped recording, need not show notification |
| 252 | if (!isStopRecording()) { |
| 253 | mHandler.sendEmptyMessage(MSG_UPDATE_NOTIFICATION); |
Benson Huang | 59668c1 | 2015-01-14 10:35:41 +0800 | [diff] [blame] | 254 | } else if (isSaveDialogShown()) { |
| 255 | // Only when save dialog is shown and FM radio is back to background, |
| 256 | // it is necessary to update playing notification. |
| 257 | // Otherwise, FmMainActivity will update playing notification. |
| 258 | mService.updatePlayingNotification(); |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 259 | } |
| 260 | } |
| 261 | |
| 262 | private void removeNotification() { |
| 263 | mHandler.removeMessages(MSG_UPDATE_NOTIFICATION); |
| 264 | if (mService != null) { |
| 265 | mService.removeNotification(); |
Benson Huang | 3cf7f5a | 2015-01-14 10:55:45 +0800 | [diff] [blame] | 266 | mService.updatePlayingNotification(); |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 267 | } |
| 268 | } |
| 269 | |
| 270 | @Override |
| 271 | protected void onSaveInstanceState(Bundle outState) { |
| 272 | outState.putInt(FmStation.CURRENT_STATION, mCurrentStation); |
| 273 | outState.putInt("last_record_state", mRecordState); |
| 274 | super.onSaveInstanceState(outState); |
| 275 | } |
| 276 | |
| 277 | @Override |
| 278 | protected void onDestroy() { |
| 279 | removeNotification(); |
| 280 | mHandler.removeCallbacksAndMessages(null); |
| 281 | if (mService != null) { |
| 282 | mService.unregisterFmRadioListener(mFmListener); |
| 283 | } |
| 284 | unbindService(mServiceConnection); |
| 285 | mContext.getContentResolver().unregisterContentObserver(mContentObserver); |
| 286 | super.onDestroy(); |
| 287 | } |
| 288 | |
| 289 | /** |
| 290 | * Recording dialog click |
| 291 | * |
| 292 | * @param recordingName The new recording name |
| 293 | */ |
| 294 | @Override |
| 295 | public void onRecordingDialogClick( |
| 296 | String recordingName) { |
| 297 | // Happen when activity recreate, such as switch language |
| 298 | if (mIsInBackground) { |
| 299 | return; |
| 300 | } |
| 301 | |
| 302 | if (recordingName != null && mService != null) { |
| 303 | mService.saveRecordingAsync(recordingName); |
| 304 | returnResult(recordingName, getString(R.string.toast_record_saved)); |
| 305 | } else { |
| 306 | returnResult(null, getString(R.string.toast_record_not_saved)); |
| 307 | } |
| 308 | finish(); |
| 309 | } |
| 310 | |
| 311 | @Override |
| 312 | public void onBackPressed() { |
| 313 | if (mService != null & !isStopRecording()) { |
| 314 | // Stop recording and wait service notify stop record state to show dialog |
| 315 | mService.stopRecordingAsync(); |
| 316 | return; |
| 317 | } |
| 318 | super.onBackPressed(); |
| 319 | } |
| 320 | |
| 321 | private final ServiceConnection mServiceConnection = new ServiceConnection() { |
| 322 | @Override |
| 323 | public void onServiceConnected(ComponentName name, android.os.IBinder service) { |
| 324 | mService = ((FmService.ServiceBinder) service).getService(); |
| 325 | mService.registerFmRadioListener(mFmListener); |
Benson Huang | 3dfd9a9 | 2014-12-22 11:09:27 +0800 | [diff] [blame] | 326 | mService.setFmRecordActivityForeground(!mIsInBackground); |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 327 | // 1. If have stopped recording, we need check whether need show save dialog again. |
| 328 | // Because when stop recording in background, we need show it when switch to foreground. |
| 329 | if (isStopRecording()) { |
| 330 | if (!isSaveDialogShown()) { |
| 331 | showSaveDialog(); |
| 332 | } |
| 333 | return; |
| 334 | } |
| 335 | // 2. If not start recording, start it directly, this case happen when start this |
| 336 | // activity from main fm activity. |
| 337 | if (!isStartRecording()) { |
| 338 | mService.startRecordingAsync(); |
| 339 | } |
| 340 | mPlayIndicator.startAnimation(); |
| 341 | mStopRecordButton.setEnabled(true); |
Benson Huang | ec7335d | 2014-12-24 14:58:24 +0800 | [diff] [blame] | 342 | mHandler.removeMessages(FmListener.MSGID_REFRESH); |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 343 | mHandler.sendEmptyMessage(FmListener.MSGID_REFRESH); |
| 344 | }; |
| 345 | |
| 346 | @Override |
| 347 | public void onServiceDisconnected(android.content.ComponentName name) { |
| 348 | mService = null; |
| 349 | }; |
| 350 | }; |
| 351 | |
Benson Huang | ec7335d | 2014-12-24 14:58:24 +0800 | [diff] [blame] | 352 | private String addPaddingForString(long time) { |
| 353 | StringBuilder builder = new StringBuilder(); |
| 354 | if (time >= 0 && time < 10) { |
| 355 | builder.append("0"); |
| 356 | } |
| 357 | return builder.append(time).toString(); |
| 358 | } |
| 359 | |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 360 | private final Handler mHandler = new Handler() { |
| 361 | @Override |
| 362 | public void handleMessage(Message msg) { |
| 363 | switch (msg.what) { |
| 364 | case FmListener.MSGID_REFRESH: |
| 365 | if (mService != null) { |
Benson Huang | 3cf7f5a | 2015-01-14 10:55:45 +0800 | [diff] [blame] | 366 | long recordTimeInMillis = mService.getRecordTime(); |
| 367 | long recordTimeInSec = recordTimeInMillis / 1000L; |
| 368 | mMintues.setText(addPaddingForString(recordTimeInSec / TIME_BASE)); |
| 369 | mSeconds.setText(addPaddingForString(recordTimeInSec % TIME_BASE)); |
| 370 | checkStorageSpaceAndStop(); |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 371 | } |
| 372 | mHandler.sendEmptyMessageDelayed(FmListener.MSGID_REFRESH, 1000); |
| 373 | break; |
| 374 | |
| 375 | case MSG_UPDATE_NOTIFICATION: |
| 376 | if (mService != null) { |
Benson Huang | ff42d62 | 2014-12-15 17:31:17 +0800 | [diff] [blame] | 377 | updateRecordingNotification(mService.getRecordTime()); |
Benson Huang | 3cf7f5a | 2015-01-14 10:55:45 +0800 | [diff] [blame] | 378 | checkStorageSpaceAndStop(); |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 379 | } |
| 380 | mHandler.sendEmptyMessageDelayed(MSG_UPDATE_NOTIFICATION, 1000); |
| 381 | break; |
| 382 | |
| 383 | case FmListener.LISTEN_RECORDSTATE_CHANGED: |
| 384 | // State change from STATE_INVALID to STATE_RECORDING mean begin recording |
| 385 | // State change from STATE_RECORDING to STATE_IDLE mean stop recording |
| 386 | int newState = mService.getRecorderState(); |
| 387 | Log.d(TAG, "handleMessage, record state changed: newState = " + newState |
| 388 | + ", mRecordState = " + mRecordState); |
| 389 | if (mRecordState == FmRecorder.STATE_INVALID |
| 390 | && newState == FmRecorder.STATE_RECORDING) { |
| 391 | mRecordState = FmRecorder.STATE_RECORDING; |
| 392 | } else if (mRecordState == FmRecorder.STATE_RECORDING |
| 393 | && newState == FmRecorder.STATE_IDLE) { |
| 394 | mRecordState = FmRecorder.STATE_IDLE; |
| 395 | mPlayIndicator.stopAnimation(); |
| 396 | showSaveDialog(); |
| 397 | } |
| 398 | break; |
| 399 | |
| 400 | case FmListener.LISTEN_RECORDERROR: |
| 401 | Bundle bundle = msg.getData(); |
| 402 | int errorType = bundle.getInt(FmListener.KEY_RECORDING_ERROR_TYPE); |
| 403 | handleRecordError(errorType); |
| 404 | break; |
| 405 | |
| 406 | default: |
| 407 | break; |
| 408 | } |
| 409 | }; |
| 410 | }; |
| 411 | |
Benson Huang | 3cf7f5a | 2015-01-14 10:55:45 +0800 | [diff] [blame] | 412 | private void checkStorageSpaceAndStop() { |
| 413 | long recordTimeInMillis = mService.getRecordTime(); |
| 414 | long recordTimeInSec = recordTimeInMillis / 1000L; |
| 415 | // Check storage free space |
| 416 | String recordingSdcard = FmUtils.getDefaultStoragePath(); |
| 417 | if (!FmUtils.hasEnoughSpace(recordingSdcard)) { |
| 418 | // Need to record more than 1s. |
| 419 | // Avoid calling MediaRecorder.stop() before native record starts. |
| 420 | if (recordTimeInSec >= 1) { |
| 421 | // Insufficient storage |
| 422 | mService.stopRecordingAsync(); |
| 423 | Toast.makeText(FmRecordActivity.this, |
| 424 | R.string.toast_sdcard_insufficient_space, |
| 425 | Toast.LENGTH_SHORT).show(); |
| 426 | } |
| 427 | } |
| 428 | } |
| 429 | |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 430 | private void handleRecordError(int errorType) { |
| 431 | Log.d(TAG, "handleRecordError, errorType = " + errorType); |
| 432 | String showString = null; |
| 433 | switch (errorType) { |
| 434 | case FmRecorder.ERROR_SDCARD_NOT_PRESENT: |
| 435 | showString = getString(R.string.toast_sdcard_missing); |
Benson Huang | bdcdbb3 | 2014-12-03 19:34:40 +0800 | [diff] [blame] | 436 | returnResult(null, showString); |
| 437 | finish(); |
| 438 | break; |
| 439 | |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 440 | case FmRecorder.ERROR_SDCARD_INSUFFICIENT_SPACE: |
| 441 | showString = getString(R.string.toast_sdcard_insufficient_space); |
| 442 | returnResult(null, showString); |
| 443 | finish(); |
| 444 | break; |
| 445 | |
| 446 | case FmRecorder.ERROR_RECORDER_INTERNAL: |
| 447 | showString = getString(R.string.toast_recorder_internal_error); |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 448 | Toast.makeText(mContext, showString, Toast.LENGTH_SHORT).show(); |
| 449 | break; |
| 450 | |
Benson Huang | 57c1518 | 2014-12-22 10:56:31 +0800 | [diff] [blame] | 451 | case FmRecorder.ERROR_SDCARD_WRITE_FAILED: |
| 452 | showString = getString(R.string.toast_recorder_internal_error); |
| 453 | returnResult(null, showString); |
| 454 | finish(); |
| 455 | break; |
| 456 | |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 457 | default: |
| 458 | Log.w(TAG, "handleRecordError, invalid record error"); |
| 459 | break; |
| 460 | } |
| 461 | } |
| 462 | |
| 463 | private void returnResult(String recordName, String resultString) { |
| 464 | Intent intent = new Intent(); |
| 465 | intent.putExtra(FmMainActivity.EXTRA_RESULT_STRING, resultString); |
| 466 | if (recordName != null) { |
| 467 | intent.setData(Uri.parse("file://" + FmService.getRecordingSdcard() |
| 468 | + File.separator + FmRecorder.FM_RECORD_FOLDER + File.separator |
Benson Huang | 1917535 | 2014-12-26 16:11:23 +0800 | [diff] [blame] | 469 | + Uri.encode(recordName) + FmRecorder.RECORDING_FILE_EXTENSION)); |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 470 | } |
| 471 | setResult(RESULT_OK, intent); |
| 472 | } |
| 473 | |
| 474 | private final ContentObserver mContentObserver = new ContentObserver(new Handler()) { |
| 475 | public void onChange(boolean selfChange) { |
| 476 | updateUi(); |
| 477 | }; |
| 478 | }; |
| 479 | |
| 480 | // Service listener |
| 481 | private final FmListener mFmListener = new FmListener() { |
| 482 | @Override |
| 483 | public void onCallBack(Bundle bundle) { |
| 484 | int flag = bundle.getInt(FmListener.CALLBACK_FLAG); |
| 485 | if (flag == FmListener.MSGID_FM_EXIT) { |
| 486 | mHandler.removeCallbacksAndMessages(null); |
| 487 | } |
| 488 | |
| 489 | // remove tag message first, avoid too many same messages in queue. |
| 490 | Message msg = mHandler.obtainMessage(flag); |
| 491 | msg.setData(bundle); |
| 492 | mHandler.removeMessages(flag); |
| 493 | mHandler.sendMessage(msg); |
| 494 | } |
| 495 | }; |
| 496 | |
| 497 | /** |
| 498 | * Show save record dialog |
| 499 | */ |
| 500 | public void showSaveDialog() { |
| 501 | removeNotification(); |
| 502 | if (mIsInBackground) { |
| 503 | Log.d(TAG, "showSaveDialog, activity is in background, show it later"); |
| 504 | return; |
| 505 | } |
| 506 | String sdcard = FmService.getRecordingSdcard(); |
| 507 | String recordingName = mService.getRecordingName(); |
Benson Huang | 31fe68d | 2015-01-19 11:46:27 +0800 | [diff] [blame] | 508 | String saveName = null; |
Benson Huang | dc76ad0 | 2014-12-17 18:33:04 +0800 | [diff] [blame] | 509 | if (TextUtils.isEmpty(mStationName.getText())) { |
Benson Huang | 31fe68d | 2015-01-19 11:46:27 +0800 | [diff] [blame] | 510 | saveName = FmRecorder.RECORDING_FILE_PREFIX + "_" + recordingName; |
Benson Huang | dc76ad0 | 2014-12-17 18:33:04 +0800 | [diff] [blame] | 511 | } else { |
Benson Huang | 31fe68d | 2015-01-19 11:46:27 +0800 | [diff] [blame] | 512 | saveName = FmRecorder.RECORDING_FILE_PREFIX + "_" + mStationName.getText() + "_" |
Benson Huang | dc76ad0 | 2014-12-17 18:33:04 +0800 | [diff] [blame] | 513 | + recordingName; |
| 514 | } |
Benson Huang | 31fe68d | 2015-01-19 11:46:27 +0800 | [diff] [blame] | 515 | FmSaveDialog newFragment = new FmSaveDialog(sdcard, recordingName, saveName); |
Benson Huang | a8b6afc | 2014-11-20 15:42:26 +0800 | [diff] [blame] | 516 | newFragment.show(mFragmentManager, TAG_SAVE_RECORDINGD); |
| 517 | mFragmentManager.executePendingTransactions(); |
| 518 | mHandler.removeMessages(FmListener.MSGID_REFRESH); |
| 519 | } |
| 520 | |
| 521 | private boolean isStartRecording() { |
| 522 | return mRecordState == FmRecorder.STATE_RECORDING; |
| 523 | } |
| 524 | |
| 525 | private boolean isStopRecording() { |
| 526 | return mRecordState == FmRecorder.STATE_IDLE; |
| 527 | } |
| 528 | |
| 529 | private boolean isSaveDialogShown() { |
| 530 | FmSaveDialog saveDialog = (FmSaveDialog) |
| 531 | mFragmentManager.findFragmentByTag(TAG_SAVE_RECORDINGD); |
| 532 | return saveDialog != null; |
| 533 | } |
| 534 | } |