We use Angular in a nx monorepo in which we have been using Capacitor 2.4 for half a year now. We only use the android platform as of now. Now, we need to upgrade to Capacitor 3.0. The app itself is running again, however, as soon as I use any Plugin I always get the following exception: ERROR Error: "Device" plugin is not implemented on android
This is the same for every Plugin I have tried to use. So, if I would use the Storage Plugin I would get the same exception only for "Storage". I have followed the Capacitor migration guide (https://capacitorjs.com/docs/v3/updating/3-0) in detail, but I can't figure out where I went wrong. In general, the app works now, as long as I have any code that uses a Capacitor Plugin commented out. The code using the Plugins did work before the upgrade.
As according to the migration guide, I added import '#capacitor/core'; at the main.ts file, although I also tried putting it in the app.module.ts but had no success there either. I have installed every plugin for the whole app (the root) and for the nx-capacitor app (the capacitor app added with #nxtend-capacitor) as suggested here https://nxtend.dev/docs/capacitor/getting-started/. I also have updated the capacitor cli, the capacitor core and the capacitor android version for both package.json files.
Furthermore, according to the android upgrading guide, I have also updated gradle and the android gradle plugin. I have also updated the Android variables accordingly.
I honestly do not have too much experience or in-depth knowledge of Capacitor and I am aware that Capacitor 3 is still in Beta as of this point. However, maybe someone has already stumbled upon this problem and found a solution. I am also not sure, if this problem could somehow be caused by using this monorepo approach with nx. Has someone had experience in upgrading Capacitor to 3.0 while using a Nx monorepo?
For reference, this is the current package.json for the capacitor app:
{
"name": "app-cap",
"dependencies": {
"#capacitor-community/electron": "^1.3.2",
"#capacitor/android": "^3.0.0-rc.0",
"#capacitor/app": "^0.3.6",
"#capacitor/camera": "^0.4.3",
"#capacitor/cli": "^3.0.0-rc.0",
"#capacitor/core": "^3.0.0-rc.0",
"#capacitor/device": "^0.5.6",
"#capacitor/filesystem": "^0.5.2",
"#capacitor/ios": "^3.0.0-rc.0",
"#capacitor/local-notifications": "^0.6.0",
"#capacitor/push-notifications": "^0.3.6",
"#capacitor/storage": "^0.3.6",
"capacitor-secure-storage-plugin": "^0.5.0",
"com-darryncampbell-cordova-plugin-intent": "^2.0.0",
"com.darktalker.cordova.screenshot": "^0.1.6",
"cordova-plugin-advanced-http": "^3.1.0",
"cordova-plugin-app-launcher": "^0.4.0",
"cordova-plugin-appcenter-analytics": "^0.5.1",
"cordova-plugin-appcenter-crashes": "^0.5.1",
"cordova-plugin-appcenter-shared": "^0.5.1",
"cordova-plugin-device": "^2.0.3",
"cordova-plugin-dialogs": "^2.0.2",
"cordova-plugin-file": "^6.0.2",
"cordova-plugin-file-opener2": "^3.0.5",
"cordova-plugin-zip": "^3.1.0",
"jetifier": "^1.6.6"
}
}
Both answers are wrong.
Capacitor 3 allows android plugins to auto register, but for that you need to remove the init method from MainActivity.java, if it's there the automatic registration won't work as init is the legacy way of registering plugins.
So you have two options:
Remove the init method from MainActivity.java as explained on the capacitor 3 updating docs
Keep the legacy init method and add plugins as you did on Capacitor 2. I.E. add(DatepickPlugin.class);
By removing android folder as answer 1 suggests, the init method gets removed and that's why that answer works, but it's destructive, it will remove all your manual changes in your projects.
And adding plugins as answer 2 suggests also works, but there is no need for doing that if using automatic plugin registration, that method is really there for non npm plugins.
Try removing android platform
(IMPORTANT: backup your android directory before removing.)
and run:
npm install #capacitor/core#next #capacitor/cli#next
npx cap init
npm install #capacitor/android#next
npx cap add android
then build your project and:
npx cap sync
I had the same problem
You need to add the plugins manually in your MainActivity.java
public class MainActivity extends BridgeActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// --- Remove bridge init as it's deprecated and add these lines
registerPlugin(com.capacitorjs.plugins.app.AppPlugin.class);
registerPlugin(com.capacitorjs.plugins.device.DevicePlugin.class);
// ---
}
}
When using live reload, make sure you have http:// in url.
As per documentation:
"server": {
"url": "http://192.168.1.68:8100",
"cleartext": true
},
When I used just ip, it rendered site, but plugins did not work (not implemented exception).
As per doc, you just need to update MainActivity.java file
https://capacitorjs.com/docs/updating/3-0
In my case, i just need to update my MainActivity.java
import com.getcapacitor.BridgeActivity;
public class MainActivity extends BridgeActivity {}
Using nxtend plugin I found that I also had to add the plugin package name to "includePlugins": [] in capacitor.config in order for sync to identify the needed plugins and populate the downstream gradle files in the android project. From what I understand cap is supposed to inspect the project package.json and automatically determine what plugins are used but this doesn't seem to be working for me.
I'm currently using Nx Monorepo with NxExt and Capacitor 4.0.
I solved the import problem by adding in the package.json of the mobile app (apps/mobile-app/package.json) the relative plugins required:
{
"name": "mobile-ionic-app",
"dependencies": {
"#capacitor/device": "^4.0.1"
},
"devDependencies": {
"#capacitor/android": "^4.2.0",
"#capacitor/cli": "^4.2.0",
"#capacitor/core": "^4.2.0"
}
}
In this way Capacitory can synchronize the plugins in the build phase:
Android Capacitor Build
This is because Capacitor changes the underlying Gradle files but Android Studio doesn't know about it
.
to fix this, go to Android studio click File -> Sync Project with Gradle Files
When I transitioned to Expo's Managed Workflow (SDK 37 and now 38 as well), in-app update checking broke.
My code:
import * as Updates from 'expo-updates';
async checkForUpdate() {
const update = await Updates.checkForUpdateAsync();
if (update.isAvailable) {
this.updateApp();
}
}
async updateApp() {
await Updates.fetchUpdateAsync();
Updates.reloadAsync();
}
Logcat shows me that the checkForUpdateAsync() promise is being rejected with this message:
Error: The method or property Updates.checkForUpdateAsync is not available on android, are you sure you’ve linked all the native dependencies properly?
For the record I did install it via expo install expo-updates
Thanks.
I solved this by creating a new Expo project and looking for differences from my many-times-upgraded one. I found two:
I was using off-the-shelf React Native instead of the Expo build, so I changed the dependency in package.json to "react-native": "https://github.com/expo/react-native/archive/sdk-38.0.1.tar.gz"
I also updated my expo version to ^38.0.8, as used by the new project.
Finally, I also deleted some build relics that I had generated during the way, but I think the fix came from one of the steps above.
I try run a blank project from hours, and I do not understand what is wrong.
I have the file app.json in my project folder :
{
"sdkVersion" : "19.0.0"
}
and when I try :
expo start
I have this message :
PS D:\Projects\VSCode\AwesomeProject> expo start
Starting project at D:\Projects\VSCode\AwesomeProject
Expo DevTools is running at http://localhost:19002
Error: Missing app.json. See https://docs.expo.io/
No Expo configuration found. Are you sure this is a project directory?
PS D:\Projects\VSCode\AwesomeProject>
If I try
expo android
I get this :
PS D:\Projects\VSCode\AwesomeProject> expo android
Error: Missing app.json. See https://docs.expo.io/
There is an error with your project. See above logs for information.
Set EXPO_DEBUG=true in your env to view the stack trace.
- Making sure project is set up correctly...
PS D:\Projects\VSCode\AwesomeProject>
This is a blank project, i do not understand what is going wrong. How can I found sdkversion in use ? I thought It was the error, but I am not sure.
Thank you for your help
looks like that was generated with react-native init and not expo, because it doesn't have an "expo" section. we should provide a better error message in this case.
{
"expo": {
"sdkVersion": "32.0.0"
...
}
}
It's part of the project I just made.
I solved this problem by adding sdkVersion, as you can see in the image
I am using this component https://github.com/wix/react-native-calendars. It Works good in iphone but having issue with android. When i open calendar page it gives me an error as
Incompatible receiver, Map required!
Environment
List of Packages Installed
"react-native": "^0.52.0",
"react-native-calendars": "^1.20.0"
Seems like there is an issue with core-js.I have also tried everything from this reference link https://github.com/zloirock/core-js/issues/368
Do anybody know, How to resolve this issue.
Thanks in advance!
Reverting back to v2.5.2 of core-js fixed it. We use core-js via babel-preset-env, in order to get it fixed the solution is to set the version hard in the resolutions property of the package.json file:
"resolutions": {
"core-js": "2.5.2"
}
the resolutions section of the package.json file is a yarn feature!
I'm using React Native 0.29 and developing for Android. I'm trying to lock the device orientation. What I need is to lock the screen in portrait mode. I tried with this repository https://github.com/yamill/react-native-orientation but it is not supporting RN 0.29 yet.
Is there any way I can lock the device orientation? Maybe any native Android hack with android studio?
Just add android:screenOrientation="portrait" to the activity in the AndroidManifest.xml.
2017 Update
Currently, there is also another way to do it once for both Android and iOS by adding:
"orientation": "portrait"
in app.json if you're using Expo:
{
"expo": {
"name": "My app",
"slug": "my-app",
"sdkVersion": "21.0.0",
"privacy": "public",
"orientation": "portrait"
}
}
Or at runtime:
ScreenOrientation.allow()
Example:
ScreenOrientation.allow(ScreenOrientation.Orientation.PORTRAIT);
Note that it only works if you're building with Expo but since this is currently (as of 2017) recommended in official guides on React Native Blog then probably a lot of people are using it so it's worth mentioning as an interesting solution in addition to hacking the Android-specific XML configuration files.
More info:
For more info see:
how to disable rotation in React Native?
There is a pull request for this to work on 0.29.2 and above:
https://github.com/yamill/react-native-orientation/pull/85
If you use his version, it should work on 0.29.2 and above:
https://github.com/youennPennarun/react-native-orientation
Steps:
unlink the previous installation with rnpm unlink react-native-orientation
rm -rf node_modules/react-native-orientation
in your package.json edit the entry of react-native-orientation to be as:
"react-native-orientation": "youennPennarun/react-native-orientation"
npm install
react-native link react-native-orientation
Things should work after this. You can track the progress of the PR and switch to main repo when it has been merged.
react-native-orientation - is no longer compatible with new version (I have tried 0.39.2). After linking this module I have the compiler's error.
As I got it, now we should use react-native-orientation-listener
npm install --save react-native-orientation-listener
rnpm link
Step:1
npm install git+https://github.com/yamill/react-native-orientation.git --save
Step2:
react-native link
Step:3
Modify the MainApplication.java file with:
import com.github.yamill.orientation.OrientationPackage;// import
#Override
protected List getPackages() {
return Arrays.asList(
new MainReactPackage(),
new OrientationPackage() //add this
);
}
You can use react-native-orientation-locker.
The 'react-native-orientation' has been deprecated.
Using the 'react-native-orientation-locker' component, you would be able to detect the current orientation, as well as locking it to Portrait/Landscape by using:
Orientation.lockToPortrait();
Orientation.lockToLandscapeLeft();
Even release the locks using
Orientation.unlockAllOrientations();