-
-
Save particle4dev/4b15f55bc1af5bc8fbc9df9446b76f44 to your computer and use it in GitHub Desktop.
Revisions
-
Venryx revised this gist
Jul 29, 2019 . 1 changed file with 4 additions and 16 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,22 +1,10 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.myapp"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <service android:name=".ForegroundService" android:enabled="true" android:exported="true"></service> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" -
Venryx revised this gist
Jul 29, 2019 . 1 changed file with 2 additions and 29 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -55,8 +55,8 @@ public class General extends Plugin { // From what I've seen you don't need the wake-lock or wifi-lock below for the audio-recorder to persist through screen-off. // However, to be on the safe side you might want to activate them anyway. (and/or if you have other functions that need them) private PowerManager.WakeLock wakeLock_partial = null; public void StartPartialWakeLock() { if (wakeLock_partial != null && wakeLock_partial.isHeld()) return; @@ -81,31 +81,4 @@ public class General extends Plugin { public void StopWifiLock() { wifiLock.release(); } } -
Venryx created this gist
Jul 29, 2019 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,75 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.myapp"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme" android:usesCleartextTraffic="true" > <service android:name=".ForegroundService" android:enabled="true" android:exported="true"></service> <activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:name="com.myapp.MainActivity" android:label="@string/title_activity_main" android:theme="@style/AppTheme.NoActionBarLaunch" android:launchMode="singleTop"> <!-- //android:launchMode="singleTask" --> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> <intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="@string/custom_url_scheme" /> </intent-filter> </activity> <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/file_paths"></meta-data> </provider> </application> <!-- Permissions --> <uses-permission android:name="android.permission.INTERNET" /> <!-- Camera, Photos, input file --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <!-- Geolocation API --> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-feature android:name="android.hardware.location.gps" /> <!-- Network API --> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- Navigator.getUserMedia --> <!-- Video --> <uses-permission android:name="android.permission.CAMERA" /> <!-- Audio --> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> <!-- v-added --> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> </manifest> This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,183 @@ package com.myapp; import android.app.Notification; import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.Intent; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioRecord; import android.media.AudioTrack; import android.media.MediaRecorder; import android.os.Build; import android.os.IBinder; import android.support.annotation.Nullable; import android.support.v4.app.NotificationCompat; import android.util.Log; import com.getcapacitor.PluginCall; import com.getcapacitor.PluginMethod; public class ForegroundService extends Service { public static final String CHANNEL_ID = "ForegroundServiceChannel"; @Override public void onCreate() { super.onCreate(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { String input = intent.getStringExtra("inputExtra"); createNotificationChannel(); Intent notificationIntent = new Intent(this, MainActivity.class); PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0); Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID) .setContentTitle("Foreground Service") .setContentText(input) .setSmallIcon(R.drawable.ic_launcher_foreground) .setContentIntent(pendingIntent) .build(); startForeground(1, notification); // do heavy work on a background thread StartRecorder(); //stopSelf(); return START_NOT_STICKY; } @Override public void onDestroy() { super.onDestroy(); } @Nullable @Override public IBinder onBind(Intent intent) { return null; } private void createNotificationChannel() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel serviceChannel = new NotificationChannel( CHANNEL_ID, "Foreground Service Channel", NotificationManager.IMPORTANCE_DEFAULT ); NotificationManager manager = getSystemService(NotificationManager.class); manager.createNotificationChannel(serviceChannel); } } private static String TAG = "ForegroundService"; // the audio recording options private static final int RECORDING_RATE = 44100; private static final int CHANNEL = AudioFormat.CHANNEL_IN_MONO; private static final int FORMAT = AudioFormat.ENCODING_PCM_16BIT; // the audio recorder private AudioRecord recorder; // the minimum buffer size needed for audio recording private static int BUFFER_SIZE = AudioRecord.getMinBufferSize(RECORDING_RATE, CHANNEL, FORMAT); // are we currently sending audio data private boolean currentlySendingAudio = false; public void StartRecorder() { Log.i(TAG, "Starting the audio stream"); currentlySendingAudio = true; startStreaming(); } public void StopRecorder() { Log.i(TAG, "Stopping the audio stream"); currentlySendingAudio = false; recorder.release(); } private void startStreaming() { Log.i(TAG, "Starting the background thread (in this foreground service) to read the audio data"); Thread streamThread = new Thread(() -> { try { Log.d(TAG, "Creating the buffer of size " + BUFFER_SIZE); //byte[] buffer = new byte[BUFFER_SIZE]; int rate = AudioTrack.getNativeOutputSampleRate(AudioManager.STREAM_SYSTEM); int bufferSize = AudioRecord.getMinBufferSize(rate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT); short[] buffer = new short[bufferSize]; android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_AUDIO); Log.d(TAG, "Creating the AudioRecord"); //recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, RECORDING_RATE, CHANNEL, FORMAT, BUFFER_SIZE * 10); recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, rate, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize); Log.d(TAG, "AudioRecord recording..."); recorder.startRecording(); while (currentlySendingAudio == true) { // read the data into the buffer int readSize = recorder.read(buffer, 0, buffer.length); double maxAmplitude = 0; for (int i = 0; i < readSize; i++) { if (Math.abs(buffer[i]) > maxAmplitude) { maxAmplitude = Math.abs(buffer[i]); } } double db = 0; if (maxAmplitude != 0) { db = 20.0 * Math.log10(maxAmplitude / 32767.0) + 90; } Log.d(TAG, "Max amplitude: " + maxAmplitude + " ; DB: " + db); } Log.d(TAG, "AudioRecord finished recording"); } catch (Exception e) { Log.e(TAG, "Exception: " + e); } }); // start the thread streamThread.start(); } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,111 @@ package com.myapp; import android.content.Context; import android.content.Intent; import android.media.AudioFormat; import android.media.AudioManager; import android.media.AudioRecord; import android.media.AudioTrack; import android.media.MediaRecorder; import android.net.wifi.WifiManager; import android.nfc.Tag; import android.os.PowerManager; import android.support.v4.content.ContextCompat; import android.util.Log; import android.widget.Button; import com.getcapacitor.JSObject; import com.getcapacitor.NativePlugin; import com.getcapacitor.Plugin; import com.getcapacitor.PluginCall; import com.getcapacitor.PluginMethod; import com.getcapacitor.PluginResult; import java.net.DatagramSocket; @NativePlugin() public class General extends Plugin { private static String TAG = "V.General"; @PluginMethod public void StartRecorder(PluginCall call) { Log.i(TAG, "Starting the foreground-thread"); Intent serviceIntent = new Intent(getActivity().getApplicationContext(), ForegroundService.class); serviceIntent.putExtra("inputExtra", "Foreground Service Example in Android"); ContextCompat.startForegroundService(getActivity(), serviceIntent); call.resolve(); } @PluginMethod public void StopRecorder(PluginCall call) { Log.i(TAG, "Stopping the foreground-thread"); Intent serviceIntent = new Intent(getActivity().getApplicationContext(), ForegroundService.class); getActivity().getApplicationContext().stopService(serviceIntent); call.resolve(); } // From what I've seen you don't need the wake-lock or wifi-lock below for the audio-recorder to persist through screen-off. // However, to be on the safe side you might want to activate them anyway. (and/or if you have other functions that need them) // wake-locks // ========== private PowerManager.WakeLock wakeLock_partial = null; public void StartPartialWakeLock() { if (wakeLock_partial != null && wakeLock_partial.isHeld()) return; Log.i("vmain", "Starting partial wake-lock."); final PowerManager pm = (PowerManager) getActivity().getApplicationContext().getSystemService(Context.POWER_SERVICE); wakeLock_partial = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "com.myapp:partial_wake_lock"); wakeLock_partial.acquire(); } public void StopPartialWakeLock() { if (wakeLock_partial != null && wakeLock_partial.isHeld()) { Log.i("vmain", "Stopping partial wake-lock."); wakeLock_partial.release(); } } private WifiManager.WifiLock wifiLock = null; public void StartWifiLock() { WifiManager wifiManager = (WifiManager) getActivity().getApplicationContext().getSystemService(Context.WIFI_SERVICE); wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, "LockTag"); wifiLock.acquire(); } public void StopWifiLock() { wifiLock.release(); } // ========== @PluginMethod() public void StartPartialWakeLock(PluginCall call) { //if (MainActivity.instance != null) MainActivity.instance.StartPartialWakeLock(); StartPartialWakeLock(); call.resolve(); } @PluginMethod() public void StopPartialWakeLock(PluginCall call) { //if (MainActivity.instance != null) MainActivity.instance.StopPartialWakeLock(); StopPartialWakeLock(); call.resolve(); } @PluginMethod() public void StartWifiLock(PluginCall call) { //if (MainActivity.instance != null) MainActivity.instance.StartPartialWakeLock(); StartWifiLock(); call.resolve(); } @PluginMethod() public void StopWifiLock(PluginCall call) { //if (MainActivity.instance != null) MainActivity.instance.StopPartialWakeLock(); StopWifiLock(); call.resolve(); } }