I am new to Java and I am getting kind of stuck by trying to loop through my JSON. I am retrieving a JSON object where I want to loop through.
My JSON looks as follow:
Code:
{"message":{"2":[{"uid":"2","title":"","message":"Test1","success":1,"created_at":null,"updated_at":null}],"3":[{"uid":"3","title":"","message":"Test2 !","success":1,"created_at":null,"updated_at":null}],"4":[{"uid":"4","title":"Bla","message":"Test3!","success":1,"created_at":null,"updated_at":null}]}}
I tried a loop like this:
Code:
for(int i = 0; i<json.names().length(); i++){
try {
Log.v("TEST", "key = " + json.names().getString(i) + " value = " + json.get(json.names().getString(i)));
} catch (JSONException e) {
e.printStackTrace();
}
}
But this will only target "message" which includes the whole JSON "string". I want to loop through each message and retrieving the value of uid 1, uid 2 etc. How can I achieve this?
Thanks in advance.
Here is how I'm doing it:
Code:
private static final String AllNewsItemsURL = "some_url_here.php";
private static final String TAG_SUCCESS = "success";
private static final String NEWS = "news";
private static final String TITLE = "title";
private static final String STORY = "story";
private final JSONParser jParser = new JSONParser();
private JSONArray newsItems = null;
..... / code snipped / ....
try {
JSONObject json = jParser.makeHttpRequest(AllNewsItemsURL, params);
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
newsItems = json.getJSONArray(NEWS);
for (int i = 0; i < newsItems.length(); i++) {
JSONObject obj = newsItems.getJSONObject(i);
Integer id = i + 1;
String title = obj.getString(TITLE);
String story = obj.getString(STORY);
}
} else {
Log.e("JSON Response", "success == 0");
}
} catch (Exception e) {
e.printStackTrace();
}
Thanks for your reply. I tried it but getting this exception:
Code:
org.json.JSONException: Value {"2":[{"uid":"2","title":"","message":"Test1","success":1,"created_at":null,"updated_at":null}],"3":[{"uid":"3","title":"","message":"Test2","success":1,"created_at":null,"updated_at":null}],"4":[{"uid":"4","title":"Bla","message":"Test3","success":1,"created_at":null,"updated_at":null}]} at messages of type org.json.JSONObject cannot be converted to JSONArray
CodeMonkeyy said:
Thanks for your reply. I tried it but getting this exception:
Code:
org.json.JSONException: Value {"2":[{"uid":"2","title":"","message":"Test1","success":1,"created_at":null,"updated_at":null}],"3":[{"uid":"3","title":"","message":"Test2","success":1,"created_at":null,"updated_at":null}],"4":[{"uid":"4","title":"Bla","message":"Test3","success":1,"created_at":null,"updated_at":null}]} at messages of type org.json.JSONObject cannot be converted to JSONArray
Click to expand...
Click to collapse
You might want to try the matching JSONParser I have for it, sorry forgot to include it:
https://github.com/JonnyXDA/WGSB/bl...om/jonny/wgsb/material/parser/JSONParser.java
Also noting that your entire JSON Array is called "message" but you also have a parameter called "message" - maybe rename the Array to "messages"?
As for the code you should have something like:
Code:
private static final String AllNewsItemsURL = "some_url_here.php";
private static final String TAG_SUCCESS = "success";
private static final String MESSAGES = "messages";
private static final String TITLE = "title";
private static final String MESSAGE = "message";
private final JSONParser jParser = new JSONParser();
private JSONArray messageItems = null;
..... / code snipped / ....
try {
JSONObject json = jParser.makeHttpRequest(AllNewsItemsURL, params);
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
messageItems = json.getJSONArray(MESSAGES);
for (int i = 0; i < messageItems.length(); i++) {
JSONObject obj = messageItems.getJSONObject(i);
String title = obj.getString(TITLE);
String message = obj.getString(MESSAGE);
}
} else {
Log.e("JSON Response", "success == 0");
}
} catch (Exception e) {
e.printStackTrace();
}
My code looks like the this:
Code:
//Message task
MessageTask task = new MessageTask(DashboardActivity.class);
task.execute();
try {
json = task.get();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
try {
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
messageItems = json.getJSONArray(MESSAGES);
for (int i = 0; i < messageItems.length(); i++) {
JSONObject obj = messageItems.getJSONObject(i);
String title = obj.getString(TITLE);
String message = obj.getString(MESSAGE);
}
} else {
Log.e("JSON Response", "success == 0");
}
} catch (Exception e) {
e.printStackTrace();
}
I am using Async Task to retrieve my JSON.
And my JSON parser looks like this:
Code:
public class JSONParser {
static InputStream is = null;
static JSONObject jObj = null;
static String json = "";
// constructor
public JSONParser() {
}
public JSONObject getJSONFromUrl(String url, List<NameValuePair> params) {
// Making HTTP request
try {
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
Log.e("JSON", json);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
}
But it doesn't get through the if statement, because it can't find the value success. ( org.json.JSONException: No value for success ). Don't really know what I am doing wrong here. Is it because I am using AsyncTask and retrieving my JSON the wrong way?
I also renamed my Array to "messages", stupid mistake thanks!
CodeMonkeyy said:
But it doesn't get through the if statement, because it can't find the value success. ( org.json.JSONException: No value for success ). Don't really know what I am doing wrong here. Is it because I am using AsyncTask and retrieving my JSON the wrong way?
I also renamed my Array to "messages", stupid mistake thanks!
Click to expand...
Click to collapse
We're getting closer! With regards to using AsyncTask - thats fine and the recommended way to do service side sync/download operations (doesn't block the UI thread) so no need to change that.
I just took a look at my reference JSON and I have the success tag outside of an item eg:
Code:
{"topical":[{"tid":"5","title":"Exam countdown... just 12 weeks left!","story":"some_story_text_here","staff":"0","red":"0","show":"1"}],[COLOR="red"]"success":1[/COLOR]}
Whereas your success tag is put in each item:
Code:
{"message":{"2":[{"uid":"2","title":"","message":"Test1","[COLOR="red"]success":1,[/COLOR]"created_at":null,"updated_at":null}],"3":[{"uid":"3","title":"","message":"Test2 !",[COLOR="red"]"success":1[/COLOR],"created_at":null,"updated_at":null}],"4":[{"uid":"4","title":"Bla","message":"Test3!","[COLOR="Red"]success":1[/COLOR],"created_at":null,"updated_at":null}]}}
I'm guessing that your php line for:
PHP:
$response["success"] = 1;
is inside of the while loop:
PHP:
while ($row = mysql_fetch_array($result)) {
Taking it out of the while loop should fix that
That makes sense, because I am trying to get a success code for my whole JSON response. I changed my PHP code to:
Code:
while($row = mysqli_fetch_array( $messages )) {
// create rowArr
$rowArr = array(
'uid' => $row['id'],
'title' => $row['title'],
'message' => $row["message"],
'created_at' => $row['created_at'],
'updated_at' => $row['updated_at'],
);
// store rowArr in $return_arr
$return_arr[$row['id']][] = $rowArr;
}
$return_arr['success'] = 1;
// Json encode
echo json_encode(array("messages" => $return_arr));
}
Retrieving the following JSON:
Code:
{"messages":{"2":[{"uid":"2","title":"","message":"Test1","created_at":null,"updated_at":null}],"3":[{"uid":"3","title":"","message":"Test2 !","created_at":null,"updated_at":null}],"4":[{"uid":"4","title":"Bla","message":"Test3!","created_at":null,"updated_at":null}],"success":1}}
But I am still getting the following exception:
Code:
org.json.JSONException: No value for success
The success tag is still being encoded as part of an inner array, not the first array - try this:
PHP:
if (mysql_num_rows($messages) > 0) {
$response["messages"] = array();
while ($row = mysql_fetch_array($messages)) {
$messagesArray= array(
'uid' => $row['id'],
'title' => $row['title'],
'message' => $row['message'],
'created_at' => $row['created_at'],
'updated_at' => $row['updated_at'],
);
array_push($response["messages"], $messagesArray);
}
$response["success"] = 1;
echo json_encode($response);
} else {
$response["success"] = 0;
$response["message"] = "No messages found";
echo json_encode($response);
}
And it's finally working!
Getting the following JSON result:
Code:
{"tag":"message","success":1,"error":0,"messages":[{"uid":"2","title":"","message":"Test1","created_at":null,"updated_at":null},{"uid":"3","title":"","message":"Test2!","created_at":null,"updated_at":null},{"uid":"4","title":"Bla","message":"Test3!","created_at":null,"updated_at":null}]}
And I can successfully loop through my JSON with the following code:
Code:
try {
int success = json.getInt(TAG_SUCCESS);
if (success == 1) {
messageItems = json.getJSONArray(MESSAGES);
for (int i = 0; i < messageItems.length(); i++) {
JSONObject obj = messageItems.getJSONObject(i);
String title = obj.getString(TITLE);
String message = obj.getString(MESSAGE);
Log.e("TITLE :", title);
Log.e("MESSAGE :", message);
}
} else {
Log.e("JSON Response", "success == 0");
}
} catch (Exception e) {
e.printStackTrace();
}
Thank you very much! So the problem was that I placed the "success" tag outside my Array?
Related
I'm an experienced developer but new to Android development. I have an app that runs some native binaries, and I provide a status indicator to show when the native process is running and when it's not. Currently I poll the device to figure this out, using the ActivityManager API to determine if specific processes are running or not.
I'm hoping there is some way to register a listener on process state changes, so I can get notified when my process starts or stops. I looked through the API, and there doesn't seem to be such a thing. Does anyone know how I can keep track of process start and stop other than polling via ActivityManager?
MidnightJava said:
I'm an experienced developer but new to Android development. I have an app that runs some native binaries, and I provide a status indicator to show when the native process is running and when it's not. Currently I poll the device to figure this out, using the ActivityManager API to determine if specific processes are running or not.
I'm hoping there is some way to register a listener on process state changes, so I can get notified when my process starts or stops. I looked through the API, and there doesn't seem to be such a thing. Does anyone know how I can keep track of process start and stop other than polling via ActivityManager?
Click to expand...
Click to collapse
Afaik there's no way to accomplish that other than your way or being system/root app. See this similar question here for reference.
Can you show how you start the process?
EmptinessFiller said:
Can you show how you start the process?
Click to expand...
Click to collapse
Sure. Here's the class that manages starting, stopping, and statusing (running or not) the binary executable. In this case, it's the omniNames service of the omni ORB (CORBA broker).
Code:
public class RHManager {
private TimerTask task = new TimerTask() {
@Override
public void run() {
if (RHManager.this.listener != null) {
listener.running(isOmniNamesRunning());
}
}
};
private IStatusListener listener;
public RHManager() {
}
public void startOmniNames() {
final Exec exec = new Exec();
final String[] args = new String[]
{RhMgrConstants.INSTALL_LOCATION_OMNI_NAMES_SCRIPTS + "/" + RhMgrConstants.OMNI_NAMES_SCRIPT_FILE,
"start"};
final String[] env = new String[] {"LD_LIBRARY_PATH=/sdcard/data/com.axiosengineering.rhmanager/omniORB/lib"};
Thread t = new Thread() {
public void run() {
try {
int res = exec.doExec(args, env);
logMsg("omniNames start return code " + res);
} catch (IOException e) {
logMsg("Failed to start omniNames");
e.printStackTrace();
}
String std = exec.getOutResult();
logMsg("omniNames start: std out==> " + std );
String err = exec.getErrResult();
logMsg("omniNames start: err out==> " + err );
};
};
t.start();
logMsg("omniNames started");
}
private boolean isOmniNamesRunning() {
String pid_s = getOmniNamesPid();
Integer pid = null;
if (pid_s != null) {
try {
pid = Integer.parseInt(pid_s);
} catch (NumberFormatException e) {
return false;
}
}
if (pid != null) {
RunningAppProcessInfo activityMgr = new ActivityManager.RunningAppProcessInfo("omniNames", pid, null);
return activityMgr.processName != null ;
}
return false;
}
public void stopOmniNames() {
String pid = getOmniNamesPid();
android.os.Process.killProcess(Integer.parseInt(pid));
android.os.Process.sendSignal(Integer.parseInt(pid), android.os.Process.SIGNAL_KILL);
}
private String getOmniNamesPid() {
Exec exec = new Exec();
final String[] args = new String[]
{RhMgrConstants.INSTALL_LOCATION_OMNI_NAMES_SCRIPTS + "/" + RhMgrConstants.OMNI_NAMES_SCRIPT_FILE,
"pid"};
String pid = "";
try {
int res = exec.doExec(args, null);
logMsg("oniNames pid return code: " + res);
} catch (IOException e) {
logMsg("Failed to start omniNames");
e.printStackTrace();
return pid;
}
String std = exec.getOutResult();
logMsg("omniNames pid: std out ==> " + std);
String err = exec.getErrResult();
logMsg("omniNames pid: err out ==> " + err);
String[] parts = std.split("\\s+");
if (parts.length >= 2) {
pid = parts[1];
}
return pid;
}
//monitor omniNames status and report status periodically to an IStatusListener
public void startMonitorProcess(IStatusListener listener, String string) {
this.listener = listener;
Timer t = new Timer();
t.schedule(task, 0, 1000);
}
private void logMsg(String msg) {
if (RhMgrConstants.DEBUG) {
System.err.println(msg);
}
}
}
Here's the Exec class that handles invocation of Runtime#exec(), consumes std and err out, and reports those and process return status to the caller.
Code:
public class Exec {
private String outResult;
private String errResult;
private Process process;
private boolean failed = false;
StreamReader outReader;
StreamReader errReader;
public int doExec(String[] cmd, String[] envp) throws IOException{
Timer t = null;
try {
process = Runtime.getRuntime().exec(cmd, envp);
outReader = new StreamReader(process.getInputStream());
outReader.setPriority(10);
errReader = new StreamReader(process.getErrorStream());
outReader.start();
errReader.start();
t = new Timer();
t.schedule(task, 10000);
int status = process.waitFor();
outReader.join();
errReader.join();
StringWriter outWriter = outReader.getResult();
outResult = outWriter.toString();
outWriter.close();
StringWriter errWriter = errReader.getResult();
errResult = errWriter.toString();
errWriter.close();
return (failed ? -1: status);
} catch (InterruptedException e) {
return -1;
} finally {
if (t != null) {
t.cancel();
}
}
}
public int doExec(String[] cmd) throws IOException{
return doExec(cmd, null);
}
public String getOutResult(){
return outResult;
}
public String getErrResult(){
return errResult;
}
private static class StreamReader extends Thread {
private InputStream is;
private StringWriter sw;
StreamReader(InputStream is) {
this.is = is;
sw = new StringWriter(30000);
}
public void run() {
try {
int c;
while ((c = is.read()) != -1){
sw.write(c);
}
}
catch (IOException e) { ; }
}
StringWriter getResult() {
try {
is.close();
} catch (IOException e) {
System.err.println("Unable to close input stream in StreamReader");
}
return sw;
}
}
private TimerTask task = new TimerTask() {
@Override
public void run() {
failed = true;
process.destroy();
}
};
}
Here's the script that startOminNames() invokes. It's the shell script installed with omniORB with functions other than start and get_pid removed, since those are handled by Android classes. You can invoke any executable in place of the script, or wrap your executable in a script.
Code:
#
# omniNames init file for starting up the OMNI Naming service
#
# chkconfig: - 20 80
# description: Starts and stops the OMNI Naming service
#
exec="/sdcard/data/com.axiosengineering.rhmanager/omniORB/bin/omniNames"
prog="omniNames"
logdir="/sdcard/data/com.axiosengineering.rhmanager/omniORB/logs"
logfile="/sdcard/data/com.axiosengineering.rhmanager/omniORB/logs/omninames-localhost.err.log"
options=" -start -always -logdir $logdir -errlog $logfile"
start() {
#[ -x $exec ] || exit 5
echo -n $"Starting $prog: "
$exec $options
}
get_pid() {
ps | grep omniNames
}
case "$1" in
start)
start && exit 0
$1
;;
pid)
get_pid
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
exit 2
esac
exit $?
And here's the IStatusListener interface
Code:
public interface IStatusListener {
public void running(boolean running);
}
Runtime.exec() has some pitfalls. See this helpful Runtime.exec tutorial for a nice explanation.
And you may also want to check out this post on loading native binaries in Android.
Hello everyone, I have an app on Google Play that shows the end user information about their device. Within this information, a Memory/Storage category is shown. Everything was good and fine until mean ol` KitKat wanted to deny access to the SDcard... Although I can understand Google's move on that subject, it can not go un-noticed that it may break many app's functionality (like my own). Anyhow, below is my class that scans for mount points, and stores them in an ArrayList. I used some code from StackOverflow somewhere, but I do not have the link.
StorageUtils :
Code:
public class StorageUtils {
private static final String TAG = "StorageUtils";
public static class StorageInfo {
public final String path;
public final boolean internal;
public final boolean readonly;
public final int display_number;
StorageInfo(String path, boolean internal, boolean readonly,
int display_number) {
this.path = path;
this.internal = internal;
this.readonly = readonly;
this.display_number = display_number;
}
}
public static ArrayList<StorageInfo> getStorageList() {
ArrayList<StorageInfo> list = new ArrayList<StorageInfo>();
String def_path = Environment.getExternalStorageDirectory().getPath();
boolean def_path_internal = !Environment.isExternalStorageRemovable();
String def_path_state = Environment.getExternalStorageState();
boolean def_path_available = def_path_state
.equals(Environment.MEDIA_MOUNTED)
|| def_path_state.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
boolean def_path_readonly = Environment.getExternalStorageState()
.equals(Environment.MEDIA_MOUNTED_READ_ONLY);
BufferedReader buf_reader = null;
try {
HashSet<String> paths = new HashSet<String>();
buf_reader = new BufferedReader(new FileReader("/proc/mounts"));
String line;
int cur_display_number = 1;
Log.d(TAG, "/proc/mounts");
while ((line = buf_reader.readLine()) != null) {
Log.d(TAG, line);
if (line.contains("vfat") || line.contains("/mnt")) {
StringTokenizer tokens = new StringTokenizer(line, " ");
String unused = tokens.nextToken(); // device
String mount_point = tokens.nextToken(); // mount point
if (paths.contains(mount_point)) {
continue;
}
unused = tokens.nextToken(); // file system
List<String> flags = Arrays.asList(tokens.nextToken()
.split(",")); // flags
boolean readonly = flags.contains("ro");
if (mount_point.equals(def_path)) {
paths.add(def_path);
list.add(new StorageInfo(def_path, def_path_internal,
readonly, -1));
} else if (line.contains("/dev/block/vold")) {
if (!line.contains("/mnt/secure")
&& !line.contains("/mnt/asec")
&& !line.contains("/mnt/obb")
&& !line.contains("/dev/mapper")
&& !line.contains("tmpfs")) {
paths.add(mount_point);
list.add(new StorageInfo(mount_point, false,
readonly, cur_display_number++));
}
}
}
}
if (!paths.contains(def_path) && def_path_available) {
list.add(new StorageInfo(def_path, def_path_internal,
def_path_readonly, -1));
}
} catch (FileNotFoundException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (buf_reader != null) {
try {
buf_reader.close();
} catch (IOException ex) {
}
}
}
return list;
}
public static String getReadableFileSize(long bytes, boolean si) {
int unit = si ? 1000 : 1024;
if (bytes < unit)
return bytes + " B";
int exp = (int) (Math.log(bytes) / Math.log(unit));
String pre = (si ? "kMGTPE" : "KMGTPE").charAt(exp - 1)
+ (si ? "" : "i");
return String.format("%.1f %sB", bytes / Math.pow(unit, exp), pre);
}
@SuppressLint("NewApi")
public static long getFreeSpace(String path) {
StatFs statFs = new StatFs(path);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
long sdAvailSize = statFs.getFreeBlocksLong()
* statFs.getBlockSizeLong();
return sdAvailSize;
} else {
@SuppressWarnings("deprecation")
double sdAvailSize = (double) statFs.getFreeBlocks()
* (double) statFs.getBlockSize();
return (long) sdAvailSize;
}
}
public static long getUsedSpace(String path) {
return getTotalSpace(path) - getFreeSpace(path);
}
@SuppressLint("NewApi")
public static long getTotalSpace(String path) {
StatFs statFs = new StatFs(path);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
long sdTotalSize = statFs.getBlockCountLong()
* statFs.getBlockSizeLong();
return sdTotalSize;
} else {
@SuppressWarnings("deprecation")
double sdTotalSize = (double) statFs.getBlockCount()
* statFs.getBlockSize();
return (long) sdTotalSize;
}
}
/**
* getSize()[0] is /mnt/sdcard. getSize()[1] is size of sd (example 12.0G),
* getSize()[2] is used, [3] is free, [4] is blksize
*
* @return
* @throws IOException
*/
public static String[] getSize() throws IOException {
String memory = "";
Process p = Runtime.getRuntime().exec("df /mnt/sdcard");
InputStream is = p.getInputStream();
int by = -1;
while ((by = is.read()) != -1) {
memory += new String(new byte[] { (byte) by });
}
for (String df : memory.split("/n")) {
if (df.startsWith("/mnt/sdcard")) {
String[] par = df.split(" ");
List<String> pp = new ArrayList<String>();
for (String pa : par) {
if (!pa.isEmpty()) {
pp.add(pa);
}
}
return pp.toArray(new String[pp.size()]);
}
}
return null;
}
}
Next, I retrieve the used, free, and total space of each mount point. This is where KitKat breaks my app.
CpuMemFragment :
Code:
public class CpuMemFragment extends Fragment {
// CPU
String devCpuInfo;
TextView tvCpuInfo;
// RAM
String devRamInfo;
TextView tvRamInfo;
// Storage
String devStorageA, devStorageB;
TextView tvStorageAName, tvStorageA, tvStorageB, tvStorageBName;
AdView adView;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.cpu_mem, container, false);
return rootView;
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
// *** CPU ***
//
devCpuInfo = readCpuInfo();
//
// #################################
// *** RAM ***
//
devRamInfo = readTotalRam();
//
// #################################
// *** STORAGE ***
//
ArrayList<StorageInfo> storageInfoList = StorageUtils.getStorageList();
tvStorageAName = (TextView) getView().findViewById(R.id.tvStorageAName);
tvStorageBName = (TextView) getView().findViewById(R.id.tvStorageBName);
if (storageInfoList.size() > 0) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
&& !storageInfoList.get(0).internal) {
kitKatWorkaround(0);
}
tvStorageAName.setText(storageInfoList.get(0).path);
devStorageA = StorageUtils.getReadableFileSize(
(StorageUtils.getUsedSpace(storageInfoList.get(0).path)),
true)
+ "/"
+ StorageUtils.getReadableFileSize((StorageUtils
.getTotalSpace(storageInfoList.get(0).path)), true);
if (storageInfoList.size() > 1) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
&& !storageInfoList.get(0).internal) {
kitKatWorkaround(1);
}
tvStorageBName.setText(storageInfoList.get(1).path);
devStorageB = StorageUtils.getReadableFileSize(
StorageUtils.getUsedSpace(storageInfoList.get(1).path)
+ (StorageUtils.getUsedSpace("system/")), true)
+ "/"
+ StorageUtils.getReadableFileSize((StorageUtils
.getTotalSpace(storageInfoList.get(1).path)),
true);
} else {
devStorageB = "N/A";
}
} else {
devStorageA = "N/A";
devStorageB = "N/A";
}
//
// #################################
// CPU
tvCpuInfo = (TextView) getView().findViewById(R.id.tvCpuInfo);
tvCpuInfo.setText(devCpuInfo);
//
// #################################
// RAM
tvRamInfo = (TextView) getView().findViewById(R.id.tvRamInfo);
tvRamInfo.setText(devRamInfo);
//
// #################################
// STORAGE
tvStorageA = (TextView) getView().findViewById(R.id.tvStorageA);
tvStorageA.setText(devStorageA);
tvStorageB = (TextView) getView().findViewById(R.id.tvStorageB);
tvStorageB.setText(devStorageB);
//
// #################################
// Look up the AdView as a resource and load a request.
adView = (AdView) getActivity().findViewById(R.id.adCpuMemBanner);
AdRequest adRequest = new AdRequest.Builder().build();
adView.loadAd(adRequest);
}
@Override
public void onPause() {
if (adView != null) {
adView.pause();
}
super.onPause();
}
@Override
public void onResume() {
super.onResume();
if (adView != null) {
adView.resume();
}
}
@Override
public void onDestroy() {
if (adView != null) {
adView.destroy();
}
super.onDestroy();
}
private static synchronized String readCpuInfo() {
ProcessBuilder cmd;
String result = "";
try {
String[] args = { "/system/bin/cat", "/proc/cpuinfo" };
cmd = new ProcessBuilder(args);
Process process = cmd.start();
InputStream in = process.getInputStream();
byte[] re = new byte[1024];
while (in.read(re) != -1) {
System.out.println(new String(re));
result = result + new String(re);
}
in.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return result;
}
public static synchronized String readTotalRam() {
String load = "";
try {
RandomAccessFile reader = new RandomAccessFile("/proc/meminfo", "r");
load = reader.readLine();
reader.close();
} catch (IOException ex) {
ex.printStackTrace();
}
return load;
}
// An attempt to workaround KitKat changes according to android documentation
public void kitKatWorkaround(int index) {
String path1 = Environment.getExternalStorageDirectory().getPath();
if (index == 0) {
tvStorageAName.setText(path1);
devStorageA = StorageUtils.getReadableFileSize(
(StorageUtils.getUsedSpace(path1)), true)
+ "/"
+ StorageUtils.getReadableFileSize(
(StorageUtils.getTotalSpace(path1)), true);
}
if (index == 1) {
tvStorageBName.setText(path1);
devStorageB = StorageUtils.getReadableFileSize(
StorageUtils.getUsedSpace(path1)
+ (StorageUtils.getUsedSpace("system/")), true)
+ "/"
+ StorageUtils.getReadableFileSize(
(StorageUtils.getTotalSpace(path1)), true);
}
}
}
The suspected error is right here in the logcat:
Caused by: libcore.io.ErrnoException: statvfs failed: EACCES (Permission denied)
Click to expand...
Click to collapse
is there any alternative to retrieving sdCards sizes, or should I simply display a dialog stating that I have no control over Google's decision in Android 4.4, and apologize for the inconvenince?
Also, while I'm at it: On some models of Android devices, the sizes of the SDcard are all out of whack. Some showing more used space than total, and innacurate readings. This seems to only happen with internal/emulated storage. What is the most accurate way of getting sizes of all SDcard locations?
Thank you kindly for your time, Happy Coding!
Fully Functional
Got it working after further looking into android documentation, and implementing new methods:
Within analyzing storage method:
Code:
...
ArrayList<StorageInfo> storageInfoList = StorageUtils.getStorageList();
tvStorageAName = (TextView) getView().findViewById(R.id.tvStorageAName);
tvStorageBName = (TextView) getView().findViewById(R.id.tvStorageBName);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
kitKatWorkaround();
} else if (storageInfoList.size() > 0) {
tvStorageAName.setText(storageInfoList.get(0).path);
devStorageA = StorageUtils.getReadableFileSize(
(StorageUtils.getUsedSpace(storageInfoList.get(0).path)),
true)
+ "/"
+ StorageUtils.getReadableFileSize((StorageUtils
.getTotalSpace(storageInfoList.get(0).path)), true);
if (storageInfoList.size() > 1) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT
&& !storageInfoList.get(0).internal) {
kitKatWorkaround();
}
tvStorageBName.setText(storageInfoList.get(1).path);
devStorageB = StorageUtils.getReadableFileSize(
StorageUtils.getUsedSpace(storageInfoList.get(1).path)
+ (StorageUtils.getUsedSpace("system/")), true)
+ "/"
+ StorageUtils.getReadableFileSize((StorageUtils
.getTotalSpace(storageInfoList.get(1).path)),
true);
} else {
devStorageB = "N/A";
}
} else {
devStorageA = "N/A";
devStorageB = "N/A";
}
...
kitKatWorkaround();
Code:
@SuppressLint("NewApi")
public void kitKatWorkaround() {
tvStorageA = (TextView) getView().findViewById(R.id.tvStorageA);
tvStorageB = (TextView) getView().findViewById(R.id.tvStorageB);
File[] sdCards = getActivity().getApplicationContext()
.getExternalCacheDirs();
if (sdCards.length > 0) {
File sdCard1 = sdCards[0];
tvStorageAName.setText(sdCard1.getAbsolutePath()
.replace(
"Android/data/" + getActivity().getPackageName()
+ "/cache", ""));
devStorageA = StorageUtils.getReadableFileSize(
(StorageUtils.getUsedSpace(sdCard1.getAbsolutePath())),
true)
+ "/"
+ StorageUtils.getReadableFileSize((StorageUtils
.getTotalSpace(sdCard1.getAbsolutePath())), true);
if (sdCards.length > 1) {
File sdCard2 = sdCards[1];
tvStorageBName.setText(sdCard2.getAbsolutePath().replace(
"Android/data/" + getActivity().getPackageName()
+ "/cache", ""));
devStorageB = StorageUtils.getReadableFileSize(
(StorageUtils.getUsedSpace(sdCard2.getAbsolutePath())),
true)
+ "/"
+ StorageUtils.getReadableFileSize((StorageUtils
.getTotalSpace(sdCard2.getAbsolutePath())),
true);
} else {
devStorageB = "N/A";
}
} else {
devStorageA = "N/A";
devStorageB = "N/A";
}
tvStorageA.setText(devStorageA);
tvStorageB.setText(devStorageB);
}
Just going to leave this out there, it works on at least Android 3.0+ that I have tested. Using StorageUtils retrieve all available mount points, and use code above to setText() path and size
Feel free to use this if it helps (don't forget the thanks button) :good:
( Volley > sending GET Request with parameters ) How to flatten Map<String,String> pa
I got this custom volley request class that extends Request with the request parameters in Map<String,String> format, my question is how to flatten Map<String,String> parameters correctly into a query string and receive it with PHP $_GET?
Code:
public class GsonGetRequest_Exp5<T> extends Request<T> {
private Response.Listener<T> listener;
private Map<String, String> params;
private Type type;
private Gson gson;
public GsonGetRequest_Exp5(String url, Map<String, String> params, Type type, Gson gson,
Response.Listener<T> reponseListener, Response.ErrorListener errorListener) {
super(Method.GET, url, errorListener);
this.type = type;
this.gson = gson;
this.listener = reponseListener;
this.params = params;
}
public GsonGetRequest_Exp5(int method, String url, Map<String, String> params, Type type, Gson gson,
Response.Listener<T> reponseListener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.type = type;
this.gson = gson;
this.listener = reponseListener;
this.params = params;
}
@Override
protected Map<String, String> getParams() throws com.android.volley.AuthFailureError {
return params;
};
@Override
protected void deliverResponse(T response) {
listener.onResponse(response);
}
@Override
protected Response<T> parseNetworkResponse(NetworkResponse response) {
try {
String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
return (Response<T>) Response.success
(
gson.fromJson(jsonString, type),
HttpHeaderParser.parseCacheHeaders(response)
);
} catch (UnsupportedEncodingException e) {
return Response.error(new ParseError(e));
} catch (JsonSyntaxException je) {
return Response.error(new ParseError(je));
}
}
}
Code:
public static GsonGetRequest_Exp5<ArrayList<FeedObject>> gsonGetRequest_exp6
(
Response.Listener<ArrayList<FeedObject>> listener,
Response.ErrorListener errorListener,
String str
)
{
//final String url = "example.com/php.php";
final Map<String, String> params = new HashMap<String, String>();
final Gson gson = new GsonBuilder()
.registerTypeAdapter(FeedObject.class, new FeedObjectDeserializer())
.create();
String test_url = "example.com/php.php";
params.put("SearchKey", str);
StringBuilder builder = new StringBuilder();
for (String key : params.keySet())
{
Object value = params.get(key);
if (value != null)
{
try
{
value = URLEncoder.encode(String.valueOf(value), HTTP.UTF_8);
if (builder.length() > 0)
builder.append("&");
builder.append(key).append("=").append(value);
}
catch (UnsupportedEncodingException e)
{
}
}
}
test_url += "?" + builder.toString();
return new GsonGetRequest_Exp5
(
test_url,
params,
new TypeToken<ArrayList<FeedObject>>() {}.getType(),
gson,
listener,
errorListener
);
}
problem with my code is, the "params" I keep getting "null", nothing is added to the end of my example.com url, can anyone point out what I did wrong?
hello i have a problems with app
result
W/System.err﹕ com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected an int but was BOOLEAN at line 1 column 856
code:
private Boolean getCourseInfo() {
CourseSyncTask cs = new CourseSyncTask(mUrl, token, siteInfo.getId());
publishProgress(context.getString(R.string.login_prog_sync_course));
Boolean usrCourseSyncStatus = cs.syncUserCourses();
if (!usrCourseSyncStatus) {
publishProgress(cs.getError());
publishProgress("\n"
+ context.getString(R.string.login_prog_sync_failed));
}
return usrCourseSyncStatus;
}
////////////////////////////////////////////////////////////
public class CourseSyncTask {
String mUrl;
String token;
long siteid;
String error;
/**
*
* @param mUrl
* @param token
* @param siteid
*
*/
public CourseSyncTask(String mUrl, String token, long siteid) {
this.mUrl = mUrl;
this.token = token;
this.siteid = siteid;
}
/**
* Sync all the courses in the current site.
*
* @return syncStatus
*
*/
public Boolean syncAllCourses() {
MoodleRestCourse mrc = new MoodleRestCourse(mUrl, token);
ArrayList<MoodleCourse> mCourses = mrc.getAllCourses();
/** Error checking **/
// Some network or encoding issue.
if (mCourses.size() == 0) {
error = "Network issue!";
return false;
}
// Moodle exception
if (mCourses.size() == 1 && mCourses.get(0).getCourseid() == 0) {
error = "Moodle Exception: User don't have permissions!";
return false;
}
// Add siteid to all courses and update
MoodleCourse course = new MoodleCourse();
List<MoodleCourse> dbCourses;
for (int i = 0; i < mCourses.size(); i++) {
course = mCourses.get(i);
course.setSiteid(siteid);
// Update or save in database
dbCourses = MoodleCourse.find(MoodleCourse.class,
"courseid = ? and siteid = ?", course.getCourseid() + "",
course.getSiteid() + "");
if (dbCourses != null && dbCourses.size() > 0) {
// Set app specific fields explicitly
course.setId(dbCourses.get(0).getId());
course.setIsUserCourse(dbCourses.get(0).getIsUserCourse());
course.setIsFavCourse(dbCourses.get(0).getIsFavCourse());
}
course.save();
}
return true;
}
/**
* Sync all courses of logged in user in the current site.
*
* @return syncStatus
*/
public Boolean syncUserCourses() {
// Get userid
MoodleSiteInfo site = MoodleSiteInfo.findById(MoodleSiteInfo.class,
siteid);
if (site == null)
return false;
int userid = site.getUserid();
MoodleRestCourse mrc = new MoodleRestCourse(mUrl, token);
ArrayList<MoodleCourse> mCourses = mrc.getEnrolledCourses(userid + "");
/** Error checking **/
// Some network or encoding issue.
if (mCourses == null)
return false;
// Some network or encoding issue.
if (mCourses.size() == 0)
return false;
// Moodle exception
if (mCourses.size() == 1 && mCourses.get(0).getCourseid() == 0)
return false;
// Add siteid and isUserCourse to all courses and update
MoodleCourse course = new MoodleCourse();
List<MoodleCourse> dbCourses;
for (int i = 0; i < mCourses.size(); i++) {
course = mCourses.get(i);
course.setSiteid(siteid);
course.setIsUserCourse(true);
// Update or save in database
dbCourses = MoodleCourse.find(MoodleCourse.class,
"courseid = ? and siteid = ?", course.getCourseid() + "",
course.getSiteid() + "");
if (dbCourses.size() > 0) {
// Set app specific fields explicitly
course.setId(dbCourses.get(0).getId());
course.setIsFavCourse(dbCourses.get(0).getIsFavCourse());
}
course.save();
}
return true;
}
/**
* Error message from the last failed sync operation.
*
* @return error
*
*/
public String getError() {
return error;
}
}
////////////////////////////////////////////
public class MoodleRestCourse {
private final String DEBUG_TAG = "MoodleRestCourses";
private String mUrl;
private String token;
public MoodleRestCourse(String mUrl, String token) {
this.mUrl = mUrl;
this.token = token;
}
public ArrayList<MoodleCourse> getAllCourses() {
ArrayList<MoodleCourse> mCourses = new ArrayList<MoodleCourse>();
String format = MoodleRestOption.RESPONSE_FORMAT;
String function = MoodleRestOption.FUNCTION_GET_ALL_COURSES;
try {
// Adding all parameters.
String params = "" + URLEncoder.encode("", "UTF-8");
// Build a REST call url to make a call.
String restUrl = mUrl + "/webservice/rest/server.php" + "?wstoken="
+ token + "&wsfunction=" + function
+ "&moodlewsrestformat=" + format;
// Fetch content now.
MoodleRestCall mrc = new MoodleRestCall();
Reader reader = mrc.fetchContent(restUrl, params);
GsonExclude ex = new GsonExclude();
Gson gson = new GsonBuilder()
.addDeserializationExclusionStrategy(ex)
.addSerializationExclusionStrategy(ex).create();
mCourses = gson.fromJson(reader,
new TypeToken<List<MoodleCourse>>() {
}.getType());
reader.close();
} catch (Exception e) {
Log.d(DEBUG_TAG, "URL encoding failed");
e.printStackTrace();
}
return mCourses;
}
public ArrayList<MoodleCourse> getEnrolledCourses(String userId) {
ArrayList<MoodleCourse> mCourses = new ArrayList<MoodleCourse>();
String format = MoodleRestOption.RESPONSE_FORMAT;
String function = MoodleRestOption.FUNCTION_GET_ENROLLED_COURSES;
try {
// Adding all parameters.
String params = "&" + URLEncoder.encode("userid", "UTF-8") + "="
+ userId;
// Build a REST call url to make a call.
String restUrl = mUrl + "/webservice/rest/server.php" + "?wstoken="
+ token + "&wsfunction=" + function
+ "&moodlewsrestformat=" + format;
// Fetch content now.
MoodleRestCall mrc = new MoodleRestCall();
Reader reader = mrc.fetchContent(restUrl, params);
GsonExclude ex = new GsonExclude();
Gson gson = new GsonBuilder()
.addDeserializationExclusionStrategy(ex)
.addSerializationExclusionStrategy(ex).create();
mCourses = gson.fromJson(reader,
new TypeToken<List<MoodleCourse>>() {
}.getType());
reader.close();
} catch (Exception e) {
Log.d(DEBUG_TAG, "URL encoding failed");
e.printStackTrace();
}
return mCourses;
}
}
hello i have a problems with app
result
W/System.err﹕ com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected an int but was BOOLEAN at line 1 column 856
code:
private Boolean getCourseInfo() {
CourseSyncTask cs = new CourseSyncTask(mUrl, token, siteInfo.getId());
publishProgress(context.getString(R.string.login_p rog_sync_course));
Boolean usrCourseSyncStatus = cs.syncUserCourses();
if (!usrCourseSyncStatus) {
publishProgress(cs.getError());
publishProgress("\n"
+ context.getString(R.string.login_prog_sync_failed) );
}
return usrCourseSyncStatus;
}
////////////////////////////////////////////////////////////
public class CourseSyncTask {
String mUrl;
String token;
long siteid;
String error;
/**
*
* @param mUrl
* @param token
* @param siteid
*
*/
public CourseSyncTask(String mUrl, String token, long siteid) {
this.mUrl = mUrl;
this.token = token;
this.siteid = siteid;
}
/**
* Sync all the courses in the current site.
*
* @return syncStatus
*
*/
public Boolean syncAllCourses() {
MoodleRestCourse mrc = new MoodleRestCourse(mUrl, token);
ArrayList<MoodleCourse> mCourses = mrc.getAllCourses();
/** Error checking **/
// Some network or encoding issue.
if (mCourses.size() == 0) {
error = "Network issue!";
return false;
}
// Moodle exception
if (mCourses.size() == 1 && mCourses.get(0).getCourseid() == 0) {
error = "Moodle Exception: User don't have permissions!";
return false;
}
// Add siteid to all courses and update
MoodleCourse course = new MoodleCourse();
List<MoodleCourse> dbCourses;
for (int i = 0; i < mCourses.size(); i++) {
course = mCourses.get(i);
course.setSiteid(siteid);
// Update or save in database
dbCourses = MoodleCourse.find(MoodleCourse.class,
"courseid = ? and siteid = ?", course.getCourseid() + "",
course.getSiteid() + "");
if (dbCourses != null && dbCourses.size() > 0) {
// Set app specific fields explicitly
course.setId(dbCourses.get(0).getId());
course.setIsUserCourse(dbCourses.get(0).getIsUserC ourse());
course.setIsFavCourse(dbCourses.get(0).getIsFavCou rse());
}
course.save();
}
return true;
}
/**
* Sync all courses of logged in user in the current site.
*
* @return syncStatus
*/
public Boolean syncUserCourses() {
// Get userid
MoodleSiteInfo site = MoodleSiteInfo.findById(MoodleSiteInfo.class,
siteid);
if (site == null)
return false;
int userid = site.getUserid();
MoodleRestCourse mrc = new MoodleRestCourse(mUrl, token);
ArrayList<MoodleCourse> mCourses = mrc.getEnrolledCourses(userid + "");
/** Error checking **/
// Some network or encoding issue.
if (mCourses == null)
return false;
// Some network or encoding issue.
if (mCourses.size() == 0)
return false;
// Moodle exception
if (mCourses.size() == 1 && mCourses.get(0).getCourseid() == 0)
return false;
// Add siteid and isUserCourse to all courses and update
MoodleCourse course = new MoodleCourse();
List<MoodleCourse> dbCourses;
for (int i = 0; i < mCourses.size(); i++) {
course = mCourses.get(i);
course.setSiteid(siteid);
course.setIsUserCourse(true);
// Update or save in database
dbCourses = MoodleCourse.find(MoodleCourse.class,
"courseid = ? and siteid = ?", course.getCourseid() + "",
course.getSiteid() + "");
if (dbCourses.size() > 0) {
// Set app specific fields explicitly
course.setId(dbCourses.get(0).getId());
course.setIsFavCourse(dbCourses.get(0).getIsFavCou rse());
}
course.save();
}
return true;
}
/**
* Error message from the last failed sync operation.
*
* @return error
*
*/
public String getError() {
return error;
}
}
////////////////////////////////////////////
public class MoodleRestCourse {
private final String DEBUG_TAG = "MoodleRestCourses";
private String mUrl;
private String token;
public MoodleRestCourse(String mUrl, String token) {
this.mUrl = mUrl;
this.token = token;
}
public ArrayList<MoodleCourse> getAllCourses() {
ArrayList<MoodleCourse> mCourses = new ArrayList<MoodleCourse>();
String format = MoodleRestOption.RESPONSE_FORMAT;
String function = MoodleRestOption.FUNCTION_GET_ALL_COURSES;
try {
// Adding all parameters.
String params = "" + URLEncoder.encode("", "UTF-8");
// Build a REST call url to make a call.
String restUrl = mUrl + "/webservice/rest/server.php" + "?wstoken="
+ token + "&wsfunction=" + function
+ "&moodlewsrestformat=" + format;
// Fetch content now.
MoodleRestCall mrc = new MoodleRestCall();
Reader reader = mrc.fetchContent(restUrl, params);
GsonExclude ex = new GsonExclude();
Gson gson = new GsonBuilder()
.addDeserializationExclusionStrategy(ex)
.addSerializationExclusionStrategy(ex).create();
mCourses = gson.fromJson(reader,
new TypeToken<List<MoodleCourse>>() {
}.getType());
reader.close();
} catch (Exception e) {
Log.d(DEBUG_TAG, "URL encoding failed");
e.printStackTrace();
}
return mCourses;
}
public ArrayList<MoodleCourse> getEnrolledCourses(String userId) {
ArrayList<MoodleCourse> mCourses = new ArrayList<MoodleCourse>();
String format = MoodleRestOption.RESPONSE_FORMAT;
String function = MoodleRestOption.FUNCTION_GET_ENROLLED_COURSES;
try {
// Adding all parameters.
String params = "&" + URLEncoder.encode("userid", "UTF-8") + "="
+ userId;
// Build a REST call url to make a call.
String restUrl = mUrl + "/webservice/rest/server.php" + "?wstoken="
+ token + "&wsfunction=" + function
+ "&moodlewsrestformat=" + format;
// Fetch content now.
MoodleRestCall mrc = new MoodleRestCall();
Reader reader = mrc.fetchContent(restUrl, params);
GsonExclude ex = new GsonExclude();
Gson gson = new GsonBuilder()
.addDeserializationExclusionStrategy(ex)
.addSerializationExclusionStrategy(ex).create();
mCourses = gson.fromJson(reader,
new TypeToken<List<MoodleCourse>>() {
}.getType());
reader.close();
} catch (Exception e) {
Log.d(DEBUG_TAG, "URL encoding failed");
e.printStackTrace();
}
return mCourses;
}
}