This is my first android app so I am quite new to it. I am able to read from a property file but facing problem on writing back to it on the save button in the same activity.
Here is my code
public class ConfigurationActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_configuration);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final EditText abc = (EditText) findViewById(R.id.abc);
...
...
...
//Reading into a activity and displaying it into the user
try {
Properties props = new Properties();;
InputStream inputStream = getApplicationContext().getAssets().open("app.properties");
props.load(inputStream);
abc.setText(props.getProperty("abc"));
...
...
...
inputStream.close();
} catch (FileNotFoundException ex) {
Log.e("Exception", "File donot exists");
} catch (IOException ex) {
Log.e("Exception","IO error");
}
//On the save button I am trying to write back to properties file
Button save = (Button) findViewById(R.id.SaveButton);
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
Properties props = new Properties();
props.setProperty("abc", abc.getText().toString());
...
...
...
props.store(getApplicationContext().getAssets().openFd("app.properties").createOutputStream(), null);
Intent intent = new Intent(ConfigurationActivity.this, MainActivity.class);
startActivity(intent);
finish();
//inputStream.close();
} catch (FileNotFoundException ex) {
Log.e("Exception", "File donot exists");
} catch (IOException ex) {
Log.e("Exception","IO error");
}
}
});
}
}
Now I am getting the data from the property file and displaying it to user but on the save button its giving FileNotFoundException. I looked for other codes on stackoverflow but I wasn't able to solve my problem
Can someone guide my in this ?
Thanks in advance
You cannot modify assets or resources at runtime. They are read-only.
Related
I have Three pages Splash_Activity , Login_Activity, Activity_One
The activity flow is Splash_Activity -> Login_Activity -> Activity_One .In that case i check the .db file is exist or not in my Splash_Activity which is always start activity of application.
I put the condition for if .db is exist then go to Activity_One
and if not then go to Login_Activity .
But the problem when i delete .db file on button click the .db file is deleted properly and display the login page.
When i exist the app without login and I again start the app first two three times run and check the .db file is not available then go to login page but after that it goes to Activity_One. Why this happen
This splash screen
public class Splash_Screen extends RootActivity
{
MyDbHelper dbhelper ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.splash_page);
Thread loading = new Thread() {
public void run()
{
try
{
File database=getApplicationContext().getDatabasePath("ClassNKK.db");
if (!database.exists()) {
// Database does not exist so copy it from assets here
Log.i("Database", "Not Found");
try
{
sleep(2000);
Intent main = new Intent(Splash_Screen.this, Login_Screen.class);
startActivity(main);
Log.e("DB "," is null !!!");
}
catch (Exception e) {
e.printStackTrace();
}
}
else {
Log.i("Database", "Found");
try {
sleep(2000);
Intent main = new Intent(Splash_Screen.this, AllPosts_Page.class);
startActivity(main);
Log.e("DB ", " is null !!!");
} catch (Exception e) {
e.printStackTrace();
}
}
} catch (SQLiteException e) {
e.printStackTrace();
}
}
};
loading.start();
}
}
And this logout button on Activity_One page
imgBtn_LogOut.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
File database = getApplicationContext().getDatabasePath(dbhelper.DATABASE_NAME);
if (!database.exists()) {
Log.e("Database", "Not Found");
} else {
Log.e("Database", "Found");
ctx.deleteDatabase(dbhelper.DATABASE_NAME);
Log.e("Database", " Deleted Completeley !!!");
File dir = new File(Environment.getExternalStorageDirectory() + "classnkk_images");
DeleteRecursive(dir);
Intent i = new Intent(Filter_Screen.this, Login_Screen.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(i);
finish();
}
}
});
I think the problem is when you start application after delete db, it will automatically create new database without data.
So please check again database had created or not ?
I suggest you to save parameter in share preference and check it when in splash screen. It better!
If you want to store login credential you can use sharedPreference instead of sqlite. I think it will be most suitable method for this.
http://androidforbegineers.blogspot.in/2013/08/shared-preference-using-registration.html
this blog will help you.:)
Why Surface View camera becomes null after switching from one activity to another in Android? When there were 2 classes and I was switching from 1st to 2nd Activity and from 2nd to 1st Activity, everything was working fine. But when I started a new activity, that is the third one, switching from third to any other activity makes camera null that's why the activity crashes but when clicked on "OK" the application continues. (In my code, Camera1 becomes null). What could be the reason of it? I don't want the message to appear that the activity has crashed
train.class(3rd Activity)
public void saveClicked(View v) {
save.setVisibility(View.INVISIBLE);
text.setVisibility(View.VISIBLE);
saveName.setVisibility(View.VISIBLE);
txtEditor.setVisibility(View.VISIBLE);
try {
//label++;
File Root = Environment.getExternalStorageDirectory();
LabelFile = new File(Root, "labels.txt");
roughFile= new File(Root,"rough.txt");
FileWriter Writter = new FileWriter(roughFile,false);
out = new BufferedWriter(Writter);
if(!roughFile.exists()){
roughFile.createNewFile();
Writter.write("a," +number);
}
///*-*---------------------------------------------------------------*-*//
aFile = new File(Root, "string.txt");
FileWriter aWritter = new FileWriter(aFile,true);
BufferedWriter bWritter = new BufferedWriter(aWritter);
bWritter.write(txtEditor.getText().toString()+"," +number+"\n");
bWritter.close();
///*-*---------------------------------------------------------------*-*//
FileWriter fileWritter = new FileWriter(LabelFile,true);
BufferedWriter bufferWritter = new BufferedWriter(fileWritter);
for (int i=0;i<10;i++) {
bufferWritter.write(txtEditor.getText().toString()+"," +number+"\n");
}
MainActivity.traincount++;
number=number+1;
Writter.write("a," +number);
Writter.close();
bufferWritter.close();
BufferedReader br = null;
String line = "";
String cvsSplitBy = ",";
try {
br = new BufferedReader(new FileReader(LabelFile));
while ((line = br.readLine()) != null) {
// use comma as separator
country = line.split(cvsSplitBy);
text.setText(country[1]);
//write=true;
}
} catch(IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Toast.makeText(this, "The contents are saved in the file.", Toast.LENGTH_LONG).show();
MainActivity.in=false;
FdActivity.my=true;
FdActivity.counterForClick=0;
MainActivity.CounterForRecog=17;
MainActivity.counterForUnknown=11;
Intent objIntent = new Intent(getApplicationContext(), FdActivity.class);
startActivity(objIntent);
} catch (Exception e) {
}
}
FdActivity.class(1st Activity)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.face_detect_surface_view);
new Timer().scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() { // this will send data through UI Thread, so you must update any UI Control only within this code.
#Override
public void run() {
counterForClick++;
if(counterForClick==6){
if(MainActivity.in==false) {
//my=true;
camera1.takePicture(null, null, mPicture1);
counterForClick=0;
}
}
}
});
}
}, 0, 500);
}
This is how the system manages its memory. The activity lifecycle is documented, and allows for such interruptions. So, your activity should implement onSaveInstanceState() and onRestoreInstanceState(), just carefully follow the instructions.
Working with camera in such scenario is a challenge, and I usually prefer to stick to one camera-based activity, and manage the in-app navigation via fragments.
The first time my app runs it creates a database in which it loads 6,000 rows from a file in /res/raw. I can't do this asynchronously as the app depends on it entirely. It runs rapidly on my phone - a Moto X - but it's really slow in all my emulators and I'm concerned it could be a bit slower on slower devices thus making the user stare at a blank screen for a few seconds before the app does anything.
Is there a way to put a progress bar while running the overrided SQLiteOpenHelper's onCreate() methood and have it update the progress bar with how far along it is, with a message saying something like "Initializing data for first use!"?
I solved this problem by starting an AsyncTask in onCreate and then only loading the layout at the end of the 'AsyncTask` (or if the data had previously been loaded). It works beautifully as a loading screen. I followed this tutorial http://www.41post.com/4588/programming/android-coding-a-loading-screen-part-1 (which explains the details more) then changed it a bit for my needs (such as loading a raw resource).
I should say that although it does it asynchronously because the main layout hasn't loaded the user has to wait for the loading to complete before he or she can continue, so hopefully that means it doing it asynchronously won't be a problem for you with the app depending on the database.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SharedPreferences sharedPref = getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE);
dataAddedToDB = (sharedPref.getBoolean(PXS_RXS_UPDATE, false));
if (!dataAddedToDB) {
new LoadViewTask(this).execute();
} else {
setContentView(R.layout.activity_main);
}
}
In the AsyncTask it loads the database showing how far it has got and showing your message and then only goes on to show the layout at the end. (BTW, it is helpful to lock the screen orientation while doing this to stop it messing it up).
EDIT: publishProgress(counter); passes the value of where the task has got to to onProgressUpdate().
private class LoadViewTask extends AsyncTask<Void, Integer, Void> {
private Context context;
public LoadViewTask(Context context) {
this.context = context.getApplicationContext();
}
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(MainActivity.this);
progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
progressDialog.setTitle("Loading...");
progressDialog.setMessage("Initializing data for first use!");
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(false);
// this counts how many line to be added to the database so it can later tell how far it has got.
final Resources resources2 = context.getResources();
InputStream inputStream2 = resources2.openRawResource(R.raw.rawherbaldata);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream2));
int lineCount = 0;
try {
String line;
while ((line = reader.readLine()) != null) {
lineCount++;
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
progressDialog.setMax(lineCount);
progressDialog.setProgress(0);
progressDialog.show();
}
#Override
protected Void doInBackground(Void... params) {
HerbalDatabaseOpenHelper mHerbalDbHelper = new HerbalDatabaseOpenHelper(MainActivity.this);
SQLiteDatabase db = mHerbalDbHelper.getWritableDatabase();
int counter = 0;
final Resources resources2 = context.getResources();
InputStream inputStream2 = resources2.openRawResource(R.raw.rawherbaldata);
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream2));
db.beginTransaction();
try {
int lineNumber = 1;
String line;
while ((line = reader.readLine()) != null) {
// CODE FOR ENTERING LINE INTO DATABASE
// EDIT: the following keeps the task updated on where it has got to, passing the count to onProgressUpdate()
counter++;
publishProgress(counter);
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
db.setTransactionSuccessful();
db.endTransaction();
db.close();
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
progressDialog.setProgress(values[0]);
}
#Override
protected void onPostExecute(Void result) {
progressDialog.dismiss();
SharedPreferences sharedPref = getSharedPreferences(getString(R.string.preference_file_key), Context.MODE_PRIVATE);
pxsRxsUpdate = true;
SharedPreferences.Editor editor = sharedPref.edit();
editor.putBoolean(PXS_RXS_UPDATE, pxsRxsUpdate);
editor.commit();
// initialize the View
setContentView(R.layout.activity_main);
}
}
You could use another intermediate activity which would show the progress dialog and then send you back to the main activity when done.
First you'll need a static method that a boolean if the DB has already been create.
Then inside of your activity's onCreate call the middleman if necessary:
DbHelper mDbHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!DbHelper.isDbCreated()) {
Intent intent = new Intent(this, DbActivity.class);
startActivity(intent);
finish();
return;
}
// Do normal stuff like instantiating the helper and so on
mDbHelper = new DbHelper();
...
}
Then inside of this "middleman" activity show the ProgressDialog and create the database.
Once you're done, hide the dialog and go back to your main activity:
mProgress.dismiss();
Intent intent = new Intent(this, MainActivity.class);
startActivity(intent);
finish();
return;
If your static method isDbCreated() is created properly, you won't reveal the MainActivity's content until the database is created.
EDIT:
Here's the method I use to check for the database. Perhaps it will help you.
public boolean isDbCreated() {
String sDatabasePath = context.getDatabasePath(DB_NAME).getPath();
SQLiteDatabase tmpDb = null;
if (mContext.getDatabasePath(DB_NAME).exists()) {
try {
tmpDb = SQLiteDatabase.openDatabase(sDatabasePath, null,
SQLiteDatabase.OPEN_READONLY);
tmpDb.close();
} catch (SQLiteException e) {
e.printStackTrace();
}
} else {
Log.e(TAG, "DB file doesn't exist.");
// If the parent dir doesn't exist, create it
File parentDir = new File(mContext.getDatabasePath(DB_NAME).getParent());
if (!parentDir.exists()) {
if (parentDir.mkdirs()) {
Log.d(TAG, "Successfully created the parent dir:" + parentDir.getName());
} else {
Log.e(TAG, "Failed to create the parent dir:" + parentDir.getName());
}
}
}
return (tmpDb != null);
}
i am using check box for saving data in database .if it is checked then app redirecting to other screen by saving data after that if i click on device back button then app showing it is not checked.how can i fix this issue?
here i am placing code
public void joinLisn(){
String shareProfileType2=Constants.PROFILE_SHARE_ALL;
String accessToken = null;
DatabaseHelper helper = new DatabaseHelper(getApplicationContext());
DatabaseUtility dao = new DatabaseUtility(helper);
try {
accessToken = dao.getAccessToken();
} catch (Exception e1) {
handler.sendEmptyMessage(1);
return;
}
if(accessToken == null || accessToken.length() == 0){
handler.sendEmptyMessage(1);
return;
}
Map<String , String> params = new HashMap<String,String>();
params.put(Constants.ACCESS_TOKEN_PARAM, accessToken);
params.put(Constants.LISN_ID_PARAM, id);
params.put(Constants.PROFILE_TYPE_PARAM,shareProfileType2);
Status status = null;
try {
status = Utils.joinLisn(params, this);
} catch (NullPointerException e) {
handler.sendEmptyMessage(12);
return;
} catch (JSONException e) {
handler.sendEmptyMessage(11);
return;
}
if(status == null){
handler.sendEmptyMessage(1);
} else if(status.getStatus().equalsIgnoreCase(Constants.SUCCESS)){
try {
Intent lisnDetailIntent = new Intent(this, LisnDetailTabView.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Bundle bundleObj = new Bundle();
bundleObj.putString("id", id);
bundleObj.putString("RSVP","In");
lisnDetailIntent.putExtras(bundleObj);
startActivityForResult(lisnDetailIntent,0);
overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right);
handler.sendEmptyMessage(8);
} catch(Exception ex) {}
} else{
handler.sendEmptyMessage(2);
return;
}
}
Override the onbackpressed to trigger your function to save the states.
public void onBackPressed() {
//Do your db saving here
super.onBackPressed();
}
If your app is redirecting to other app, your app will be put to background. Make use of onSaveInstanceState and onRestoreInstanceState to save and restore the checkbox state.
I am trying to test a simple file i/o program on android where i type in some text in
EditText and when i click the Save Button, it writes the content in a file. and when i click the Load button it loads the content back into the EditText.
here is my code---
public class Activity2 extends Activity {
private EditText textBox;
private static final int READ_BLOCK_SIZE = 100;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout2);
textBox = (EditText) findViewById(R.id.txtText1);
Button saveBtn = (Button) findViewById(R.id.btnSave);
Button loadBtn = (Button) findViewById(R.id.btnLoad);
saveBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String str = textBox.getText().toString();
try
{
PrintWriter PR=new PrintWriter(new File("text1.txt"));
PR.write(str);
PR.flush();
PR.close();
//textBox.setText("");
//---display file saved message---
Toast.makeText(getBaseContext(),
"File saved successfully!",
Toast.LENGTH_SHORT).show();
//---clears the EditText---
textBox.setText("");
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
});
loadBtn.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
try
{
File f=new File("text1.txt");
BufferedReader BR=new BufferedReader(new FileReader(f));
String txt="";
String str;
while((str=BR.readLine())!=null)
{
txt+=str;
}
//---set the EditText to the text that has been
// read---
textBox.setText(txt);
BR.close();
Toast.makeText(getBaseContext(),
"File loaded successfully!",
Toast.LENGTH_SHORT).show();
}
catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
}
}
`
why is it not working? Thanks in advance for any help. Any explanation would be highly appreciated.
Using new File("text1.txt") as output does not work on Android. The current working directoy is always / which is not writable for your app. Use
File f = new File(Environment.getExternalStorageDirectory(), "text1.txt");
getExternalStorageDirectory() is the internal storage for newer phones.
Your app Context has several paths that you can use if you want to store data in your app-private folder. Paths from Environment are in public places where you can simply read the data with a filemanager
And don't forget to add
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
in case you want to write to those public paths