Detached ExpoKit and Headless JS - react-native

Cross-posting from Expo's forums:
I have been having problems trying to get Headless JS task to execute on a detached ExpoKit project (SDK25). I have used the React Native documentation to do this.
I have a broadcast receiver
public class MessageReceivedReceiver extends BroadcastReceiver {
private static final String TAG = "MessageReceivedReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "onReceive");
if (!isAppOnForeground((context))) {
Log.i(TAG, "Not in foreground");
/**
We will start our service and send extra info about
network connections
**/
Intent serviceIntent = new Intent(context, JSBackgroundService.class);
serviceIntent.putExtras(intent.getExtras());
context.startService(serviceIntent);
HeadlessJsTaskService.acquireWakeLockNow(context);
}
}
...
A HeadlessJS Task Service:
public class JSBackgroundService extends HeadlessJsTaskService {
final static String TAG = "JSBackgroundService";
#Override
protected #Nullable
HeadlessJsTaskConfig getTaskConfig(Intent intent) {
Bundle extras = intent.getExtras();
Log.i(TAG, String.format("getTaskConfig: %s", extras));
if (extras != null) {
return new HeadlessJsTaskConfig(
"Test",
Arguments.fromBundle(extras),
5000, // timeout for the task
false // optional: defines whether or not the task is allowed in foreground. Default is false
);
}
return null;
}
}
My MainApplication implements ReactApplication:
public class MainApplication extends ExpoApplication implements ReactApplication {
private static final String TAG = MainApplication.class.getSimpleName();
private List<ReactPackage> packages = Arrays.<ReactPackage>asList(
// new MainReactPackage(),
new MyReactPackage()
);
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
#Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
#Override
protected List<ReactPackage> getPackages() {
return packages;
}
};
#Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
…
In App.js I have:
…
import JSBackgroundService from ‘./services/jsbackgroundservice’;
AppRegistry.registerHeadlessTask(‘Test’, () => {console.log(“Got it”); return JSBackgroundService; });
export default class App extends React.Component {
…
And JsBackgroundService:
module.exports = async (e) => {
// do stuff
console.log("Running the background service");
console.log(e);
};
Based on logs I know that getTaskConfig is executed but for some reason, I don’t see anything in the console logs, looks like the javascript never gets executed. I have tried also running the Headless JS in foreground for testing purposes but to no avail.
Does anyone have any ideas what could I be doing wrong?
Any help is appreciated :)

Related

Cannot override receiveCommand method in React Native Module manager

I'm trying to call UI component's method from Javascript. I follow official React Native documentation but I got this error:
error: method does not override or implement a method from a supertype
My WidgetManager.java
public class WidgetManager extends SimpleViewManager<LinearLayout> {
public static final String REACT_CLASS = "WidgetManager";
public WidgetManager(ReactApplicationContext reactContext) {}
#Override
public String getName() {
return REACT_CLASS;
}
#Override
public WidgetLayoutView createViewInstance(ThemedReactContext context) {
return new WidgetLayoutView(context);
}
#Override
public void receiveCommand(
#NonNull WidgetLayoutView view,
String commandId,
#Nullable ReadableArray args
) {
Log.v("ReactNative", commandId);
switch (commandId) {
case "addWidget":
{
view.addWidget(args.getInt(0));
return;
}
default:
throw new IllegalArgumentException(
String.format(
"Unsupported command %d received by %s.",
commandId,
getClass().getSimpleName()
)
);
}
}
}
I dispatch command via dispatchViewManagerCommand method.
UIManager.dispatchViewManagerCommand(
findNodeHandle(WidgetManagerRef.current),
'addWidget',
undefined,
);
What am I doing wrong?

ReactNavice Onesignal Integration Issiue

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(){
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new ReactNativeOneSignalPackage(),
new MapsPackage(),
new VectorIconsPackage());
}
#Override protected String getJSMainModuleName(){return"index";}
};
#Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
#Override
public void onCreate() {
super.onCreate();
SoLoader.init(this, /* native exopackage */ false);
}
//This part is giving error:
#Override
public List<ReactPackage> createAdditionalReactPackages() {
return getPackages();
}
}
Hi there i have a problem with integration onesignal push notification into myapp.
As you see i added necessary codes as documanted. But onesignal is not working and if i add createAdditionalReactPackages it gives error and not building. If i remove that part project building succesfully but onIds not working.
What is wrong i dont understand please help me
Thanks in advance.

Code-Push with React-Native bundle is always null

We are attempting to implement CodePush from Microsoft App Center. We have managed to get to the point where the application downloads the package, and unpacks it. However, it always ends with the response
Update is invalid - A JS bundle file named "null" could not be found within the downloaded contents. Please check that you are releasing your CodePush updates using the exact same JS bundle file name that was shipped with your app's binary.
react#16.2.0
react-native#0.53.3
react-native-code-push#5.3.2
We've made the changes to the MainApplication.java
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
#NonNull
#Override
protected String getJSBundleFile() {
return CodePush.getJSBundleFile();
}
and
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
// Add additional packages you require here
// No need to add RnnPackage and MainReactPackage
new ActionSheetPackage(),
new PickerPackage(),
new ReactNativeOneSignalPackage(),
new CodePush(getResources().getString(R.string.reactNativeCodePush_androidDeploymentKey), getApplicationContext(), BuildConfig.DEBUG),
new CalendarEventsPackage()
);
}
In the app code, we call
Navigation.registerComponent(ScreenNames.Landing.id, () => CodePush(codePushOptions)(LandingScreen), store, Provider);
The final logs from code-push debug android
[11:31:37] Awaiting user action.
[11:31:42] Downloading package.
[11:31:43] An unknown error occurred.
[11:31:43] Update is invalid - A JS bundle file named "null" could not be found within the downloaded contents. Please check that you are releasing your CodePush updates using the exact same JS bundle file name that was shipped with your app's binary.
It appears the react-native linker is putting some things in the wrong class
public class MainApplication extends NavigationApplication {
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this)
{
#NonNull
#Override
public String getJSBundleFile() {
return CodePush.getJSBundleFile();
}
The override should be on MainApplication, not the ReactNativeHost
public class MainApplication extends NavigationApplication {
#NonNull
#Override
public String getJSBundleFile() {
return CodePush.getJSBundleFile();
}
private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this)
{ /*... */ }
You have to Override it inside the ReactGateway createReactGateway(){} method.
That's works for me.
#Override
protected ReactGateway createReactGateway() {
ReactNativeHost host = new NavigationReactNativeHost(this, isDebug(), createAdditionalReactPackages()) {
#Override
protected String getJSMainModuleName() {
return "index";
}
#NonNull
#Override
public String getJSBundleFile() {
return CodePush.getJSBundleFile();
}
};
return new ReactGateway(this, isDebug(), host);
}

Has anyone successfully implemented react-native headless js?

https://facebook.github.io/react-native/releases/next/docs/headless-js-android.html#headless-js
I can't seem to find the right way to do it
I am running React-native 0.40
I implemented the HeadlessJsTaskService to execute some react native code.
For me the ReactExecutorService just silently failed, because i didn't provide any Extras when calling startService(new Intent(this, MyTaskService.class));. The following code fixes that:
#Override
#Nullable
protected HeadlessJsTaskConfig getTaskConfig(Intent intent) {
Bundle extras = intent.getExtras();
WritableMap data = extras != null ? Arguments.fromBundle(extras) : null;
return new HeadlessJsTaskConfig(
"FeatureExecutor",
data,
5000);
}
I also had an existing Application class, that didn't implement ReactApplication. I had to add some code to make the HeadlessJsTaskService work:
private final ReactNativeHost reactNativeHost = new ReactNativeHost(this) {
#Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
#Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
// Insert your packages, e.g.
new MainReactPackage()
);
}
};
#Override
public ReactNativeHost getReactNativeHost() {
return reactNativeHost;
}
You also have to add your custom service to the manifest. For example:
<service android:name=".MyTaskService"/>
Please provide some additional information about your issues in case the solutions above do not help.

Android volley singleton for JSON and image

Intially i was using volley mainly for JSONObject. the following was my singleton
package com.simha.yatras;
import android.app.Application;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.Volley;
public class MyApplication extends Application {
private RequestQueue mRequestQueue;
private static MyApplication mInstance;
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized MyApplication getInstance() {
return mInstance;
}
public RequestQueue getReqQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToReqQueue(Request<T> req, String tag) {
getReqQueue().add(req);
}
public <T> void addToReqQueue(Request<T> req) {
getReqQueue().add(req);
}
public void cancelPendingReq(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
Now i want to use volley for bitmap imagerequest. I want the images to be cached so that i need not load them everytime.
So what should be the singleton code be.
You can use Volley provide ImageRequest class:
ImageView mImageView;
String url = "http://i.imgur.com/7spzG.png";
mImageView = (ImageView) findViewById(R.id.myImage);
// Retrieves an image specified by the URL, displays it in the UI.
ImageRequest request = new ImageRequest(url,
new Response.Listener<Bitmap>() {
#Override
public void onResponse(Bitmap bitmap) {
mImageView.setImageBitmap(bitmap);
}
}, 0, 0, null,
new Response.ErrorListener() {
public void onErrorResponse(VolleyError error) {
mImageView.setImageResource(R.drawable.image_load_error);
}
});
// Access the RequestQueue through your singleton class.
MySingleton.getInstance(this).addToRequestQueue(request);## Heading ##