Skip to content

uelab/KidsRecorder

Repository files navigation

KidsRecorder

API Build Status

A recorder for research with kids. Associated with the CHI 19 paper: Anchored Audio Sampling: A Seamless Method for Exploring Children's Thoughts During Deployment Studies

How to use

If you just want to use the core recorder and file functions, you can in your project:

	allprojects {
		repositories {
			...
			maven { url 'https://jitpack.io' }
		}
	}

And then configure the dependency:

	dependencies {
	        implementation 'com.github.uelab:KidsRecorder:0.11'
	}

However, if you want to also use the UI for recorder, the file explorer UI: please download the code and add them in your project. Examples are provided in this project.

AndroidManifest

1 - Add permissions into you AndroidManifest.xml and request for them in Android 6.0+

<uses-permission android:name="android.permission.RECORD_AUDIO" />  
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />  
<uses-permission android:name="android.permission.WAKE_LOCK" /> //for recording during lock screen 
<uses-permission android:name="android.permission.INTERNET" />  
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />  
<uses-permission android:name="android.permission.VIBRATE"/> //for vibrating the phone as indicator

1.5 - If you want to use Amazon AWS for uploading recording files, please add the AmazonAuthenticationActivity in the AndroidManifest.xml. Add FileExplorerActivity and FileExplorerActivity as well if you want the activities. Please specify the later two activities as the child activity of the main recording activity.

  • For AmazonAuthenticationActivity
<activity android:name=".UI.AmazonAuthenticationActivity">  
<intent-filter> <action android:name="android.intent.action.MAIN" />  
<category android:name="android.intent.category.LAUNCHER" />  
</intent-filter></activity>
  • For FileExplorerActivity and FileExplorerActivity (the MainActivity is the main recording activity)
<activity android:name=".UI.FileExplorerActivity">  
 <meta-data  android:name="android.support.PARENT_ACTIVITY"  
  android:value=".UI.MainActivity" />  
</activity>  
  
<activity android:name=".UI.SettingsActivity"  
  android:theme="@style/AppTheme.SettingsTheme">  
 <meta-data  android:name="android.support.PARENT_ACTIVITY"  
  android:value=".UI.MainActivity" />  
</activity>

2 - Because the RecordingManager is a Service, we need to add corresponding Service in the AndroidManifest.xml.

<service android:name=".Recording.RecordingManager" />
<service android:name="com.amazonaws.mobileconnectors.s3.transferutility.TransferService"  
  android:enabled="true" />

3 - If you want to enable share function of the recording files, please add following settings in the AndroidManifest.xml to enable file sharing uri.

<provider  
  android:name="android.support.v4.content.FileProvider"  
  android:authorities="${applicationId}.fileprovider"  
  android:exported="false"  
  android:grantUriPermissions="true">  
 <meta-data  android:name="android.support.FILE_PROVIDER_PATHS"  
  android:resource="@xml/provider_paths" />  
</provider>

RecordingManager & DataManager

RecordingManager is the main recording class. It supports

  • Record/Stop/Pause/Resume in Background/Foreground mode
  • Broadcasting when record status changes
  • Communicates with DataManager when recording finishes. DataManager will manage remaining data operations.
  • Supports preceding recording mode (Record the preceding x seconds before the formal recording, will describe later)

DataManager is the main data operator to manage recording storage/deletion/uploading. It supports

  • Store newly recorded clips into Room Database
  • Delete old recordings to only keep recent n recordings
  • Upload automatically to AWS, and reuploading if the uploading the fails
  • Uploading buffer. Delay the uploading by keeping the newly records in a buffer. Only upload them when the buffer is full
  • Handle preceding files and delete them regularly (will discuss later)

RecordingManager and DataManager is used together to handle the whole recording-file storage-file uploading process

1 - Initialize the RecordingManager and DataManager in your recording activity. Notice that DataManager is a singleton class (which means there would only be one instance in the whole application), thus we need to call DataManager.getInstance() to get the instance.

  • First, initialize the DataManager
//The procedure to instantiate the datamanager  
//first call getInstance, then setfoldername, then call Initialize  
dataManager = DataManager.getInstance();  
try {
	//set the name of local folder where the recordings will be stored
    dataManager.setFolderName("KidsRecorder");  
	dataManager.Initialize(context);  
  
} catch (IOException e) {  
    e.printStackTrace();  
}  
  • Ask for permissions on RECORD_AUDIO and WRITE_EXTERNAL_STORAGE. The example activity in the project provides "how to" code.

  • Then after checking all permissions, start the RecordingManager Service. Because we will interact with the service later, thus we need to bind it to get its instance. The following code describes how to start the service and bind it.

void startRecordingService() {
	Intent recorderIntent = new Intent(this, RecordingManager.class);  
	startService(recorderIntent);  
	bindService(recorderIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}

//Binding this Client to the AudioPlayer Service  
private ServiceConnection serviceConnection = new ServiceConnection() {  
    @Override  
  public void onServiceConnected(ComponentName name, IBinder service) {  
        // We've bound to LocalService, cast the IBinder and get Service instance  
  RecordingManager.LocalBinder binder = (RecordingManager.LocalBinder) service;  
  //Here we retrieve the RecordingManager service
  recordingManager = binder.getServiceInstance();  
  serviceBound = true;  
  }  
  
    @Override  
  public void onServiceDisconnected(ComponentName name) {  
        serviceBound = false;  
  }  
};

2 - Let's start recording!

  • To start a timed recording (in seconds)
recordingManager.StartRecording(dataManager.getRecordingNameOfTime(), time_limit);  
  • To start a recording (without timing)
recordingManager.StartRecording(dataManager.getRecordingNameOfTime(), 0); 
  • To stop a recording
if (recordingManager.isRecording())  
    recordingManager.StopRecording();
  • To pause/resume a recording
recordingManager.PauseRecording();
recordingManager.ResumeRecording();

3 - Configure recording/storage settings

//set buffer size
dataManager.setBufferSize(int);  
//set max local file storage
dataManager.setMaxFilesBeforeDelete(int);  
//set whether upload autimatically
dataManager.setAutoUpload(boolean);  

//set whether recording even screen is locked  
recordingManager.setAlwaysRunning(boolean);  
//enable preceding mode 
recordingManager.setShouldPrecede(true);
//set preceding time before the formal recording, in seconds
recordingManager.setPrecedingTime(int);

Foreground/Background recording

Because RecordingManager is a service, it also runs in the background (when the app is not the current screen app). Thus if you want to only record in foreground, you can stop the recording in onStop():

@Override  
protected void onStop() {  
    super.onStop();  
	//if the background recording is off, then stop current recording  
	if (!record_background && recordingManager != null && recordingManager.isRecording()){  
		recordingManager.StopRecording();  
  }  
}

Preceding mode

Preceding mode means when recording, a preceding time will also be recorded. For example, if we set preceding time to 10 seconds, when the user click "record" button (a formal recording), 10 seconds before the buttonclicking would also be stored.

The mechanism of preceding mode is that RecordingManager would keep recording small clips that equal to length precedingTime. When the formal recording is triggered, it would stop the small recording, and keep the former two clips, then start the formal recording. When the formal recording ends, it would start small clips recording again. If there is no formal recording, it will discard the small clips constantly.

  • To enable preceding mode, we need to set
recordingManager.setPrecedingTime(int); //specify how long before the formal recording we need to keep
  • Then start the always-on recording using silent mode
recordingManager.StartRecordingSilently(String filename)
  • If we want to start a formal recording, call StartRecording (not the silent mode) (the normal recording procedure)
recordingManager.StartRecording(dataManager.getRecordingNameOfTime(), 0); 
  • and Stop
recordingManager.StopRecording();
  • If we want to stop the preceding always-on recording, we need to call
recordingManager.StopRecordingWithoutStartingBackground();

In this way, we stopped all recordings (including the formal recording)

Merge Preceding Files with the Recording File

  • you can set the recordingManager's should_mergeprecede to true to enable the merge function. The defualt is true. It will merge the preceding files with the anchor file together, thus resulting in a larger recording file. If it's false, then separate files will be stored, including the preceding files with name " -preceding.wav" and the anchor file.

Notice that because the formal recording might interrupt the preceding small clip recording, thus to make sure the preceding recording is long enough, we store the two preceding recordings rather than one. Preceding recordings is named with "Preceding" prefix

AWS Authentication & Uploading

To enable the AWS integration, please refre to [here] (https://docs.aws.amazon.com/aws-mobile/latest/developerguide/aws-mobile-android-and-iOS.html)

And put your mobile hub configuration file into /app/src/main/res/raw/

UI

FileExplorer

To use the FileExplorerActivity in the library, you can just include them in your project.

For more details, please read the comments in the corresponding files.

Dependencies

Citation

If you use the code in your paper, then please cite it as:

@inproceedings{Hiniker:2019:AAS:3290605.3300238,
 author = {Hiniker, Alexis and Froehlich, Jon E. and Zhang, Mingrui and Beneteau, Erin},
 title = {Anchored Audio Sampling: A Seamless Method for Exploring Children's Thoughts During Deployment Studies},
 booktitle = {Proceedings of the 2019 CHI Conference on Human Factors in Computing Systems},
 series = {CHI '19},
 year = {2019},
 isbn = {978-1-4503-5970-2},
 location = {Glasgow, Scotland Uk},
 pages = {8:1--8:13},
 articleno = {8},
 numpages = {13},
 url = {http://doi.acm.org/10.1145/3290605.3300238},
 doi = {10.1145/3290605.3300238},
 acmid = {3300238},
 publisher = {ACM},
 address = {New York, NY, USA},
 keywords = {cci, context-aware esm, data collection tools, early childhood, field deployments, study methods},
} 

License

MIT License

Copyright (c) 2018 Mingrui Zhang

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.