Getting a timestamp from a file on an Android device - android

I have a device running Android 11 connected to my Windows 7 laptop via USB cable. I can see the device using Windows Explorer and drill down through the folders. The file names, types, and modify dates all show up nicely in Explorer. I'm writing software in Visual Foxpro which will put the file list into a listbox and allow the user to select which ones to copy to the PC. When I run it, the names and types are good but the date shows up as a zero date which in VFP shows up as 12/30/1899 00:00:00.
The code I'm using looks something like this ("iX14" is the name of the Android device) :
* Search the PC's namespace for the iX14 folder and set the name space variable
oFOLDER = oSHELLAPP.Namespace("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")
for each oITEM in oFOLDER.Items
if oITEM.Name = "iX14"
mNAMESPACE = oITEM.Path
exit
endif
next
* reset oFOLDER to the particular folder in the iX14 which has the files we need
oFOLDER = oShellApp.Namespace(mNAMESPACE + "\Internal shared storage\Download\AutoLog")
for each oITEM in oFOLDER.Items
thisform.listbox.AddItem(oITEM.ModifyDate)
At this point I have nowhere else to go since I'm a database guy and my focus is within databases and I know very little about using the Win32API and other OS level tasks. I tried stepping through using the debugger to try to see exactly what was being returned from oITEM.ModifyDate but the debugger just shows up what I'm already getting, 12/30/1899 00:00:00.

Would you please test this code on your system:
Local mNAMESPACE
oShellApp = Createobject("shell.application")
* Search the PC's namespace for the iX14 folder and set the name space variable
oFOLDER = oShellApp.Namespace("::{20D04FE0-3AEA-1069-A2D8-08002B30309D}")
For Each oITEM In oFOLDER.Items
If oITEM.Name = "iX14"
mNAMESPACE = oITEM.Path
Exit
Endif
Next
If !Empty(m.mNAMESPACE)
Local lcPath
lcPath = Addbs(m.mNAMESPACE) + "Internal shared storage\Download\AutoLog"
GetTree(m.lcPath, '*.*')
Select ;
cast(filepath As Varchar(250)) As filepath, ;
cast(filename As Varchar(250)) As filename, ;
filesize, fattr, createtime, lastacc, lastwrite ;
From filelist ;
ORDER By 1,2
Endif
Function GetTree
Lparameters tcStartDir, tcSkeleton
tcSkeleton = Evl(m.tcSkeleton, "*.*")
Create Cursor filelist ;
(filepath m, filename m, filesize i, ;
fattr c(8), createtime T, lastacc T, lastwrite T)
oFiler = Createobject('filer.fileutil')
With oFiler
.SearchPath = m.tcStartDir
.Subfolder = 1
.FileExpression = m.tcSkeleton
.Find(0)
For ix=1 To .Files.Count
With .Files(ix)
Insert Into filelist ;
(filepath, filename, filesize, fattr, createtime, lastacc, lastwrite) ;
values ;
(.Path, .Name, .Size, Attr2Char(.Attr), ;
Num2Time2(.Datetime), Num2Time2(.LastAccessTime), Num2Time2(.LastWriteTime) )
Endwith
Endfor
Return .Files.Count
Endwith
Endfunc
Function Num2Time2
Lparameters tnFloat
Return Dtot(Date(1899,12,30) + m.tnFloat)
Endfunc
Function Attr2Char
Lparameters tnAttr
Return ;
IIF(Bittest(m.tnAttr,0),'RO','RW')+;
IIF(Bittest(m.tnAttr,1),'H','_')+;
IIF(Bittest(m.tnAttr,2),'S','_')+;
IIF(Bittest(m.tnAttr,4),'D','_')+;
IIF(Bittest(m.tnAttr,5),'A','_')+;
IIF(Bittest(m.tnAttr,6),'E','_')+;
IIF(Bittest(m.tnAttr,7),'N','_')
Endfunc

Related

Code pasted, but it executed reversed order of row on Android SSH client

When use an terminal application on android such as Terminus and i create a code snippet or just paste the copied code Function to the powershell terminal. It execute reversed order from Final line to First. Althought originaly all row of code order is ascending not descending. How can i fix that to run code in normal order without delete all line break?
Sample code in original format:
Function Get-DiskSize {$Disks = #()
$DiskObjects = Get-WmiObject -namespace "root/cimv2" -query "SELECT Name, Capacity, FreeSpace FROM Win32_Volume"
$DiskObjects | % {
$Disk = New-Object PSObject -Property #{
Name = $_.Name
Capacity = [math]::Round($_.Capacity / 1073741824, 2)
FreeSpace = [math]::Round($_.FreeSpace / 1073741824, 2)
FreePercentage = [math]::Round($_.FreeSpace / $_.Capacity * 100, 1)
}
$Disks += $Disk
}
Write-Output $Disks | Sort-Object Name
}
Code in pasted format:

How to use a Python script to run sqlite statements via ADB in order to populate a table from a JSON file?

Although the title might not be very good, I think the doubt is legit. I'm developing for Android and using SQLite on my persistence layer. In order to make tests (not unit or instrumented tests, just development tests, like opening a screen and checking some data to see the layout, for instance) I need data to get populated on my database - this is something very annoying to do because I need to insert lots of data and I don't want to pollute my code with this.
I wanted to do that in a very simple way that I could reuse for any application, library or module that I come to develop later on, therefore I decided to use Android Debug Bridge (ADB) to get access to the emulator shell and, from there, run the sql scripts to insert the data I want - read from a json file. For that I came up with the following script:
import sys
import json
import subprocess
# ADDS ROOT DIR TO PATH
sys.path.insert(0, '..')
COMMANDS = "abd root ; adb remount ; adb shell; sqlite3 {} ; .headers on ; insert into {} ({}) values ({}); exit ;"
ERROR_INVALID_INPUT = "You must specify the TableName and database full path"
def get_columns_and_values(object):
columns = ""
values = ""
for key, value in object.items():
columns += str(key) + ","
values += str(value) + ","
return [columns, values]
def get_table_name():
return sys.argv[1]
def get_database_path():
return sys.argv[2]
def validate_input():
return len(sys.argv) == 3
def run_commands(columns, values):
formatted_commands = COMMANDS.format(
get_database_path(),
get_table_name(),
columns,
values
)
process = subprocess.Popen(formatted_commands.split(), stdout=subprocess.PIPE)
output, error = process.communicate()
if validate_input():
with open(ARG_SAMPLE_JSON_FILE) as json_file:
data = json.load(json_file)
for object in data:
normalizedRow = get_columns_and_values(object)
run_commands(normalizedRow[0], normalizedRow[1])
else:
print ERROR_INVALID_INPUT
The problem is: the script starts by accessing the bash and, from there, it enters on emulator's shell just to get inside sqlite3 command line. When that happen, I do not know how I can use Python to run commands there - perhaps title of question could be how to run commands from Python into Android Emulator's shell? :p
Any help is very much appreciated.
P.S.: I know there are more elegant ways to achieve what I want like switching Dagger2 dependencies in order to offer mocked data, however this requires lots of configurations and debugs and, sometimes, you just wanna a fast way to starting seeing stuff on the screen.
Ok, I ended up figuring out that you can run sqlite commands in one line. The script below does exactly what I wanted:
import sys
import json
import subprocess
# ADDS ROOT DIR TO PATH
sys.path.insert(0, '..')
ARG_SAMPLE_JSON_FILE = "resources/WorkingDays.json"
CMD_SQL_INSERT = "adb shell sqlite3 {} \"INSERT INTO {} ({}) VALUES ({})\""
CMD_SQL_SELECT = "adb shell sqlite3 {} \"SELECT {} FROM {}\""
CMD_SQL_DELETE = "adb shell sqlite3 {} \"DELETE FROM {}\""
ACTION_INSERT = 'INSERT'
ACTION_DELETE = 'DELETE'
ACTION_SELECT = 'SELECT'
ERROR_INVALID_INPUT = "You must specify the table name, database full path and SQL action to be executed"
ERROR_INVALID_ACTION = "Unrecognized actions. Valid actions are: SELECT, DELETE and INSERT"
def get_columns_and_values(object):
columns = ""
values = ""
for key, value in object.items():
columns += str(key) + ","
if is_number(value):
values += str(value) + ","
else:
values += "'" + str(value) + "'" + ","
return [columns[:-1], values[:-1].replace("False", '0').replace("True", '1')]
def is_number(s):
try:
int(s)
return True
except ValueError:
return False
def get_json_file():
return sys.argv[1]
def get_table_name():
return sys.argv[2]
def get_database_path():
return sys.argv[3]
def get_action():
return sys.argv[4]
def validate_input():
return len(sys.argv) == 5
def run_commands(columns, values):
action = get_action()
if action == ACTION_SELECT:
formatted_command = CMD_SQL_SELECT.format(get_database_path(), columns, get_table_name())
elif action == ACTION_DELETE:
formatted_command = CMD_SQL_DELETE.format(get_database_path(), get_table_name())
elif action == ACTION_INSERT:
formatted_command = CMD_SQL_INSERT.format(get_database_path(), get_table_name(), columns, values)
else:
print ERROR_INVALID_ACTION
return
print "Executing command: {}".format(formatted_command)
process = subprocess.Popen(
formatted_command.split(),
stdout=subprocess.PIPE
)
output, error = process.communicate()
formatted_output = "OUTPUT: {}".format(output)
formatted_error = "ERROR: {}".format(error)
print formatted_output, formatted_error
if validate_input():
with open(get_json_file()) as json_file:
data = json.load(json_file)
for object in data:
normalizedRow = get_columns_and_values(object)
run_commands(normalizedRow[0], normalizedRow[1])
else:
print ERROR_INVALID_INPUT

Saving the value of a stepper in Corona SDK to a json file

I want to be able to pass the value from a stepper widget in corona into a json file. So far I've got my stepper to display and increment and decrement and display the current value on screen. I've written a function to save the value to a file as json, but i'm having trouble calling that function. I want to be able to have other setting on screen which have their values save to json. Here the code I have to save the setting:
local function saveSettings (e)
-- body
print("testtesttest")
if (file) then
local content = file:read("*a")
else
settings = {}
settings.houses = StepperNo
file = io.open(path, "w")
local json_setting = json.encode(settings)
file:write(json_setting)
io.close(file)
end
end
and then the code to display the stepper:
local StepperNo = 1
local displayNoOfHouses = display.newText("Number of houses: "..StepperNo,180,135, native.systemFontBold,16)
local function onStepperPress( e )
if ("increment" == e.phase) then
StepperNo = StepperNo + 1
elseif ("decrement") == e.phase then
StepperNo = StepperNo - 1
end
displayNoOfHouses.text = "Number of houses: "..StepperNo
end
local HouseStepper = widget.newStepper {left = 100, top = 100, minimumValue = 0, maximumValue = 9, onPress = onStepperPress}
I dont know how to call the savesetting function after the stepper is pressed. I think I might have done this incorrectly or may be missing something obvious, I am very new to Lua...
There is a very simple to implement table saver and loader presented in this tutorial:
http://coronalabs.com/blog/2014/10/14/tutorial-saving-and-loading-lua-tables-with-json/
It uses JSON to encode a Lua table to save and when needed, read the JSON back in and decode it to a Lua table.

How to Spawn objects in corona sdk

hey i am new to the Corona sdk world i want to learn how to spawn some objects and make them move across the screen i try everything and it never work i read the forum on spawning the right way and try it but still end up with a error in my code help this is my code
local mRandom = math.random
local mAbs = math.abs
local objects = {"rocket02" ,"rocket01","coin01"}
local function spawnObject()
local objIdx = mRandom(#objects)
local objName = objects[objIdx]
local object = display.newImage("image/object_"..objName..".png")
object.x = mRandom (screenLeft +30,screenRight-30)
object.y = screenTop
if objIdx < 4 then
object.type = "food"
else
object.type = "other"
end
end
Also can some one tell me how to make it move across the screen
Please help Thanks
here's the media file for you to take a look at
I'll show you a method. For that, I have rewritten your code as follows:
local mRandom = math.random
local objects = {"rocket02" ,"rocket01","coin01"}
local objectTag = 0
local object = {}
local function spawnObject()
objectTag = objectTag + 1
local objIdx = mRandom(#objects)
local objName = objects[objIdx]
object[objectTag] = display.newImage(objName..".png") -- see the difference here
object[objectTag].x = 30+mRandom(320)
object[objectTag].y = 200
object[objectTag].name = objectTag
print(objectTag)
end
timer.performWithDelay(1,spawnObject,3)
Here I've used a timer for displaying the object. You can also use for loop for the same purpose.
Here you can call any object with tag as object[objectTag].
For your information:
display.newImage(objName..".png")
--[[ will display object named rocket02.png or rocket01.png or coin01.png
placed in the same folder where your main.lua resides --]]
And
display.newImage("image/object_"..objName..".png")
--[[ will display object named object_rocket02.png or object_rocket01.png
or object_coin01.png placed in a folder named 'image'. And the folder
'image' should reside in the same folder where your main.lua is. --]]
And for moving your object from top to bottom, you can use:
either
function moveDown()
object[objectTag].y = object[objectTag].y + 10
--replace 'objectTag' in above line with desired number (ir., 1 or 2 or 3)
end
timer.performWithDelay(100,moveDown,-1)
or
transition.to(object[objectTag],{time=1000,y=480})
--[[ replace 'objectTag' in above line with desired number (ir., 1 or 2 or 3)
eg: transition.to(object[1],{time=1000,y=480}) --]]
Keep coding.............. :)

Extracting substring

i have some problems extracting strings
i am making a multiple choice with 4 choices (e.g. as buttons), with the choices by referencing to the filename. The file (i.e. the question) is a png and the filename is Number-Q01AZ7BZ8CZ9DZ10ANZ8.png. These png are put under assets folder.
Set<String> regions = regionsMap.keySet(); // get Set of regions
// loop through each region
for (String region : regions)
{
if (regionsMap.get(region)) // if region is enabled
{
// get a list of all flag image files in this region
String[] paths = assets.list(region);
for (String path : paths)
fileNameList.add(path.replace(".png", ""));
} // end if
} // end for
String fileName = fileNameList.get(randomIndex);
if (!quizCountriesList.contains(fileName))
{
quizCountriesList.add(fileName); // add the file to the list
String nextImageName = quizCountriesList.remove(0);
correctAnswer = nextImageName; // update the correct answer
int AZ = correctAnswer.indexOf("AZ");
int BZ = correctAnswer.indexOf("BZ");
int CZ = correctAnswer.indexOf("CZ");
int DZ = correctAnswer.indexOf("DZ");
int ANZ = correctAnswer.indexOf("ANZ");
String choiceA = null;
String choiceB = null;
String choiceC = null;
String choiceD = null;
choiceA = correctAnswer.substring( (AZ+2), (BZ) );
choiceB = correctAnswer.substring( (BZ+2), (CZ) );
choiceC = correctAnswer.substring( (CZ+2), (DZ) );
choiceD = correctAnswer.substring( (DZ+2), (ANZ) );
The logcat is as follows:
11-09 21:14:08.495: E/AndroidRuntime(25905): FATAL EXCEPTION: main
11-09 21:14:08.495: E/AndroidRuntime(25905): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.trial.quizgame/com.trial.quizgame.QuizGame}: java.lang.StringIndexOutOfBoundsException: length=15; regionStart=1; regionLength=-2
11-09 21:14:08.495: E/AndroidRuntime(25905): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:1967)
I have tried to set the buttons as .setText(correctAnswer) and it will correctly show as Number-Q01AZ7BZ8CZ9DZ10ANZ8, so the top part of getting the String for "correctAnswer" should be ok. The problem left at extracting strings, yet BZ must be at a position behind AZ, so as CZ behind BZ, etc:
From the logcat the regionLength is -2? How could I handle this?
I would like it to be for Q01, choice A=7, B=8, C=9, D=10 and ANZ=8
thanks in advance for your advice!
Your assumption on the strings value is wrong. This code, if AZ, BZ, CZ, DZ, ANZ is present, should run with no error.
Either run debugger as advised in comments, or use android logcat to provide some debugging context. android.utils.Log.d("APP", String.format("AZ=%d", AZ));
How you store your data is not a big deal. You can tune it for days... You could create xml files that contain the name of the image, and the four possible answers... You can use the underscore approach, you can stay with your current one. Til it is only used by you, it doesn't really matter. You should just keep it simple. More complex => more chance for bugs...
So I'd advise reading about debugging and logging instead of refining the way you store the information... Storing it in the filename, that's a smart idea, quick and efficient, an ideal hack...

Categories

Resources