i did an application to collects light sensor data, such that these data are stored in text file in the external sdcard, the data is stored correctly and file are created successfully but the problem is when then application running on the my device for x period (e.g 1 min)the data is stored but when is close the application and re running it on from the device for the same period also the new collected data are append stored to the previous stored data from previous running and i noted that when the sizes of the text files is increases with each running.
i need for each running ,the collected data is stored totally (for the whole period of the running i.e 1 min ) in the text file and when i re- running the application again the new collected data of the new running to be overwriting on previous stored data.
i attempted to do that using arraylist, i .e when then app starts running i put all gathered reading in array list and when the running is stopped the arraylist will out all gathered data to the text file but when i re-running app the array list also gathered data and append out it into the text file next to the previous running stored data, where this is the problem which need to solve,i need to overwrite new running gathered data on the previous running stored data.
the code of collecting light sensor data looks like:
#Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType()==Sensor.TYPE_LIGHT){
max = msensorManager.getDefaultSensor(Sensor.TYPE_LIGHT).getMaximumRange();
//getMaximumRange() is the maximum range of the sensor in the sensor's unit.
//tv1.setText("Max Reading: " + String.valueOf(max));
tv1.setText(msg +"Max Reading: " + String.valueOf(max) );
tv1.invalidate();
lightMeter.setMax((int)max);
//setMax is the max of the upper range of this progress bar
currentReading = event.values[0];
//timestamp = event.timestamp;
lightMeter.setProgress((int)currentReading);
Toast.makeText(MainActivity.this,"Event Happend '", Toast.LENGTH_SHORT).show();
tv2.setText("Current Reading: " + String.valueOf(currentReading));
current_reading_list.add((double) currentReading);
}
the code of writing from array list into file looks like :
public void writing_in_file_1(){
try{
fw = new FileWriter(file_1, true);
bw = new BufferedWriter(fw);
out = new PrintWriter(bw);
//out.append( String.valueOf(currentReading + " \t"));
//out.append(String.valueOf(current_reading_list));
out.print(String.valueOf(current_reading_list));
out.flush();
Toast.makeText(this,"Done writing SD 'specific text file'", Toast.LENGTH_SHORT).show();
}
catch (IOException e)
{
e.printStackTrace();
}
finally{
try {
bw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
the writing is done when the stop button is pressed:
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt1:
counter_function();
//onResume();
break;
case R.id.bt2:
onPause();
writing_in_file_1();
tv1.setText("");
tv2.setText("");
break;
default:
break;
}
}
can any one help me?
thank you in advance.
You are using the constructor FileWriter(File file, boolean append) with append = true
Replace
fw = new FileWriter(file_1, true);
with
fw = new FileWriter(file_1, false);
Related
I have an app that can take a text file from the devices internal storage and reads the contents of the file to which it places it into an arraylist for me to compare against some other data.
Some example data in the text file is:
1.10
1.11
1.12
My app displays the last element of the array list, so in this example it would be '1.12' that is displayed.
The issue I am having is that if I change '1.12' to '1.13', it only updates to the new value when I run the app for the second time.
I can't figure out why this is. I have tested to make sure the file does update using adb and thats all updated but it appears as if the app is still reading the contents of the old version of the file rather than the new overwritten file on the first run. My code is below for reading the files contents.
public void readVersionList(){
download = (TextView) findViewById(R.id.download_version_path);
try {
Scanner scan = new Scanner(new File("/sdcard/version-nums.txt"));
ArrayList<String> list = new ArrayList<String>();
while (scan.hasNext()){
list.add(s.next());
}
scan.close();
updateVersionNum = list.get(list.size()-1);
download.setText(updateVersionNum);
Log.i("VERSIONNUM", updateVersionNum);
}catch (FileNotFoundException e){
e.printStackTrace();
}
catch (IOException e){
e.printStackTrace();
}
}
I just started to learn developping android and I have a (probably) basic questions, but I didn't find anything clear.
I'm trying to store data in a JSON file, well, I've understood the logic to store it, my way is:
public boolean writeFileJson(JSONObject jobj) {
try {
FileOutputStream fOut = openFileOutput(file, Context.MODE_PRIVATE);
fOut.write(jobj.toString().getBytes());
fOut.close();
Toast.makeText(getBaseContext(), "file saved", Toast.LENGTH_SHORT).show();
} catch (Exception e1) {
e1.printStackTrace();
}
return true;
}
But my problem is to read, and concretely for the first time, because the way I do it is:
public String readFileJson() {
int c;
String temp = "";
try {
FileInputStream fin = openFileInput(file);
while ((c = fin.read()) != -1) {
temp = temp + Character.toString((char) c);
}
Toast.makeText(getBaseContext(), "file read", Toast.LENGTH_SHORT).show();
} catch (Exception e2) {
}
return temp;
}
So wen I read it for the first time and I want to acces to a parameter of my JSON is obvious that any JSON Object already exist in the file.
So I try to save a first JSON Object with my parameters in onCreate() method and save it in the file, but wen I run the app, and I stop it, it returns again to execute onCreate() and deletes all data stored during the run time.
So my question is: There is any way to init only for one time the parameters of the JSON file to could access for the first time unlike it's empty???
I hope that I'd explained well!!
Thanxxxx!!!!
You can create your own flag boolean and check when you start.
Well I don't understand well why you can use a flag if the flag is set to init value in onCreate(), but I've tried a basic method: check each time if the json file is null. But it's like so basic no? Is there any ther way, or trying to understand how to use flags without reset their values?
msgjson = readFileJson();
if(msgjson == "") {
json.put("ARRAY", jsonArray);
}else{
json = new JSONObject(msgjson);
}
Thanx!!
I am currently writing an android app that logs the accelerometer. (its a test app at the moment so i can prototype an algorithm.
To write out a list of SensorEventStore's (which is just a way of storing the data from a SensorEvent) to the SD card from a 30 minute recording, locks up the GUI for about 20 - 30 seconds while writing the file.
I am using the following code to write out the file to the SD card.
#Override
public void onMessage(Messages message, Object param[]) {
if(message == IDigest.Messages.SaveData) {
File folder = (File) param[0];
File accFileAll = new File(folder, startTime + "_all.acc");
FileWriter accFileWriterAll;
try {
accFileWriterAll = new FileWriter(accFileAll);
} catch (IOException e) {
accFileWriterAll = null;
}
for(Iterator<SensorEventStore> i=eventList.iterator(); i.hasNext();) {
SensorEventStore e = i.next();
if(accFileWriterAll != null) {
try {
accFileWriterAll.write(
String.format(
"%d,%d,%f,%f,%f\r\n",
e.timestamp,
e.accuracy,
e.values[0],
e.values[1],
e.values[2]
)
);
accFileWriterAll.flush();
} catch (IOException ex) {
}
}
}
new SingleMediaScanner(RunBuddyApplication.Context, accFileAll);
}
}
Can anyone give me any pointers to make this not lock up the UI, or not have to take the amount of time it currently takes to write out the file.
Firstly you should try to do this in the background. The AsyncTask is fairly well suited for the task.
Other than that, you should remove the flush() statement, and probperly close() your file writer. The flush causes the data to be written to disk in rather small portions, which is really slow. If you leave the filewriter to its own flushing, it will determine a buffer size on its own. When you properly close the FileWriter, the remaining data should be written to disk as well.
Also, you could take a look at "Try with resources" for your filewriter, but that is optional.
hi friend i am trying to make game and i need to create demo version of my game
i need a button that when users click on it the game run but just 3 time.
after 3 time users clicked on button the app show message "you should buy the game"
i used sharedpreferences . after 3 click on button the game show message but when user delete app and install it again , game not show message and run game. are there any ways to save sharedpreferences after delete app ?
this is my code :
Button frist = ((Button)findViewById(R.id.test));
final SharedPreferences check = getSharedPreferences("check",MODE_PRIVATE);
final Editor edit = check.edit();
frist.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if(check.getInt("check1",0)<3){
Intent intent = new Intent(MainActivity.this,choose_name.class
);
startActivity(intent);
edit.putInt("check1", check.getInt("check1",0)+1).commit();
}
}
});
edit : friend im trying to write a file and save my setting into it , can i save my file in any directory that users cant see it and my file dont delete after user delete app and i dont need to use permission?
Try Backing up and restoring a user’s SharedPreferences. This will backup your preference to any External Storage.
Before user uninstall app, you can take back up of it. Add some logic that if file is present in External Storage, restore it back.
Edit
Use following code to back your preference.
Preferences stored in the SharedPreferences class get saved into /data/data//shared_prefs/_preferences.xml - backing up is easy, you just need to copy the contents of this file to external storage:
public static void backupUserPrefs(Context context) {
final File prefsFile = new File(context.getFilesDir(), "../shared_prefs/" + context.getPackageName() + "_preferences.xml");
final File backupFile = new File(context.getExternalFilesDir(null),
"preferenceBackup.xml");
String error = "";
try {
FileChannel src = new FileInputStream(prefsFile).getChannel();
FileChannel dst = new FileOutputStream(backupFile).getChannel();
dst.transferFrom(src, 0, src.size());
src.close();
dst.close();
Toast toast = Toast.makeText(context, "Backed up user prefs to " + backupFile.getAbsolutePath(), Toast.LENGTH_SHORT);
toast.show();
return;
} catch (FileNotFoundException e) {
error = e.getMessage();
e.printStackTrace();
} catch (IOException e) {
error = e.getMessage();
e.printStackTrace();
}
Use following code to restore preference
But restoring provides more of a challenge, since the shared_prefs file isn’t directly writable by the app, and the SharedPrefs class doesn’t directly expose its functionality to serialise from xml. Instead you have to parse the XML yourself and push the values back in. Thankfully the XML file has a straightforward structure, so it’s easy to loop over the elements and turn these back into preferences.
public static boolean restoreUserPrefs(Context context) {
final File backupFile = new File(context.getExternalFilesDir(null),
"preferenceBackup.xml");
String error = "";
try {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
Editor editor = sharedPreferences.edit();
InputStream inputStream = new FileInputStream(backupFile);
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(inputStream);
Element root = doc.getDocumentElement();
Node child = root.getFirstChild();
while (child != null) {
if (child.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element) child;
String type = element.getNodeName();
String name = element.getAttribute("name");
// In my app, all prefs seem to get serialized as either "string" or
// "boolean" - this will need expanding if yours uses any other types!
if (type.equals("string")) {
String value = element.getTextContent();
editor.putString(name, value);
} else if (type.equals("boolean")) {
String value = element.getAttribute("value");
editor.putBoolean(name, value.equals("true"));
}
}
child = child.getNextSibling();
}
editor.commit();
Toast toast = Toast.makeText(context, "Restored user prefs from " + backupFile.getAbsolutePath(), Toast.LENGTH_SHORT);
toast.show();
return true;
} catch (FileNotFoundException e) {
error = e.getMessage();
e.printStackTrace();
} catch (ParserConfigurationException e) {
error = e.getMessage();
e.printStackTrace();
} catch (SAXException e) {
error = e.getMessage();
e.printStackTrace();
} catch (IOException e) {
error = e.getMessage();
e.printStackTrace();
}
Toast toast = Toast.makeText(context, "Failed to restore user prefs from " + backupFile.getAbsolutePath() + " - " + error, Toast.LENGTH_SHORT);
toast.show();
return false;
}
Toast toast = Toast.makeText(context, "Failed to Back up user prefs to " + backupFile.getAbsolutePath() + " - " + error, Toast.LENGTH_SHORT);
toast.show();
}
Finally, you need to restart your app before these preferences will take hold:
if (restoreUserPrefs(context)) {
// Restart
AlarmManager alm = (AlarmManager) context.getSystemService(
Context.ALARM_SERVICE);
alm.set(AlarmManager.RTC,
System.currentTimeMillis() + 1000, PendingIntent.getActivity(context, 0,
new Intent(context, MainActivityName.class), 0));
android.os.Process.sendSignal(android.os.Process.myPid(),
android.os.Process.SIGNAL_KILL);
}
if user uninstall/delete app or clean data through setting then all the data in shared preference will get vanished
your problem is when user do such kind of things with your application shared preference value get initialized from 0/starting value
you can use webservice for that for ex. you can take users IMEI number through code and against of that you can save its sharedpreference value of " number of play counter"
and then through smart logic check your requirement
Android provides several options for you to save persistent application data. The solution you choose depends on your specific needs, such as whether the data should be private to your application or accessible to other applications (and the user) and how much space your data requires.
Your data storage options are the following:
Shared Preferences Store private primitive data in key-value pairs.
Internal Storage Store private data on the device memory.
External Storage Store public data on the shared external storage.
SQLite Databases Store structured data in a private database.
Network Connection Store data on the web with your own network server.
Android provides a way for you to expose even your private data to other applications — with a content provider. A content provider is an optional component that exposes read/write access to your application data, subject to whatever restrictions you want to impose. For more information about using content providers, see the Content Providers documentation.
SharedPreferences are deleted when you uninstall an app, so no: SharedPreferences aren't the best option here. I would recommend using some kind of remote database to track the usage of your app.
Shared Preferences are always cleared along with uninstalling app. But since android-21 Backup task stores preferences by default to cloud. Later when you uninstall then install newer version .You are probably going to use restored preferences. You just have to add this to your manifest ( or at least manifest for debug). -
<application ...
android:allowBackup="true">
...
</application>
Read this:http://developer.android.com/guide/topics/data/backup.html
It's Important to mention here that process of backup is blackbox .. you don't know when it starts, and period between checks ... so better for developing to disable it.
I confess I'm a bit stumped on this one. I've just started with Android programming and am loving the experience so far, but I've got a mysterious problem where I write to files but they remain indefinitely empty (no, I'm pretty sure I'm not overwriting them accidentally).
The scenario is that I'd like to record a few seconds of sensor data to a log file on the SD card upon hitting a button. I also display the same content to the screen. However, though the content that appears on the screen is correct, the log file gets created but is empty.
I can only assume that it has something to do with the fact that I'm calling write from the onSensorChanged(Event) method, since the same code executes just fine when used elsewhere.
public MyClass(....){
....
sensorManager.registerListener(this, accelerometer, sensorManager.SENSOR_DELAY_NORMAL);
Thread.sleep(time * 1000);
sensorManager.unregisterListener(this);
try {
logWriter.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void onSensorChanged(SensorEvent event){
String msg = msgFor(event);
try {
logWriter.write("SOME_TEXT" + msg + "\n"); // FileWriter logWriter is a field, but the file is empty in the end
} catch (IOException e){
e.printStackTrace();
}
resultBox.append("\n" + msg); // TextView resultBox is a field, and writes to screen correctly
Log.d("SENSOR-CHANGE", msg);
}
private String msgFor(SensorEvent event){
return event.timestamp+", "+event.sensor.getName()+", "+Arrays.toString(event.values);
}
Any advice would be greatly appreciated! I am aware that there are some similar threads out there, but I didn't find exactly what I needed.