Yah, the `${applicationId}.provider` value is the authority used to allow the 
app access to that storage location. The authority has to match the one defined 
in the [authorities 
config](https://github.com/apache/cordova-plugin-camera/blob/master/plugin.xml#L65).

### Background
After a lot of investigation, I think I understand this now. The .BuildConfig 
class is an Android auto generated class that 
[BuildHelper.getBuildConfigValue](https://github.com/apache/cordova-plugin-compat/blob/master/src/android/BuildHelper.java#L50)
 is trying to access via reflection to find the APPLICATION_ID field.

Example BuildConfig.java that sits in 
build/generated/source/buildConfig/debug/com/company/project/
```
/**
 * Automatically generated file. DO NOT MODIFY
 */
package com.company.project;

public final class BuildConfig {
  public static final boolean DEBUG = Boolean.parseBoolean("true");
  public static final String APPLICATION_ID = "com.company.project";
  public static final String BUILD_TYPE = "debug";
  public static final String FLAVOR = "";
  public static final int VERSION_CODE = 1;
  public static final String VERSION_NAME = "2018.1-SNAPSHOT";
}
```

We were running into the same issue where BuildHelper.getBuildConfigValue was 
returning null and crashing the app, because we didn't have the `<preference 
name="applicationId" value="{PACKAGE_ID}"/>` set either. This is because the 
application's package name is different from the one that's ultimately built 
into the APK. We updated the package name of the app, because it's a new 
version of the app with new branding, but we need to submit the previous 
package name in the APK so it can goto the same Google Store page.

build.gradle
```
android {
    defaultConfig {
        applicationId "com.company.oldname"
    }
}
```
`Java app package: com.company.newname;`

In our example, `cordova.getActivity().getPackageName() == 
"com.company.oldname"` but the `com.company.oldname.BuildConfig` doesn't exist 
(Android has created the `com.company.newname.BuildConfig`). Because 
`com.company.oldname.BuildConfig` doesn't exist, 
BuildHelper.getBuildConfigValue returns null. In most cases, 
BuildHelper.getBuildConfigValue works fine, but this is an edge case where this 
fails. This would also fail for apps with [multiple 
productFlavors](http://tools.android.com/tech-docs/new-build-system/applicationid-vs-packagename).

### Possible Solution
The Camera Plugin could support all three options: 
- First use preference.applicationId. 
- If null, use BuildHelper.getBuildConfigValue.
- If null, use cordova.getActivity().getPackageName() and hope it's good enough.

I'm not sure if `cordova.getActivity().getPackageName()` will always be the 
right package name because I'm not sure if the Cordova activity/context would 
have the same package name as the app using it. But I think it's worth it to 
try to prevent this.applicationId from just being null to crash later on.

Important note, CordovaInterface.getContext() was added in Cordova Android 7.0, 
so it might be better to use cordova.getActivity() to support previous versions 
(this is important to us because we're stuck with Cordova Android 6.3.0 for the 
minute).

Let me know if you want me to submit a PR with these suggested changes, or if 
you want to just make them in this PR.

[ Full content available at: 
https://github.com/apache/cordova-plugin-camera/pull/320 ]
This message was relayed via gitbox.apache.org for devnull@infra.apache.org

Reply via email to