Convert java to kotlin
This commit is contained in:
parent
c928da0122
commit
3d32f391e6
|
@ -1,82 +1,8 @@
|
|||
apply plugin: "com.android.application"
|
||||
apply plugin: "kotlin-android"
|
||||
|
||||
import com.android.build.OutputFile
|
||||
|
||||
/**
|
||||
* The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
|
||||
* and bundleReleaseJsAndAssets).
|
||||
* These basically call `react-native bundle` with the correct arguments during the Android build
|
||||
* cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
|
||||
* bundle directly from the development server. Below you can see all the possible configurations
|
||||
* and their defaults. If you decide to add a configuration block, make sure to add it before the
|
||||
* `apply from: "../../node_modules/react-native/react.gradle"` line.
|
||||
*
|
||||
* project.ext.react = [
|
||||
* // the name of the generated asset file containing your JS bundle
|
||||
* bundleAssetName: "index.android.bundle",
|
||||
*
|
||||
* // the entry file for bundle generation. If none specified and
|
||||
* // "index.android.js" exists, it will be used. Otherwise "index.js" is
|
||||
* // default. Can be overridden with ENTRY_FILE environment variable.
|
||||
* entryFile: "index.android.js",
|
||||
*
|
||||
* // https://reactnative.dev/docs/performance#enable-the-ram-format
|
||||
* bundleCommand: "ram-bundle",
|
||||
*
|
||||
* // whether to bundle JS and assets in debug mode
|
||||
* bundleInDebug: false,
|
||||
*
|
||||
* // whether to bundle JS and assets in release mode
|
||||
* bundleInRelease: true,
|
||||
*
|
||||
* // whether to bundle JS and assets in another build variant (if configured).
|
||||
* // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
|
||||
* // The configuration property can be in the following formats
|
||||
* // 'bundleIn${productFlavor}${buildType}'
|
||||
* // 'bundleIn${buildType}'
|
||||
* // bundleInFreeDebug: true,
|
||||
* // bundleInPaidRelease: true,
|
||||
* // bundleInBeta: true,
|
||||
*
|
||||
* // whether to disable dev mode in custom build variants (by default only disabled in release)
|
||||
* // for example: to disable dev mode in the staging build type (if configured)
|
||||
* devDisabledInStaging: true,
|
||||
* // The configuration property can be in the following formats
|
||||
* // 'devDisabledIn${productFlavor}${buildType}'
|
||||
* // 'devDisabledIn${buildType}'
|
||||
*
|
||||
* // the root of your project, i.e. where "package.json" lives
|
||||
* root: "../../",
|
||||
*
|
||||
* // where to put the JS bundle asset in debug mode
|
||||
* jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
|
||||
*
|
||||
* // where to put the JS bundle asset in release mode
|
||||
* jsBundleDirRelease: "$buildDir/intermediates/assets/release",
|
||||
*
|
||||
* // where to put drawable resources / React Native assets, e.g. the ones you use via
|
||||
* // require('./image.png')), in debug mode
|
||||
* resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
|
||||
*
|
||||
* // where to put drawable resources / React Native assets, e.g. the ones you use via
|
||||
* // require('./image.png')), in release mode
|
||||
* resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
|
||||
*
|
||||
* // by default the gradle tasks are skipped if none of the JS files or assets change; this means
|
||||
* // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
|
||||
* // date; if you have any other folders that you want to ignore for performance reasons (gradle
|
||||
* // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
|
||||
* // for example, you might want to remove it from here.
|
||||
* inputExcludes: ["android/**", "ios/**"],
|
||||
*
|
||||
* // override which node gets called and with what additional arguments
|
||||
* nodeExecutableAndArgs: ["node"],
|
||||
*
|
||||
* // supply additional arguments to the packager
|
||||
* extraPackagerArgs: []
|
||||
* ]
|
||||
*/
|
||||
|
||||
project.ext.react = [
|
||||
enableHermes: false, // clean and rebuild if changing
|
||||
]
|
||||
|
@ -84,60 +10,28 @@ project.ext.react = [
|
|||
apply from: "../../node_modules/react-native/react.gradle"
|
||||
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
|
||||
|
||||
/**
|
||||
* Set this to true to create two separate APKs instead of one:
|
||||
* - An APK that only works on ARM devices
|
||||
* - An APK that only works on x86 devices
|
||||
* The advantage is the size of the APK is reduced by about 4MB.
|
||||
* Upload all the APKs to the Play Store and people will download
|
||||
* the correct one based on the CPU architecture of their device.
|
||||
*/
|
||||
def enableSeparateBuildPerCPUArchitecture = false
|
||||
|
||||
/**
|
||||
* Run Proguard to shrink the Java bytecode in release builds.
|
||||
*/
|
||||
def enableProguardInReleaseBuilds = false
|
||||
|
||||
/**
|
||||
* The preferred build flavor of JavaScriptCore.
|
||||
*
|
||||
* For example, to use the international variant, you can use:
|
||||
* `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
|
||||
*
|
||||
* The international variant includes ICU i18n library and necessary data
|
||||
* allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
|
||||
* give correct results when using with locales other than en-US. Note that
|
||||
* this variant is about 6MiB larger per architecture than default.
|
||||
*/
|
||||
def jscFlavor = 'org.webkit:android-jsc:+'
|
||||
|
||||
/**
|
||||
* Whether to enable the Hermes VM.
|
||||
*
|
||||
* This should be set on project.ext.react and that value will be read here. If it is not set
|
||||
* on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
|
||||
* and the benefits of using Hermes will therefore be sharply reduced.
|
||||
*/
|
||||
def enableHermes = project.ext.react.get("enableHermes", false);
|
||||
|
||||
/**
|
||||
* Architectures to build native code for.
|
||||
*/
|
||||
def reactNativeArchitectures() {
|
||||
def value = project.getProperties().get("reactNativeArchitectures")
|
||||
return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
|
||||
}
|
||||
|
||||
android {
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
}
|
||||
|
||||
packagingOptions {
|
||||
pickFirst '**/armeabi-v7a/libfolly_runtime.so'
|
||||
pickFirst '**/x86/libfolly_runtime.so'
|
||||
pickFirst '**/arm64-v8a/libfolly_runtime.so'
|
||||
pickFirst '**/x86_64/libfolly_runtime.so'
|
||||
jniLibs {
|
||||
pickFirsts += ['**/armeabi-v7a/libfolly_runtime.so', '**/x86/libfolly_runtime.so', '**/arm64-v8a/libfolly_runtime.so', '**/x86_64/libfolly_runtime.so']
|
||||
}
|
||||
}
|
||||
ndkVersion rootProject.ext.ndkVersion
|
||||
|
||||
compileSdkVersion rootProject.ext.compileSdkVersion
|
||||
|
||||
defaultConfig {
|
||||
|
@ -150,7 +44,6 @@ android {
|
|||
buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
// We configure the NDK build only if you decide to opt-in for the New Architecture.
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
arguments "APP_PLATFORM=android-21",
|
||||
|
@ -163,8 +56,6 @@ android {
|
|||
"NODE_MODULES_DIR=$rootDir/../node_modules"
|
||||
cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
|
||||
cppFlags "-std=c++17"
|
||||
// Make sure this target name is the same you specify inside the
|
||||
// src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
|
||||
targets "massive_appmodules"
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +68,6 @@ android {
|
|||
}
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
// We configure the NDK build only if you decide to opt-in for the New Architecture.
|
||||
externalNativeBuild {
|
||||
ndkBuild {
|
||||
path "$projectDir/src/main/jni/Android.mk"
|
||||
|
@ -195,15 +85,9 @@ android {
|
|||
into("$buildDir/react-ndk/exported")
|
||||
}
|
||||
afterEvaluate {
|
||||
// If you wish to add a custom TurboModule or component locally,
|
||||
// you should uncomment this line.
|
||||
// preBuild.dependsOn("generateCodegenArtifactsFromSchema")
|
||||
preDebugBuild.dependsOn(packageReactNdkDebugLibs)
|
||||
preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
|
||||
|
||||
// Due to a bug inside AGP, we have to explicitly set a dependency
|
||||
// between configureNdkBuild* tasks and the preBuild tasks.
|
||||
// This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
|
||||
configureNdkBuildRelease.dependsOn(preReleaseBuild)
|
||||
configureNdkBuildDebug.dependsOn(preDebugBuild)
|
||||
reactNativeArchitectures().each { architecture ->
|
||||
|
@ -221,7 +105,7 @@ android {
|
|||
abi {
|
||||
reset()
|
||||
enable enableSeparateBuildPerCPUArchitecture
|
||||
universalApk false // If true, also generate a universal APK
|
||||
universalApk false
|
||||
include (*reactNativeArchitectures())
|
||||
}
|
||||
}
|
||||
|
@ -238,20 +122,14 @@ android {
|
|||
signingConfig signingConfigs.debug
|
||||
}
|
||||
release {
|
||||
// Caution! In production, you need to generate your own keystore file.
|
||||
// see https://reactnative.dev/docs/signed-apk-android.
|
||||
signingConfig signingConfigs.debug
|
||||
minifyEnabled enableProguardInReleaseBuilds
|
||||
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
|
||||
}
|
||||
}
|
||||
|
||||
// applicationVariants are e.g. debug, release
|
||||
applicationVariants.all { variant ->
|
||||
variant.outputs.each { output ->
|
||||
// For each separate APK per architecture, set a unique version code as described here:
|
||||
// https://developer.android.com/studio/build/configure-apk-splits.html
|
||||
// Example: versionCode 1 will generate 1001 for armeabi-v7a, 1002 for x86, etc.
|
||||
def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
|
||||
def abi = output.getFilter(OutputFile.ABI)
|
||||
if (abi != null) { // null for the universal-debug, universal-release variants
|
||||
|
@ -265,28 +143,16 @@ android {
|
|||
|
||||
dependencies {
|
||||
def work_version = "2.7.1"
|
||||
// (Java only)
|
||||
|
||||
implementation "androidx.work:work-runtime:$work_version"
|
||||
|
||||
// Kotlin + coroutines
|
||||
implementation "androidx.work:work-runtime-ktx:$work_version"
|
||||
|
||||
// optional - RxJava2 support
|
||||
implementation "androidx.work:work-rxjava2:$work_version"
|
||||
|
||||
// optional - GCMNetworkManager support
|
||||
implementation "androidx.work:work-gcm:$work_version"
|
||||
|
||||
// optional - Test helpers
|
||||
androidTestImplementation "androidx.work:work-testing:$work_version"
|
||||
// optional - Multiprocess support
|
||||
implementation "androidx.work:work-multiprocess:$work_version"
|
||||
|
||||
implementation fileTree(dir: "libs", include: ["*.jar"])
|
||||
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation "com.facebook.react:react-native:+" // From node_modules
|
||||
|
||||
implementation "androidx.core:core-ktx:1.8.0"
|
||||
implementation project(':react-native-sqlite-storage')
|
||||
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
|
||||
|
||||
|
@ -304,7 +170,6 @@ dependencies {
|
|||
}
|
||||
|
||||
if (enableHermes) {
|
||||
//noinspection GradleDynamicVersion
|
||||
implementation("com.facebook.react:hermes-engine:+") { // From node_modules
|
||||
exclude group:'com.facebook.fbjni'
|
||||
}
|
||||
|
@ -314,9 +179,6 @@ dependencies {
|
|||
}
|
||||
|
||||
if (isNewArchitectureEnabled()) {
|
||||
// If new architecture is enabled, we let you build RN from source
|
||||
// Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
|
||||
// This will be applied to all the imported transtitive dependency.
|
||||
configurations.all {
|
||||
resolutionStrategy.dependencySubstitution {
|
||||
substitute(module("com.facebook.react:react-native"))
|
||||
|
@ -329,8 +191,6 @@ if (isNewArchitectureEnabled()) {
|
|||
}
|
||||
}
|
||||
|
||||
// Run this once to be able to run the application with BUCK
|
||||
// puts all compile dependencies into folder libs for BUCK to use
|
||||
task copyDownloadableDepsToLibs(type: Copy) {
|
||||
from configurations.implementation
|
||||
into 'libs'
|
||||
|
@ -339,9 +199,5 @@ task copyDownloadableDepsToLibs(type: Copy) {
|
|||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
||||
|
||||
def isNewArchitectureEnabled() {
|
||||
// To opt-in for the New Architecture, you can either:
|
||||
// - Set `newArchEnabled` to true inside the `gradle.properties` file
|
||||
// - Invoke gradle with `-newArchEnabled=true`
|
||||
// - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
|
||||
return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package com.massive;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class AlarmActivity extends Activity {
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState) {
|
||||
Log.d("AlarmActivity", "Call to AlarmActivity");
|
||||
super.onCreate(savedInstanceState);
|
||||
Context context = getApplicationContext();
|
||||
context.stopService(new Intent(context, AlarmService.class));
|
||||
Intent intent = new Intent(context, MainActivity.class);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) {
|
||||
return super.onCreateView(name, context, attrs);
|
||||
}
|
||||
}
|
28
android/app/src/main/java/com/massive/AlarmActivity.kt
Normal file
28
android/app/src/main/java/com/massive/AlarmActivity.kt
Normal file
|
@ -0,0 +1,28 @@
|
|||
package com.massive
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.WindowManager
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.massive.AlarmService
|
||||
import com.massive.MainActivity
|
||||
|
||||
class AlarmActivity : Activity() {
|
||||
@RequiresApi(Build.VERSION_CODES.O_MR1)
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
Log.d("AlarmActivity", "Call to AlarmActivity")
|
||||
super.onCreate(savedInstanceState)
|
||||
val context = applicationContext
|
||||
context.stopService(Intent(context, AlarmService::class.java))
|
||||
savedInstanceState.apply { setShowWhenLocked(true) }
|
||||
val intent = Intent(context, MainActivity::class.java)
|
||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
context.startActivity(intent)
|
||||
}
|
||||
}
|
|
@ -1,73 +0,0 @@
|
|||
package com.massive; // replace com.your-app-name with your app’s name
|
||||
|
||||
import static android.content.Context.ALARM_SERVICE;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.MediaPlayer;
|
||||
import android.os.Build;
|
||||
import android.os.SystemClock;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
import androidx.work.OneTimeWorkRequest;
|
||||
import androidx.work.PeriodicWorkRequest;
|
||||
import androidx.work.WorkManager;
|
||||
import androidx.work.WorkRequest;
|
||||
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class AlarmModule extends ReactContextBaseJavaModule {
|
||||
AlarmModule(ReactApplicationContext context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "AlarmModule";
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
@ReactMethod()
|
||||
public void timer(int milliseconds) {
|
||||
Log.d("AlarmModule", "Queue alarm for " + milliseconds + " delay");
|
||||
Intent intent = new Intent(getReactApplicationContext(), MyBroadcastReceiver.class);
|
||||
PendingIntent pendingIntent = PendingIntent.getBroadcast(
|
||||
getReactApplicationContext(), 69, intent, PendingIntent.FLAG_IMMUTABLE);
|
||||
AlarmManager alarmManager = (AlarmManager) getReactApplicationContext().getSystemService(ALARM_SERVICE);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
Log.d("AlarmModule", "Can schedule: " + alarmManager.canScheduleExactAlarms());
|
||||
}
|
||||
AlarmManager.AlarmClockInfo info = new AlarmManager.AlarmClockInfo(System.currentTimeMillis() + milliseconds, pendingIntent);
|
||||
alarmManager.setAlarmClock(info, pendingIntent);
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public void stop() {
|
||||
Log.d("AlarmModule", "Request to stop timer.");
|
||||
Intent intent = new Intent(getReactApplicationContext(), MyBroadcastReceiver.class);
|
||||
intent.setAction("stop");
|
||||
getReactApplicationContext().startActivity(intent);
|
||||
}
|
||||
}
|
46
android/app/src/main/java/com/massive/AlarmModule.kt
Normal file
46
android/app/src/main/java/com/massive/AlarmModule.kt
Normal file
|
@ -0,0 +1,46 @@
|
|||
package com.massive
|
||||
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule
|
||||
import android.app.PendingIntent
|
||||
import android.app.AlarmManager
|
||||
import androidx.annotation.RequiresApi
|
||||
import com.facebook.react.bridge.ReactMethod
|
||||
import android.content.Intent
|
||||
import com.massive.MyBroadcastReceiver
|
||||
import android.app.AlarmManager.AlarmClockInfo
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
|
||||
// replace com.your-app-name with your app’s name
|
||||
class AlarmModule internal constructor(context: ReactApplicationContext?) :
|
||||
ReactContextBaseJavaModule(context) {
|
||||
private var pendingIntent: PendingIntent? = null
|
||||
private var alarmManager: AlarmManager? = null
|
||||
override fun getName(): String {
|
||||
return "AlarmModule"
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
@ReactMethod
|
||||
fun timer(milliseconds: Int) {
|
||||
Log.d("AlarmModule", "Queue alarm for $milliseconds delay")
|
||||
val intent = Intent(reactApplicationContext, MyBroadcastReceiver::class.java)
|
||||
pendingIntent = PendingIntent.getBroadcast(
|
||||
reactApplicationContext, 69, intent, PendingIntent.FLAG_IMMUTABLE
|
||||
)
|
||||
alarmManager =
|
||||
reactApplicationContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
|
||||
val info = AlarmClockInfo(System.currentTimeMillis() + milliseconds, pendingIntent)
|
||||
alarmManager!!.setAlarmClock(info, pendingIntent)
|
||||
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
fun stop() {
|
||||
Log.d("AlarmModule", "Request to stop timer.")
|
||||
alarmManager?.cancel(pendingIntent)
|
||||
reactApplicationContext.stopService(Intent(reactApplicationContext, AlarmService::class.java))
|
||||
}
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
package com.massive;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class AlarmPackage implements ReactPackage {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(
|
||||
@NonNull ReactApplicationContext reactContext) {
|
||||
List<NativeModule> modules = new ArrayList<>();
|
||||
|
||||
modules.add(new AlarmModule(reactContext));
|
||||
|
||||
return modules;
|
||||
}
|
||||
|
||||
}
|
22
android/app/src/main/java/com/massive/AlarmPackage.kt
Normal file
22
android/app/src/main/java/com/massive/AlarmPackage.kt
Normal file
|
@ -0,0 +1,22 @@
|
|||
package com.massive
|
||||
|
||||
import com.facebook.react.ReactPackage
|
||||
import com.facebook.react.bridge.NativeModule
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.uimanager.ViewManager
|
||||
import com.massive.AlarmModule
|
||||
import java.util.ArrayList
|
||||
|
||||
class AlarmPackage : ReactPackage {
|
||||
override fun createViewManagers(reactContext: ReactApplicationContext): List<ViewManager<*, *>> {
|
||||
return emptyList()
|
||||
}
|
||||
|
||||
override fun createNativeModules(
|
||||
reactContext: ReactApplicationContext
|
||||
): List<NativeModule> {
|
||||
val modules: MutableList<NativeModule> = ArrayList()
|
||||
modules.add(AlarmModule(reactContext))
|
||||
return modules
|
||||
}
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
package com.massive;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioAttributes;
|
||||
import android.media.MediaPlayer;
|
||||
import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
public class AlarmService extends Service implements MediaPlayer.OnPreparedListener {
|
||||
private static final String ACTION_PLAY = "com.example.action.PLAY";
|
||||
MediaPlayer mediaPlayer = null;
|
||||
private Vibrator vibrator;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
Log.d("AlarmService", "Starting alarm: " + intent.getAction());
|
||||
mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.argon);
|
||||
mediaPlayer.start();
|
||||
mediaPlayer.setOnCompletionListener(mediaPlayer -> vibrator.cancel());
|
||||
long[] pattern = {0, 300, 1300, 300, 1300, 300};
|
||||
vibrator = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
|
||||
AudioAttributes audioAttributes = new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.setUsage(AudioAttributes.USAGE_ALARM)
|
||||
.build();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
vibrator.vibrate(VibrationEffect.createWaveform(pattern, 1), audioAttributes);
|
||||
} else {
|
||||
vibrator.vibrate(pattern, 1, audioAttributes);
|
||||
}
|
||||
return START_STICKY;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public IBinder onBind(Intent intent) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Called when MediaPlayer is ready */
|
||||
public void onPrepared(MediaPlayer player) {
|
||||
player.start();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (mediaPlayer != null) mediaPlayer.release();
|
||||
if (vibrator != null) vibrator.cancel();
|
||||
}
|
||||
}
|
46
android/app/src/main/java/com/massive/AlarmService.kt
Normal file
46
android/app/src/main/java/com/massive/AlarmService.kt
Normal file
|
@ -0,0 +1,46 @@
|
|||
package com.massive
|
||||
|
||||
import android.app.Service
|
||||
import android.media.MediaPlayer.OnPreparedListener
|
||||
import android.media.MediaPlayer
|
||||
import android.os.Vibrator
|
||||
import androidx.annotation.RequiresApi
|
||||
import android.content.Intent
|
||||
import android.media.AudioAttributes
|
||||
import android.os.Build
|
||||
import android.os.VibrationEffect
|
||||
import android.os.IBinder
|
||||
|
||||
class AlarmService : Service(), OnPreparedListener {
|
||||
var mediaPlayer: MediaPlayer? = null
|
||||
private var vibrator: Vibrator? = null
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
||||
mediaPlayer = MediaPlayer.create(applicationContext, R.raw.argon)
|
||||
mediaPlayer?.start()
|
||||
mediaPlayer?.setOnCompletionListener { vibrator?.cancel() }
|
||||
val pattern = longArrayOf(0, 300, 1300, 300, 1300, 300)
|
||||
vibrator = applicationContext.getSystemService(VIBRATOR_SERVICE) as Vibrator
|
||||
val audioAttributes = AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.setUsage(AudioAttributes.USAGE_ALARM)
|
||||
.build()
|
||||
vibrator!!.vibrate(VibrationEffect.createWaveform(pattern, 1), audioAttributes)
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent): IBinder? {
|
||||
return null
|
||||
}
|
||||
|
||||
override fun onPrepared(player: MediaPlayer) {
|
||||
player.start()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
mediaPlayer?.release()
|
||||
vibrator?.cancel()
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package com.massive;
|
||||
|
||||
import com.facebook.react.ReactActivity;
|
||||
import com.facebook.react.ReactActivityDelegate;
|
||||
import com.facebook.react.ReactRootView;
|
||||
|
||||
public class MainActivity extends ReactActivity {
|
||||
|
||||
/**
|
||||
* Returns the name of the main component registered from JavaScript. This is used to schedule
|
||||
* rendering of the component.
|
||||
*/
|
||||
@Override
|
||||
protected String getMainComponentName() {
|
||||
return "massive";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and
|
||||
* you can specify the renderer you wish to use - the new renderer (Fabric) or the old renderer
|
||||
* (Paper).
|
||||
*/
|
||||
@Override
|
||||
protected ReactActivityDelegate createReactActivityDelegate() {
|
||||
return new MainActivityDelegate(this, getMainComponentName());
|
||||
}
|
||||
|
||||
public static class MainActivityDelegate extends ReactActivityDelegate {
|
||||
public MainActivityDelegate(ReactActivity activity, String mainComponentName) {
|
||||
super(activity, mainComponentName);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ReactRootView createRootView() {
|
||||
ReactRootView reactRootView = new ReactRootView(getContext());
|
||||
// If you opted-in for the New Architecture, we enable the Fabric Renderer.
|
||||
reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
|
||||
return reactRootView;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean isConcurrentRootEnabled() {
|
||||
// If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18).
|
||||
// More on this on https://reactjs.org/blog/2022/03/29/react-v18.html
|
||||
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||
}
|
||||
}
|
||||
}
|
28
android/app/src/main/java/com/massive/MainActivity.kt
Normal file
28
android/app/src/main/java/com/massive/MainActivity.kt
Normal file
|
@ -0,0 +1,28 @@
|
|||
package com.massive
|
||||
|
||||
import com.facebook.react.ReactActivity
|
||||
import com.facebook.react.ReactActivityDelegate
|
||||
import com.facebook.react.ReactRootView
|
||||
|
||||
class MainActivity : ReactActivity() {
|
||||
override fun getMainComponentName(): String? {
|
||||
return "massive"
|
||||
}
|
||||
|
||||
override fun createReactActivityDelegate(): ReactActivityDelegate {
|
||||
return MainActivityDelegate(this, mainComponentName)
|
||||
}
|
||||
|
||||
class MainActivityDelegate(activity: ReactActivity?, mainComponentName: String?) :
|
||||
ReactActivityDelegate(activity, mainComponentName) {
|
||||
override fun createRootView(): ReactRootView {
|
||||
val reactRootView = ReactRootView(context)
|
||||
reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED)
|
||||
return reactRootView
|
||||
}
|
||||
|
||||
override fun isConcurrentRootEnabled(): Boolean {
|
||||
return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,92 +0,0 @@
|
|||
package com.massive;
|
||||
|
||||
import android.app.Application;
|
||||
import android.content.Context;
|
||||
import com.facebook.react.PackageList;
|
||||
import com.facebook.react.ReactApplication;
|
||||
import com.facebook.react.ReactInstanceManager;
|
||||
import com.facebook.react.ReactNativeHost;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.soloader.SoLoader;
|
||||
import com.massive.newarchitecture.MainApplicationReactNativeHost;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import org.pgsqlite.SQLitePluginPackage;
|
||||
|
||||
public class MainApplication extends Application implements ReactApplication {
|
||||
|
||||
private final ReactNativeHost mReactNativeHost =
|
||||
new ReactNativeHost(this) {
|
||||
@Override
|
||||
public boolean getUseDeveloperSupport() {
|
||||
return BuildConfig.DEBUG;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<ReactPackage> getPackages() {
|
||||
@SuppressWarnings("UnnecessaryLocalVariable")
|
||||
List<ReactPackage> packages = new PackageList(this).getPackages();
|
||||
packages.add(new SQLitePluginPackage());
|
||||
packages.add(new AlarmPackage());
|
||||
return packages;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getJSMainModuleName() {
|
||||
return "index";
|
||||
}
|
||||
};
|
||||
|
||||
private final ReactNativeHost mNewArchitectureNativeHost =
|
||||
new MainApplicationReactNativeHost(this);
|
||||
|
||||
@Override
|
||||
public ReactNativeHost getReactNativeHost() {
|
||||
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||
return mNewArchitectureNativeHost;
|
||||
} else {
|
||||
return mReactNativeHost;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
// If you opted-in for the New Architecture, we enable the TurboModule system
|
||||
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
|
||||
SoLoader.init(this, /* native exopackage */ false);
|
||||
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
|
||||
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
|
||||
*
|
||||
* @param context
|
||||
* @param reactInstanceManager
|
||||
*/
|
||||
private static void initializeFlipper(
|
||||
Context context, ReactInstanceManager reactInstanceManager) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
try {
|
||||
/*
|
||||
We use reflection here to pick up the class that initializes Flipper,
|
||||
since Flipper library is not available in release mode
|
||||
*/
|
||||
Class<?> aClass = Class.forName("com.massive.ReactNativeFlipper");
|
||||
aClass
|
||||
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
|
||||
.invoke(null, context, reactInstanceManager);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IllegalAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InvocationTargetException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
72
android/app/src/main/java/com/massive/MainApplication.kt
Normal file
72
android/app/src/main/java/com/massive/MainApplication.kt
Normal file
|
@ -0,0 +1,72 @@
|
|||
package com.massive
|
||||
|
||||
import android.app.Application
|
||||
import android.content.Context
|
||||
import com.facebook.react.*
|
||||
import com.facebook.react.config.ReactFeatureFlags
|
||||
import com.facebook.soloader.SoLoader
|
||||
import com.massive.newarchitecture.MainApplicationReactNativeHost
|
||||
import org.pgsqlite.SQLitePluginPackage
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
|
||||
class MainApplication : Application(), ReactApplication {
|
||||
private val mReactNativeHost: ReactNativeHost = object : ReactNativeHost(this) {
|
||||
override fun getUseDeveloperSupport(): Boolean {
|
||||
return BuildConfig.DEBUG
|
||||
}
|
||||
|
||||
override fun getPackages(): List<ReactPackage> {
|
||||
val packages: MutableList<ReactPackage> = PackageList(this).packages
|
||||
packages.add(SQLitePluginPackage())
|
||||
packages.add(AlarmPackage())
|
||||
return packages
|
||||
}
|
||||
|
||||
override fun getJSMainModuleName(): String {
|
||||
return "index"
|
||||
}
|
||||
}
|
||||
|
||||
private val mNewArchitectureNativeHost: ReactNativeHost = MainApplicationReactNativeHost(this)
|
||||
override fun getReactNativeHost(): ReactNativeHost {
|
||||
return if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||
mNewArchitectureNativeHost
|
||||
} else {
|
||||
mReactNativeHost
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
|
||||
SoLoader.init(this, false)
|
||||
initializeFlipper(this, reactNativeHost.reactInstanceManager)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private fun initializeFlipper(
|
||||
context: Context, reactInstanceManager: ReactInstanceManager
|
||||
) {
|
||||
if (BuildConfig.DEBUG) {
|
||||
try {
|
||||
val aClass = Class.forName("com.massive.ReactNativeFlipper")
|
||||
aClass
|
||||
.getMethod(
|
||||
"initializeFlipper",
|
||||
Context::class.java,
|
||||
ReactInstanceManager::class.java
|
||||
)
|
||||
.invoke(null, context, reactInstanceManager)
|
||||
} catch (e: ClassNotFoundException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: NoSuchMethodException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: IllegalAccessException) {
|
||||
e.printStackTrace()
|
||||
} catch (e: InvocationTargetException) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
package com.massive;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.app.NotificationManagerCompat;
|
||||
|
||||
public class MyBroadcastReceiver extends BroadcastReceiver {
|
||||
private static final String CHANNEL_ID = "MassiveAlarm";
|
||||
private static final int ALARM_ID = 59;
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
Log.d("MyBroadcastReceiver", "Received intent for BroadcastReceiver.");
|
||||
String action = intent.getAction();
|
||||
Log.d("MyBroadcastReceiver", "Action: " + action);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
int importance = NotificationManager.IMPORTANCE_HIGH;
|
||||
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_ID, importance);
|
||||
channel.setDescription("Alarms for rest timings.");
|
||||
NotificationManager notificationManager = context.getSystemService(NotificationManager.class);
|
||||
notificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
context.startService(new Intent(context, AlarmService.class));
|
||||
Intent contentIntent = new Intent(context.getApplicationContext(), AlarmActivity.class);
|
||||
PendingIntent pendingContent = PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_IMMUTABLE);
|
||||
long[] pattern = {0, 100, 1000, 200, 2000};
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID)
|
||||
.setSmallIcon(R.drawable.rn_edit_text_material)
|
||||
.setContentTitle("Rest")
|
||||
.setContentText("Break times over!")
|
||||
.setContentIntent(pendingContent)
|
||||
.setAutoCancel(true)
|
||||
.setVibrate(pattern)
|
||||
.setCategory(NotificationCompat.CATEGORY_ALARM)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH);
|
||||
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
|
||||
notificationManager.notify(ALARM_ID, builder.build());
|
||||
}
|
||||
|
||||
private void vibrate(Context context) {
|
||||
}
|
||||
}
|
||||
|
||||
|
51
android/app/src/main/java/com/massive/MyBroadcastReceiver.kt
Normal file
51
android/app/src/main/java/com/massive/MyBroadcastReceiver.kt
Normal file
|
@ -0,0 +1,51 @@
|
|||
package com.massive
|
||||
|
||||
import androidx.annotation.RequiresApi
|
||||
import android.content.Intent
|
||||
import android.app.NotificationManager
|
||||
import android.app.NotificationChannel
|
||||
import com.massive.MyBroadcastReceiver
|
||||
import com.massive.AlarmService
|
||||
import com.massive.AlarmActivity
|
||||
import android.app.PendingIntent
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.Context
|
||||
import android.os.Build
|
||||
import android.util.Log
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.app.NotificationManagerCompat
|
||||
|
||||
class MyBroadcastReceiver : BroadcastReceiver() {
|
||||
@RequiresApi(api = Build.VERSION_CODES.M)
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
Log.d("MyBroadcastReceiver", "Received intent for BroadcastReceiver.")
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val importance = NotificationManager.IMPORTANCE_HIGH
|
||||
val channel = NotificationChannel(CHANNEL_ID, CHANNEL_ID, importance)
|
||||
channel.description = "Alarms for rest timings."
|
||||
val notificationManager = context.getSystemService(
|
||||
NotificationManager::class.java
|
||||
)
|
||||
notificationManager.createNotificationChannel(channel)
|
||||
}
|
||||
context.startService(Intent(context, AlarmService::class.java))
|
||||
val contentIntent = Intent(context.applicationContext, AlarmActivity::class.java)
|
||||
val pendingContent =
|
||||
PendingIntent.getActivity(context, 0, contentIntent, PendingIntent.FLAG_IMMUTABLE)
|
||||
val builder = NotificationCompat.Builder(context, CHANNEL_ID)
|
||||
.setSmallIcon(R.drawable.ic_baseline_timer_24)
|
||||
.setContentTitle("Rest")
|
||||
.setContentText("Break times over!")
|
||||
.setContentIntent(pendingContent)
|
||||
.setAutoCancel(true)
|
||||
.setCategory(NotificationCompat.CATEGORY_ALARM)
|
||||
.setPriority(NotificationCompat.PRIORITY_HIGH)
|
||||
val notificationManager = NotificationManagerCompat.from(context)
|
||||
notificationManager.notify(ALARM_ID, builder.build())
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val CHANNEL_ID = "MassiveAlarm"
|
||||
private const val ALARM_ID = 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
<vector android:height="24dp" android:tint="#000000"
|
||||
android:viewportHeight="24" android:viewportWidth="24"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="@android:color/white" android:pathData="M15,1L9,1v2h6L15,1zM11,14h2L13,8h-2v6zM19.03,7.39l1.42,-1.42c-0.43,-0.51 -0.9,-0.99 -1.41,-1.41l-1.42,1.42C16.07,4.74 14.12,4 12,4c-4.97,0 -9,4.03 -9,9s4.02,9 9,9 9,-4.03 9,-9c0,-2.12 -0.74,-4.07 -1.97,-5.61zM12,20c-3.87,0 -7,-3.13 -7,-7s3.13,-7 7,-7 7,3.13 7,7 -3.13,7 -7,7z"/>
|
||||
</vector>
|
|
@ -4,6 +4,7 @@ import org.apache.tools.ant.taskdefs.condition.Os
|
|||
|
||||
buildscript {
|
||||
ext {
|
||||
kotlin_version = '1.6.10'
|
||||
buildToolsVersion = "31.0.0"
|
||||
minSdkVersion = 21
|
||||
compileSdkVersion = 31
|
||||
|
@ -22,9 +23,10 @@ buildscript {
|
|||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath("com.android.tools.build:gradle:7.1.1")
|
||||
classpath('com.android.tools.build:gradle:7.2.1')
|
||||
classpath("com.facebook.react:react-native-gradle-plugin")
|
||||
classpath("de.undercouch:gradle-download-task:5.0.1")
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user