I am trying to save some user data internally. Ideally, I would like to save
String[] text;
String name;
String file_name;
Together in one (for lack of a better term) package, and then use all saves name's with the other data to populate another activities listView, where I can load the saved information. Here is the code I am trying to use to save the information:
Button fileName;
fileName = (Button) findViewById(R.id.save_text);
fileName.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
outputStream = openFileOutput(file_name, Context.MODE_APPEND);
ObjectOutputStream phone_save = new ObjectOutputStream(outputStream);
phone_save.writeObject(name);
phone_save.writeObject(text);
Log.i("Save", "Files saved");
} catch (Exception e) {
e.printStackTrace();
}
}
});
Then this is the code that tries to get that saved information(for now I just have it trying to set the text of a text View, not a listView yet)
Button load;
TextView load_text
load = (Button) findViewById(R.id.load);
load.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
fin = openFileInput(file_name);
ObjectInputStream ois = new ObjectInputStream(fin);
String[] Loaded_Text = (String[]) ois.readObject();
ois.close();
load_text.setText(Html.fromHtml(Arrays.toString(Loaded_Text)));
} catch (Exception e) {
e.printStackTrace();
}
}
});
I am having a problem saving and loading the data, no log statement appears when I push the filename button, and nothing appears in the textView when I push the load Button. Essentially none of it works, and I have absolutely no clue how to fix it. I'm sure this code is a mess, but this is really my first time working with storage. Thanks everyone!
Posting as an answer you can accept.
Did you consider using SharedPreferences? I think that would be a lot simpler than writing and reading files. You store key-value pairs, so any piece of data needs a unique string to identify it.
prefs.putString("key1",stringValue);
prefs.putString("key2", anotherStringValue);
You would just need to convert your string array to and from a string.
You should consider implementing database support for your application. Database data is easier to maintain, in contrast to SharedPreferences. Here is a good tutorial that explains how to implement an SQLite database.
Related
Am still new to Android in some stuff and I want to do something that I do on my php script which is kind of a SAAS. There I have some line of code that runs online to check for new update of my cms when the use opens the admin dashboard.
I want to do the same with my android app by maybe saving a txt file on a github repository like
http://github.com/wasiro/myapp/version.txt
which I will be updating when i make a major app update
Where i save something like 1.0.9.734 so that my app can get the variable and use it to inform my user that there is a new update alternatively
currenty i have this on my code
public static final String BaseUrl = "http://github.com/wasiro/myapp/version.txt";
Any assistance on achieving this would help alot and if there are better ways to do it please enlighten me.
Don't confuse this to JSON because I want to use GitHub to store my variable like I do with my phone script
Edit:
When I tried this instead of the variable in the file being extracted and read it was the path to the file that got on the way of the code
I think everyone is too quick to brush the question aside to being a duplicate instead of understanding what is all about? So sad this is what the SO community has become.
Your issue is to open a file located elsewhere.
private class myStreamReader extends AsyncTask<String, Void, String> {
String str = "";
#Override
protected String doInBackground(String... params) {
try {
URL url = new URL("http://github.com/wasiro/myapp/version.txt");
BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));
str = in.readLine();
in.close();
} catch (MalformedURLException e) {
} catch (IOException e) {
}
return "Executed";
}
#Override
protected void onPostExecute(String result) {
//do something here
httpStuff.setText(str);
}
#Override
protected void onPreExecute() {}
#Override
protected void onProgressUpdate(Void... values) {}
}
I'm downloading images and data from server, it comes after few seconds and populates arraylist that has objects containing address of image, and you know recyclerView's onBindViewHolder is faster than data fetching from server.
So in onBindViewHolder im using picasso to load data from addresses in arraylist, in this case (you know onBindViewHolder runs faster than fetching data from server) when still arraylist is empty(because data is not come from server) picasso try to accesses object in arraylist and ended up outOfboundException
I want onbindViewHolder(or picasso maybe) wait till data come and arraylist is not empty then start loading images through picasso how can I do that, my implementation:
Picasso.with(mContext)
.load(NetworkUtils.getList().get(getAdapterPosition()).getImage()).placeholder(R.drawable.flower)
.into(mMovieImageView);
OnResponse of Volley:
public void onResponse(Object o) {
try {
JSONObject jsonObject = new JSONObject(o.toString());
arrayData = jsonObject.getJSONArray("results");
} catch (JSONException e) {
e.printStackTrace();
}
for(int i =0; i < 50; i++) {
data = new ModelDataClass();
try {
if (arrayData.equals("")) {
Log.i("mainactivity " , "null array data");
}
else{
response = arrayData.getJSONObject(i);
data.setTitle(response.getString("original_title"));
data.setRating(response.getDouble("vote_average"));
data.setDescription(response.getString("overview"));
data.setImage(response.getString("poster_path"));}
}catch(JSONException e){
e.printStackTrace();
}
list.add(data);
}
You have to setup your UI in onResponse method, when you already got the data from server and parsed it. This is the best UX practice. In the time of loading show a progress bar or analog to the user.
public void onRequestStart(){
showProgressBar(true);
}
public void onResponse(){
//fetch your data
//add your data to list or arrayList
showProgressBar(false);
setupRecycler(list);
}
public void setupRecycler(List<Object> response){
YourRecyclerViewAdapter adapter = new YourRecyclerViewAdapter(response);
recyclerView.setLayoutManager(...); // your layout manager
recyclerView.setAdapter(adapter);
}
I am writing code for an Android app using Eclipse that is supposed to download an image from a URL (which is generated by the app, elsewhere in the code, using GPS information), then attach the newly downloaded image to an e-mail to be sent. I am able to, in general, accomplish this without much issue.
My problem is this: I only want one image downloaded by the app to be present in the device's external storage at any given time. Deleting the image after the email intent does not work, because because the app doesn't always call onStop or onDestroy when switching to another app to send the email. Time-sensitive deleting of the image will not work either, because I cannot assume that the user will send only one email from the app per hour. I want to give the user the freedom of sending as many of these emails (with one newly downloaded image, each) as they wish.
My current method (which works MOST of the time) is this: in the downloadFile method, simply check for the file's existence (I call it sensorMap.png), then delete it if it exists, before downloading a new one. This SHOULD ensure that there may be only one sensorMap.png image in external storage at any given time (EDIT: it does do this), and that when it comes time to attach the image to the email intent, there will be exactly one image ready to go. Instead, I see that sometimes a second sensorMap image is sometimes being downloaded into storage (i.e. "sensorMap-1.png"), OR the image cannot be attached to the email due to a "File size: 0 bytes" error, OR the image cannot be attached due to a "File does not exist" error. I am unsure what the difference between the latter two problems is. EDIT: Upon manually examining the contents of the directory I created, it seems that, as intended, I end up with only one image titled "sensorMap.png" at a time; it remains in the directory after the app closes, as expected. However, I still occasionally get the "File size: 0 bytes" message or the "File does not exist." message with no attached image, even though I see that the image DOES exist upon looking in directory afterwards. Other times, everything works just fine. It's rather bewildering.
In addition, there is an issue of the button which sends the email becoming unresponsive occasionally. Most of the time, it prompts the user to select an email client, as intended, but occasionally the button will LOOK as if clicked, but do nothing. When this happens, the logcat does not sense that the button was even clicked (I inserted a println statement to test it).
I am unsure of why my delete-before-download is not working flawlessly; the basic idea, at least, appears to be logically sound. Here is the code pertaining to my issue:
Code used to download file (in MainCountActivity.java):
//Function to download image given URL. Will use to attach image file to email.
public void downloadFile(String uRl) {
//delete existing file first so that only one sensorMap image exists in memory
//at any given time.
File file = new File(Environment.getExternalStorageDirectory()+"/SensorLocationImages");
File checkFile = new File(Environment.getExternalStorageDirectory()+"/SensorLocationImages/sensorMap.png");
if(checkFile.exists())
{
//debugging:
System.out.println("About to delete file!");
//deleteFiles(Environment.getExternalStorageDirectory()+"/SensorLocationImages");
checkFile.delete();
}
DownloadManager mgr = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE);
Uri downloadUri = Uri.parse(uRl);
DownloadManager.Request request = new DownloadManager.Request(
downloadUri);
request.setAllowedNetworkTypes(
DownloadManager.Request.NETWORK_WIFI
| DownloadManager.Request.NETWORK_MOBILE)
.setAllowedOverRoaming(false).setTitle("Sensor Location Map")
.setDescription("Pinpointed is the location from which the log file was sent.")
.setDestinationInExternalPublicDir("/SensorLocationImages", "sensorMap.png");
mgr.enqueue(request);
}
public Activity getActivity() //I wasn't sure if this would work, but it did. Or at least appears to.
{ return this; }
Method to send email (in MainCountActivity.java):
public void sendEmail(String toAddress, String ccAddress, String bccAddress, String subject, String body, String attachmentMimeType) throws Exception{
try {
Intent emailIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
emailIntent.setType(attachmentMimeType); //new
String sToAddress[] = { toAddress };
String sCCAddress[] = { ccAddress};
String sBCCAddress[] = { bccAddress };
emailIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
emailIntent.putExtra(Intent.EXTRA_EMAIL, sToAddress);
emailIntent.putExtra(android.content.Intent.EXTRA_CC, sCCAddress);
emailIntent.putExtra(android.content.Intent.EXTRA_BCC, sBCCAddress);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(Intent.EXTRA_TEXT, body);
//get URI of logfile
File tempFile = new File(Environment.getExternalStorageDirectory () + MainCountActivity.dirPath);
Uri uri = Uri.fromFile(tempFile);
//create URI arraylist and add first URI
ArrayList<Uri> uris = new ArrayList<Uri>();
uris.add(uri);
//get URI of map image and add to arraylist
//make sure it is there to attach
File file = new File(Environment.getExternalStorageDirectory()+"/SensorLocationImages");
do {
downloadFile(getMapLink());
//createDirectoryAndSaveFile(getBitmapFromURL(getMapLink()), "sensorMap.png");
} while (!file.exists());
uris.add(Uri.fromFile(new File(Environment
.getExternalStorageDirectory()
+ "/SensorLocationImages/sensorMap.png")));
//+ "/sdcard/SensorLocationImages/sensorMap.png")));
emailIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
startActivity(emailIntent);
}
catch(Exception ex) {
ex.printStackTrace();
throw ex;
}
}
OnClick method, for my occasional button issue (In MaincountActivity.java):
public void onClick(View v){
switch(v.getId())
{
case R.id.textView1:
{
break;
}
case R.id.Reset:
{
//allowCounting will let the program know when to let it to count or not, depending if Start or Stop button are pressed.
logCount=0;
mCounter.setText("Total: 0");
mToggle.setChecked(false);
break;
}
/* case R.id.toggleButton:
{
break;
}*/
case R.id.SendEmail:
{
//for debugging purposes:
System.out.println("Email button being clicked!");
LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER))
{
Toast.makeText(this, "GPS is enabled in your device", Toast.LENGTH_SHORT).show();
try {
sendEmail("","","","Sensor Log Info",getEmailBody(),"multipart/mixed");
} catch (Exception e) {
e.printStackTrace();
}
}
else
{
showGPSAlertForEmail();
}
break;
}
}
Basically, I really want to know why my delete-then-download method has not worked every time. Logcat errors have provided no insight. Thank you for your time.
How does Lastpass manage this?!
AccessibilityNodeInfo has a setText() method, but I feel like this is a red herring as the docs state,
Note: Cannot be called from an AccessibilityService. This class is made immutable before being delivered to an AccessibilityService.
Another user asked a similar question a while back, but the recent updates to LastPass prove that it is indeed possible.
Set text in AccessibilityNodeInfo
I found some better solution rather than ACTION_PASTE. I feel ACTION_PASTE makes delay and didn't work properly. ACTION_SET_TEXT works fine for me, check with you.
public void pasteText(AccessibilityNodeInfo node, String text) {
Bundle arguments = new Bundle();
arguments.putString(AccessibilityNodeInfoCompat.ACTION_ARGUMENT_SET_TEXT_CHARSEQUENCE, text);
node.performAction(AccessibilityNodeInfoCompat.ACTION_SET_TEXT, arguments);
}
I have figured this out and have it implemented in my app, TapN.
First get the original clipboard contents, save that, copy to the clipboard your content, then paste it, then copy the original content back.
public void inputData(Context c, String data, AccessibilityNodeInfo source) {
try {
String lastClip = clipboard.getPrimaryClip().getItemAt(0).coerceToText(c)
.toString();
} catch (Exception e) {
lastClip = "";
}
Log.d("THE NODE INFO", source.toString());
ClipData clip = ClipData.newPlainText("nfc_input", data);
clipboard.setPrimaryClip(clip);
Log.d("SENDING DATA", Boolean.toString(source.refresh()));
Log.d("SENDING DATA", Boolean.toString(source
.performAction(AccessibilityNodeInfo.ACTION_PASTE)));
ClipData clip = ClipData.newPlainText("nfc_input", lastClip);
clipboard.setPrimaryClip(clip);
}
This shouldn't be that hard, but I cannot figure this out. I need to save an image, on my end only, and build it dynamically so all my users will view these images. The tutorials on Parse.com are very helpful, but not in the case of images. I need detailed explanations or helpful links. Thanks for looking.
This is all I have so far as far as saving an image. I am properly getting the file in my Data Browser, but if I try to view it, it only shows my string "beatdown.jpg" not the actual jpg.
....
private void saveImage() {
// TODO Auto-generated method stub
InputStream header = new FileInputStream("beatdown.jpg");
byte[] head = IOUtils.toByteArray(header);
ParseFile file = new ParseFile(head);
try{
file.save();
} catch (ParseException e) {
e.printStackTrace();
}
ParseObject displayImage = new ParseObject("displayImage");
displayImage.put("header", file);
try{
displayImage.save();
} catch (ParseException e1){
e1.printStackTrace();
}
}
I understand I am trying to get the string of "beatdown.jpg" to bytes in the code above, and it is not handling it as a .jpg. But I don't know how to make it a .jpg.
EDIT: I added commons-io. But when I run the code (see the above updated code), it won't register on anything on parse.com. I am getting this in my logcat;
Service com.android.exchange.ExchangeService has leaked ServiceConnection com.android.emailcommon.service.ServiceProxy$ProxyConnection#40cf2498 that was originally bound here
The key elements are:
File f = new File("pathToFile");
FileInputStream fis = new FileInputStream(f);
byte[] bytes = new byte[f.length()];
fis.read(bytes);
Of course there's exception handling and the like to do, but this should be enough to give you the general idea.