phonegap / phonegap-plugin-barcodescanner

cross-platform BarcodeScanner for Cordova / PhoneGap
MIT License
1.27k stars 1.41k forks source link

Failed to install my custom plugin, Error: There was a conflict trying to modify attributes with <edit-config> in my plugin #743

Closed JackRo closed 5 years ago

JackRo commented 5 years ago

There was no conflict with install my custom plugin after install barcodescanner plugin

After install barcodescanner plugin, then install my custom plugin, There was a conflict trying to modify attributes with in my plugin

my custom plugin's plugin.xml is like below:

`<?xml version="1.0" encoding="utf-8"?>
<plugin id="com-flux-location" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<name>
    com-flux-location
</name>
<js-module name="fluxLocation" src="www/location.js">
    <clobbers target="fluxLocation" />
</js-module>
<platform name="android">
    <preference name="GAODE_API_KEY_FOR_ANDROID" />
    <config-file parent="/*" target="res/xml/config.xml">
        <feature name="GaodeLocation">
            <param name="android-package" value="com.flux.location.GaodeLocation" />
        </feature>
    </config-file>
    <config-file parent="/manifest/application" target="AndroidManifest.xml">
        <meta-data android:name="com.amap.api.v2.apikey" android:value="$GAODE_API_KEY_FOR_ANDROID" />
        <service android:name="com.amap.api.location.APSService" android:enabled="true" />
        <service android:name="com.flux.location.service.LocationService" android:enabled="true" android:process=":remote" />
        <receiver android:name="com.flux.location.service.AlarmReceiver" android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <action android:name="android.intent.action.USER_PRESENT" />
                <action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
                <action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.PACKAGE_ADDED" />
                <action android:name="android.intent.action.PACKAGE_REMOVED" />
                <data android:scheme="package" />
            </intent-filter>
        </receiver>
    </config-file>
    <edit-config file="AndroidManifest.xml" target="/manifest/application" mode="merge">
        <application android:name="com.flux.location.MyApp" />      
    </edit-config>
    <config-file parent="/*" target="AndroidManifest.xml">
        <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
        <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
        <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
        <uses-permission android:name="android.permission.INTERNET" />
        <uses-permission android:name="android.permission.READ_PHONE_STATE" />
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
        <uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
        <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    </config-file>

</platform>

`

first install the barcodescanner plugin, then install my custom plugin

Android 8.1

No devices, just install plugin conflict

Cordova CLI version and cordova platform version

cordova --version 8.0.0
cordova platforms android 7.1.0

Plugin version

cordova plugin version | grep phonegap-plugin-barcodescanner

8.0.1

Sample Code that illustrates the problem

i have no idea

Logs taken while reproducing problem

Failed to install 'com-flux-location': Error: There was a conflict trying to modify attributes with <edit-config> in plugin com-flux-location. The conflicting plugin, undefined, already modified the same attributes. The conflict must be resolved before com-flux-location can be added. You may use --force to add the plugin and overwrite the conflicting attributes.
at PlatformMunger.add_plugin_changes (/Users/jack/Desktop/demo/platforms/android/cordova/node_modules/cordova-common/src/ConfigChanges/ConfigChanges.js:148:19)
at /Users/jack/Desktop/demo/platforms/android/cordova/node_modules/cordova-common/src/PluginManager.js:123:29
at _fulfilled (/Users/jack/Desktop/demo/platforms/android/cordova/node_modules/q/q.js:854:54)
at /Users/jack/Desktop/demo/platforms/android/cordova/node_modules/q/q.js:883:30
at Promise.promise.promiseDispatch (/Users/jack/Desktop/demo/platforms/android/cordova/node_modules/q/q.js:816:13)
at /Users/jack/Desktop/demo/platforms/android/cordova/node_modules/q/q.js:877:14
at runSingle (/Users/jack/Desktop/demo/platforms/android/cordova/node_modules/q/q.js:137:13)
at flush (/Users/jack/Desktop/demo/platforms/android/cordova/node_modules/q/q.js:125:13)
at process._tickCallback (internal/process/next_tick.js:61:11)
manjunath143 commented 5 years ago

I am also facing same issue ,were you able to fix this issue ?

JackRo commented 5 years ago

I am also facing same issue ,were you able to fix this issue ?

I have been able to fix this issue, but I fixed this issue by Cordova Hook mechanism.

I removed the edit-config from my custom plugin's plugin.xml. Then I used the Cordova Hook mechanism to satisfy my demand that added MyApp.java to my Cordova Project and configured the AndroidManifest.xml of Cordova Project's android platform

If you want to fix this issue, you also could see Cordova Hook Guide first.

phyr0s commented 5 years ago

@JackRo Can you provide your hook example?

JackRo commented 5 years ago

@videmort The hook example like this:

the plugin.xml like below:

<platform name="android">
    <hook type="after_plugin_install" src="scripts/afterPluginInstall.js" />
    <hook type="before_plugin_uninstall" src="scripts/beforePluginUninstall.js" />

the afterPluginInstall.js like below:

#!/usr/bin/env node

module.exports = function(context) {
  let fs = context.requireCordovaModule('fs'),
    path = context.requireCordovaModule('path');

  // android platform directory
  let platformAndroidDir = path.join(context.opts.projectRoot, 'platforms/android');

  // android app module directory
  let platformAndroidAppModuleDir = path.join(platformAndroidDir, 'app');

  // android manifest file
  let androidManifestFile = path.join(platformAndroidAppModuleDir, 'src/main/AndroidManifest.xml');

  if (fs.existsSync(androidManifestFile)) {

    fs.readFile(androidManifestFile, 'UTF-8', function(err, data) {
      if (err) {
        throw new Error('Unable to find AndroidManifest.xml: ' + err);
      }

      // the Android Application class that need to config to Android manifest file
      let applicationClassName = 'com.jackro.example.MyApp';

      if (data.indexOf(applicationClassName) === -1) {

        let result = data.replace(/<application/g, '<application android:name="' + applicationClassName + '"');

        fs.writeFile(androidManifestFile, result, 'UTF-8', function(err) {
          if (err)
            throw new Error('Unable to write into AndroidManifest.xml: ' + err);
        })
      }
    });
  }
};

the beforePluginUninstall.js like below:

#!/usr/bin/env node

module.exports = function(context) {

  let fs = context.requireCordovaModule('fs'),
    path = context.requireCordovaModule('path');

  // android platform directory
  let platformAndroidDir = path.join(context.opts.projectRoot, 'platforms/android');

  // android app module directory
  let platformAndroidAppModuleDir = path.join(platformAndroidDir, 'app');

  // android manifest file
  let androidManifestFile = path.join(platformAndroidAppModuleDir, 'src/main/AndroidManifest.xml');

  // android app module gradle
  let androidAppModuleGradleFile = path.join(platformAndroidAppModuleDir, 'build.gradle');

  if (fs.existsSync(androidManifestFile)) {

    fs.readFile(androidManifestFile, 'UTF-8', function(err, data) {
      if (err) {
        throw new Error('Unable to find AndroidManifest.xml: ' + err);
      }

      //Android Application of Android manifest that need to delete config
      let applicationClassConfig = 'android:name="com.jackro.example.MyApp"';

      if (data.indexOf(applicationClassConfig) !== -1) {

        let result = data.replace(applicationClassConfig, '');

        fs.writeFile(androidManifestFile, result, 'UTF-8', function(err) {
          if (err)
            throw new Error('Unable to write into AndroidManifest.xml: ' + err);
        })
      }
    });
  }
  if (fs.existsSync(androidAppModuleGradleFile)) {

    fs.readFile(androidAppModuleGradleFile, 'UTF-8', function(err, data) {
      if (err) {
        throw new Error('Unable to find build.gradle: ' + err);
      }

      let androidAppModuleGradleConfigLine = 'apply from: "../com-jackro-example/app-jackroexample.gradle"';

      if (data.indexOf(androidAppModuleGradleConfigLine) !== -1) {

        let result = data.replace(androidAppModuleGradleConfigLine, '');

        fs.writeFile(androidAppModuleGradleFile, result, 'UTF-8', function(err) {
          if (err)
            throw new Error('Unable to write into build.gradle: ' + err);
        })
      }
    });
  }
};
stale[bot] commented 5 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

lock[bot] commented 5 years ago

This thread has been automatically locked.