Merge branch 'audiorecorder-2.0.0'
This commit is contained in:
commit
d7da700bb7
20 changed files with 386 additions and 113 deletions
|
|
@ -8,8 +8,8 @@ android {
|
|||
applicationId "com.github.axet.audiorecorder"
|
||||
minSdkVersion 9
|
||||
targetSdkVersion 23
|
||||
versionCode 154
|
||||
versionName "1.7.4"
|
||||
versionCode 155
|
||||
versionName "2.0.0"
|
||||
}
|
||||
signingConfigs {
|
||||
release {
|
||||
|
|
@ -43,5 +43,5 @@ android {
|
|||
dependencies {
|
||||
compile fileTree(dir: 'libs', include: ['*.jar'])
|
||||
testCompile 'junit:junit:4.12'
|
||||
compile 'com.github.axet:android-audio-library:0.0.55' // compile project(':android-audio-library')
|
||||
compile 'com.github.axet:android-audio-library:0.0.58' // compile project(':android-audio-library')
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
|
||||
<application
|
||||
android:name=".app.MainApplication"
|
||||
|
|
@ -23,6 +24,7 @@
|
|||
<activity
|
||||
android:name=".activities.MainActivity"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name"
|
||||
android:launchMode="singleInstance"
|
||||
android:theme="@style/RecThemeLight.NoActionBar">
|
||||
|
|
@ -35,8 +37,32 @@
|
|||
<activity
|
||||
android:name=".activities.RecordingActivity"
|
||||
android:configChanges="orientation|keyboardHidden|screenSize"
|
||||
android:exported="true"
|
||||
android:launchMode="singleInstance"
|
||||
android:showOnLockScreen="true" />
|
||||
|
||||
<receiver
|
||||
android:name=".services.OnBootReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".services.OnUpgradeReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.PACKAGE_REPLACED" />
|
||||
|
||||
<data android:scheme="package" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".services.OnExternalReceiver">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
|
|
|||
|
|
@ -2,9 +2,11 @@ package com.github.axet.audiorecorder.activities;
|
|||
|
||||
import android.Manifest;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.net.Uri;
|
||||
|
|
@ -18,6 +20,7 @@ import android.util.Log;
|
|||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
|
@ -26,6 +29,7 @@ import com.github.axet.audiolibrary.app.Recordings;
|
|||
import com.github.axet.audiolibrary.app.Storage;
|
||||
import com.github.axet.audiorecorder.R;
|
||||
import com.github.axet.audiorecorder.app.MainApplication;
|
||||
import com.github.axet.audiorecorder.services.RecordingService;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
|
|
@ -44,6 +48,16 @@ public class MainActivity extends AppCompatActivity {
|
|||
|
||||
int themeId;
|
||||
|
||||
BroadcastReceiver receiver = new BroadcastReceiver() {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
String a = intent.getAction();
|
||||
if (a.equals(Intent.ACTION_SCREEN_OFF)) {
|
||||
moveTaskToBack(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
public static void startActivity(Context context) {
|
||||
Intent i = new Intent(context, MainActivity.class);
|
||||
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
|
|
@ -65,6 +79,9 @@ public class MainActivity extends AppCompatActivity {
|
|||
setAppTheme(getAppTheme(this));
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
|
||||
WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
|
||||
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
progressEmpty = findViewById(R.id.progress_empty);
|
||||
|
|
@ -103,6 +120,13 @@ public class MainActivity extends AppCompatActivity {
|
|||
Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
RecordingService.startIfEnabled(this);
|
||||
|
||||
IntentFilter ff = new IntentFilter();
|
||||
ff.addAction(Intent.ACTION_SCREEN_OFF);
|
||||
ff.addAction(Intent.ACTION_SCREEN_ON);
|
||||
registerReceiver(receiver, ff);
|
||||
}
|
||||
|
||||
void checkPending() {
|
||||
|
|
@ -257,14 +281,15 @@ public class MainActivity extends AppCompatActivity {
|
|||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
recordings.close();
|
||||
unregisterReceiver(receiver);
|
||||
}
|
||||
|
||||
void updateHeader() {
|
||||
File f = storage.getStoragePath();
|
||||
long free = storage.getFree(f);
|
||||
long sec = storage.average(free);
|
||||
long free = Storage.getFree(f);
|
||||
long sec = Storage.average(this, free);
|
||||
TextView text = (TextView) findViewById(R.id.space_left);
|
||||
text.setText(((MainApplication) getApplication()).formatFree(free, sec));
|
||||
text.setText(MainApplication.formatFree(this, free, sec));
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,9 @@ import com.github.axet.audiorecorder.app.Storage;
|
|||
import com.github.axet.audiorecorder.services.RecordingService;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.ShortBuffer;
|
||||
|
||||
public class RecordingActivity extends AppCompatActivity {
|
||||
public static final String TAG = RecordingActivity.class.getSimpleName();
|
||||
|
|
@ -72,7 +75,7 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
// pitch size in samples. how many samples count need to update view. 4410 for 100ms update.
|
||||
int samplesUpdate;
|
||||
// output target file 2016-01-01 01.01.01.wav
|
||||
File targetFile;
|
||||
File targetFile = null;
|
||||
// how many samples passed for current recording
|
||||
long samplesTime;
|
||||
// current cut position in samples from begining of file
|
||||
|
|
@ -92,6 +95,8 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
RecordingReceiver receiver;
|
||||
Handler handler = new Handler();
|
||||
|
||||
ShortBuffer dbBuffer = null;
|
||||
|
||||
public static void startActivity(Context context, boolean pause) {
|
||||
Intent i = new Intent(context, RecordingActivity.class);
|
||||
if (pause) {
|
||||
|
|
@ -162,8 +167,19 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
|
||||
edit(false, false);
|
||||
|
||||
SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
try {
|
||||
targetFile = storage.getNewFile();
|
||||
if (storage.recordingPending()) {
|
||||
String file = shared.getString(MainApplication.PREFERENCE_TARGET, null);
|
||||
if (file != null)
|
||||
targetFile = new File(file);
|
||||
}
|
||||
if (targetFile == null)
|
||||
targetFile = storage.getNewFile();
|
||||
SharedPreferences.Editor editor = shared.edit();
|
||||
editor.putString(MainApplication.PREFERENCE_TARGET, targetFile.toString());
|
||||
editor.commit();
|
||||
} catch (RuntimeException e) {
|
||||
Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
|
|
@ -172,7 +188,6 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
|
||||
title.setText(targetFile.getName());
|
||||
|
||||
SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
if (shared.getBoolean(MainApplication.PREFERENCE_CALL, false)) {
|
||||
TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
|
|
@ -181,8 +196,11 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
|
||||
sampleRate = Integer.parseInt(shared.getString(MainApplication.PREFERENCE_RATE, ""));
|
||||
sampleRate = Sound.getValidRecordRate(MainApplication.getInMode(this), sampleRate);
|
||||
if (sampleRate == -1)
|
||||
throw new RuntimeException("Unable to initailze audio");
|
||||
if (sampleRate == -1) {
|
||||
Toast.makeText(this, "Unable to initailze audio", Toast.LENGTH_SHORT).show();
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
samplesUpdate = (int) (pitch.getPitchTime() * sampleRate / 1000.0);
|
||||
|
||||
updateBufferSize(false);
|
||||
|
|
@ -282,20 +300,20 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
int len = rs.read(buf);
|
||||
rs.close();
|
||||
|
||||
pitch.clear(cut / samplesUpdate);
|
||||
for (int i = 0; i < len; i += samplesUpdate * MainApplication.getChannels(this)) {
|
||||
double dB = 0;
|
||||
for (int c = 0; c < MainApplication.getChannels(this); c++) {
|
||||
dB += RawSamples.getDB(buf, i + samplesUpdate * c, samplesUpdate);
|
||||
}
|
||||
dB = dB / MainApplication.getChannels(this);
|
||||
int samplesUpdateStereo = samplesUpdate * MainApplication.getChannels(this);
|
||||
pitch.clear(cut / samplesUpdateStereo);
|
||||
int lenUpdate = len / samplesUpdateStereo * samplesUpdateStereo; // cut right overs (leftovers from right)
|
||||
for (int i = 0; i < lenUpdate; i += samplesUpdateStereo) {
|
||||
double dB = RawSamples.getDB(buf, i, samplesUpdateStereo);
|
||||
pitch.add(dB);
|
||||
}
|
||||
updateSamples(samplesTime);
|
||||
}
|
||||
|
||||
boolean isEmulator() {
|
||||
return "goldfish".equals(Build.HARDWARE);
|
||||
int diff = len - lenUpdate;
|
||||
if (diff > 0) {
|
||||
dbBuffer = ShortBuffer.allocate(samplesUpdateStereo);
|
||||
dbBuffer.put(buf, lenUpdate, diff);
|
||||
}
|
||||
}
|
||||
|
||||
void pauseButton() {
|
||||
|
|
@ -422,7 +440,7 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
}
|
||||
|
||||
void setState(String s) {
|
||||
long free = storage.getFree(storage.getTempRecording());
|
||||
long free = Storage.getFree(storage.getTempRecording());
|
||||
|
||||
final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
|
||||
|
|
@ -433,7 +451,7 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
long perSec = (c * m * rate);
|
||||
long sec = free / perSec * 1000;
|
||||
|
||||
state.setText(s + "\n(" + ((MainApplication) getApplication()).formatFree(free, sec) + ")");
|
||||
state.setText(s + "\n(" + MainApplication.formatFree(this, free, sec) + ")");
|
||||
}
|
||||
|
||||
void editPlay(boolean show) {
|
||||
|
|
@ -549,7 +567,7 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
receiver = null;
|
||||
}
|
||||
|
||||
RecordingService.stopService(this);
|
||||
RecordingService.stopRecording(this);
|
||||
|
||||
if (pscl != null) {
|
||||
TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
|
|
@ -561,6 +579,10 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
encoder.close();
|
||||
encoder = null;
|
||||
}
|
||||
|
||||
final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(this);
|
||||
SharedPreferences.Editor editor = shared.edit();
|
||||
editor.remove(MainApplication.PREFERENCE_TARGET);
|
||||
}
|
||||
|
||||
void startRecording() {
|
||||
|
|
@ -596,7 +618,6 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
|
||||
rs.open(samplesTime);
|
||||
|
||||
|
||||
int c = MainApplication.getInMode(RecordingActivity.this);
|
||||
int min = AudioRecord.getMinBufferSize(sampleRate, c, Sound.DEFAULT_AUDIOFORMAT);
|
||||
if (min <= 0)
|
||||
|
|
@ -619,13 +640,15 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
|
||||
boolean stableRefresh = false;
|
||||
|
||||
int samplesUpdateStereo = samplesUpdate * MainApplication.getChannels(RecordingActivity.this);
|
||||
|
||||
while (!Thread.currentThread().isInterrupted()) {
|
||||
synchronized (bufferSizeLock) {
|
||||
if (buffer == null || buffer.length != bufferSize)
|
||||
buffer = new short[bufferSize];
|
||||
}
|
||||
|
||||
final int readSize = recorder.read(buffer, 0, buffer.length);
|
||||
int readSize = recorder.read(buffer, 0, buffer.length);
|
||||
if (readSize <= 0) {
|
||||
break;
|
||||
}
|
||||
|
|
@ -635,16 +658,30 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
|
||||
start = end;
|
||||
|
||||
int s = readSize / MainApplication.getChannels(RecordingActivity.this);
|
||||
int samples = readSize / MainApplication.getChannels(RecordingActivity.this);
|
||||
|
||||
if (stableRefresh || diff >= s) {
|
||||
if (stableRefresh || diff >= samples) {
|
||||
stableRefresh = true;
|
||||
|
||||
rs.write(buffer, readSize);
|
||||
rs.write(buffer, 0, readSize);
|
||||
|
||||
int ps = samplesUpdate * MainApplication.getChannels(RecordingActivity.this);
|
||||
for (int i = 0; i < readSize; i += ps) {
|
||||
final double dB = RawSamples.getDB(buffer, i, ps);
|
||||
short[] dbBuf;
|
||||
int readSizeUpdate;
|
||||
if (dbBuffer != null) {
|
||||
ShortBuffer bb = ShortBuffer.allocate(dbBuffer.position() + readSize);
|
||||
dbBuffer.flip();
|
||||
bb.put(dbBuffer);
|
||||
bb.put(buffer, 0, readSize);
|
||||
dbBuf = new short[bb.position()];
|
||||
readSize = dbBuf.length;
|
||||
bb.flip();
|
||||
bb.get(dbBuf, 0, dbBuf.length);
|
||||
} else {
|
||||
dbBuf = buffer;
|
||||
}
|
||||
readSizeUpdate = readSize / samplesUpdateStereo * samplesUpdateStereo;
|
||||
for (int i = 0; i < readSizeUpdate; i += samplesUpdateStereo) {
|
||||
final double dB = RawSamples.getDB(dbBuf, i, samplesUpdateStereo);
|
||||
handle.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
|
@ -652,9 +689,16 @@ public class RecordingActivity extends AppCompatActivity {
|
|||
}
|
||||
});
|
||||
}
|
||||
int readSizeLen = readSize - readSizeUpdate;
|
||||
if (readSizeLen > 0) {
|
||||
dbBuffer = ShortBuffer.allocate(readSizeLen);
|
||||
dbBuffer.put(dbBuf, readSizeUpdate, readSizeLen);
|
||||
} else {
|
||||
dbBuffer = null;
|
||||
}
|
||||
|
||||
samplesTime += s;
|
||||
samplesTimeCount += s;
|
||||
samplesTime += samples;
|
||||
samplesTimeCount += samples;
|
||||
if (samplesTimeCount > samplesTimeUpdate) {
|
||||
final long m = samplesTime;
|
||||
handle.post(new Runnable() {
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ import com.github.axet.audiolibrary.app.Storage;
|
|||
import com.github.axet.audiorecorder.R;
|
||||
import com.github.axet.audiorecorder.app.MainApplication;
|
||||
import com.github.axet.audiolibrary.encoders.Factory;
|
||||
import com.github.axet.audiorecorder.services.RecordingService;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
|
|
@ -215,6 +216,13 @@ public class SettingsActivity extends AppCompatActivity implements SharedPrefere
|
|||
startActivity(new Intent(this, SettingsActivity.class));
|
||||
overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
|
||||
}
|
||||
if (key.equals(MainApplication.PREFERENCE_CONTROLS)) {
|
||||
if (sharedPreferences.getBoolean(MainApplication.PREFERENCE_CONTROLS, false)) {
|
||||
RecordingService.start(this);
|
||||
} else {
|
||||
RecordingService.stopService(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -255,6 +263,11 @@ public class SettingsActivity extends AppCompatActivity implements SharedPrefere
|
|||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,9 @@ import com.github.axet.audiorecorder.R;
|
|||
|
||||
public class MainApplication extends com.github.axet.audiolibrary.app.MainApplication {
|
||||
|
||||
public static final String PREFERENCE_CONTROLS = "controls";
|
||||
public static final String PREFERENCE_TARGET = "target";
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
package com.github.axet.audiorecorder.services;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
public class OnBootReceiver extends BroadcastReceiver {
|
||||
String TAG = OnBootReceiver.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent i) {
|
||||
Log.d(TAG, "onReceive");
|
||||
RecordingService.startIfEnabledPending(context);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
package com.github.axet.audiorecorder.services;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.util.Log;
|
||||
|
||||
public class OnExternalReceiver extends BroadcastReceiver {
|
||||
String TAG = OnExternalReceiver.class.getSimpleName();
|
||||
|
||||
boolean isExternal(Context context) {
|
||||
PackageManager pm = context.getPackageManager();
|
||||
try {
|
||||
PackageInfo pi = pm.getPackageInfo(context.getPackageName(), 0);
|
||||
ApplicationInfo ai = pi.applicationInfo;
|
||||
return (ai.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == ApplicationInfo.FLAG_EXTERNAL_STORAGE;
|
||||
} catch (PackageManager.NameNotFoundException ignore) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.d(TAG, "onReceive");
|
||||
|
||||
if (!isExternal(context))
|
||||
return;
|
||||
|
||||
RecordingService.startIfEnabledPending(context);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
package com.github.axet.audiorecorder.services;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
/**
|
||||
* http://stackoverflow.com/questions/2133986
|
||||
*/
|
||||
public class OnUpgradeReceiver extends BroadcastReceiver {
|
||||
String TAG = OnUpgradeReceiver.class.getSimpleName();
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.d(TAG, "onReceive");
|
||||
RecordingService.startIfEnabledPending(context);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.github.axet.audiorecorder.services;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
|
|
@ -7,18 +8,25 @@ import android.content.BroadcastReceiver;
|
|||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import com.github.axet.androidlibrary.widgets.OptimizationPreferenceCompat;
|
||||
import com.github.axet.audiolibrary.app.Storage;
|
||||
import com.github.axet.audiorecorder.R;
|
||||
import com.github.axet.audiorecorder.activities.MainActivity;
|
||||
import com.github.axet.audiorecorder.activities.RecordingActivity;
|
||||
import com.github.axet.audiorecorder.app.MainApplication;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* RecordingActivity more likly to be removed from memory when paused then service. Notification button
|
||||
* does not handle getActvity without unlocking screen. The only option is to have Service.
|
||||
|
|
@ -34,23 +42,31 @@ public class RecordingService extends Service {
|
|||
|
||||
public static String SHOW_ACTIVITY = RecordingService.class.getCanonicalName() + ".SHOW_ACTIVITY";
|
||||
public static String PAUSE_BUTTON = RecordingService.class.getCanonicalName() + ".PAUSE_BUTTON";
|
||||
public static String RECORD_BUTTON = RecordingService.class.getCanonicalName() + ".RECORD_BUTTON";
|
||||
|
||||
RecordingReceiver receiver;
|
||||
Storage storage = new Storage(this); // for storage path
|
||||
|
||||
String targetFile;
|
||||
boolean recording;
|
||||
boolean encoding;
|
||||
public static void startIfEnabled(Context context) {
|
||||
SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
if (!shared.getBoolean(MainApplication.PREFERENCE_CONTROLS, false))
|
||||
return;
|
||||
start(context);
|
||||
}
|
||||
|
||||
public class RecordingReceiver extends BroadcastReceiver {
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
|
||||
// showRecordingActivity();
|
||||
}
|
||||
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
|
||||
// do nothing. do not annoy user. he will see alarm screen on next screen on event.
|
||||
}
|
||||
public static void startIfEnabledPending(Context context) {
|
||||
Storage s = new Storage(context);
|
||||
if (s.recordingPending()) {
|
||||
final SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
String f = shared.getString(MainApplication.PREFERENCE_TARGET, "");
|
||||
File file = new File(f);
|
||||
startService(context, file.getName(), false, false);
|
||||
return;
|
||||
}
|
||||
startIfEnabled(context);
|
||||
}
|
||||
|
||||
public static void start(Context context) {
|
||||
context.startService(new Intent(context, RecordingService.class));
|
||||
}
|
||||
|
||||
public static void startService(Context context, String targetFile, boolean recording, boolean encoding) {
|
||||
|
|
@ -61,6 +77,15 @@ public class RecordingService extends Service {
|
|||
);
|
||||
}
|
||||
|
||||
public static void stopRecording(Context context) {
|
||||
SharedPreferences shared = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
if (shared.getBoolean(MainApplication.PREFERENCE_CONTROLS, false)) {
|
||||
start(context);
|
||||
return;
|
||||
}
|
||||
stopService(context);
|
||||
}
|
||||
|
||||
public static void stopService(Context context) {
|
||||
context.stopService(new Intent(context, RecordingService.class));
|
||||
}
|
||||
|
|
@ -72,11 +97,7 @@ public class RecordingService extends Service {
|
|||
public void onCreate() {
|
||||
super.onCreate();
|
||||
Log.d(TAG, "onCreate");
|
||||
receiver = new RecordingReceiver();
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(Intent.ACTION_SCREEN_ON);
|
||||
filter.addAction(Intent.ACTION_SCREEN_OFF);
|
||||
registerReceiver(receiver, filter);
|
||||
startForeground(NOTIFICATION_RECORDING_ICON, build(new Intent()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
@ -85,17 +106,18 @@ public class RecordingService extends Service {
|
|||
|
||||
if (intent != null) {
|
||||
String a = intent.getAction();
|
||||
|
||||
if (a == null) {
|
||||
targetFile = intent.getStringExtra("targetFile");
|
||||
recording = intent.getBooleanExtra("recording", false);
|
||||
encoding = intent.getBooleanExtra("encoding", false);
|
||||
showNotificationAlarm(true);
|
||||
showNotificationAlarm(true, intent);
|
||||
} else if (a.equals(PAUSE_BUTTON)) {
|
||||
Intent i = new Intent(RecordingActivity.PAUSE_BUTTON);
|
||||
sendBroadcast(i);
|
||||
} else if (a.equals(SHOW_ACTIVITY)) {
|
||||
} else if (a.equals(RECORD_BUTTON)) {
|
||||
RecordingActivity.startActivity(this, false);
|
||||
} else if (a.equals(SHOW_ACTIVITY)) {
|
||||
if (intent.getStringExtra("targetFile") == null)
|
||||
MainActivity.startActivity(this);
|
||||
else
|
||||
RecordingActivity.startActivity(this, !intent.getBooleanExtra("recording", false));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -119,61 +141,97 @@ public class RecordingService extends Service {
|
|||
super.onDestroy();
|
||||
Log.d(TAG, "onDestory");
|
||||
|
||||
showNotificationAlarm(false);
|
||||
stopForeground(false);
|
||||
|
||||
unregisterReceiver(receiver);
|
||||
showNotificationAlarm(false, null);
|
||||
}
|
||||
|
||||
public Notification build(Intent intent) {
|
||||
String targetFile = intent.getStringExtra("targetFile");
|
||||
boolean recording = intent.getBooleanExtra("recording", false);
|
||||
boolean encoding = intent.getBooleanExtra("encoding", false);
|
||||
|
||||
PendingIntent main = PendingIntent.getService(this, 0,
|
||||
new Intent(this, RecordingService.class).setAction(SHOW_ACTIVITY).putExtra("targetFile", targetFile).putExtra("recording", recording),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
PendingIntent pe = PendingIntent.getService(this, 0,
|
||||
new Intent(this, RecordingService.class).setAction(PAUSE_BUTTON),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
PendingIntent re = PendingIntent.getService(this, 0,
|
||||
new Intent(this, RecordingService.class).setAction(RECORD_BUTTON),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
RemoteViews view = new RemoteViews(getPackageName(), MainApplication.getTheme(getBaseContext(),
|
||||
R.layout.notifictaion_recording_light,
|
||||
R.layout.notifictaion_recording_dark));
|
||||
|
||||
String title;
|
||||
String text;
|
||||
if (targetFile == null) {
|
||||
title = getString(R.string.app_name);
|
||||
File f = storage.getStoragePath();
|
||||
long free = Storage.getFree(f);
|
||||
long sec = Storage.average(this, free);
|
||||
text = MainApplication.formatFree(this, free, sec);
|
||||
view.setViewVisibility(R.id.notification_record, View.VISIBLE);
|
||||
view.setOnClickPendingIntent(R.id.notification_record, re);
|
||||
view.setViewVisibility(R.id.notification_pause, View.GONE);
|
||||
} else {
|
||||
if (recording)
|
||||
title = getString(R.string.recording_title);
|
||||
else
|
||||
title = getString(R.string.pause_title);
|
||||
text = ".../" + targetFile;
|
||||
view.setViewVisibility(R.id.notification_record, View.GONE);
|
||||
view.setViewVisibility(R.id.notification_pause, View.VISIBLE);
|
||||
}
|
||||
|
||||
if (encoding) {
|
||||
view.setViewVisibility(R.id.notification_pause, View.GONE);
|
||||
title = getString(R.string.encoding_title);
|
||||
}
|
||||
|
||||
view.setOnClickPendingIntent(R.id.status_bar_latest_event_content, main);
|
||||
view.setTextViewText(R.id.notification_title, title);
|
||||
view.setTextViewText(R.id.notification_text, text);
|
||||
view.setOnClickPendingIntent(R.id.notification_pause, pe);
|
||||
view.setImageViewResource(R.id.notification_pause, !recording ? R.drawable.ic_play_arrow_black_24dp : R.drawable.ic_pause_black_24dp);
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
|
||||
.setOngoing(true)
|
||||
.setContentTitle(title)
|
||||
.setContentText(text)
|
||||
.setTicker(title)
|
||||
.setSmallIcon(R.drawable.ic_mic_24dp)
|
||||
.setContent(view);
|
||||
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
builder.setContentIntent(main);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 21)
|
||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
// alarm dismiss button
|
||||
public void showNotificationAlarm(boolean show) {
|
||||
public void showNotificationAlarm(boolean show, Intent intent) {
|
||||
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
|
||||
if (!show) {
|
||||
notificationManager.cancel(NOTIFICATION_RECORDING_ICON);
|
||||
} else {
|
||||
PendingIntent main = PendingIntent.getService(this, 0,
|
||||
new Intent(this, RecordingService.class).setAction(SHOW_ACTIVITY),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
PendingIntent pe = PendingIntent.getService(this, 0,
|
||||
new Intent(this, RecordingService.class).setAction(PAUSE_BUTTON),
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
|
||||
RemoteViews view = new RemoteViews(getPackageName(), MainApplication.getTheme(getBaseContext(),
|
||||
R.layout.notifictaion_recording_light,
|
||||
R.layout.notifictaion_recording_dark));
|
||||
|
||||
String title = getString(R.string.recording_title);
|
||||
String text = ".../" + targetFile;
|
||||
|
||||
if (encoding) {
|
||||
view.setViewVisibility(R.id.notification_pause, View.GONE);
|
||||
title = getString(R.string.encoding_title);
|
||||
}
|
||||
|
||||
view.setOnClickPendingIntent(R.id.status_bar_latest_event_content, main);
|
||||
view.setTextViewText(R.id.notification_title, title);
|
||||
view.setTextViewText(R.id.notification_text, text);
|
||||
view.setOnClickPendingIntent(R.id.notification_pause, pe);
|
||||
view.setImageViewResource(R.id.notification_pause, !recording ? R.drawable.ic_play_arrow_black_24dp : R.drawable.ic_pause_black_24dp);
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
|
||||
.setOngoing(true)
|
||||
.setContentTitle(title)
|
||||
.setContentText(text)
|
||||
.setTicker(title)
|
||||
.setSmallIcon(R.drawable.ic_mic_24dp)
|
||||
.setContent(view);
|
||||
|
||||
if (Build.VERSION.SDK_INT < 11) {
|
||||
builder.setContentIntent(main);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= 21)
|
||||
builder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||
|
||||
notificationManager.notify(NOTIFICATION_RECORDING_ICON, builder.build());
|
||||
notificationManager.notify(NOTIFICATION_RECORDING_ICON, build(intent));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onTaskRemoved(Intent rootIntent) {
|
||||
super.onTaskRemoved(rootIntent);
|
||||
Log.d(TAG, "onTaskRemoved");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,15 +24,16 @@
|
|||
<string name="action_settings">Einstellungen</string>
|
||||
<string name="not_permitted">Nicht erlaubt</string>
|
||||
<string name="no_folder_app">Keine App zur Anzeige von Ordnern installiert</string>
|
||||
<string name="hold_by_call">Pause (bei Anruf)</string>
|
||||
<string name="encoding">Encoding</string>
|
||||
<string name="pause">Pause</string>
|
||||
<string name="edit">Bearbeiten</string>
|
||||
<string name="hold_by_call">pause (bei Anruf)</string>
|
||||
<string name="recording">aufnehmen</string>
|
||||
<string name="encoding">encoding</string>
|
||||
<string name="pause">pause</string>
|
||||
<string name="edit">bearbeiten</string>
|
||||
<string name="confirm_cancel">Bestätige Abbruch</string>
|
||||
<string name="are_you_sure_cancel">Willst du wirklich abbrechen?</string>
|
||||
<string name="recording">Aufnehmen</string>
|
||||
<string name="encoding_title">Encoding...</string>
|
||||
<string name="recording_title">Aufnahme</string>
|
||||
<string name="pause_title">Pause...</string>
|
||||
<string name="open_recording_folder">Öffne Aufnahme-Ordner</string>
|
||||
<string name="recording_list_is_empty">Aufnahmeliste ist leer\n\nDrücke \'Aufnehmen\' um die Aufnahme zu starten</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -25,14 +25,15 @@
|
|||
<string name="not_permitted">許可されていません</string>
|
||||
<string name="no_folder_app">フォルダーを表示するアプリケーションがインストールされていません</string>
|
||||
<string name="hold_by_call">一時停止 (着信により保留)</string>
|
||||
<string name="recording">録音中</string>
|
||||
<string name="encoding">エンコーディング</string>
|
||||
<string name="pause">一時停止</string>
|
||||
<string name="edit">編集</string>
|
||||
<string name="confirm_cancel">キャンセルの確認</string>
|
||||
<string name="are_you_sure_cancel">キャンセルしてもよろしいですか?</string>
|
||||
<string name="recording">録音中</string>
|
||||
<string name="encoding_title">エンコード中...</string>
|
||||
<string name="recording_title">録音中</string>
|
||||
<string name="pause_title">一時停止...</string>
|
||||
<string name="open_recording_folder">録音フォルダーを開く</string>
|
||||
<string name="recording_list_is_empty">録音リストは空です\n\n録音をクリックすると録音を開始します</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -25,14 +25,15 @@
|
|||
<string name="not_permitted">Não permitido</string>
|
||||
<string name="no_folder_app">Não foi encontrado um aplicativo para explorar arquivos</string>
|
||||
<string name="hold_by_call">pausado (chamada atendida)</string>
|
||||
<string name="recording">gravando</string>
|
||||
<string name="encoding">codificando</string>
|
||||
<string name="pause">pausado</string>
|
||||
<string name="edit">editando</string>
|
||||
<string name="confirm_cancel">Confirme o cancelamento</string>
|
||||
<string name="are_you_sure_cancel">Tem certeza que deseja cancelar?</string>
|
||||
<string name="recording">gravando</string>
|
||||
<string name="encoding_title">Codificando...</string>
|
||||
<string name="recording_title">Gravando</string>
|
||||
<string name="pause_title">Pausado...</string>
|
||||
<string name="open_recording_folder">Abrir pasta das gravações</string>
|
||||
<string name="recording_list_is_empty">A lista de gravações está vazia\n\nToque no ícone de microfone para começar a gravar</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -25,14 +25,15 @@
|
|||
<string name="not_permitted">Доступ запрещен</string>
|
||||
<string name="no_folder_app">Программа для просмотра папок не установлена</string>
|
||||
<string name="hold_by_call">пауза (звонок)</string>
|
||||
<string name="recording">запись</string>
|
||||
<string name="encoding">кодировка</string>
|
||||
<string name="pause">пауза</string>
|
||||
<string name="edit">редактор</string>
|
||||
<string name="confirm_cancel">Отменить запись</string>
|
||||
<string name="are_you_sure_cancel">Вы уверены?</string>
|
||||
<string name="recording">запись</string>
|
||||
<string name="encoding_title">Кодирование...</string>
|
||||
<string name="recording_title">Запись</string>
|
||||
<string name="recording_title">Запись...</string>
|
||||
<string name="pause_title">Пауза...</string>
|
||||
<string name="open_recording_folder">Открыть папку с записями</string>
|
||||
<string name="recording_list_is_empty">Список записей пуст.\n\nНажмите на \'Микрофон\' чтобы начать запись.</string>
|
||||
</resources>
|
||||
|
|
|
|||
|
|
@ -57,13 +57,14 @@
|
|||
<string name="not_permitted">Not permitted</string>
|
||||
<string name="no_folder_app">No folder view application installed</string>
|
||||
<string name="hold_by_call">pause (hold by call)</string>
|
||||
<string name="recording">recording</string>
|
||||
<string name="encoding">encoding</string>
|
||||
<string name="pause">pause</string>
|
||||
<string name="edit">edit</string>
|
||||
<string name="confirm_cancel">Confirm cancel</string>
|
||||
<string name="are_you_sure_cancel">Are you sure you want to cancel?</string>
|
||||
<string name="recording">recording</string>
|
||||
<string name="encoding_title">Encoding...</string>
|
||||
<string name="pause_title">Pause...</string>
|
||||
<string name="recording_title">Recording</string>
|
||||
<string name="open_recording_folder">Open Recording Folder</string>
|
||||
<string name="recording_list_is_empty">Recording List is Empty\n\nClick Record to Start Recording</string>
|
||||
|
|
|
|||
|
|
@ -58,6 +58,12 @@
|
|||
android:summary="Aktiviere Audio-Profil \'Nicht Stören\' während Aufnahmen"
|
||||
android:title="Ruhe-Modus" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="controls"
|
||||
android:summary="Zeige Steuerelemente im Sperrbildschirm an"
|
||||
android:title="Steuerelemente im Sperrbildschirm" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="Theme_White"
|
||||
android:entries="@array/themes_text"
|
||||
|
|
|
|||
|
|
@ -58,6 +58,12 @@
|
|||
android:summary="録音中、電話を 'マナーモード' にします"
|
||||
android:title="マナーモード" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="controls"
|
||||
android:summary="Show controls when phone is locked"
|
||||
android:title="Lockscreen Controls" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="Theme_White"
|
||||
android:entries="@array/themes_text"
|
||||
|
|
|
|||
|
|
@ -58,6 +58,12 @@
|
|||
android:summary="Silenciar o aparelho durante a gravação"
|
||||
android:title="Modo silencioso" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="controls"
|
||||
android:summary="Mostrar controles quando a tela estiver bloqueada"
|
||||
android:title="Controle da tela bloqueada" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="Theme_White"
|
||||
android:entries="@array/themes_text"
|
||||
|
|
|
|||
|
|
@ -58,6 +58,12 @@
|
|||
android:summary="Включать беззвучный режим на время записи"
|
||||
android:title="Режим тишины" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="controls"
|
||||
android:summary="Показывать панель управления когда телефон заблокирован"
|
||||
android:title="Панель управления" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="Theme_White"
|
||||
android:entries="@array/themes_text"
|
||||
|
|
|
|||
|
|
@ -58,6 +58,12 @@
|
|||
android:summary="Put phone in 'silence mode' during recording"
|
||||
android:title="Silence mode" />
|
||||
|
||||
<SwitchPreferenceCompat
|
||||
android:defaultValue="false"
|
||||
android:key="controls"
|
||||
android:summary="Show controls when phone is locked"
|
||||
android:title="Lockscreen Controls" />
|
||||
|
||||
<ListPreference
|
||||
android:defaultValue="Theme_White"
|
||||
android:entries="@array/themes_text"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue