Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add required=false to the uses-feature #86

Closed
wants to merge 3 commits into from
Closed

Add required=false to the uses-feature #86

wants to merge 3 commits into from

Conversation

ochakov
Copy link

@ochakov ochakov commented Dec 19, 2016

Platforms affected

Android

What does this PR do?

Modifies plugin.xml to allow installation of applications using this plugin on devices without GPS

What testing has been done on this change?

Complete test

Checklist

  • Reported an issue in the JIRA database
  • Commit message follows the format: "CB-3232: (android) Fix bug with resolving file paths", where CB-xxxx is the JIRA ID & "android" is the platform affected.
  • Added automated test coverage as appropriate for this change.

@cordova-qa

This comment has been minimized.

@cordova-qa

This comment has been minimized.

@patrickbussmann
Copy link

patrickbussmann commented Mar 16, 2017

You can add this line to your config.xml.

<hook type="before_compile" src="hooks/before_compile/change_required_features_to_optional.js" />

With this content.

#!/usr/bin/env node

module.exports = function (context) {
  var
    Q = context.requireCordovaModule('q'),
    deferral = new Q.defer(),
    fs = context.requireCordovaModule('fs'),
    path = context.requireCordovaModule('path'),
    platformRoot = path.join(context.opts.projectRoot, 'platforms/android'),
    manifestFile = path.join(platformRoot, 'AndroidManifest.xml')
    ;

  if (fs.existsSync(manifestFile)) {
    fs.readFile(manifestFile, 'utf8', function (err, data) {
      if (err) {
        deferral.resolve();
        throw new Error('Unable to find AndroidManifest.xml: ' + err);
      }

      fs.writeFile(manifestFile, (function (str) {
        str = str.replace(/android:required="true"/ig, 'android:required="false"');
        str = str.replace(/<uses-feature android:name="([^"]+)" ?\/>/ig, '<uses-feature android:name="$1" android:required="false" />');
        return str;
      })(data), 'utf8', function (err) {
        deferral.resolve();
        if (err) throw new Error('Unable to write into AndroidManifest.xml: ' + err);
      });
    });
  } else {
    deferral.resolve();
  }

  return deferral.promise;
};

Then it will work fine and you will have no more dependencies 👍

But yes your pull request should be merged as soon as possible 👍

@ochakov
Copy link
Author

ochakov commented Apr 24, 2017

@patrickbussmann the workaround with the hook will create duplicate uses line in AndroidManifest.xml if you have another plugin declaring the same uses with required false.

@andreujuanc
Copy link

@patrickbussmann Any news on this? As of now I have to manually change the plugin's file

@precz
Copy link

precz commented Jan 18, 2019

Hi, this somehow should be and option in plugin. For now you could add this line to config.xml in your project, under widget:

<edit-config file="AndroidManifest.xml" target="/manifest/uses-feature[@android:name='android.hardware.location.gps']" mode="overwrite">
      <uses-feature android:name="android.hardware.location.gps" android:required="false"/>
</edit-config>

It will work only for the first time, unfortunately. Every next run you need to remove duplicated key from platforms/android/app/src/main/AndroidManifest.xml.

@hvaughan3
Copy link

@precz We use the cordova-custom-config plugin without issue:

<custom-config-file parent="/*" target="AndroidManifest.xml">
    <uses-feature android:name="android.hardware.location" android:required="false" />
    <uses-feature android:name="android.hardware.location.network" android:required="false" />
</custom-config-file>

@Saturnyn
Copy link

Hi, do you have any news on this ? I have the same problem with my app and could not figure out why some customers weren't able to install it until I saw this.

@janpio
Copy link
Member

janpio commented Jun 12, 2019

Noone in here really explained what exactly the problem is that this change solves - could someone please explain when this is useful and why? How does the plugin work without GPS being present?

@breautek
Copy link
Contributor

breautek commented Jun 12, 2019

Noone in here really explained what exactly the problem is that this changes solves - could someone please explain when this is useful and why? How does the plugin work without GPS being present?

In Android Manifest, if the app is defined to use the GPS feature, and it has required=true then that tells Google that the phone must have GPS hardware on their phone to use the app.

required=false will allow the app to be installed on an android device without GPS hardware, which allows apps to be more flexible, such as supporting customers without GPS hardware, but provide a better experience for users who do have GPS hardware under the same app. Obviously the app itself would have to determine if GPS hardware is available before using GPS features.

https://developer.android.com/guide/topics/manifest/uses-feature-element
A better explanation is probably from Android documentation itself...

Boolean value that indicates whether the application requires the feature specified in android:name.
When you declare android:required="true" for a feature, you are specifying that the application cannot function, or is not designed to function, when the specified feature is not present on the device.

When you declare android:required="false" for a feature, it means that the application prefers to use the feature if present on the device, but that it is designed to function without the specified feature, if necessary.

@janpio
Copy link
Member

janpio commented Jun 12, 2019

Ok, so this change would let those apps include the plugin, but of course still not (in any useful way) use it - that would then have to be handled by the developer manually. Correct? What could be disadvantages of allowing this?

@breautek
Copy link
Contributor

Correct. When a feature is marked as required. It signals that the app cannot function without that feature. When the feature is marked as not required, it says the app will use the feature, if available on the device.

@breautek
Copy link
Contributor

breautek commented Jun 12, 2019

I personally wouldn't hard code true or false for this value. This should be a configurable option based on the developers requirements. In my opinion, the default value for this configuration should be true to match both the android default and previous behaviour and via a config variable, allow the developer to specify required=false.

If hard-coded false, then this will put all cordova apps on android that uses GPS on visible on the app store, even if the app cannot function without the feature.

@andreszs
Copy link

I've created a new PR #171 with an ANDROID_GPS_REQUIRED parameter, so the requirement (true/false) can be set when installing the plugin. Please endorse the PR so it gets merged soon, thanks. Tested with [email protected] and [email protected].

@databu
Copy link

databu commented Nov 18, 2019

Ok, so this change would let those apps include the plugin, but of course still not (in any useful way) use it.

Actually this is not completely correct, there are other locationing methods such as network-based, which might be less precise but still often sufficient for most apps, or at least better than nothing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.