It does not detect my webcam xamarin community tools - xamarin.forms

I am trying to connect my webcam from my cell phone through xamarin, however, it is not working, when using my front camera and my back camera it works, however when I use CameraOptions = "External" it does not detect the webcam This is my code with which I create the camera view:
<xct:CameraView
Grid.Column="0"
x:Name="cameraView"
CaptureMode="Photo"
CameraOptions="External"
FlashMode="Off"
HorizontalOptions="FillAndExpand"
MediaCaptured="CameraView_MediaCaptured"
OnAvailable="CameraView_OnAvailable"
VerticalOptions="FillAndExpand" />
In my main activity I defined this intent filter and this meta data for the detection of usb devices:
[IntentFilter(new[] { Android.Hardware.Usb.UsbManager.ActionUsbDeviceAttached })]
[MetaData(name: "Android.Hardware.Usb.UsbManager.ActionUsbDeviceAttached", Resource = "#xml/device_filter")]
In the application path Android \ Resources I defined a folder called xml where I created a file called device_filter.xml to be able to define the properties of my camera
<?xml version="1.0" encoding="utf-8" ?>
<resources>
<usb-device vendor-id="2431" product-id="4653" class="33" subclass="33" protocol="1"/>
</resources>
Also in the BuildAction property of device_filter.xml I defined as parameter AndroidResource
And request the camera permissions and record audio:
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
What could I do to make it detect my webcam?

Related

HTTP Request failed in IONIC for latest android

IONIC 3
I am getting "Request failed" error when I am sending POST request to server.
This issue only comes on latest android devices.
I have set all necessary headers in my server already.
Please check attachment for more details.
Probably one reason is that you are using http not https
set android:usesCleartextTraffic="true" in AndroidManifest.xml file
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:usesCleartextTraffic="true"
...>
...
</application>
</manifest>

Your app(s) are using a content provider with an unsafe implementation of openFile

I've received this email after publishing my app on playstore:
Hello Google Play Developer,
We reviewed [MyAppName], with package name com.example.myappname, and found that your app uses software that contains security vulnerabilities for users. Apps with these vulnerabilities can expose user information or damage a user’s device, and may be considered to be in violation of our Malicious Behavior policy.
Below is the list of issues and the corresponding APK versions that were detected in your recent submission. Please migrate your apps to use the updated software as soon as possible and increment the version number of the upgraded APK.
Your app(s) are using a content provider with an unsafe implementation of openFile.
To address this issue, follow the steps in this Google Help Center article.
Vulnerability APK Version(s) Deadline to fix
Path Traversal
Your app(s) are using a content provider with an unsafe implementation of openFile.
To address this issue, follow the steps in this Google Help Center article.
1 June 25, 2019
Vulnerability APK Version(s) Deadline to fix
To confirm you’ve upgraded correctly, submit the updated version of your app to the Play Console and check back after five hours. We’ll show a warning message if the app hasn’t been updated correctly.
I've used Realm database, iText pdf library, file provider in my app. I'm using FileProvider to open pdf file from storage using intent.
res>xml>provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path
name="external_files"
path="." />
</paths>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.appName">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_icon"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_icon"
android:supportsRtl="true"
android:theme="#style/AppTheme">
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
</application>
</manifest>
TemplatesFragment.java
File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyCvs/Templates/" + templateName);
Uri uriPdf = FileProvider.getUriForFile(getActivity(), BuildConfig.APPLICATION_ID + ".provider", file);
Intent target = new Intent(Intent.ACTION_VIEW);
target.setDataAndType(uriPdf, "application/pdf");
target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
target.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
Intent intent = Intent.createChooser(target, "Open File");
try {
startActivity(intent);
} catch (Exception e) {
// Instruct the user to install a PDF reader here, or something
Toast.makeText(getActivity(), "" + e.getMessage(), Toast.LENGTH_SHORT).show();
}
Don't put "." in the path, instead, give the name of the folder that you wanna use.
For example, If you want to access/use Download folder then in provider_paths.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path
name="downloads"
path="Download/" />
</paths>
They actually provide one with all one needs to know; see support.google.com:
Implementations of openFile in exported ContentProviders can be vulnerable if they do not properly validate incoming Uri parameters. A malicious app can supply a crafted Uri (for example, one that contains “/../”) to trick your app into returning a ParcelFileDescriptor for a file outside of the intended directory, thereby allowing the malicious app to access any file accessible to your app.
The FileProvider must reject any Uri containing .. ...which are deemed "exploitable".

Cleartext HTTP traffic to 192.168.1.2 not permitted [duplicate]

I had reports from users with Android 8 that my app (that uses back-end feed) does not show content. After investigation I found following Exception happening on Android 8:
08-29 12:03:11.246 11285-11285/ E/: [12:03:11.245, main]: Exception: IOException java.io.IOException: Cleartext HTTP traffic to * not permitted
at com.android.okhttp.HttpHandler$CleartextURLFilter.checkURLPermitted(HttpHandler.java:115)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:458)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:127)
at com.deiw.android.generic.tasks.AbstractHttpAsyncTask.doConnection(AbstractHttpAsyncTask.java:207)
at com.deiw.android.generic.tasks.AbstractHttpAsyncTask.extendedDoInBackground(AbstractHttpAsyncTask.java:102)
at com.deiw.android.generic.tasks.AbstractAsyncTask.doInBackground(AbstractAsyncTask.java:88)
at android.os.AsyncTask$2.call(AsyncTask.java:333)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:245)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
(I've removed package name, URL and other possible identifiers)
On Android 7 and lower everything works, I do not set android:usesCleartextTraffic in Manifest (and setting it to true does not help, that is the default value anyway), neither do I use Network Security Information. If I call NetworkSecurityPolicy.getInstance().isCleartextTrafficPermitted(), it returns false for Android 8, true for older version, using the same apk file.
I tried to find some mention of this on Google info about Android O, but without success.
According to Network security configuration -
Starting with Android 9 (API level 28), cleartext support is disabled
by default.
Also have a look at Android M and the war on cleartext traffic
Codelabs explanation from Google
Option 1 -
First try hitting the URL with https:// instead of http://
Option 2 -
Create file res/xml/network_security_config.xml -
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">api.example.com(to be adjusted)</domain>
</domain-config>
</network-security-config>
AndroidManifest.xml -
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:networkSecurityConfig="#xml/network_security_config"
...>
...
</application>
</manifest>
Option 3 -
android:usesCleartextTraffic Doc
AndroidManifest.xml -
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:usesCleartextTraffic="true"
...>
...
</application>
</manifest>
Also as #david.s' answer pointed out android:targetSandboxVersion can be a problem too -
According to Manifest Docs -
android:targetSandboxVersion
The target sandbox for this app to use. The higher the sandbox version
number, the higher the level of security. Its default value is 1; you
can also set it to 2. Setting this attribute to 2 switches the app to
a different SELinux sandbox. The following restrictions apply to a
level 2 sandbox:
The default value of usesCleartextTraffic in the Network Security Config is false.
Uid sharing is not permitted.
So Option 4 -
If you have android:targetSandboxVersion in <manifest> then reduce it to 1
AndroidManifest.xml -
<?xml version="1.0" encoding="utf-8"?>
<manifest android:targetSandboxVersion="1">
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>
My problem in Android 9 was navigating on a webview over domains with http
The solution from this answer
<application
android:networkSecurityConfig="#xml/network_security_config"
...>
and:
res/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
In the AndroidManifest I found this parameter:
android:networkSecurityConfig="#xml/network_security_config"
and #xml/network_security_config is defined in network_security_config.xml as:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<!--Set application-wide security config using base-config tag.-->
<base-config cleartextTrafficPermitted="false"/>
</network-security-config>
just I changed cleartextTrafficPermitted to true
You might only want to allow cleartext while debugging, but keep the security benefits of rejecting cleartext in production. This is useful for me because I test my app against a development server that does not support https. Here is how to enforce https in production, but allow cleartext in debug mode:
In build.gradle:
// Put this in your buildtypes debug section:
manifestPlaceholders = [usesCleartextTraffic:"true"]
// Put this in your buildtypes release section
manifestPlaceholders = [usesCleartextTraffic:"false"]
In the application tag in AndroidManifest.xml
android:usesCleartextTraffic="${usesCleartextTraffic}"
Ok, that's ⇒⇒ NOT ⇐⇐ the thousands repeat of add it to your Manifest, but an hint which based on this, but give you additional Benefit (and maybe some Background Info).
Following solution allow you to set the protocol (HTTP / HTTPS) per ENVIRONMENT.
This way you are able to use http for your DEV-Environment, and https for your PRODUCTION-Environment, without the need to change it all the time!
And this is needed, because generally you don't have an https-certificate for your local or dev environment, but it's a MUST-HAVE for production (and maybe for staging) environments.
Android has a kind of overwriting functionality for the src-Directory.
By default, you have
/app/src/main
But you can add additional directories to overwrite your AndroidManifest.xml. Here is how it works:
Create the Directory /app/src/debug
Inside create the AndroidManifest.xml
Inside of this File, you don't have to put all the Rules inside, but only the ones you like to overwrite from your /app/src/main/AndroidManifest.xml
Here an Example how it looks like for the requested CLEARTEXT-Permission:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yourappname">
<application
android:usesCleartextTraffic="true"
android:name=".MainApplication"
android:label="#string/app_name"
android:icon="#mipmap/ic_launcher"
android:allowBackup="false"
android:theme="#style/AppTheme">
</application>
</manifest>
With this knowledge it's now easy as 1,2,3 for you to overload your Permissions depending on your debug | main | release Enviroment.
The big benefit on it... you don't have debug-stuff in your production-Manifest and you keep an straight and easy maintainable structure
If possible change your url's from HTTP to HTTPS;
It works out!!!
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">***Your URL(ex: 127.0.0.1)***</domain>
</domain-config>
</network-security-config>
In the suggestion provided above I was providing my URL as http://xyz.abc.com/mno/
I changed that to xyz.abc.com then it started working.
It could be useful for someone.
We recently had the same issue for Android 9, but we only needed to display some Urls within WebView, nothing very special. So adding android:usesCleartextTraffic="true" to Manifest worked, but we didn't want to compromise security of the whole app for this.
So the fix was in changing links from http to https
For React Native projects
It was already fixed on RN 0.59.
You can find on upgrade diff from 0.58.6 to 0.59
You can apply it without upgrading you RN versionust follow the below steps:
Create files:
android/app/src/debug/res/xml/react_native_config.xml -
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="false">localhost</domain>
<domain includeSubdomains="false">10.0.2.2</domain>
<domain includeSubdomains="false">10.0.3.2</domain>
</domain-config>
</network-security-config>
android/app/src/debug/AndroidManifest.xml -
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<application tools:targetApi="28"
tools:ignore="GoogleAppIndexingWarning"
android:networkSecurityConfig="#xml/react_native_config" />
</manifest>
Check the accepted answer to know the root cause.
I have removed this line from the android manifest file which is already there
android:networkSecurityConfig="#xml/network_security_config"
and added
android:usesCleartextTraffic="true"
this in to application tag in manifest
<application
android:usesCleartextTraffic="true"
android:allowBackup="true"
android:label="#string/app_name"
android:largeHeap="true"
android:supportsRtl="true"
android:theme="#style/AppTheme"
>
then this error Cleartext HTTP traffic to overlay.openstreetmap.nl not permitted is gone for me in android 9 and 10.I hope this will work for android 8 also if it is helped you don't forget to vote thank you
Adding ...
android:usesCleartextTraffic="true"
... to your manifest file may appear to fix the problem but it opens a threat to data integrity.
For security reasons I used manifest placeholders with android:usesCleartextTraffic inside the manifest file (like in Option 3 of the accepted answer i.e #Hrishikesh Kadam's response) to only allow cleartext on debug environment.
Inside my build.gradle(:app) file, I added a manifest placeholder like this:
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
manifestPlaceholders.cleartextTrafficPermitted ="true"
}
}
Note the placeholder name cleartextTrafficPermitted at this line above
manifestPlaceholders.cleartextTrafficPermitted ="true"
Then in my Android Manifest, I used the same placeholder ...
AndroidManifest.xml -
<?xml version="1.0" encoding="utf-8"?>
<manifest ...>
<uses-permission android:name="android.permission.INTERNET" />
<application
...
android:usesCleartextTraffic="${cleartextTrafficPermitted}"
...>
...
</application>
</manifest>
With that, cleartext traffic is only permitted under the debug environment.
Simple and Easiest Solution [Xamarin Form]
For Android
Goto Android Project, then Click on Properties,
Open AssemblyInfo.cs and paste this code right there:
[assembly: Application(UsesCleartextTraffic =true)]
For iOS
Use NSAppTransportSecurity:
You have to set the NSAllowsArbitraryLoads key to YES under NSAppTransportSecurity dictionary in your info.plist file.
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
Okay, I have figured this out. It is due to the Manifest parameter android:targetSandboxVersion="2", that I have added because we also have Instant App version - it should make sure than once user upgrades from Instant App to regular app, he will not loose his data with the transfer. However as the vague description suggest:
Specifies the target sandbox this app wants to use. Higher sanbox versions will have increasing levels of security.
The default value of this attribute is 1.
It obviously also adds new level of security policy, at least on Android 8.
To apply these various answers to Xamarin.Android, you can use class and assembly level Attributes vs. manually editing the AndroidManifest.xml
Internet permission of course is needed (duh..):
[assembly: UsesPermission(Android.Manifest.Permission.Internet)]
Note: Typically assembly level attributes are added to your AssemblyInfo.cs file, but any file, below the using and above the namespace works.
Then on your Application subclass (create one if needed), you can add NetworkSecurityConfig with a reference to an Resources/xml/ZZZZ.xml file:
#if DEBUG
[Application(AllowBackup = false, Debuggable = true, NetworkSecurityConfig = "#xml/network_security_config")]
#else
[Application(AllowBackup = true, Debuggable = false, NetworkSecurityConfig = "#xml/network_security_config"))]
#endif
public class App : Application
{
public App(IntPtr javaReference, Android.Runtime.JniHandleOwnership transfer) : base(javaReference, transfer) { }
public App() { }
public override void OnCreate()
{
base.OnCreate();
}
}
Create a file in the Resources/xml folder (create the xml folder if needed).
Example xml/network_security_config file, adjust as needed (see other answers)
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">www.example.com</domain>
<domain includeSubdomains="true">notsecure.com</domain>
<domain includeSubdomains="false">xxx.xxx.xxx</domain>
</domain-config>
</network-security-config>
You can also use the UsesCleartextTraffic parameter on the ApplicationAttribute:
#if DEBUG
[Application(AllowBackup = false, Debuggable = true, UsesCleartextTraffic = true)]
#else
[Application(AllowBackup = true, Debuggable = false, UsesCleartextTraffic = true))]
#endif
While the working answer, for me, was this by #PabloCegarra:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
You may receive a security warning regarding the cleartextTrafficPermitted="true"
If you know the domains to 'white list' you should mix both accepted answer and the above one:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="false">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">books.google.com</domain>
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</domain-config>
</network-security-config>
This code is working for me, but my app needs to retrieve data from books.google.com only.
By this way the security warning disappears.
I am also got the same "Cleartext HTTP traffic not permitted" error while developing my Application. I am using Retrofit2 for network calls in my application and I have two project environments(dev & production). My Production domain is having SSL certificate with HTTPS calls and dev won't have https. The configuration is added in the build flavors. But when I change to dev, this issue will trigger. So I have added below-solution for that.
I have added cleartext traffic in the manifest
android:usesCleartextTraffic="true"
Then I have added a connection spec in the retrofit configuration class OKHttp creation time.
.connectionSpecs(CollectionsKt.listOf(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT))
Complete OkHttpClient creation is given below
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.readTimeout(10, TimeUnit.SECONDS)
.connectTimeout(10, TimeUnit.SECONDS)
.cache(null)
.connectionSpecs(CollectionsKt.listOf(ConnectionSpec.MODERN_TLS, ConnectionSpec.CLEARTEXT))
.addInterceptor(new NetworkInterceptor(context))
.addInterceptor(createLoggingInterceptor())
.addInterceptor(createSessionExpiryInterceptor())
.addInterceptor(createContextHeaderInterceptor())
.build();
Update December 2019 ionic - 4.7.1
<manifest xmlns:tools=“http://schemas.android.com/tools”>
<application android:usesCleartextTraffic=“true” tools:targetApi=“28”>
Please add above content in android manifest .xml file
Previous Versions of ionic
Make sure you have the following in your config.xml in Ionic Project:
<edit-config file="app/src/main/AndroidManifest.xml" mode="merge" target="/manifest/application" xmlns:android="http://schemas.android.com/apk/res/android">
<application android:networkSecurityConfig="#xml/network_security_config" />
<application android:usesCleartextTraffic="true" />
</edit-config>
Run ionic Cordova build android. It creates Android folder under Platforms
Open Android Studio and open the Android folder present in our project
project-platforms-android. Leave it for few minutes so that it builds the gradle
After gradle build is finished we get some errors for including minSdVersion in manifest.xml.
Now what we do is just remove <uses-sdk android:minSdkVersion="19" /> from manifest.xml.
Make sure its removed from both the locations:
app → manifests → AndroidManifest.xml.
CordovaLib → manifests → AndroidManifest.xml.
Now try to build the gradle again and now it builds successfully
Make sure you have the following in Application tag in App → manifest → Androidmanifest.xml:
<application
android:networkSecurityConfig="#xml/network_security_config" android:usesCleartextTraffic="true" >
Open network_security_config (app → res → xml → network_security_config.xml).
Add the following code:
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">xxx.yyyy.com</domain>
</domain-config>
</network-security-config>
Here xxx.yyyy.com is the link of your HTTP API. Make sure you don't include any Http before the URL.
Note: Now build the app using Android Studio (Build -- Build Bundle's/APK -- Build APK) and now you can use that App and it works fine in Android Pie. If you try to build app using ionic Cordova build android it overrides all these settings so make sure you use Android Studio to build the Project.
If you have any older versions of app installed, Uninstall them and give a try or else you will be left with some error:
App not Installed
Create file - res / xml / network_security.xml
In network_security.xml ->
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">192.168.0.101</domain>
</domain-config>
</network-security-config>
Open AndroidManifests.xml :
android:usesCleartextTraffic="true" //Add this line in your manifests
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="#style/AppTheme">
cleartext support is disabled by default.Android in 9 and above
Try This one I hope It will work fine
1 Step:-> add inside android build gradle (Module:App)
useLibrary 'org.apache.http.legacy'
android {
compileSdkVersion 28
useLibrary 'org.apache.http.legacy'
}
Then 2 Step:-> manifest
add inside manifest application tag
<application
android:networkSecurityConfig="#xml/network_security_config">//add drawable goto Step 4
// Step --->3 add to top this line
<uses-library
android:name="org.apache.http.legacy"
android:required="false" />
</application>
//Step 4-->> Create Drawable>>Xml file>>name as>> network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
Put following into your resources/android/xml/network_security_config.xml :
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
This solves Failed to load resource: net::ERR_CLEARTEXT_NOT_PERMITTED problem on Android for Cordova / Ionic.
I would suggest to add both dev and prod network configs:
add res/xml/network_security_config_dev.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">10.0.2.2</domain>
</domain-config>
</network-security-config>
addres/xml/network_security_config_prod.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="false">
<domain includeSubdomains="true">yourdomain.com</domain>
</domain-config>
</network-security-config>
under Gradle Scripts (in android studio), find build.gradle (android.app) and look for buildTypes: release and debug (create if not exists):
buildTypes {
release {
minifyEnabled false
manifestPlaceholders.securityConfig = "#xml/network_security_config_prod"
}
debug {
manifestPlaceholders.securityConfig = "#xml/network_security_config_dev"
}
}
in AndroidManifest.xml use securityConfig placeholder as following (which was defined in build.gradle):
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:networkSecurityConfig="${securityConfig}" <------- here
Just add android:usesCleartextTraffic="true" inside the in AndroidManifest.xml file
In my case that URL is not working in browser also.
I check with https://www.google.com/
webView.loadUrl("https://www.google.com/")
And it worked for me.
For Xamarin.Android developers make sure HttpClient implementation and SSL/TLS is set to Default.
It can be found under Andorid Options -> Advanced Android Options.
This is done for security reasons, you should always prefer to use HTTPS (HTTP Secure) where possible.
You can read more about it here
There are multiple solutions for this issue depending on your condition.
If you are trying to communicate with a first party service, IE: your own web server
Server side: You should add HTTPS support to that server and use HTTPS instead of HTTP. These days you can even do it for free using services like LetsEncrypt and others
Client side: If you are using the HttpURLConnection from the java.net package you can switch to HttpsURLConnection of the java.net.ssl package, it has a similar if not identical API, so the switch should be effortless.
If you are using a third party service, like Google, Facebook, a weather service, etc.
In case that the service you are communicating with supports HTTPS (which it most likely does) you can just change your request URL from http://abc.xyz to https://abc.xyz.
As a last resort, if the third party service that you want to communicate with does not support HTTPS or any other form of secure communication, you can use this answer, but again, this is not recommended as it defeats the purpose of this much needed security feature.
If you are using ionic and getting this error during native http plugin, following fix needs to be done-
goto resources/android/xml/network_security_config.xml
Change it to-
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">localhost</domain>
<domain includeSubdomains="true">api.example.com(to be adjusted)</domain>
</domain-config>
</network-security-config>
That worked for me!
I using Cordova 8 with cordova-plugin-whitelist 1.3.4
and it default configuration my app no access to internet and i only add a parameter in the manifest.xml -> android:usesCleartextTraffic="true"
The path of mainfest changed in Cordova 8: platform/android/app/src/main/AndroidManifest.xml.
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="10000" android:versionName="1.0.0" package="io.cordova.hellocordova" xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
<application
android:hardwareAccelerated="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:usesCleartextTraffic="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|smallestScreenSize|screenLayout|uiMode" android:label="#string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:theme="#android:style/Theme.DeviceDefault.NoActionBar" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="#string/launcher_name">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
this is a real stupid because it obvious that your app need access to internet....
videoView can't open this video Online video
Create file res/xml/network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<certificates src="system" />
</trust-anchors>
</base-config>
</network-security-config>
New in the AndroidManifest.xml file under application:
android:networkSecurityConfig="#xml/network_security_config"
https://techprogrammingideas.blogspot.com/2021/02/android-code-for-displaying-video-with.html
https://youtu.be/90hWWAqfdUU
Upgrade to React Native 0.58.5 or higher version.
They have includeSubdomain in their config files in RN 0.58.5.
ChangeLog
In Rn 0.58.5 they have declared network_security_config with their server domain. Network security configuration allows an app to permit cleartext traffic from a certain domain. So no need to put extra effort by declaring android:usesCleartextTraffic="true" in the application tag of your manifest file. It will be resolved automatically after upgrading the RN Version.
After changed API version 9.0 getting the error Cleartext HTTP traffic to YOUR-API.DOMAIN.COM not permitted (targetSdkVersion="28"). in xamarin, xamarin.android and android studio.
Two steps to solve this error in xamarin, xamarin.android and android studio.
Step 1: Create file resources/xml/network_security_config.xml
In network_security_config.xml
<?xml version="1.0" encoding="utf-8" ?>
<network-security-config>
<domain-config cleartextTrafficPermitted="true">
<domain includeSubdomains="true">mobapi.3detrack.in</domain>
</domain-config>
</network-security-config>
Step 2: update AndroidManifest.xml -
Add android:networkSecurityConfig="#xml/network_security_config" on application tag.
e.g:
<application android:label="your App Name" android:icon="#drawable/icon" android:networkSecurityConfig="#xml/network_security_config">

push notifications not handled by onMessage if received when app closed using IBM MobileFirst Platform 7.0

We are using MFP 7.0.0.00-20150907-1450 and building a hybrid app targeting iOS and Android.
We're using the "send bulk messages" REST API to send broadcast messages.
We've implemented WL.Client.Push.onMessage in our app, and as long as the app is running when the notification is received, it handles the message.
If the application is closed when the notification reaches the phone, the message payload doesn't seem to get to our onMessage implementation.
This behavior is identical between iOS and Android.
I suspect there's a timing issue between our onMessage function being assigned and when the MFP framework is trying to pass the the message into our app.
Some pointers on how we might get the message handled in the case where it was received when the app was closed would be great!
(Below are some details of our setup.)
We're using Angular and had this in our main app module:
if (angular.isDefined(window.WL) && angular.isDefined(window.WL.Client.Push)) {
window.WL.Client.Push.onMessage = function (props, payload) {
console.log('Received push notification in client', JSON.stringify(props), JSON.stringify(payload));
$rootScope.$broadcast('pushNotification', props, payload);
};
}
After noticing this ("You must declare it outside any function.") in the docs for onMessage, I've moved the assignment out to the top of a JavaScript file, outside of even an IIFE. This function doesn't seem to be called, certainly there's no logging and the variable remains undefined:
var lastPushMessage;
function pushMessageRecorder(props, payload) {
lastPushMessage = {
props: props,
payload: payload
};
console.log('MFP: push received: ' + JSON.stringify(lastPushMessage, null, 2));
}
WL.Client.Push.onMessage = pushMessageRecorder;
Our security test (users don't have to log in, just have a app packaged with our keys):
<customSecurityTest name="customTests">
<test realm="wl_antiXSRFRealm" step="1" />
<test realm="wl_authenticityRealm" step="1" />
<test realm="wl_remoteDisableRealm" step="1" />
<test realm="wl_directUpdateRealm" mode="perSession" step="1" />
<test realm="wl_anonymousUserRealm" isInternalUserID="true" step="1" />
<test realm="wl_deviceNoProvisioningRealm" isInternalDeviceID="true" step="2" />
</customSecurityTest>
It looks like I've got it working.
(Mostly. If the app is not running and the user swipes away the notification, or opens the app directly from the launcher, then the notification still doesn't show up in the app.)
There were 2 things that needed doing:
the assignment to WL.Client.Push.onMessage had to be done "outside of any function"
it looks like the value for the string "app_name" in native/res/values/strings.xml is used to locate the app from the push service and make sure the message comes through
The second point still doesn't really make sense to me, but it looks like the intent-filter action android:name value in AndroidManifest.xml is built using these values:
{AndroidManifest.xml:/manifest[#package]}.{res/values/strings.xml:/resources/string[#name="app_name"]}.NOTIFICATION
Since the app_name value is used to build the notification qualifier, it can't have any spaces, which is not so nice for the name of your app that's displayed on the phone.
I've worked around that by adding another variable to the strings.xml file (although I could have just hard coded the name in the AndroidManifest.xml too, and then use that variable as my label.
Here's what's working:
res/values/strings.xml:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">MyApp</string>
<string name="app_label">My App</string>
<string name="push_notification_title">My App</string>
<!-- ... -->
</resources>
AndroidManifest.xml:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.MyProject" android:versionCode="1" android:versionName="1.0">
<uses-sdk android:minSdkVersion="19" android:targetSdkVersion="19"/>
<supports-screens android:smallScreens="false" android:normalScreens="true" android:largeScreens="false"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Push permissions -->
<permission android:name="com.MyProject.permission.C2D_MESSAGE" android:protectionLevel="signature"/>
<uses-permission android:name="com.MyProject.permission.C2D_MESSAGE"/>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:label="#string/app_label" android:icon="#drawable/icon">
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
<activity android:name=".MyApp" android:label="#string/app_name" android:configChanges="orientation|keyboardHidden|screenSize" android:launchMode="singleTask" android:theme="#android:style/Theme.Translucent.NoTitleBar" android:screenOrientation="portrait" android:windowSoftInputMode="adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="com.MyProject.MyApp.NOTIFICATION"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
<!-- Preference Activity -->
<activity android:name="com.worklight.common.WLSettingActivity" android:label="Worklight Settings"/>
<!-- UI Activity for displaying native dialogs -->
<activity android:name="com.worklight.wlclient.ui.UIActivity"/>
<!-- Push service -->
<!-- In order to use the c2dm library, an application must declare a class with the name C2DMReceiver, in its own package, extending com.google.android.c2dm.C2DMBaseReceiver
It must also include this section in the manifest, replacing "com.google.android.apps.chrometophone" with its package name. -->
<service android:name=".GCMIntentService"/>
<service android:name=".ForegroundService"/>
<!-- Only google service can send data messages for the app. If permission is not set - any other app can generate it -->
<receiver android:name="com.worklight.androidgap.push.WLBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<!-- Receive the actual message -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE"/>
<category android:name="com.MyProject"/>
</intent-filter>
<!-- Receive the registration id -->
<intent-filter>
<action android:name="com.google.android.c2dm.intent.REGISTRATION"/>
<category android:name="com.MyProject"/>
</intent-filter>
</receiver>
</application>
</manifest>

SyncAdapter onPerformSync() gets called on emulator but NOT when run on physical device

I have followed Google's tutorial to use a SyncAdapter with a dummyAccount and no ContentProvider.
The tutorial is quite straight forward, and I'm aware of the limitations of using stubs for the Account and ContentProvider. I implemented it and when run on the emulator, it works wonderfully. I see the message in the Log of when it is periodically called with periodicSync(..) and when I request specifically to be called with requestSync(..).
Here is the mind-blowing part, when I run the app on my BQ 5 HD (Android 4.1.2) the SyncAdapter is never ever called. If re-installed the app, but nothing seems to be happening. I've wasted weeks with this, and I can´t figure it out.
Here is the my manifestFile
<?xml version="1.0" encoding="utf-8"?>
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
....Whole bunch of activities...
<provider
android:name="com.sf.app_name.stubs.StubProvider"
android:authorities="com.sf.app_name.provider"
android:exported="false"
android:syncable="true" />
<service android:name="com.sf.app_name.stubs.AuthenticatorService"
android:exported="false">
<intent-filter>
<action android:name="android.accounts.AccountAuthenticator" />
</intent-filter>
<meta-data
android:name="android.accounts.AccountAuthenticator"
android:resource="#xml/authenticator" />
</service>
<service
android:name="com.sf.app_name.sync.SyncService"
android:exported="false"
android:process=":sync" >
<intent-filter>
<action android:name="android.content.SyncAdapter" />
</intent-filter>
<meta-data
android:name="android.content.SyncAdapter"
android:resource="#xml/syncadapter" />
</service>
</application>
authenticator.xml
<?xml version="1.0" encoding="utf-8"?>
<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
android:accountType="com.sf.app_name"
android:userVisible="false" />
syncadapter.xml
<?xml version="1.0" encoding="utf-8"?>
<sync-adapter
xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="com.sf.app_name.provider"
android:accountType="com.sf.app_name"
android:userVisible="false"
android:supportsUploading="false"
android:allowParallelSyncs="true"
android:isAlwaysSyncable="true"/>
Input is very much appreciated.
Finally figured out what's wrong thanks to ye-old-faithful Log.d(...). It's a definite noob mistake and I'm posting the answer to prevent other beginners from committing the same mistake.
In my code where I create and add the "dummyAccount" needed by the SyncAdapter framework, I did the following:
Account[] accounts = accountManager.getAccounts();
if(accounts.length == 0){
Account newAccount = new Account(ACCOUNT, ACCOUNT_TYPE);
ContentResolver.setIsSyncable(newAccount, AUTHORITY, 1);
ContentResolver.setSyncAutomatically(newAccount, AUTHORITY, true);
ContentResolver.addPeriodicSync(newAccount, AUTHORITY, new Bundle(), 40l);
accountManager.addAccountExplicitly(newAccount, null, null);
Log.d("serverSync", "ContetResolver set periodic sync");
}
The methodgetAccounts() returns all of the accounts associated to the device. Obviously it is going to return ZERO when run in the emulator because the emulator has no account associated whatsoever. So I thought it save to do it like this. I create my account of type ACCOUNT_TYPE add it, and go merrily along my way. (By the way, the reason for the addPeriodicSync on top of the setIsSyncable and setSyncAutomatially is to solve a problem that pertains to another matter.
Ofcourse, the SyncAdapter of my APP was getting called when the following was executed:
ContentResolver.requestSync(signedInAccountInstance.getDummyAccount(),
AccountManagerActivity.AUTHORITY, bundle);
They getDummyAccount(..) was gotten like so:
Account[] accounts = accountManager.getAccounts();
return accounts[0];
When this was run on the actual physical device, I should have realized that getAccounts(..) would also return (atleast) the gmail account associated to my Android device. Hence when I would do
ContentResolver.requestSync(signedInAccountInstance.getDummyAccount(),
AccountManagerActivity.AUTHORITY, bundle);
the "dummyAccount" sent would be Google's AccountType, and hence why my app's SyncAdapter would never be called. Instead, it was the gmail app's SyncAdapter who was getting called with my bundle.
How did I discover this? By printing out my dummyAccount in Log after looking into the Accounts of my physical device under Settings>Accounts, and realizing that for some reason when I executed my app on my mobile, my gmail account would display a "sync error".
All this could have been prevented by doing things correctly the first time:
Account[] accounts = accountManager.getAccountsByType(ACCOUNT_TYPE);
Where ACCOUNT_TYPE is static final variable used in my app.
// An account type, in the form of a domain name
public static final String ACCOUNT_TYPE = "com.sf.app_name";
Hope this helps save someone some headaches.

Resources