I've written a UWP class library that doesn't seem to scan for BLE devices. Looking at the DeviceWatcher, it skips from the status Created to EnumerationComplete. I've tried creating a manifest for my library but the issue persists. Below is some of the code, and my manifest.
Adapter.cs
private DeviceWatcher deviceWatcher;
public override IList<IDevice> ConnectedDevices => ConnectedDeviceRegistry.Values.ToList();
/// <summary>
/// Used to store all connected devices
/// </summary>
public Dictionary<string, IDevice> ConnectedDeviceRegistry { get; }
/// <summary>
/// Registry used to store device instances for pending operations : connect
/// </summary>
public Dictionary<string, IDevice> DeviceOperationRegistry { get; }
public Adapter(DeviceWatcher deviceWatcher)
{
Platform = PLATFORM.WINDOWS;
DeviceOperationRegistry = new Dictionary<string, IDevice>();
ConnectedDeviceRegistry = new Dictionary<string, IDevice>();
this.deviceWatcher = deviceWatcher;
/*DeviceInformation.CreateWatcher(
aqsAllBluetoothLEDevices,
requestedProperties,
DeviceInformationKind.AssociationEndpoint);*/
deviceWatcher.Added += DeviceWatcher_Added;
deviceWatcher.Updated += DeviceWatcher_Updated;
deviceWatcher.Removed += DeviceWatcher_Removed;
deviceWatcher.EnumerationCompleted += DeviceWatcher_EnumerationCompleted;
deviceWatcher.Stopped += DeviceWatcher_Stopped;
}
protected override Task StartScanningForDevicesNativeAsync(Guid[] serviceUuids, bool allowDuplicatesKey, CancellationToken scanCancellationToken)
{
// clear out the list
DiscoveredDevices.Clear();
deviceWatcher.Start();
return Task.FromResult(true);
}
BleImplementation.cs
string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected", "System.Devices.Aep.Bluetooth.Le.IsConnectable" };
// BT_Code: Example showing paired and non-paired in a single query.
string aqsAllBluetoothLEDevices = "(System.Devices.Aep.ProtocolId:=\"{bb7bb05e-5972-42b5-94fc-76eaa7084d49}\")";
DeviceWatcher deviceWatcher;
protected override IAdapter CreateNativeAdapter()
{
deviceWatcher = DeviceInformation.CreateWatcher(
aqsAllBluetoothLEDevices,
requestedProperties,
DeviceInformationKind.AssociationEndpoint);
return new Adapter(deviceWatcher);
}
Package.appxmanifest
<?xml version="1.0" encoding="utf-8"?>
<Package xmlns="http://schemas.microsoft.com/appx/2010/manifest">
<Prerequisites>
<OSMinVersion></OSMinVersion>
<OSMaxVersionTested></OSMaxVersionTested>
</Prerequisites>
<Resources>
<Resource Language="" />
</Resources>
<Applications>
<Application Id="" StartPage="">
<VisualElements DisplayName="" Description=""
Logo="" SmallLogo=""
ForegroundText="" BackgroundColor="">
<SplashScreen Image="" />
</VisualElements>
</Application>
</Applications>
<Identity Name="MyCompany.MySuite.MyApp"
Version="1.0.0.0"
Publisher="CN=MyCompany, O=MyCompany, L=MyCity, S=MyState, C=MyCountry"/>
<Properties>
<DisplayName>MyApp</DisplayName>
<PublisherDisplayName>MyCompany</PublisherDisplayName>
<Logo>images\icon.png</Logo>
</Properties>
<Capabilities>
<Capability Name="internetClient" />
<!--BT_Code: Always declare the bluetooth capability when using Bluetooth-->
<DeviceCapability Name="bluetooth" />
</Capabilities>
</Package>
Related
How can I play a audio file from System.Environment.SpecialFolder.LocalApplicationData in Xamarin Android?
The Error is: Java.IO.IOException: 'setDataSourceFD failed.: status=0x80000000' FD is FileDescriptor? When yes have i to declare it? I've commented him out now, and also in the sample there isn't one....
The file path is consisting of:
string pathToNewFolder = System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
string file = Path.Combine(pathToNewFolder, Path.GetFileName(url));
public void PlayAudioFile(string file, int time)
{
var player = new MediaPlayer();
// var fd = global::Android.App.Application.Context.Assets.OpenFd(file);
player.Prepared += (s, e) =>
{
player.SeekTo(Convert.ToInt32(time));
player.Start();
};
player.Reset();
player.SetDataSource(file);
player.Prepare();
}
This could implemented by dependency service.However,this time I play the mp3 file in Assets folder.I think playing it from System.Environment.SpecialFolder.LocalApplicationData folder is quite similar with my solution.Hope it can shed some light on it.
Step 1: Add IAudio interface to your shared project.
public interface IAudio
{
void PlayAudioFile(string fileName);
}
Step2:In your Android project, add AudioService.cs that implements IAudio interface
[assembly: Dependency(typeof(AudioService))]
namespace AppAudio.Droid
{
public class AudioService : IAudio
{
public AudioService()
{
}
protected MediaPlayer player;
public void PlayAudioFile(string fileName)
{
player = new MediaPlayer();
var fd = global::Android.App.Application.Context.Assets.OpenFd(fileName);
player.Prepared += (s, e) =>
{
player.Start();
};
player.SetDataSource(fd.FileDescriptor, fd.StartOffset, fd.Length);
player.Prepare();
}
}
}
Step3: Call below line to play the mp3 file.
DependencyService.Get<IAudio>().PlayAudioFile("AllSong.mp3");
Last but not least,don't forget to add below permissions in your manifest file.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Useful link.
I am working on an app that is responsible for formatting a USB drive and prepare it for further use on an embedded system.
I am formatting the drive using the following method that I found on stack overflow (unfortunately I did not save the link. I'll post it there if I find it again)
public static bool FormatUSB(string driveLetter, string fileSystem = "FAT32", bool quickFormat = true,
int clusterSize = 4096, string label = "USB_0000", bool enableCompression = false)
{
//add logic to format Usb drive
//verify conditions for the letter format: driveLetter[0] must be letter. driveLetter[1] must be ":" and all the characters mustn't be more than 2
if (driveLetter.Length != 2 || driveLetter[1] != ':' || !char.IsLetter(driveLetter[0]))
return false;
//query and format given drive
//best option is to use ManagementObjectSearcher
var files = Directory.GetFiles(driveLetter);
var directories = Directory.GetDirectories(driveLetter);
foreach (var item in files)
{
try
{
File.Delete(item);
}
catch (UnauthorizedAccessException) { }
catch (IOException) { }
}
foreach (var item in directories)
{
try
{
Directory.Delete(item);
}
catch (UnauthorizedAccessException) { }
catch (IOException) { }
}
ManagementObjectSearcher searcher = new ManagementObjectSearcher(#"select * from Win32_Volume WHERE DriveLetter = '" + driveLetter + "'");
foreach (ManagementObject vi in searcher.Get())
{
try
{
var completed = false;
var watcher = new ManagementOperationObserver();
watcher.Completed += (sender, args) =>
{
Console.WriteLine("USB format completed " + args.Status);
completed = true;
};
watcher.Progress += (sender, args) =>
{
Console.WriteLine("USB format in progress " + args.Current);
};
vi.InvokeMethod(watcher, "Format", new object[] { fileSystem, quickFormat, clusterSize, label, enableCompression });
while (!completed) { System.Threading.Thread.Sleep(1000); }
}
catch
{
}
}
return true;
}
I also added all the capabilities that should be required (I think) in order to access a removable drive in my manifest:
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
xmlns:iot="http://schemas.microsoft.com/appx/manifest/iot/windows10"
IgnorableNamespaces="uap mp rescap iot">
<Identity
Name="7b9becad-6afd-4872-bcb7-7f414c098edf"
Publisher="CN=vitto"
Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="7b9becad-6afd-4872-bcb7-7f414c098edf" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>DiskMakerApp</DisplayName>
<PublisherDisplayName>vitto</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="DiskMakerApp.App">
<uap:VisualElements
DisplayName="DiskMakerApp"
Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png"
Description="DiskMakerApp"
BackgroundColor="transparent">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png"/>
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<rescap:Capability Name="broadFileSystemAccess" />
<rescap:Capability Name="appCaptureSettings" />
<Capability Name="internetClient" />
<uap:Capability Name="removableStorage" />
<iot:Capability Name="systemManagement"/>
<DeviceCapability Name="usb"/>
</Capabilities>
</Package>
And also allowed access to the file system in Window's settings page:
But I am still getting:
I am wondering if I am missing anything. Is there a way I could run the app as an administrator^ Would that solve the issue? (In any case, only admins would be able to run that app in a real life scenario)
UWP application unable to access USB drive even though permissions are set
Directory.GetFiles can't not use to access file with path in UWP platform. And you can only use Windows Storage API to access file with path (enable broadFileSystemAccess ), by the way, System.Management Namespace is not work for UWP platform, and if you want to format USB device within UWP app, please use desktop extension to process. for more please refer stefan' blog UWP with Desktop Extension
I'm trying to start listening on one of UDP ports on Android device. I'm using Xamarin.Forms and I'm testing it on physical android phone.
public void StartListening(int port = 13000)
{
ListenerPort = port;
udpClient = new UdpClient(ListenerPort);
udpClient.BeginReceive(new AsyncCallback(handleIncomingMessages), null);
}
This function is being used on application start:
public partial class App : Application
{
[...]
protected override void OnStart()
{
network.StartListening(LISTENING_ON_PORT);
}
}
The are many similar questions on SO, but most of them were solved by adding INTERNET permission to android manifest. Here is mine:
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.ddand">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
<application android:label="ddAnd.Android" android:theme="#style/MainTheme"></application>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
</manifest>
What I see after deploying my app is:
System.Net.Sockets.SocketException: 'Access denied'
and no other details provided.
I've thought my port is being used by another process, but I've check many of them (outside of 1-1024 range) and using all of them gave the same results.
Are there any other reasons for this exception? Do you have any ideas how can I throubleshoot the problem (e.g. how to find available port)?
EDIT:
As suggested in comments, I tried to gain access at runtime (though it should not be necessary, INTERNET permission is granted by default by Xamarin in Debug mode).
This line returns information that permission is granted.
var havePermission = ContextCompat.CheckSelfPermission(this, Manifest.Permission.Internet);
Nevertheless I tried to manually get access at runtime
ActivityCompat.RequestPermissions(this, new String[] { Manifest.Permission.Internet }, 1);
Result is the same as before.
Can you try with the following code? (adapted from the documentation)
public void StartListening(int port = 13000)
{
ListenerPort = port;
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Any, ListenerPort);
udpClient = new UdpClient(ipEndPoint);
UdpState udpState = new UdpState();
udpState.e = ipEndPoint;
udpState.u = udpClient;
udpState.BeginReceive(new AsyncCallback(handleIncomingMessages), udpState);
}
Unity 2018.4.15. Build project for Android platform with error:
CommandInvokationFailure: Gradle build failed. J:\Program
Files\2018.4.15f1\Editor\Data\PlaybackEngines\AndroidPlayer/Tools\OpenJDK\Windows\bin\java.exe
-classpath "J:\Program Files\2018.4.15f1\Editor\Data\PlaybackEngines\AndroidPlayer\Tools\gradle\lib\gradle-launcher-5.1.1.jar"
org.gradle.launcher.GradleMain "-Dorg.gradle.jvmargs=-Xmx4096m"
"assembleRelease"
stderr[ D8: Program type already present:
com.android.installreferrer.api.InstallReferrerClient$1
FAILURE: Build failed with an exception.
What went wrong: Execution failed for task ':transformDexArchiveWithExternalLibsDexMergerForRelease'.
There is only one lib with name "installreferrer-1.0.aar" in Assets/Plugins/Android/ folder. I use Facebook plugin (7.18.0), GoogleMobileAds (4.2.1), Applovin SDK (9.11.1) with Facebook mediation (5.6.1.0).
If I deleted installreferrer-1.0.aar - project compile ok, but it crashes after running on device. If I rollback library & delete the Facebook plugin the project compiles ok, but crashes as well. I think that FB connect is causing my error, but I cannot resolve it.
Manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" xmlns:tools="http://schemas.android.com/tools" android:installLocation="preferExternal">
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
<application android:theme="#style/UnityThemeSelector" android:icon="#mipmap/app_icon" android:label="#string/app_name" android:networkSecurityConfig="#xml/network_security_config"
android:name="android.support.multidex.MultiDexApplication" tools:replace="android:icon">
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>
<activity android:name="com.facebook.unity.FBUnityLoginActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:theme="#android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
<activity android:name="com.facebook.unity.FBUnityDialogsActivity" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:theme="#android:style/Theme.Translucent.NoTitleBar.Fullscreen" />
<activity android:name="com.facebook.unity.FBUnityAppLinkActivity" android:exported="true" />
<activity android:name="com.facebook.unity.FBUnityDeepLinkingActivity" android:exported="true" />
<activity android:name="com.facebook.unity.FBUnityGameRequestActivity" />
<activity android:name="com.facebook.unity.FBUnityCreateGameGroupActivity" />
<activity android:name="com.facebook.unity.FBUnityJoinGameGroupActivity" />
<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="fb2575328535843348" />
<meta-data android:name="com.facebook.sdk.AutoLogAppEventsEnabled" android:value="true" />
<meta-data android:name="com.facebook.sdk.AdvertiserIDCollectionEnabled" android:value="true" />
<provider android:name="com.facebook.FacebookContentProvider" android:authorities="com.facebook.app.FacebookContentProvider2575328535843348" android:exported="true" />
<receiver android:name="com.appsflyer.SingleInstallBroadcastReceiver" android:exported="true">
<intent-filter>
<action android:name="com.android.vending.INSTALL_REFERRER" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="com.android.vending.BILLING" />
</manifest>
mainTeplate.gradle
// GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.0'
**BUILD_SCRIPT_DEPS**}
}
allprojects {
repositories {
google()
jcenter()
flatDir {
dirs 'libs'
}
}
}
// Android Resolver Repos Start
([rootProject] + (rootProject.subprojects as List)).each {
ext {
it.setProperty("android.useAndroidX", true)
it.setProperty("android.enableJetifier", true)
}
}
([rootProject] + (rootProject.subprojects as List)).each { project ->
project.repositories {
def unityProjectPath = $/file:///**DIR_UNITYPROJECT**/$.replace("\\", "/")
maven {
url "https://maven.google.com"
}
maven {
url "https://maven.google.com/" // Assets/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml:7
}
maven {
url "https://adcolony.bintray.com/AdColony" // Assets/MaxSdk/Mediation/AdColony/Editor/Dependencies.xml:8
}
maven {
url "https://applovin.bintray.com/Android-Adapter-SDKs" // Assets/MaxSdk/Mediation/Fyber/Editor/Dependencies.xml:8, Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8
}
maven {
url "https://s3.amazonaws.com/smaato-sdk-releases/" // Assets/MaxSdk/Mediation/Smaato/Editor/Dependencies.xml:8
}
mavenLocal()
jcenter()
mavenCentral()
}
}
// Android Resolver Repos End
apply plugin: 'com.android.application'
**APPLY_PLUGINS**
dependencies {
implementation 'com.android.support:multidex:1.0.1'
implementation fileTree(dir: 'libs', include: ['*.jar'])
// Android Resolver Dependencies Start
implementation 'com.android.support:appcompat-v7:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
implementation 'com.android.support:appcompat-v7:28.+' // Assets/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml:10
implementation 'com.android.support:cardview-v7:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
implementation 'com.android.support:customtabs:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
implementation 'com.android.support:recyclerview-v7:28.+' // Assets/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml:9
implementation 'com.android.support:support-v4:25.3.1' // Facebook.Unity.Editor.AndroidSupportLibraryResolver.addSupportLibraryDependency
implementation 'com.applovin.mediation:adcolony-adapter:4.1.2.1' // Assets/MaxSdk/Mediation/AdColony/Editor/Dependencies.xml:8
implementation 'com.applovin.mediation:facebook-adapter:[5.6.1.0]' // Assets/MaxSdk/Mediation/Facebook/Editor/Dependencies.xml:8
implementation 'com.applovin.mediation:fyber-adapter:7.5.0.0' // Assets/MaxSdk/Mediation/Fyber/Editor/Dependencies.xml:8
implementation 'com.applovin.mediation:google-adapter:[17.2.1.7]' // Assets/MaxSdk/Mediation/Google/Editor/Dependencies.xml:5
implementation 'com.applovin.mediation:ironsource-adapter:6.13.0.1.0' // Assets/MaxSdk/Mediation/IronSource/Editor/Dependencies.xml:8
implementation 'com.applovin.mediation:mintegral-adapter:10.1.51.2' // Assets/MaxSdk/Mediation/Mintegral/Editor/Dependencies.xml:4
implementation 'com.applovin.mediation:smaato-adapter:21.3.1.0' // Assets/MaxSdk/Mediation/Smaato/Editor/Dependencies.xml:8
implementation 'com.applovin.mediation:tapjoy-adapter:12.4.0.0' // Assets/MaxSdk/Mediation/Tapjoy/Editor/Dependencies.xml:4
implementation 'com.applovin.mediation:unityads-adapter:3.4.0.1' // Assets/MaxSdk/Mediation/UnityAds/Editor/Dependencies.xml:4
implementation 'com.applovin:applovin-sdk:9.11.1' // Assets/MaxSdk/AppLovin/Editor/Dependencies.xml:4
implementation 'com.facebook.android:facebook-applinks:[5,6)' // Assets/FacebookSDK/Plugins/Editor/Dependencies.xml:6
implementation 'com.facebook.android:facebook-core:[5,6)' // Assets/FacebookSDK/Plugins/Editor/Dependencies.xml:5
implementation 'com.facebook.android:facebook-login:[5,6)' // Assets/FacebookSDK/Plugins/Editor/Dependencies.xml:7
implementation 'com.facebook.android:facebook-share:[5,6)' // Assets/FacebookSDK/Plugins/Editor/Dependencies.xml:8
implementation 'com.google.android.gms:play-services-ads:18.2.0' // Assets/GoogleMobileAds/Editor/GoogleMobileAdsDependencies.xml:7
implementation 'com.google.android.gms:play-services-ads-identifier:[16.0.0]' // Assets/MaxSdk/AppLovin/Editor/Dependencies.xml:5
implementation 'com.parse.bolts:bolts-android:1.4.0' // Assets/FacebookSDK/Plugins/Editor/Dependencies.xml:4
// Android Resolver Dependencies End
**DEPS**}
// Android Resolver Exclusions Start
android {
packagingOptions {
exclude ('/lib/armeabi/*' + '*')
exclude ('/lib/mips/*' + '*')
exclude ('/lib/mips64/*' + '*')
exclude ('/lib/x86/*' + '*')
exclude ('/lib/x86_64/*' + '*')
}
}
// Android Resolver Exclusions End
android {
compileSdkVersion **APIVERSION**
buildToolsVersion '**BUILDTOOLS**'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
multiDexEnabled true
minSdkVersion **MINSDKVERSION**
targetSdkVersion **TARGETSDKVERSION**
applicationId '**APPLICATIONID**'
ndk {
abiFilters **ABIFILTERS**
}
versionCode **VERSIONCODE**
versionName '**VERSIONNAME**'
}
dexOptions {
javaMaxHeapSize "16g"
}
lintOptions {
abortOnError false
}
aaptOptions {
noCompress = ['.unity3d', '.ress', '.resource', '.obb'**STREAMING_ASSETS**]
}**SIGN**
buildTypes {
debug {
minifyEnabled **MINIFY_DEBUG**
useProguard **PROGUARD_DEBUG**
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'**USER_PROGUARD**
jniDebuggable true
}
release {
minifyEnabled **MINIFY_RELEASE**
useProguard **PROGUARD_RELEASE**
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-unity.txt'**USER_PROGUARD****SIGNCONFIG**
}
}**PACKAGING_OPTIONS****SPLITS**
**BUILT_APK_LOCATION**
bundle {
language {
enableSplit = false
}
density {
enableSplit = false
}
abi {
enableSplit = true
}
}
}**SPLITS_VERSION_CODE****REPOSITORIES****SOURCE_BUILD_SETUP**
Change your Facebook android dependencies from "[5,6)" to "5.13.0". This was included into your mainTemplate.gradle from file
Assets/FacebookSDK/Plugins/Editor/Dependencies.xml
Resolve problem:
Remove FB plugin, FB Mediation from project and manifest
Exit from Unity
Remove Library folder
Launch Unity and compile without FB!
Install FB
Change your Facebook android dependencies from "[5,6)" to "5.13.0"
Assets -> GooglePlayResolver -> Android Resolver -> Settings -> Force Resolve
Profit!
I want to open a PDF on the Phone via the File-Path but i cant figure out how i could do this properly without using 3rd party packages.
You have any suggestion for this?
I already tried to use this on Android:
public void OpenFile(string filePath)
{
var fileToOpen = new Java.IO.File(filePath);
var uri = FileProvider.GetUriForFile(Application.Context, Application.Context.PackageName + ".fileprovider", fileToOpen);
var intent = new Intent();
var mime = IOUtil.GetMimeType(uri.ToString());
intent.SetAction(Intent.ActionView);
intent.SetDataAndType(uri, mime);
intent.SetFlags(ActivityFlags.NewTask);
intent.AddFlags(ActivityFlags.GrantReadUriPermission);
Application.Context.StartActivity(intent);
}
But i get the following Error:
Unhandled Exception:
Java.Lang.NullPointerException: Attempt to invoke virtual method
'android.content.res.XmlResourceParser
android.content.pm.ProviderInfo.loadXmlMetaData(android.content.pm.PackageManager,
java.lang.String)' on a null object reference
first you should addd this code to your manifest file :
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.easyphotopicker.fileprovider"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/filepaths"
tools:replace="android:resource"/>
</provider>
and create filepaths :
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<root-path name="root" path="" /> //root directory of the device new File("/");
<files-path name="files" path="" /> //context.getFilesDir()
<cache-path name="cache" path="" /> //context.getCacheDir()
<external-path name="external" path="" /> //Environment.getExternalStorageDirectory()
<external-files-path name="name" path="path" /> //context.getExternalFilesDirs()
<external-cache-path name="name" path="path" /> //getExternalCacheDirs()
</paths>
Your error is telling us that there is no file at the location matching that's passed into the function. There's a few ways of doing this, one of them is as shown. After accepting permissions to access folders and files, this should be one of the simplest ways. You seem to be close:
public void OpenPdfFile(string filename)
{
var f = new Java.IO.File(filename);
if (f.Exists())
{
System.Diagnostics.Debug.WriteLine("File exists!");
try
{
var openFileIntent = new Intent(Intent.ActionView);
openFileIntent.SetDataAndType(Android.Net.Uri.FromFile(f), "application/pdf");
openFileIntent.SetFlags(ActivityFlags.NoHistory);
StartActivity(Intent.CreateChooser(openFileIntent, "Open pdf file"));
}
catch (ActivityNotFoundException)
{
//handle when no available apps
}
}
}
I haven't tested your work, but the first thing would be to see if you added this to the Manifest file
android:authorities="com.{package}.{name}.fileprovider"
since your code says Application.Context.PackageName + ".fileprovider"