Convert java to kotlin

This commit is contained in:
Brandon Presley 2022-07-05 12:43:04 +12:00
parent c928da0122
commit 3d32f391e6
17 changed files with 314 additions and 552 deletions

View File

@ -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"
}
}

View File

@ -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);
}
}

View 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)
}
}

View File

@ -1,73 +0,0 @@
package com.massive; // replace com.your-app-name with your apps 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);
}
}

View 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 apps 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))
}
}

View File

@ -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;
}
}

View 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
}
}

View File

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

View 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()
}
}

View File

@ -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;
}
}
}

View 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
}
}
}

View File

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

View 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()
}
}
}
}
}

View File

@ -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) {
}
}

View 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
}
}

View File

@ -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>

View File

@ -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
}