Accessing Database stored in Internal Storage of Android Q - c#

I would like to access the database that is stored in the Internal storage. I'm using the following code to do so.
db_connection_string = "URI=file:" + GetAndroidInternalFilesDir() + "/employee.db";
Debug.Log("db_connection_string" + db_connection_string);
db_connection = new SqliteConnection(db_connection_string);
Following is my GetAndroidInternalFilesDir function.
public static string GetAndroidInternalFilesDir()
{
string[] potentialDirectories = new string[]
{
"/storage/Company",
"/sdcard/Company",
"/storage/emulated/0/Company",
"/mnt/sdcard/Company",
"/storage/sdcard0/Company",
"/storage/sdcard1/Company"
};
if(Application.platform == RuntimePlatform.Android)
{
for(int i = 0; i < potentialDirectories.Length; i++)
{
if(Directory.Exists(potentialDirectories[i]))
{
return potentialDirectories[i];
}
}
}
return "";
}
The above code works fine in every device that is <Android10 but it fails with Android 11 and above. The SDK Version is set to 30 in my Unity3D. I have also tried changing it to 29 with no success. How can I fix this?
UPDATE:
I have used the following code to trigger the permission for scoped storage but still, it shows zero success.
void initiate()
{
AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject packageManager = jc.Call<AndroidJavaObject>("getPackageManager");
AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("android.provider.Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION");
AndroidJavaObject launchIntent = packageManager.Call<AndroidJavaObject>("getLaunchIntentForPackage", packageManager);
launchIntent = jo.Call<AndroidJavaObject>("setData", packageManager);
jc.Call("startActivity", launchIntent);
}

if you want to search in listed directories (not in scope of your app) then you need a MANAGE_EXTERNAL_STORAGE permission. some doc in HERE

Related

can't Specify an audio profile using Google.Cloud.TextToSpeech.V1 in c#

I'm trying to convert Text To audio using Google.Cloud.TextToSpeech.V1. it works fine but I do not know how can I Specify an audio profile to use using c# while I found code in Node.js and python But Not anything in c# this is my code
static void Main(string[] args)
{
List<Word> lst = IntialData();
System.Environment.SetEnvironmentVariable("GOOGLE_APPLICATION_CREDENTIALS", #"C:\Users\Admin\TextToSpeechApiDemo\key.json");
var client = TextToSpeechClient.Create();
// The input to be synthesized, can be provided as text or SSML.
foreach (Word item in lst)
{
var input = new SynthesisInput
{
Text = item.Name,
};
// Build the voice request.
var voiceSelection = new VoiceSelectionParams
{
LanguageCode = "ar",
//SsmlGender = SsmlVoiceGender.Female,
Name = "ar-XA-Wavenet-A"
};
// Specify the type of audio file.
var audioConfig = new AudioConfig
{
AudioEncoding = AudioEncoding.Linear16,
};
// Perform the text-to-speech request.
var response = client.SynthesizeSpeech(input, voiceSelection, audioConfig);
// Write the response to the output file.
using (var output = File.Create(#"E:\Noursound\sim\ar-XA-Wavenet-A\" + item.Id.ToString() + ".wav"))
{
response.AudioContent.WriteTo(output);
}
}
}
I found this code in python he set effects_profile_id
audio_config = texttospeech.AudioConfig(
audio_encoding=texttospeech.AudioEncoding.MP3,
effects_profile_id=[effects_profile_id],
How can i do that using c#
The problem was in the version on the NuGet package i used 1.0.0-beta01 , and it's not have the EffectsProfileId property but after update it to version to Google.Cloud.TextToSpeech.V1 version 2.3.0 i found the property.
using Google.Cloud.TextToSpeech.V1;
class Program
{
static void Main(string[] args)
{
var config = new AudioConfig
{
AudioEncoding = AudioEncoding.Mp3,
EffectsProfileId = { "your profile ID" }
};
}
}
i created git issue for that on github Here's a link!

Get "initial Key" value from .mp3 file

I can't find a way to read the "initial key" property from an mp3 file to use the song information in my application.
I've already tried to find libraries which do the job for me. I found TagLib# which is a very cool solution for getting tags/properties of different file formats. (including mp3).
I can use this library to get the title, the artist, the beats per minute and so on.. only the initial key value is missing for my use which isn't featured, unfortunately.
I also tried to find other solutions which support the initial key property but I haven't found one.
I already found a source which seems to address the same issue and solves it with using TagLib#, but I can't figure out how he solved that problem.
Use Ctrl + F and search for "Initial" to find the code block.
You can find the link here
I'll post a short part of my code which can be used to determine different info about one song in a pattern like this: (["bpm"]"title" - "artist")
var file = TagLib.File.Create(filePath);
return $"[{file.Tag.BeatsPerMinute}]{file.Tag.Title} - {file.Tag.FirstPerformer}";
Thanks for any help or recommendations in advance! :)
Try this:
public static void Main(string[] args)
{
var path = …
var file = TagLib.File.Create (path);
var id3tag = (TagLib.Id3v2.Tag)file.GetTag (TagTypes.Id3v2);
var key = ReadInitialKey (id3tag);
Console.WriteLine ("Key = " + key);
}
static string ReadInitialKey(TagLib.Id3v2.Tag id3tag)
{
var frame = id3tag.GetFrames<TextInformationFrame>().Where (f => f.FrameId == "TKEY").FirstOrDefault();
return frame.Text.FirstOrDefault() ;
}
On Windows 10 you can also use:
async Task<string> ReadInitialKey(string path)
{
StorageFile file = await StorageFile.GetFileFromPathAsync(path);
Windows.Storage.FileProperties.MusicProperties musicProperties = await file.Properties.GetMusicPropertiesAsync();
var props = await musicProperties.RetrievePropertiesAsync(null);
var inkp = props["System.Music.InitialKey"];
return (string)inkp;
}
See here for documentation on MusicProperties object and here for the valid music properties.
You can use the Shell to read all MP3 properties.
Test on Windows 10, VS 2015 =>
// Add Reference Shell32.DLL
string sFolder = "e:\\";
string sFile= "01. IMANY - Don't Be so Shy (Filatov & Karas Remix).mp3";
List<string> arrProperties = new List<string>();
Shell objShell = new Shell();
Folder objFolder;
objFolder = objShell.NameSpace(sFolder);
int nMaxProperties = 332;
for (int i = 0; i < nMaxProperties; i++)
{
string sHeader = objFolder.GetDetailsOf(null, i);
arrProperties.Add(sHeader);
}
FolderItem objFolderItem = objFolder.ParseName(sFile);
if (objFolderItem != null)
{
for (int i = 0; i < arrProperties.Count; i++)
{
Console.WriteLine((i + ('\t' + (arrProperties[i] + (": " + objFolder.GetDetailsOf(objFolderItem, i))))));
}
}
Just borrowing code from nuget: mono TaglibSharp:
var tfile = TagLib.File.Create(#"..");
string initialKey = null;
if (tfile.GetTag(TagTypes.Id3v2) is TagLib.Id3v2.Tag id3v2)
{
/*
// test: add custom Initial Key tag
var frame = TextInformationFrame.Get(id3v2, "TKEY", true);
frame.Text = new[] {"qMMM"};
frame.TextEncoding = StringType.UTF8;
tfile.Save();
*/
var frame = TextInformationFrame.Get(id3v2, "TKEY", false);
initialKey = frame?.ToString();
}

Change Image in Update With NFC (Clear Android Intent Issue)

I have the next code:
void Update ()
{
if (Application.platform == RuntimePlatform.Android)
{
if(!already_switched){
try
{
// Create new NFC Android object
AndroidJavaObject mActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity"); // Activities open apps
mIntent = mActivity.Call<AndroidJavaObject>("getIntent");
string sAction = mIntent.Call<String>("getAction"); // resulte are returned in the Intent object
if (sAction == "android.nfc.action.NDEF_DISCOVERED")
{
Debug.Log("Tag of type NDEF");
}
else if (sAction == "android.nfc.action.TECH_DISCOVERED")
{
GetComponent<ButtonScrollingUp>().actual_pos = GetComponent<ButtonScrollingUp>().actual_pos + 1;
if (GetComponent<ButtonScrollingUp>().actual_pos > GetComponent<ButtonScrollingUp>().images.Count) GetComponent<ButtonScrollingUp>().actual_pos = 0;
image.GetComponent<SpriteRenderer>().sprite = GetComponent<ButtonScrollingUp>().images[GetComponent<ButtonScrollingUp>().actual_pos];
text_.GetComponent<Text>().text = GetComponent<ButtonScrollingUp>().texts[GetComponent<ButtonScrollingUp>().actual_pos];
return;
}
else if (sAction == "android.nfc.action.TAG_DISCOVERED")
{
tag_output_text.text += "Not supported";
}
else
{
tag_output_text.text = "Scan a NFC tag to make the cube disappear...";
return;
}
}
catch (Exception ex)
{
string text = ex.Message;
tag_output_text.text = text;
}
}
}
}
The code change an image when a NFC get close to the phone, the problem is that it changes the image one time per frame. I could do it just to change one time, but I don't want that, I want that each time that someone get close the NFC it changes. I think that I could solve that if I clear the intent stack, and I can do it with this:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
But I don't know how to do that in c# and unity.
Could someone help me?
I think that I could solve that if I clear the intent stack, and I can
do it with this:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
But I don't know how to do that in c# and unity.
You already have the intent stored in the mIntent variable:
AndroidJavaObject mActivity = new AndroidJavaClass("com.unity3d.player.UnityPlayer").GetStatic<AndroidJavaObject>("currentActivity"); // Activities open apps
AndroidJavaObject mIntent = mActivity.Call<AndroidJavaObject>("getIntent");
To get the equivalent of the Java code below:
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
First, get the Intent.FLAG_ACTIVITY_NEW_TASK and Intent.FLAG_ACTIVITY_CLEAR_TASK int values in C# from the Intent:
int FLAG_ACTIVITY_NEW_TASK = mIntent.GetStatic<int>("FLAG_ACTIVITY_NEW_TASK");
int FLAG_ACTIVITY_CLEAR_TASK = mIntent.GetStatic<int>("FLAG_ACTIVITY_CLEAR_TASK");
Now, you can do the bitwise operation and pass them to the setFlags function:
int orOP = FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TASK;
mIntent.Call<AndroidJavaObject>("setFlags", orOP);
Maybe something like this:

ZeroMQ C# Ironhouse example

I am fairly new to ZeroMQ and have been comparing security of messages using the ZeroMQ NuGet package and the NetMQ & NetMQ Security NuGet packages.
So far, I have not been able to find a C# version of the Ironhouse example using Curve Security. There is a "todo" item on the ZGuides repo but so far nothing implemented. (https://github.com/metadings/zguide/issues/1)
I am also trying to determine whether the NetMQ.Security approach to security is better than the curve security approach that is built into ZeroMQ 4. It seems like most information about Curve is at least from 2014 or earlier.
Any information would be greatly appreciated!
Both publisher and subscriber need to use its own set of public\private keys. In your sample code for subscriber you set CurvePublicKey (to that of server, which is wrong but still) but do not set CurveSecretKey - that's why you get "cannot open client INITIATE vouch". Here is your sample from another question fixed:
public class Program
{
static void Main(string[] args) {
using (var context = new ZContext()) {
Console.WriteLine($"Curve Supported: {ZeroMQ.ZContext.Has("curve")}");
byte[] serverPublicKey;
byte[] serverSecretKey;
Z85.CurveKeypair(out serverPublicKey, out serverSecretKey);
var publisher = new ZSocket(context, ZSocketType.PUB);
publisher.CurvePublicKey = serverPublicKey;
publisher.CurveSecretKey = serverSecretKey;
publisher.CurveServer = true;
publisher.Bind("tcp://*:5050");
var subscriber = new ZSocket(context, ZSocketType.SUB);
byte[] subPublicKey;
byte[] subSecretKey;
Z85.CurveKeypair(out subPublicKey, out subSecretKey);
subscriber.CurvePublicKey = subPublicKey;
subscriber.CurveSecretKey = subSecretKey;
subscriber.CurveServerKey = serverPublicKey;
ZError connectError;
subscriber.Connect("tcp://mybox:5050", out connectError);
if (connectError != null) {
Console.WriteLine($"Connection error: {connectError.Name} - {connectError.Number} - {connectError.Text}");
}
subscriber.SubscribeAll();
// Publish some messages
Task.Run(() => {
for (var i = 1; i <= 5; i++) {
var msg = $"Pub msg: {Guid.NewGuid().ToString()}";
using (var frame = new ZFrame(msg)) {
publisher.Send(frame);
}
}
});
Task.Run(() => {
// Receive some messages
while (true) {
using (var frame = subscriber.ReceiveFrame()) {
var msg = frame.ReadString();
Console.WriteLine($"Received: {msg}");
}
}
});
Console.WriteLine("Press ENTER to exit");
Console.ReadLine();
ZError subError;
subscriber.Disconnect("tcp://mybox:5050", out subError);
subscriber.Dispose();
ZError pubError;
publisher.Disconnect("tcp://*:5050", out pubError);
publisher.Dispose();
}
}
}
Indeed, there are not much C# examples with NetMQ. I found this that works "CurveTests.cs":
public void CurveTest()
{
var serverPair = new NetMQCertificate();
using var server = new DealerSocket();
server.Options.CurveServer = true;
server.Options.CurveCertificate = serverPair;
server.Bind($"tcp://127.0.0.1:55367");
var clientPair = new NetMQCertificate();
using var client = new DealerSocket();
client.Options.CurveServerKey = serverPair.PublicKey;
client.Options.CurveCertificate = clientPair;
client.Connect("tcp://127.0.0.1:55367");
for (int i = 0; i < 100; i++)
{
client.SendFrame("Hello");
var hello = server.ReceiveFrameString();
Assert.Equal("Hello", hello);
server.SendFrame("World");
var world = client.ReceiveFrameString();
Assert.Equal("World", world);
}
}
Important note - if you want to share server public key between different applications, don't use string representation (serverPair.PublicKeyZ85), because encryption won't work. I assume it related to encoding. Better save byte array representation to some file and share it instead:
File.WriteAllBytes("serverPublicKey.txt", serverPair.PublicKey);

equavalant of [DllImport("wininet.dll")] for INTERNET_COOKIE_HTTPONLY in android

I am looking for the equavalant of this DLL in android to handle INTERNET_COOKIE_HTTPONLY does anybody know this?
I most android systems the SET-COOKIES shows up only on one of our 5.1 android systems its does not show the SET-COOKIES.
This might be some security setting, but we cant find out what and where, somebody knows this?
WE have this code now, in most android systems we see the Cookie_Httponly, but in one system it does not
URL url = new URL (urlAddress);
String COOKIES_HEADER = "Set-Cookie";
var connection = (HttpURLConnection)url.OpenConnection ();
try
{
var stream = connection.InputStream;
using (var reader = new StreamReader (stream))
{
var content = reader.ReadToEnd ();
Console.WriteLine(content);
}
var headerFields = connection.HeaderFields;
if( headerFields.ContainsKey(COOKIES_HEADER))
{
var cookiesHeader = headerFields [COOKIES_HEADER];
if (cookiesHeader != null)
{
foreach (String cookie in cookiesHeader)
{
var _c = HttpCookie.Parse (cookie) [0];
cookies[_c.Name] = _c.Value;
}
}
}
return true;
}

Categories