Skip to content

Instantly share code, notes, and snippets.

@particle4dev
Forked from Venryx/AndroidManifest.xml
Created June 29, 2020 07:18
Show Gist options
  • Select an option

  • Save particle4dev/4b15f55bc1af5bc8fbc9df9446b76f44 to your computer and use it in GitHub Desktop.

Select an option

Save particle4dev/4b15f55bc1af5bc8fbc9df9446b76f44 to your computer and use it in GitHub Desktop.

Revisions

  1. @Venryx Venryx revised this gist Jul 29, 2019. 1 changed file with 4 additions and 16 deletions.
    20 changes: 4 additions & 16 deletions AndroidManifest.xml
    Original 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">
    <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"
    <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>
    <service android:name=".ForegroundService" android:enabled="true" android:exported="true"></service>
    <activity
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
  2. @Venryx Venryx revised this gist Jul 29, 2019. 1 changed file with 2 additions and 29 deletions.
    31 changes: 2 additions & 29 deletions General.java (place that launches service)
    Original 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)

    // wake-locks
    // ==========


    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();
    }
    // ==========

    @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();
    }
    }
  3. @Venryx Venryx created this gist Jul 29, 2019.
    75 changes: 75 additions & 0 deletions AndroidManifest.xml
    Original 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>
    183 changes: 183 additions & 0 deletions ForegroundService.java
    Original 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();
    }
    }
    111 changes: 111 additions & 0 deletions General.java (place that launches service)
    Original 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();
    }
    }