I wrote a test Android app in Xamarin, where sample data was stored in a file. Somehow I copied test data file to emulator, successfully run the app and forgot about the project for couple of months.
Now I am resuscitating the project and - I can't find the file in Android Device Manager although it is still accessible in the emulator. It drives me nuts, I need to edit it!
Perhaps someone can point me to the right way to locate the file. Thanks!
Following is the code fragment that reads the file. I added debug output in the comments after each relevant line
var fileName = "NursePurse.jobjson1.txt";
var assembly = typeof(pageJobs).GetTypeInfo().Assembly;
//assembly.base.CodeBase = "file:///storage/emulated/0/Android/data/NursePurse.Droid/files/.__override__/NursePurse.dll"
String fname = assembly.FullName;
//fname = NursePurse, Version=1.0.6504.22050, Culture=neutral, PublicKeyToken=null
Stream stream = assembly.GetManifestResourceStream(fileName);
List<String> t = assembly.GetManifestResourceNames().ToList();
// there are two entries
// "NursePurse.AppResources.resources","NursePurse.jobjson1.txt"
// here is my file! But I don't see neither of these files in the android device manager.
Question - where is it?
Following is the screenshot of Android Dev.Manager View and Device definition with SIM card
Related
For the last 2 weeks I've been successfully converting a WPF application to a Xamarin.forms android app. Everything works as intended except for 1 thing. I've been searching the web for a few days for a solution but I can't find a working solution.
This is my current setup:
Xamarin.Froms android app
Target android version: Android 10.0
Minimum android version: Android 7.0
Xamarin.Essentials version: 1.6.0
READ_EXTERNAL_STORAGE permission
WRITE_EXTERNAL_STORAGE permission
My app should be able to open a selected file, using the Xamarin.Essientials FilePicker, Do some stuff and save the File again to the same path. The file selection is handled in the following code:
var pickresult = await FilePicker.PickAsync();
if (pickresult != null)
{
try
{
var result = await pickresult.OpenReadAsync();
var reader = new StreamReader(result);
var jsonstring = reader.ReadToEnd();
ConfigData = JsonConvert.DeserializeObject<ProjectData>(jsonstring);
PLC_Data.ProjectLoaded = true;
L_LoadedProject.Text = pickresult.FileName;
ProjectData.Filepath = pickresult.FullPath;
reader.Close();
result.Close();
//Load login page
B_Next.IsEnabled = true;
}
This is where the problem occurs. Let me clearify what happens step by step:
The FilePicker opens a File picking window.
I navigate to my preferred file in the "download" folder, could be any folder.
The file is read and converted to an object
The file path is saved
when i check the filepath i get the following string:
"/storage/emulated/0/Android/data/com.FAIS.motorconfigapp/cache/2203693cc04e0be7f4f024d5f9499e13/303bc84665374139b6303c03255e9018/config1.json"
So the FilePicker copies the "External" file to the App cache folder and returns the filepath from the Apps cache folder. When i check this folder there is indeed a copy of my selected file inside it. Reading from and writing to this file works as it should.
Now the actual question:
Why does the FilePicker copy my selected file to his cache folder and how can i prevent it?
The user should be able to select a file from anywere on the device and find the updated file in the same location.
I've checked all my settings and in my opinion everyting should be correct so i don't get why a copy is created. Does anyone have an idea?
If you need more settings, pictures, versions please ask.
Thanks in advance
I tried a while to get the pretrained model working on android. The problem is, I only got the ckpt and meta file for the pretrained net. In my opinion I need the .pb for the android app. So I tried to convert the given files to an .pb file.
Therefore I tried the freeze_graph.py but without succes. So I used the example code from https://github.com/openimages/dataset/blob/master/tools/classify.py and modified it to store a pb. file after loading
if not os.path.exists(FLAGS.checkpoint):
tf.logging.fatal(
'Checkpoint %s does not exist. Have you download it? See tools/download_data.sh',
FLAGS.checkpoint)
g = tf.Graph()
with g.as_default():
input_image = tf.placeholder(tf.string)
processed_image = PreprocessImage(input_image)
with slim.arg_scope(inception.inception_v3_arg_scope()):
logits, end_points = inception.inception_v3(
processed_image, num_classes=FLAGS.num_classes, is_training=False)
predictions = end_points['multi_predictions'] = tf.nn.sigmoid(
logits, name='multi_predictions')
init_op = control_flow_ops.group(tf.global_variables_initializer(),
tf.global_variables_initializer(),
data_flow_ops.initialize_all_tables())
saver = tf_saver.Saver()
sess = tf.Session()
saver.restore(sess, FLAGS.checkpoint)
outpt_filename = 'output_graph.pb'
#output_graph_def = sess.graph.as_graph_def()
output_graph_def = graph_util.convert_variables_to_constants(sess, sess.graph.as_graph_def(), ["multi_predictions"])
with gfile.FastGFile(outpt_filename, 'wb') as f:
f.write(output_graph_def.SerializeToString())
Now my problem is that I have the .pb file but I don't have any opinion what is the input node name and I am not sure if multi_predictions is the right output name. In the example android app I have to specify both. And the android app crashed with:
tensorflow_inference_jni.cc:138 Could not create Tensorflow Graph: Invalid argument: No OpKernel was registered to support Op 'DecodeJpeg' with these attrs.
I don't know if there are more problem by trying to fix the .pb problem. Or if anyone knows a better way to port the ckpt and meta files to a .pd file in my case or knows a source for the final file with input and ouput names please give me a hint to complete this task.
Thanks
You'll need to use the optimize_for_inference.py script to strip out the unused nodes in your graph. "decodeJpeg" is not supported on Android -- pixel values should be fed in directly. ClassifierActivity.java has more detail about the specific nodes to use for inception v3.
I read and hope that I have followed the advice about the resource access, mentioned in How to access a resource in Java project using Gradle? .. but without success.
My configuration is not really the same (but I think that it does not matter):
In src/main/java: there is the package called "pack" in which there are all java files
In src/main/resources, there are all mp3 and wav files
And here is the part of Java code:
String musicFile = "deepSpaceInit.mp3";
URL resource = GluonApplication.class.getClassLoader()getResource(musicFile); // that works
// URL resource = GluonApplication.class.getResource(musicFile); // that works too with the same result
// resource is equal to jar:file/data/app/pack-2/base.apk!/deepSpaceInit.mp3
BUT, this next line does not work whereas the URL seems to be found (and correct):
Media soundMedia = new Media(resource.toExternalForm());
// Media soundMedia = new Media(resource.toString()); // it does not work too
The error (through adb) is:
" D/QMCX983D (374): Waiting for enable m or o sensor"
"QMC_IOCTL_GET_OPEN_STATUS failed"
"QMC_IOCTL_GET_DELAY failed"
"QMC_IOCTL_GET_YPR failed"
Have you an idea for solving this problem?
Note: GluonApplication is the "main" class for Gluon (i.e.the class in which there is the "start" input)
Note: Before getting this problem above, the javafx code worked fine in "pure" Java debug (application for PC platform), but it did not work when this application was ported for Android platform:
String musicFile = "deepSpaceInit.mp3";
Media sound = new Media(new File(repertoireMP3 + musicFile).toURI().toString()); // it does not work
with repertoireMP3 = "" or "/" or "./" or "src/main/resources" or "/src/main/resources" ... without success
Ok, Quick heads up that I am new to android programming.
I have very basic experience with java from uni.
I've recently been messing around with android studio and app building for my Samsung Galaxy Tab.
Sorry if this has been asked before but i couldn't see it.
I have tried to make an app that displays all the names of files on my SD card. Just at the top level. I made a quick interface with just a button and a text view to start (i'm away a single text view wont display a list but had problems but i got to that anyway)
ended up with the following code.
*public void ShowFolder(View view){
TextView test = (TextView)findViewById(R.id.View);
root = new File(Environment.getRootDirectory().toString());
File[] Files;
Files = root.listFiles();
String[] File_List;
File_List = root.list();*
I then ran this using the debugger to see what ended up in both the array lists.
I ran this code three times over but varied the "Environment.getRootDirectory" to "getExternalStorageDirectory()" and "getDataDirectory()".
Only the getRootDirectory version will return anything.In both other instances the debugger shows NULL for both Files and Files_list.
I know they are valid locations because used those commands then outputted to strings which i can manually find on my tablet with a file browser.
So, simply put, why dont all three of these options return file lists?
My first thought it permissions but I was unsure how to confirm this.
(Sorry for the long post)
Don't use toString() to create File. getRootDirectory() already returns File object.
Try something like this:
File root = Environment.getRootDirectory();
String[] rootList = root.list();
File[] rootListFiles = root.listFiles();
Also you need to obtain READ_EXTERNAL_STORAGE permission as you can see here in the docs of getExternalStorageDirectory()
I have some level definitions in xml format (with .txt extension) inside (without any subfolders) my project's rescources folder
I for more scalability, I have a plain text file naming all these level definition XMLs
I read that file using
TextAsset WorldList = (TextAsset)Resources.Load("WorldList");
And then I load the needed world:
TextAsset TA = (TextAsset)Resources.Load(/*"LevelDefs/" +*/ Worlds[worldToload]);
xps.parseXml(TA.text);
loadLevel(levelToLoad);
(you see that I have moved these rescources out of subfolder to reduce the chance of them not loading)
worldToload here is the index number of that world
program works fine on windows but nothing loads on my android test device.
I seem to have problems debugging on device so I only guess something went wrong in loading phase.
any suggestions?
From Unity Documentation:
Most assets in Unity are combined into the project when it is built.
However, it is sometimes useful to place files into the normal
filesystem on the target machine to make them accessible via a
pathname. An example of this is the deployment of a movie file on iOS
devices; the original movie file must be available from a location in
the filesystem to be played by the PlayMovie function.
Any files placed in a folder called StreamingAssets in a Unity project
will be copied verbatim to a particular folder on the target machine.
You can retrieve the folder using the Application.streamingAssetsPath
property. It’s always best to use Application.streamingAssetsPath to
get the location of the StreamingAssets folder, it will always point
to the correct location on the platform where the application is
running.
So below snippet should work:
// Put your file to "YOUR_UNITY_PROJ/Assets/StreamingAssets"
// example: "YOUR_UNITY_PROJ/Assets/StreamingAssets/Your.xml"
if (Application.platform == RuntimePlatform.Android)
{
// Android
string oriPath = System.IO.Path.Combine(Application.streamingAssetsPath, "Your.xml");
// Android only use WWW to read file
WWW reader = new WWW(oriPath);
while ( ! reader.isDone) {}
realPath = Application.persistentDataPath + "/Your"; // no extension ".xml"
var contents = System.IO.File.ReadAll(realPath);
}
else // e.g. iOS
{
dbPath = System.IO.Path.Combine(Application.streamingAssetsPath, "Your.xml");
}
Thanks to David I have resolved this problem.
for more precision I add some small details:
1-As David points out in his answer (and as stated in unity documentations), we should use StreamingAssets if we want to have the same folder structure. One should use Application.streamingAssetsPathto retrieve the path.
However, files are still in the apk package in android's case, so they should be accessed using unity android's www class.
a good practice here is to create a method to read the file (even mandatory if you are going to read more than one file)
here is one such method:
private IEnumerator LoadDataFromResources(string v)
{
WWW fileInfo = new WWW(v);
yield return fileInfo;
if (string.IsNullOrEmpty(fileInfo.error))
{
fileContents = fileInfo.text;
}
else
fileContents = fileInfo.error;
}
This is a coroutine, and to use it we need to call it using
yield return StartCoroutine(LoadDataFromResources(path + "/fileName.ext"));
Yet another remark: we can not write into this file or modify it as it's still inside the apk package.