Show different layout depending on a condition - java

In my case I have two layout, but I have check the mainactivity's oncreate, if the file is created then open indexpage, activity_indexpage2.xml, but I can't not print this result to check bug.
protected void onCreate(Bundle savedInstanceState) {
try {
contentfile = read();
} catch (IOException e) {
e.printStackTrace();
}
if(contentfile!=null
){
Intent intent = new Intent(MainActivity.this, indexpage.class);
setContentView(R.layout.activity_indexpage2);
startActivity(intent);
}
`super.onCreate(savedInstanceState);`
public String read() throws IOException {
FileInputStream input = this.openFileInput(File_NAME);
byte[] temp = new byte[1024];
StringBuffer stringBuffer = new StringBuffer("");
int len = 0;
while ((len = input.read(temp)) > 0) {
stringBuffer.append(new String(temp, 0, len));
}
input.close();
return stringBuffer.toString();
}

In onCreate() your first statement should be setContentView() then you need to request permission for reading external storage then if you have permission granted then check if the file exists or not. Then depending on the condition show your proper layout or navigate to another activity using Intent

Related

AutoCompleteTextView is not showing strings loaded from the Internal Storage

I want make a AutoCompleteTextview which will load previously saved suggestion from the internal storage. I successfully loaded the strings from the internal storage to a string array(i used logging to check....).
then as i loaded the string array to an adapter and set the adapter to the AutoCompleteTextview, after that the AutoCompleteTextview is not showing the suggestion-strings which i loaded from the Internal Storage but it is showing the suggestion-string(s) which i loaded to the string array at runtime.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//this is the array where i am trying to save my data into
loadedString=new String[1];
loadedString[0]="the pre-loaded String"
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, loadedString);
atcv = (AutoCompleteTextView) findViewById(R.id.autocomplete);
int objectCounter = 0;
try {
FileInputStream fis = this.openFileInput(FILENAME);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String temp;
while ((temp = br.readLine()) != null) {
//here i am calculating the lines of my data-file
//as 1 line contains 1 string object
//so that i can initialize the string array
objectCounter++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//intializing the array
// objectCounter+1 and index =1 because i loaded an object before
loadedString = new String[objectCounter+1];
int index = 1;
try {
FileInputStream fis = this.openFileInput(FILENAME);
InputStreamReader isr = new InputStreamReader(fis);
BufferedReader br = new BufferedReader(isr);
String temp;
while ((temp = br.readLine()) != null) {
loadedString[index] = temp;
index++;
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
adapter.notifyDataSetChanged();
atcv.setAdapter(adapter);
atcv.setThreshold(1);
}
this is the method i am using to save the data
public void saver(View view) {
String string;
if(actv.getText()!=null){
advice = advices.getText().toString();}
advice=advice+"\n";
try{
FileOutputStream fos = openFileOutput(FILENAME, context.MODE_APPEND);
fos.write(advice.getBytes());
fos.close();
Toast.makeText(this, "File saved" , Toast.LENGTH_LONG).show();
}
catch (Exception e){
Toast.makeText(this, "File could not be saved", Toast.LENGTH_LONG).show();
}
Please help. Note that i used notifyDataSetChanged() method. I will be really grateful.
Note that i used notifyDataSetChanged() method
In your case, that is useless. The ArrayAdapter will continue to use your old String[1]. It does not know about your new String[].
First, do not do disk I/O on the main application thread, as you are doing here. Use some form of background operation, like an AsyncTask.
Second, do not read the data in twice, as that is twice as slow for the user. For example, you could use a data structure like ArrayList<String>, which can expand its size on the fly.
Then, do not create the ArrayAdapter until after you have loaded the strings.

How to forbide to kill the app while writing to file continue

My app uses the serialization to store data. Save() function is called in Activity the onStop() method. Since the data was small, everything was fine. Today serialization takes a time, and I was surpised to find a way to corrupt the data.
If I exit from the app by Home button, then quickly manually kill the app form backround activities screen (on long home button tap), my data seems to be lost. I think its because app was written to file and was interrupted.
Is there an opportunity to forbide to kill the process until my save() method works? I was thinking to rewrite serialisation by myself, and it can be faster in times, but as I understand sometimes this problem will happen again.
Thank you.
// Activity code:
#Override
protected void onStop(){
try {
ms.save();
} catch (IOException e) {
e.printStackTrace();
}
super.onStop();
}
// Singleton save fucntion
public void save() throws IOException {
Runnable r = new Runnable()
{
#Override
public void run()
{
try {
FileOutputStream fos;
ObjectOutputStream os;
if (data != null){
fos = context.openFileOutput("Data.dat", Context.MODE_PRIVATE);
os = new ObjectOutputStream(fos);
os.writeObject(data);
os.flush();
os.close();
fos.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
};
Thread t = new Thread(r);
t.start();
}
Ok, I got it using the IntentService in Background. Thanks to RyanB for the help.
save() in Singleton:
Intent mServiceIntent = new Intent(context, ServiceDatastore.class);
mServiceIntent.setData(Uri.parse("dsf"));
context.startService(mServiceIntent);
ServiceDatastore.java
#Override
protected void onHandleIntent(Intent workIntent) {
final int myID = 1234;
Intent intent = new Intent(); // empty Intent to do nothing in case we click on notification.
PendingIntent pendIntent = PendingIntent.getActivity(this, 0, intent, 0);
Notification notice = new Notification(R.drawable.icon, getString(R.string.saving), System.currentTimeMillis());
notice.setLatestEventInfo(this, "Saving...", "", pendIntent);
notice.flags |= Notification.FLAG_NO_CLEAR;
startForeground(myID, notice);
try {
Singleton ms = Singleton.getInstance(this);
FileOutputStream fos;
ObjectOutputStream os;
//copy settings
if (ms.data != null) {
fos = this.openFileOutput("Data.dat", Context.MODE_PRIVATE);
os = new ObjectOutputStream(fos);
os.writeObject(ms.data);
os.flush();
os.close();
fos.close();
}
}
catch (Exception e){
e.printStackTrace();
}
stopForeground(true); // to kill the process if the app was killed.
}

how to internal storage item display on another activity of editbox

I am a new android developer. my problem is how items display from internal storage to another activity of the edit box. internal storage file contains (name, age, position) that file item display on three edit box of another activity.
In my project user select MSG from Inbox and that MSG display on text view of activity_main.xml .when I click save button that file stored in internal storage but when I click on the read button that all item display on one edit box not separately all three edit box from internal storage .
for example in my internal storage file contain(abc,14,ANDROID DEVLOPER) that all item display of another activity of three edit box separately.
Mainctivity.java
Read.setOnClickListener(new View.OnClickListener() {
//private Context context;
#Override
public void onClick(View v) {
//Intent intent = new Intent(getApplicationContext(), MessageBox.class);
// TODO Auto-generated method stub
//Intent intent = new Intent(context,MessageBox.class);
try{
FileInputStream fin = openFileInput(file);
int c;
String temp="";
while( (c = fin.read()) != -1){
temp = temp + Character.toString((char)c);
Intent in = new Intent(getApplicationContext(),data.class);
//String msg = null;
in.putExtra("Msg_Detail", temp);
startActivity(in);
// et.setText(temp);
Toast.makeText(getBaseContext(),"file read",
Toast.LENGTH_SHORT).show();
}
}catch(Exception e){
}
}
});}
public void save(View view){
data = tv.getText().toString();
try {
FileOutputStream fOut = openFileOutput(file,MODE_WORLD_READABLE);
fOut.write(data.getBytes());
fOut.close();
Toast.makeText(getBaseContext(),"file saved",
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
**data.java**
setContentView(R.layout.data);
et11 = (EditText)(findViewById(R.id.eText123));
Intent intent = getIntent();
String msg = intent.getStringExtra("Msg_Detail");
//String msg = intent.getExtras().getString("Msg_Detail");
((EditText)findViewById(R.id.eText123)).setText(msg);
//et11.setText(msg);
activity_main.xml contain save, read and text view and data.xml contain three edit box(name,age,position).how that msg display on edit box of data.xml from internal storage.
Internal file generate and user select msg display on text view of activity_main.xml of another project but how internal file item display on edit box.
problem is when I click read button all data item display on one edit box.
This snippet...
while( (c = fin.read()) != -1){
temp = temp + Character.toString((char)c);
Intent in = new Intent(getApplicationContext(),data.class);
//String msg = null;
in.putExtra("Msg_Detail", temp);
startActivity(in);
// et.setText(temp);
Toast.makeText(getBaseContext(),"file read",
Toast.LENGTH_SHORT).show();
}
is actually doing nothing else but starting a new activity and pausing the current activity as soon as the file stream reads the first byte and it also leaves the file stream open. That's why you are probably getting nothing in data.java.
You should wait till the file stream finishes reading the file to start the new activity and make sure you close that stream. So, move the code that creates the intent, starts the activity and shows the toast out of the while loop...
FileInputStream in = null;
int c;
String temp="";
try{
fin = openFileInput(file);
while( (c = fin.read()) != -1){
temp = temp + Character.toString((char)c);
}
}
catch(Exception e){...}
finally{
if(in != null)
in.close();
}
Intent in = new Intent(getApplicationContext(),data.class);
in.putExtra("Msg_Detail", temp);
startActivity(in);
Toast.makeText(getBaseContext(),"file read", Toast.LENGTH_SHORT)
.show();

Android PDF Load Timing

The requirements: ensure that the PDF document is deleted from the device after the user has left the PDF viewing screen
The problem: on certain devices (Samsung 4.4.2 and Samsung 4.1.2 for sure, but not Asus 4.2.1) only the first time that the PDF is requested after restarting the application an error message is displayed stating "This document cannot be opened". Thereafter the PDF will load normally. I'm thinking this is a timing issue due to processes that need to be started the first time, but are running after the first attempted load.
The code: note that createFile() is called first, then startActivityForIntentResult()
private File file;
private ArrayList<Uri> uriList = new ArrayList<Uri>();
private void createFile() {
int fileNameLength = pdfFileName[0].length();
String fileName = pdfFileName[0].substring(0, fileNameLength - 4) + DateTime.now();
String fileExtension = pdfFileName[0].substring(fileNameLength - 4, fileNameLength);
byte[] content = Base64.decodeBase64(pdfData[0].getBytes());
BufferedOutputStream outputStream = null;
try {
File path = new File(getExternalFilesDir(null).getAbsolutePath(), "temp");
if (!path.exists()) {
path.mkdirs();
}
file = new File(path, fileName + fileExtension);
outputStream = new BufferedOutputStream(new FileOutputStream(file));
outputStream.write(content);
file.deleteOnExit();
uriList.add(Uri.fromFile(file));
}
catch (FileNotFoundException ex) {
ex.printStackTrace();
}
catch (IOException ex) {
ex.printStackTrace();
}
finally {
try {
if (outputStream != null) {
outputStream.flush();
outputStream.close();
}
}
catch (IOException ex) {
ex.printStackTrace();
}
}
}
private static int REQUEST_CODE = 1;
private Intent intent;
private void startActivityForIntentResult() {
if (file.exists()) {
Uri targetUri = uriList.get(0);
intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(targetUri, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
try {
startActivityForResult(intent, REQUEST_CODE);
}
catch (ActivityNotFoundException e) {
toastTitle = "Error Displaying PDF";
toastMessage = "Please make sure you have an application for viewing PDFs installed on your device and try again.";
toast = new GenericCustomToast();
toast.show(toastTitle, toastMessage, QueryForPDF.this);
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (resultCode == RESULT_CANCELED && requestCode == REQUEST_CODE) {
if(!file.delete()) {
file.delete();
}
}
searchAgain();
}
#Override
public void onBackPressed() {
super.onBackPressed();
if(!file.delete()) {
file.delete();
}
searchAgain();
}
#Override
public void onStop() {
super.onStop();
if(!file.delete()) {
file.delete();
}
}
#Override
public void onDestroy() {
super.onDestroy();
if(!file.delete()) {
file.delete();
}
}
EDIT: I have also tried implementing a callback to be absolutely certain that createFile() has finished it's work. I even tried adding delays (of different time increments) as well as adding (the completely unnecessary) flags for Intent.FLAG_GRANT_READ_URI_PERMISSION, Intent.FLAG_GRANT_WRITE_URI_PERMISSION, and Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION.
I still don't know why this works, but here's the solution in case anyone else runs into this issue:
It's the directory where the file is created. For some reason on the two Samsung devices there was something different in how the files were either accessed or created versus the Asus device. So File path = new File(getExternalFilesDir(null).getAbsolutePath(), "temp"); becomes File path = new File(getExternalCacheDir().getAbsolutePath()); and the problem goes away.

Variables Not Containing Data?

I am trying to use my download code that works perfectly fine in my other app, but it is acting very strange in this new app I am trying to make.
public class DownloadFile extends AsyncTask<Void, Integer, String> {
String SDCardRoot;
String mixtapeurl = "http://xxxxxx.com/xxxxxxxxxxxx/Mixtapes/NCredible/J.%20Cole%20-%20Cole%20World.zip";
NotificationManager notificationManager;
Notification notification2;
ProgressBar progressBar;
#Override
protected void onPreExecute() {
// configure the intent
Intent intent = new Intent();
final PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
// configure the notification
notification2 = new Notification(R.drawable.download, "DOWNLOADING: " + mixtapeurl, System
.currentTimeMillis());
notification2.flags = notification2.flags | Notification.FLAG_ONGOING_EVENT;
notification2.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.download_progress);
notification2.contentIntent = pendingIntent;
notification2.contentView.setTextViewText(R.id.percentage, 0 + "%" );
notification2.contentView.setTextViewText(R.id.status_text, "DOWNLOADING: " + mixtapeurl);
notification2.contentView.setProgressBar(R.id.status_progress, 100, 0, false);
getApplicationContext();
notificationManager = (NotificationManager) getApplicationContext().getSystemService(
Context.NOTIFICATION_SERVICE);
notificationManager.notify(2, notification2);
}
#Override
protected String doInBackground(Void... params) {
try {
//set the download URL, a url that points to a file on the internet
//this is the file to be downloaded
URL url = new URL(mixtapeurl);
//create the new connection
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
//set up some things on the connection
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
//and connect!
urlConnection.connect();
//set the path where we want to save the file
//in this case, going to save it on the root directory of the
//sd card.
SDCardRoot = Environment.getExternalStorageDirectory() + "/download/";
//create a new file, specifying the path, and the filename
//which we want to save the file as.
File file = new File(SDCardRoot,mixtapeurl);
//this will be used to write the downloaded data into the file we created
FileOutputStream fileOutput = new FileOutputStream(file);
//this will be used in reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
//this is the total size of the file
int totalSize = urlConnection.getContentLength();
//variable to store total downloaded bytes
int downloadedSize = 0;
int myProgress;
//create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0; //used to store a temporary size of the buffer
int previousProgress = 0;
//now, read through the input buffer and write the contents to the file
while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
//add the data in the buffer to the file in the file output stream (the file on the sd card
fileOutput.write(buffer, 0, bufferLength);
//add up the size so we know how much is downloaded
downloadedSize += bufferLength;
//this is where you would do something to report the prgress, like this maybe
//updateProgress(downloadedSize, totalSize);
//publishProgress((int)(total*100/lenghtOfFile));
myProgress = (int) ((downloadedSize/(double)totalSize) * (double)100);
if ((myProgress) > 1 && (myProgress) > ((previousProgress ))) {
previousProgress= myProgress;
publishProgress(myProgress);
}
}
//close the output stream when done
fileOutput.close();
//catch some possible errors...
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return "success";}
#Override
protected void onProgressUpdate(Integer... progression) {
String percent;
percent = progression[0].toString();
notification2.contentView.setProgressBar(R.id.status_progress, 100, progression[0], false);
notification2.contentView.setTextViewText(R.id.percentage, percent + "%" );
notificationManager.notify(2, notification2);
}
#Override
protected void onPostExecute(String result) {
// TODO Auto-generated method stub
Toast toast = Toast.makeText(getApplicationContext(), mixtapeurl + " downloaded to: " + SDCardRoot, Toast.LENGTH_LONG);
toast.show();
}
}
Here is how I implement it:
new DownloadFile().execute();
And what i get is "http://xxxxxx.com/xxxxxxxxxxxx/Mixtapes/NCredible/J.%20Cole%20-%20Cole%20World.zip download to null" for my toast right after I click the button and the file does not download at all.
This sounds like a very common issue: Forgot to set permission in manifest.
<uses-permission android:name="android.permission.INTERNET" />

Categories

Resources