I'm trying to pick pictures files and copy them to app local folder, and save path as string in database to display images, the code works fine on UWP but does not on Android (I'm using Uno Platform):
string SImag = string.Empty;
private async Task<string> MediaxPicAsync()
{
Windows.Storage.Pickers.FileOpenPicker openPicker = new Windows.Storage.Pickers.FileOpenPicker();
openPicker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
openPicker.FileTypeFilter.Add(".bmp");
openPicker.FileTypeFilter.Add(".gif");
openPicker.FileTypeFilter.Add(".jpg");
openPicker.FileTypeFilter.Add(".jpeg");
openPicker.FileTypeFilter.Add(".png");
Windows.Storage.StorageFile file = await openPicker.PickSingleFileAsync();
if (file != null)
{
try
{
Windows.Storage.StorageFile temp = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync("TempFile." + file.FileType);
await file.CopyAndReplaceAsync(temp);
return temp.Path;
}
catch (Exception ex)
{
await new Windows.UI.Popups.MessageDialog("Could not open image!", "Error image loading").ShowAsync();;
}
}
return string.Empty;
}
Xaml Code:
<Image>
<Image.Source>
<BitmapImage UriSource="{x:Bind SImag, Mode=OneWay,Converter={StaticResource appClsConvStr2Imag}}" />
</Image.Source>
</Image>
Converter:
public class ClsConvStr2Imag : Windows.UI.Xaml.Data.IValueConverter
{
object Windows.UI.Xaml.Data.IValueConverter.Convert(object value, Type targetType, object parameter, string language)
{
if (string.IsNullOrEmpty(value as string))
{
return null;
}
else
{
string sPath = (string)value;
if (sPath.Contains("/") | sPath.Contains("\\"))
{
}
else
{
if (parameter == null)
{
sPath = Windows.Storage.ApplicationData.Current.LocalFolder.Path + "\\" + sPath;
}
else
{
sPath = Windows.Storage.ApplicationData.Current.LocalFolder.Path + "\\" + parameter + "\\" + sPath;
}
}
return new Uri(sPath);
}
}
object Windows.UI.Xaml.Data.IValueConverter.ConvertBack(object value, Type targetType, object parameter, string language)
{
return value;
}
}
On Visual studio output during Android debug it shows error as:
[BitmapFactory] Unable to decode stream: java.io.FileNotFoundException: /data/user/0/Sale.Sale/files/TempFile.png (No such file or directory)
Any help to overcome this issue is most welcome, I did research for 3 days and could not find clean solution for this issue. Many thanks in advance for time and expertise.
Related
Im investigating the use of citeproc in my current Android application
api 'de.undercouch:citeproc-java:2.0.0'
implementation 'org.citationstyles:styles:20.11'
implementation 'org.citationstyles:locales:20.11'
Its working fine using
// https://repo1.maven.org/maven2/com/eclipsesource/j2v8/j2v8/6.2.0/
implementation(name: 'j2v8-6.2.0', ext: 'aar')
However as Im running on Android OS the CSL static method
CSL.getSupportedStyles()
returns an empty list.
the underlying code in this method is as follows:-
private static Set<String> getAvailableFiles(String prefix,
String knownName, String extension) throws IOException {
Set<String> result = new LinkedHashSet<>();
// first load a file that is known to exist
String name = prefix + knownName + "." + extension;
URL knownUrl = CSL.class.getResource("/" + name);
if (knownUrl != null) {
String path = knownUrl.getPath();
// get the jar file containing the file
if (path.endsWith(".jar!/" + name)) {
String jarPath = path.substring(0, path.length() - name.length() - 2);
URI jarUri;
try {
jarUri = new URI(jarPath);
} catch (URISyntaxException e) {
// ignore
return result;
}
try (ZipFile zip = new ZipFile(new File(jarUri))) {
Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();
if (e.getName().endsWith("." + extension) &&
(prefix.isEmpty() || e.getName().startsWith(prefix))) {
result.add(e.getName().substring(
prefix.length(), e.getName().length() - 4));
}
}
}
}
}
return result;
}
Is it possible to list get getAvailableFiles method to work on Android OS?
The following aproach does not work
val name: String = "$prefix$knownName.$extension"
val knownUrl: URL? = CSL::class.java.classLoader.getResource("$name")
All I require is the list of ".csl" files that in an Eclipse java project show as residing in styles-20.11.jar file
When I extract my Application APK file the ".csl" files are all listed seperately
Where am I going wrong?
How can I get a list of all ".csl" files available to CSL?
Your provided detail guides me to find the solution. That's enough to define apk in the checker condition.
class CLSHelper {
public static Set<String> getSupportedStyles() throws IOException {
return getAvailableFiles("", "ieee", "csl");
}
/**
* Customizing this function to able run in Android environment
*/
private static Set<String> getAvailableFiles(String prefix,
String knownName, String extension) throws IOException {
Set<String> result = new LinkedHashSet<>();
// first load a file that is known to exist
String name = prefix + knownName + "." + extension;
URL knownUrl = CSL.class.getResource("/" + name);
if (knownUrl != null) {
String path = knownUrl.getPath();
// get the jar or apk file containing the file
if (path.endsWith(".jar!/" + name) || path.endsWith(".apk!/" + name)) { // changing this line
String jarPath = path.substring(0, path.length() - name.length() - 2);
URI jarUri;
try {
jarUri = new URI(jarPath);
} catch (URISyntaxException e) {
// ignore
return result;
}
try (ZipFile zip = new ZipFile(new File(jarUri))) {
Enumeration<? extends ZipEntry> entries = zip.entries();
while (entries.hasMoreElements()) {
ZipEntry e = entries.nextElement();
if (e.getName().endsWith("." + extension) &&
(prefix.isEmpty() || e.getName().startsWith(prefix))) {
result.add(e.getName().substring(
prefix.length(), e.getName().length() - 4));
}
}
}
}
}
return result;
}
}
Output:
CSL.getSupportedStyles() // []
CLSHelper.getSupportedStyles() // [dependent/annals-of-occupational-and-environmental-medicine, dependent/photoacoustics, dependent/statistical-science, twentieth-century-music, dependent/aims-medical-science, dependent/cell-systems, dependent/nursingplus-open, dependent/computer-science-review,...]
P.S: To running on AndroidStudio I had to add these lines in build.gradle
android{
...
packagingOptions {
exclude 'META-INF/truffle/language'
}
}
I have a File and i want to send it to Spring Backend from Android. After receiving the image at Spring I am changing the name of the Image by Generating the UUID and then uploading it to AWS S3. My problem is i am getting null value as response.
Android Side ->
My Android Upload File Function ->
private void UploadFiles() {
File uploadFile = fileArrayList.get(0);
if (uploadFile != null) {
Log.d(TAG, "UploadFiles: File Name is -> " + uploadFile.getName());
// cropImageRequest.setCropId(uploadFile.getParentFile().getName());
// Parsing any Media type file
RequestBody requestFile = RequestBody.create(MediaType.parse("multipart/form-data"), uploadFile);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part cropImage = MultipartBody.Part.createFormData("cropImage", uploadFile.getName(), requestFile);
Api.uploadCropImage(cropImage, new Callback<BasicResponse>() {
#Override
public void onResponse(Call<BasicResponse> call, Response<BasicResponse> response) {
if (response.body() != null) {
Log.d(TAG, "onResponse: Success" + response.body().getResponse());
}
else{
Log.d(TAG, "onResponse: null Response");
}
}
#Override
public void onFailure(Call<BasicResponse> call, Throwable t) {
Log.d(TAG, "onResponse: Failure");
}
});
}
}
**uploadImageFunction -> **
public static void uploadCropImage(MultipartBody.Part cropImage, Callback<BasicResponse> callback) {
UploadCropImageApi uploadCropImageApi = retrofit.create(UploadCropImageApi.class);
Call<BasicResponse> call = uploadCropImageApi.uploadCropImage(cropImage);
call.enqueue(callback);
}
My Interface ->
public interface UploadCropImageApi {
#Multipart
#POST(UPLOAD_FILE_TO_AWS_URL)
Call<BasicResponse> uploadCropImage(#Part MultipartBody.Part cropImage);
}
This is my Spring File ->
#RequestMapping(value = "/UploadCropImage", method = RequestMethod.POST, consumes = {"multipart/form-data"})
#ResponseBody
public String UploadImage(#RequestBody MultipartFile cropImage,HttpServletRequest request) {
mAmazonClient = AmazonClient.GetAmazonClientInstance();
UUIDUtils uuid = new UUIDUtils();
try {
System.out.println(cropImage);
String KeyName = uuid.GenerateUUID(cropImage.getName());
String Code = mAmazonClient.uploadImage(KeyName, cropImage);
System.out.println(Code);
return Code;
} catch (Exception e) {
// TODO Auto-generated catch block
System.out.println(e.getMessage());
return null;
}
}
This Controller is printing following value ->
org.springframework.web.multipart.commons.CommonsMultipartFile#b0b5de0
File Name is -: cropImage
null
My Problem is that as you can see the file sent by Retrofit and received by Spring is not null, I am sending that file via AWS, but it's not uploading the file and returns null as value. But when i use POSTMAN it's easily sending the file to AWS and returns the KeyName.
Okay so i debug a little bit and found out an exception while uploading Image file. and the exception is this -> The filename, directory name, or volume label syntax is incorrect.
Your exception says there is something wrong in your file name. The problem is naming convention as it was uploading file name containing ":" sign and there may be other signs as well which is not accepted by AWS. so, just change file name and separate the names by _(Underscore) sign instead of " "(space), (:) and other signs. This will successfully upload the file to the AWS. Hope it helps.
How can I send HTTP GET and POST requests in C# with Unity?
What I want is:
send json data in post request (I use Unity serializer, so no need in
new one, I just want to pass string in post data and have ability to
set ContentType to application/json);
get response code and body without any problems;
do it all asynchronous without blocking ui rendering.
What I've tried:
implementing with HttpWebRequest/HttpWebResponse, but it's too hard and low level (if I won't found anything better, I'll have to use it);
using unity WWW, but it doesn't match my requirements;
using some external packages from NuGet - Unity don't accept them :(
Most problems were with threading, I'm not experienced enough in it in C#.
IDE, I use, is Intellij Rider.
The WWW API should get this done but UnityWebRequest replaced it so I will answer the newer API. It's really simple. You have to use coroutine to do this with Unity's API otherwise you have have to use one of C# standard web request API and Thread. With coroutine you can yield the request until it is done. This will not block the main Thread or prevent other scripts from running.
Note:
For the examples below, if you are using anything below Unity 2017.2, replace SendWebRequest() with Send() and then replace isNetworkError with isError. This will then work for the lower version of Unity. Also, if you need to access the downloaded data in a binary form instead, replace uwr.downloadHandler.text with uwr.downloadHandler.data. Finally, the SetRequestHeader function is used to set the header of the request.
GET request:
void Start()
{
StartCoroutine(getRequest("http:///www.yoururl.com"));
}
IEnumerator getRequest(string uri)
{
UnityWebRequest uwr = UnityWebRequest.Get(uri);
yield return uwr.SendWebRequest();
if (uwr.isNetworkError)
{
Debug.Log("Error While Sending: " + uwr.error);
}
else
{
Debug.Log("Received: " + uwr.downloadHandler.text);
}
}
POST request with Form:
void Start()
{
StartCoroutine(postRequest("http:///www.yoururl.com"));
}
IEnumerator postRequest(string url)
{
WWWForm form = new WWWForm();
form.AddField("myField", "myData");
form.AddField("Game Name", "Mario Kart");
UnityWebRequest uwr = UnityWebRequest.Post(url, form);
yield return uwr.SendWebRequest();
if (uwr.isNetworkError)
{
Debug.Log("Error While Sending: " + uwr.error);
}
else
{
Debug.Log("Received: " + uwr.downloadHandler.text);
}
}
POST request with Json:
void Start()
{
StartCoroutine(postRequest("http:///www.yoururl.com", "your json"));
}
IEnumerator postRequest(string url, string json)
{
var uwr = new UnityWebRequest(url, "POST");
byte[] jsonToSend = new System.Text.UTF8Encoding().GetBytes(json);
uwr.uploadHandler = (UploadHandler)new UploadHandlerRaw(jsonToSend);
uwr.downloadHandler = (DownloadHandler)new DownloadHandlerBuffer();
uwr.SetRequestHeader("Content-Type", "application/json");
//Send the request then wait here until it returns
yield return uwr.SendWebRequest();
if (uwr.isNetworkError)
{
Debug.Log("Error While Sending: " + uwr.error);
}
else
{
Debug.Log("Received: " + uwr.downloadHandler.text);
}
}
POST request with Multipart FormData/Multipart Form File:
void Start()
{
StartCoroutine(postRequest("http:///www.yoururl.com"));
}
IEnumerator postRequest(string url)
{
List<IMultipartFormSection> formData = new List<IMultipartFormSection>();
formData.Add(new MultipartFormDataSection("field1=foo&field2=bar"));
formData.Add(new MultipartFormFileSection("my file data", "myfile.txt"));
UnityWebRequest uwr = UnityWebRequest.Post(url, formData);
yield return uwr.SendWebRequest();
if (uwr.isNetworkError)
{
Debug.Log("Error While Sending: " + uwr.error);
}
else
{
Debug.Log("Received: " + uwr.downloadHandler.text);
}
}
PUT request:
void Start()
{
StartCoroutine(putRequest("http:///www.yoururl.com"));
}
IEnumerator putRequest(string url)
{
byte[] dataToPut = System.Text.Encoding.UTF8.GetBytes("Hello, This is a test");
UnityWebRequest uwr = UnityWebRequest.Put(url, dataToPut);
yield return uwr.SendWebRequest();
if (uwr.isNetworkError)
{
Debug.Log("Error While Sending: " + uwr.error);
}
else
{
Debug.Log("Received: " + uwr.downloadHandler.text);
}
}
DELETE request:
void Start()
{
StartCoroutine(deleteRequest("http:///www.yoururl.com"));
}
IEnumerator deleteRequest(string url)
{
UnityWebRequest uwr = UnityWebRequest.Delete(url);
yield return uwr.SendWebRequest();
if (uwr.isNetworkError)
{
Debug.Log("Error While Sending: " + uwr.error);
}
else
{
Debug.Log("Deleted");
}
}
Use HttpClient and something like:
public static HttpContent DoPost(object payload, string subPath)
{
var httpClient = new HttpClient();
HttpClient.BaseAddress = new Uri(Global.BaseUrl);
HttpClient.DefaultRequestHeaders.Clear();
HttpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); // if you're using json service
// make request
var response = Global.HttpClient.PostAsJsonAsync(subPath.TrimLeadingSlash(), payload).Result;
// check for error
response.EnsureSuccessStatusCode();
// return result
return response.Content;
}
Payload is an object to be serialized to json. If all requests are going to the same baseUrl, you can set up HttpClient globally, and reuse it here
https://www.patrykgalach.com/2019/04/18/how-to-call-rest-api-in-unity/
Please refer this link cleanest way to play with data
and do not use www instead of use UnityWebRequest
We can use WWW and UnityWebRequest classes to initiate API calls. WWW got obsolete now and Unity recommends using UnityWebRequest over WWW.
void Start() {
string url = "https://retrofit-backend-demo.herokuapp.com/book";
StartCoroutine(GetBooksUsingWWW(url));
StartCoroutine(GetBooksUsingUnityWebRequest(url));
}
IEnumerator GetBooksUsingWWW(string url) {
using (WWW www = new WWW(url)){
yield return www;
Debug.Log(www.text);
JSONNode jsonNode = JSON.Parse(www.text);
string title = jsonNode[0]["title"].ToString();
Debug.Log("Title: " + title);
}
}
IEnumerator GetBooksUsingUnityWebRequest(string url) {
UnityWebRequest www = UnityWebRequest.Get(url);
yield return www.SendWebRequest();
if(www.isNetworkError || www.isHttpError) {
Debug.Log(www.error);
}
else {
Debug.Log(www.downloadHandler.text);
JSONNode jsonNode = JSON.Parse(www.downloadHandler.text);
string title = jsonNode[0]["title"].ToString();
Debug.Log("Title: " + title);
}
}
For demo: https://github.com/codemaker2015/api-interaction-unity3d-demo
I'm using ZXing in an Android app being developed in Xamarin to scan a QR code and start playing the corresponding audio file automatically.
My problem is that when I get a result from scanning, it takes some time for the audio player activity to load so it gets called twice or more due to subsequent successful scannings.
Is there a way to stop continuous scanning as soon as I get a correct result?
Here's the code:
//Start scanning
scanner.ScanContinuously(opt, HandleScanResult);
}
private void HandleScanResult(ZXing.Result result)
{
string msg = "";
if (result != null && !string.IsNullOrEmpty(result.Text))
{
msg = result.Text;
var playerActivity = new Intent(myContext, typeof(AudioActivity));
//-------------------------------------------------------------
// Prerequisite: load all tracks onto "Assets/tracks" folder
// You can put here qr code - track assignments here below
// msg: decoded qr code
// playerActivity.Putextra second parameter is a relative path
// under "Assets" directory
//--------------------------------------------------------------
//Iterate through tracks stored in assets and load their titles into an array
System.String[] trackArray = Application.Context.Assets.List("tracks");
bool trackFound = false;
foreach (string track in trackArray)
{
if (track.Equals(msg + ".mp3"))
{
playerActivity.PutExtra("Track", "tracks/" + msg + ".mp3");
for (int i = 0; i < PostList.postList.Count; i++)
{
if (PostList.postList.ElementAt(i).code.Equals(msg))
playerActivity.PutExtra("TrackTitle", PostList.postList.ElementAt(i).title);
}
myContext.StartActivity(playerActivity);
trackFound = true;
}
}
Thank you!
Old question but i'll post it anyway for anyone still looking for this information.
You need your scanner to be a class variable. This is my code:
public MobileBarcodeScanner scanner = new MobileBarcodeScanner();
private void ArrivalsClick(object sender, EventArgs e)
{
try
{
if (Arrivals.IsEnabled)
{
MobileBarcodeScanningOptions optionsCustom = new MobileBarcodeScanningOptions();
scanner.TopText = "Scan Barcode";
optionsCustom.DelayBetweenContinuousScans = 3000;
scanner.ScanContinuously(optionsCustom, ArrivalResult);
}
}
catch (Exception)
{
throw;
}
}
private async void ArrivalResult(ZXing.Result result)
{
if (result != null && result.Text != "")
{
// Making a call to a REST API
if (resp.StatusCode == System.Net.HttpStatusCode.OK)
{
int? res = JsonConvert.DeserializeObject<int>(resp.Content);
if (res == 0)
{
scanner.Cancel(); // <----- Stops scanner (Something went wrong)
Device.BeginInvokeOnMainThread(async () =>
{
await DisplayAlert("..", "..", "ΟΚ");
});
}
else
{
Plugin.SimpleAudioPlayer.ISimpleAudioPlayer player = Plugin.SimpleAudioPlayer.CrossSimpleAudioPlayer.Current;
player.Load("beep.wav");
player.Play(); // Scan successful
}
}
else
{
scanner.Cancel();
Device.BeginInvokeOnMainThread(async () =>
{
await DisplayAlert("..", "..", "ΟΚ");
});
}
}
}
I am new to android phonegap. i am storing and retrieving data using native application. i dont know how to display the retrieved data from native to phonegap(HTML)page.
can anyone pls guide me how to access sqlite with phonegap.?
Thanks in advance.
You need to first create a Android plugin for Phonegap through which you will be able to access the native code and hence the native DB like this
public class SqlitePlugin extends Plugin {
private static final String TAG = "SqlitePlugin";
private static final String CREATE_DB_ACTION = "createDatabase";
private static final String SHOW_DB_VALUES_ACTION = "showValues";
#Override
public PluginResult execute(String action, JSONArray data, String callbackId) {
Log.i(TAG, "Plugin Called");
PluginResult result = null;
if (CREATE_DB_ACTION.equals(action)) {
Log.d(TAG, "CREATE_DB_ACTION");
DB _db = new DB(ctx);
_db.insertValues();
}
else if (SHOW_DB_VALUES_ACTION.equals(action)) {
Log.d(TAG, "SHOW_DB_VALUES_ACTION");
JSONObject DBInfo = null;
try {
DBInfo = getDBValuesListing();
} catch (JSONException e) {
e.printStackTrace();
}
result = new PluginResult(Status.OK, DBInfo);
}
else {
result = new PluginResult(Status.INVALID_ACTION);
Log.d(TAG, "Invalid action : " + action + " passed");
}
return result;
}
}
After that Create a sqlite.js file like this
function SqlitePlugin() {
};
SqlitePlugin.prototype.createDatabase = function(successCallback, failCallback) {
return PhoneGap.exec(successCallback, failCallback, "SqlitePlugin",
"createDatabase", [ null ]);
};
SqlitePlugin.prototype.showValues = function(params, successCallback, failCallback) {
return PhoneGap.exec(successCallback, failCallback, 'SqlitePlugin', 'showValues',
[ params ]);
};
PhoneGap.addConstructor(function() {
PhoneGap.addPlugin("SqlitePlugin", new SqlitePlugin());
});
Import this sqlite.js in your page(index.html) and then finally use the plugin like this
function showValues() {
window.plugins.SqlitePlugin.showValues('showValues',
showValuesSuccessCallBack, showValuesFailCallBack);
}
function showValuesSuccessCallBack(e) {
if (e.Rows.length > 0) {
alert("Success");
for (i = 0; i < e.Rows.length; i++) {
alert("Id = " + e.Rows[i].id);
alert("Number = " + e.Rows[i].number);
}
} else {
alert("No values in Database");
}
}
function showValuesFailCallBack(f) {
alert("Failure");
}
Let me know if this worked out for you
Write an phonegap plugin to pass the data from native side to html (js)
http://wiki.phonegap.com/w/page/36753494/How%20to%20Create%20a%20PhoneGap%20Plugin%20for%20Android
Well, you probably should use the HTML5 functions to store and retrieve data from a sqlite DB. However, if you are set on doing it with native code you should look at our implementation which was used for older Android devices that don't support sqlite.
https://github.com/cordova/cordova-android/blob/master/framework/assets/js/storage.js
https://github.com/cordova/cordova-android/blob/master/framework/src/com/phonegap/Storage.java