How to create custom native module android for react native app? - react-native

I've build simple service in android studio to run a service every second in console log,
and I want to implement my android studio code in react native
there's a way to do that?
let say I've a code :
myService.class
public class myService extends Service {
private Handler handler= new Handler();
private boolean run = true;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public void onStart(Intent i, int startId){
super.onStart(i, startId);
handler.postDelayed(new Runnable() {
#Override
public void run() {
if (run){
Log.e("Second", "test");
}
handler.postDelayed(this,1000);
}
},1000);
}
public void onDestroy(){
super.onDestroy();
run=false;
Log.d("Test", "Screen on");
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onPause() {
super.onPause();
Log.d("Test", "Screen off");
startService(new Intent(this, myService.class));
}
#Override
protected void onResume() {
super.onResume();
startService(new Intent(this, myService.class));
}
}

You can use RN Native modules. For background tasks Headless JS is useful. And for listening events LifecycleEventListener is what you are looking for. getReactApplicationContext().startService(new Intent(getReactApplicationContext(), myService.class) will do the rest. I am ready for further help
Please refer to https://facebook.github.io/react-native/docs/native-modules-android

You can follow the docs: https://facebook.github.io/react-native/docs/native-modules-android
The other answer pretty much covers the way you implement RN Modules. A useful tip is how to send events to JavaScript, such as below:
private void sendEvent(ReactContext reactContext,
String eventName,
#Nullable WritableMap params) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
...
WritableMap params = Arguments.createMap();
...
sendEvent(reactContext, "keyboardWillShow", params);
Further Reading (for your intended feature) for background tasks [ANDROID]
Just to add, you seem like you want to create a background task in React Native. Now from experience, if you want to run something every second - this will work as expected, until the device goes into Doze mode. If you don't want the service to run in the background or Doze mode - that's fine. If so, you may want to start reading about Doze mode and how to test your service in a Doze mode environment.
The issue with background tasks, is that if the phone is idle or stationary - the phone will go into Doze mode. This impacts upon some functionality, such as network. It is expected that if you need to perform actions in Doze mode that you do within a Maintenance Window
Now, I've managed to overcome some issues - by using an Alarm Clock Manager and resetting it to stop Doze mode. However, this does not work in all cases. You'll need a combination of that and a service to keep it alive (but will act differently on a lot of phones). Sometimes the GC just ditches it and kills the process.
Useful links:
Testing your service in Doze mode:
https://developer.android.com/training/monitoring-device-state/doze-standby#testing_doze
Understanding Doze:
https://developer.android.com/training/monitoring-device-state/doze-standby#understand_doze

Related

How display Firebase In-App Messaging on TWA?

I tried to display In-App Messaging but it didn't show up with TWA.
In-App Messaging works without any problems with normal Activity.
I use https://github.com/GoogleChrome/android-browser-helper/tree/main/demos/twa-basic to test TWA.
My application is correctly configured with Firebase.
I created a campaign.
My logs after publishing the campaign:
I closed my application and then launched it and I didn't see In-App Messaging.
I tested another application with a standard Activity and there was no problem displaying In-App Messaging.
I took a lot of time today to answer this question for myself.
In my opinion TWA can't work with In-App Messaging.
I am not an Android programmer and I could be wrong.
This is my test Activity:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FirebaseInAppMessaging.getInstance().setMessagesSuppressed(true);
}
public void onClick(View view) {
CampaignMetadata campaignMetadata = new CampaignMetadata("test_campaign", "name", true);
Text title = Text.builder().setText("test").setHexColor("#000000").build();
Text body = Text.builder().setText("test").setHexColor("#000000").build();
ModalMessage message = ModalMessage.builder()
.setBackgroundHexColor("#ffffff")
.setTitle(title)
.setBody(body)
.build(campaignMetadata, null);
FirebaseInAppMessagingDisplay.getInstance().testMessage(this, message, null);
FirebaseInAppMessaging.getInstance().setMessagesSuppressed(false);
}
#Override
protected void onResume() {
super.onResume();
}
}
To display In App Messaging we need a Activity. I think we can only In App Messaging display on splash screen TWA but i didn't try it.

React Native how to use Braintree PayPal Value

I use react-native to develop an app, and I need to connect to braintree (paypal value). The official provides 3 kinds of sdk, js, android, and ios. I try to connect to the native android library, but it doesn't seem to have any effect.After calling the native method in ReactNative, only "react-native-test" is output (No error is reported, and there is no change on the interface. It seems that it should jump to PayPal authorization to be normal). I'm not sure if it's my problem . I also tried to use js library in react-native, but after importing a certain method, my program doesn't start. Or can I only do it in webView? Has anyone connected with PayPal value? Can you give me some advice? Thanks.
Here is the documentation I refer to.
Below is my android codeļ¼š
public class BraintreeValueModule extends ReactContextBaseJavaModule implements PayPalListener {
private static ReactApplicationContext reactContext;
private Callback successCallback;
private Callback errorCallback;
private BraintreeClient braintreeClient;
private PayPalClient payPalClient;
public BraintreeValueModule(ReactApplicationContext context) {
super(context);
reactContext = context;
}
#NonNull
#Override
public String getName() {
return "BraintreeValueModule";
}
#ReactMethod
public void test(){
System.out.println("react-native-test");
braintreeClient = new BraintreeClient(reactContext.getApplicationContext(), "sandbox_ykbznr4s_ctmssyj6wz2qcj2g");
FragmentActivity activity = (FragmentActivity) getCurrentActivity();
activity.runOnUiThread(new MyRunnable(activity,braintreeClient));
//The following writing method will report an error: Method addObserver must be called on the main thread
//if(activity != null){
// payPalClient = new PayPalClient(activity, braintreeClient);
// payPalClient.setListener(this);
//}
}
#Override
public void onPayPalSuccess(#NonNull PayPalAccountNonce payPalAccountNonce) {
successCallback.invoke(payPalAccountNonce.toString());
}
#Override
public void onPayPalFailure(#NonNull Exception error) {
if (error instanceof UserCanceledException) {
// user canceled
errorCallback.invoke("use canceled");
} else {
// handle error
errorCallback.invoke("error");
}
}
}
public class MyRunnable implements Runnable, PayPalListener {
private BraintreeClient braintreeClient;
private PayPalClient payPalClient;
private FragmentActivity activity;
MyRunnable(FragmentActivity activity,BraintreeClient braintreeClient){
this.activity = activity;
this.braintreeClient = braintreeClient;
}
#Override
public void run() {
if(activity != null){
payPalClient = new PayPalClient(activity, braintreeClient);
payPalClient.setListener(this);
}
}
#Override
public void onPayPalSuccess(#NonNull PayPalAccountNonce payPalAccountNonce) {
System.out.println(payPalAccountNonce.getString());
}
#Override
public void onPayPalFailure(#NonNull Exception error) {
if (error instanceof UserCanceledException) {
// user canceled
System.out.println("use canceled");
} else {
// handle error
System.out.println("error");
}
}
}
I believe you might have missed out the following few lines:
PayPalVaultRequest request = new PayPalVaultRequest();
request.setBillingAgreementDescription("Your agreement description");
payPalClient.tokenizePayPalAccount(getCurrentActivity(), request);
However, I believe it might still not work as I had similar problem when I was trying to integrate the drop-in.
I'm afraid that you'll need to initialise your clients (in your case, BraintreeClient and PaypalClient) in the onCreate method of your MainActivity.
And then try to call a reference to the client (either by SharedPreference or static variable) in your module to launch the drop in.
Pretty sure it's similar issue to your case.
This only applies to the v4 library.
Read more on this thread:
https://github.com/braintree/braintree-android-drop-in/issues/374#issuecomment-1345929549

How do I make the "user operation is waiting" dialog invisible in Eclipse RCP?

I'm creating a web development framework with Eclipse RCP.
The wizard is creating a feature that creates a project when you press Finish.
I want to show Process Monitor at the bottom of the wizard
I wrote the code as below.
public abstract class CreateProjectWizard extends Wizard {
public CreateProjectWizard () {
...
setNeedsProgressMonitor(true);
}
...
#Override
public boolean performFinish() {
IRunnableWithProgress runnable= new IRunnableWithProgress() {
#Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
...
IStatus status = createProject(input, monitor);
...
}
};
try {
getContainer().run(true, true, runnable);
}
...
return true;
}
}
How do I make the "user operation is waiting" dialog invisible?
I will let you know if you need additional information.
It looks like you should be able to call Dialog.setBlockedHandler with something that implements IDialogBlockedHandler to change this dialog (both in org.eclipse.jface.dialogs).
The blocked handler does not have to display a dialog, the default JFace handler is just:
new IDialogBlockedHandler() {
#Override
public void clearBlocked() {
// No default behavior
}
#Override
public void showBlocked(IProgressMonitor blocking,
IStatus blockingStatus, String blockedName) {
// No default behavior
}
#Override
public void showBlocked(Shell parentShell, IProgressMonitor blocking,
IStatus blockingStatus, String blockedName) {
// No default behavior
}
};
Eclipse normally replaces this with org.eclipse.ui.internal.dialogs.WorkbenchDialogBlockedHandler which shows the dialog you see (BlockedJobsDialog).
Note that this will not stop the operation waiting for the blocking jobs to finish it will just stop the dialog appearing.

Realtime checking the progress monitor using Job.getJobManager.IsIdle()

I am trying to continuously check if the progress monitor has an operation that is running in the background.
For this, I used Job.getJobManager.IsIdle().
I have tried the following:
Put it inside a Job.
WorkspaceJob job = new WorkspaceJob("Hello")
{
#Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException
{
while(!Job.getJobManager().isIdle())
{
System.out.println(!Job.getJobManager().isIdle());
}
return Status.OK_STATUS;
}
};
job.setPriority(Job.SHORT);
job.schedule();
But this does not work as Job.getJobManager.isIdle will never return false because Job 'Hello' is running.
Put it inside an asynchronous thread.
new Thread(new Runnable()
{
#Override
public void run()
{
Display.getDefault().asyncExec(new Runnable()
{
#Override
public void run()
{
while(!Job.getJobManager().isIdle())
{
System.out.println("hi");
}
}
});
}
}).start();
But this does not work either as this will freeze the main Eclipse GUI preventing other processes (if there are any existing) to finish.
If anyone has suggestions or any input on how it should be done, it would be great!
You can use a job change listener IJobChangeListener to listen for all changes to job states. You can than test for idle in appropriate places in the listener. Do not try and loop calling isIdle.
You can use the JobChangeAdapter class which provides default implementations of the IJobChangeListener methods so that you only have to override the events you are interested in, probably just the done method:
Job.getJobManager().addJobChangeListener(new JobChangeAdapter()
{
#Override
public void done(IJobChangeEvent event)
{
if (Job.getJobManager().isIdle() {
// Manager is idle
}
}
});

Eclipse Plugin - execute when user changes window in perspective

I would like to ask how would you automatically execute a plugin when a user switches windows in the perspective.
Can this be done maybe with startup handler and IWorkbench?
You can use IPartListener to listen to changes in which part is active.
You can set this up in using IStartup but you need to do this using something like this:
public class StartUp implements IStartup
{
#Override
public void earlyStartup()
{
IWorkbench workbench = PlatformUI.getWorkbench();
workbench.getDisplay().asyncExec(new Runnable() {
#Override
public void run() {
IWorkbenchWindow window = workbench.getActiveWorkbenchWindow();
if (window != null) {
window.getPartService().addPartListener(your part listener);
}
}
});
}
}
This is using Display.asyncExec to delay setting up the part listener until after the startup has completed as the workbench window will not be available when earlyStartup runs.