I am creating a new class for database, the first function is to access the database
the problem is that I always get error on MODE_PRIVATE
I tried to pass the context as parameter but still shows error
anyone know how to access the database from a non activity class
public class DB {
public void OpenDB(Context ctx, SQLiteDatabase dataB)
{
dataB = openOrCreateDatabase("Schlogger", ctx.MODE_PRIVATE,null);
}
}
Change
dataB = openOrCreateDatabase("Schlogger", ctx.MODE_PRIVATE,null);
to
dataB = ctx.openOrCreateDatabase("Schlogger", ctx.MODE_PRIVATE,null);
openOrCreateDatabase is a method of Context class so you need a object of Context to call it.
use context to open databse ctx.openOrCreateDatabase("Schlogger", ctx.MODE_PRIVATE,null);
Related
So, I am trying to write text to a file in Android Studio. I have the following code:
public void sampleFunction() {
File file = new File(getExternalFilesDir(null), "sample-file.txt");
}
The issue is that the method getExternalFilesDir(null) cannot be resolved. After doing some research I have noted that I need to provide the Context class. Such as:
public void sampleFunction(Context c) {
File file = new File(c.getExternalFilesDir(null), "equation_history.xml");
}
And when I called sampleFunction, I would simply pass in the current Context:
sampleFunction(this);
This normally would work, however, I need to call this function inside a setOnClickListener function for a Button. For example:
Button b_go = findViewById(R.id.b_go);
b_go.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Functions.sampleFunction(this);
}
});
So the return value for this is android.view.View.OnClickListener rather than android.content.Context.
How might I get around this? Any advice would be greatly appreciated.
Instead of passing "this" as an argument try calling getApplicationContext() or if you are in fragment just call getActivity().
What is often done is that a Context myContext variable is declared in the class, then onCreate, you populate it with myContext = this; Then, in any listener or Async Task, you can use myContext.getExternalFilesDir(null)
File storageDir = getActivity().getExternalFilesDir(Environment.DIRECTORY_PICTURES);
I guess this question is more about understanding context and how to use it properly.
After having googled and "stackoverflowed" a lot I could not find the answer.
Problem:
when using DateUtils.formatDateTime I cannot use "this" as a context. The error message is as described in the title.
Application Info:
This is a simple weather app retrieving weather information via JSON and displaying it on the screen.
Activities:
- MainActivity.java
- FetchData.java
MainActivity: displaying the info
FetchData: getting JSON info from the API, formatting it and sending it back to MainActivity
I am using DateUtils.formatDateTime in the FetchData.java activity and using "this" as a context does not work.
As from my understanding Context provided the "environment" (?) of where the method is being called.
Why is the "environment" of FetchData not valid?
What content should be provided instead?
Help is much appreciated.
Thank you :)
Code:
private ArrayList<String> getWeatherDataFromJson(String forecastJsontStr) throws JSONException {
ArrayList<String> dailyWeatherInfo = new ArrayList<>();
int dataCount;
DateUtils tempDate = new DateUtils();
JSONObject weatherData = new JSONObject(forecastJsontStr);
JSONArray threeHourWeatherData = weatherData.getJSONArray(JSON_LIST);
dataCount = weatherData.getInt("cnt");
JSONObject tempJSONWeatherData;
for (int i = 0; i < dataCount; i++) {
tempJSONWeatherData = threeHourWeatherData.getJSONObject(i);
tempDate.formatDateTime(this,tempJSONWeatherData.getLong("dt"),
DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY |
DateUtils.FORMAT_ABBREV_ALL);
[more code here]
return dailyWeatherInfo;
}
Edit: I just realized I left out an important detail, namely this activity extends AsyncTask. After some further research apparently you provide the context bei adding WeakReference and then adding context in the constructor.
I added the following code:
private WeakReference<Context> contextWeakReference;
public FetchData (Content context) {
contextWeakReference = new WeakReference<>();
}
tempDate.formatDateTime(contextWeakReference.get(),tempJSONWeatherData.getLong("dt"),
DateUtils.FORMAT_SHOW_DATE | DateUtils.FORMAT_SHOW_WEEKDAY |
DateUtils.FORMAT_ABBREV_ALL);
This made the error disappear but I still don't understand why "this" doesn't work.
I am using DateUtils.formatDateTime in the FetchData.java activity and
using "this" as a context does not work. As from my understanding
Context provided the "environment" (?) of where the method is being
called.
You're incorrect, Context is Android context which is (from documentation):
Interface to global information about an application environment. This
is an abstract class whose implementation is provided by the Android
system. It allows access to application-specific resources and
classes, as well as up-calls for application-level operations such as
launching activities, broadcasting and receiving intents, etc.
DateUtils.formatDateTime() needs Context as one of its parameter. So, you need to pass a context.
Android Activity is sub class of Context, so you can use this (which refer to itself) as the context like the following:
public class MyActivity extends Activity {
...
protected void doSomething() {
// this refer to the MyActivity instance which is a Context.
DateUtils.formatDateTime(this, ...);
}
...
}
You need to pass the Context for every class that is not a Context subclass.
You can't use this in AsyncTask because it's not a Context subclass. So, you need to pass the Context using WeakReference to avoid Context leaking, like the following:
private class AsyncTaskRunner extends AsyncTask<String, String, String> {
private WeakReference<Context> contextWeakReference;
public FetchData (Content context) {
contextWeakReference = new WeakReference<>();
}
private void doSomething() {
// We have the context from the WeakReference
Context context = contextWeakReference.get();
DateUtils.formatDateTime(context, ...);
}
}
Last, you don't need to create a DateUtils object when calling DateUtils.formatDateTime(), so this isn't necessary:
DateUtils tempDate = new DateUtils();
tempDate.formatDateTime(...);
You can directly call it because it's a static method:
DateUtils.formatDateTime(...);
tempDate.formatDateTime(this,tempJSONWeatherData.getLong("dt"), instead of this you can pass context of application, this refers on class FetchData
I am trying to test using AndroidTestCase. I am trying to test only one particular class in my application, however this class does not extend Activity, Service or anything else. It is basically a plain Java class apart from the fact that it requires a Context. It is a pojo and some of its variables are objects that require android api calls in their creation, e.g. a call to the SensorManager.
I tried to use:
Context context = getContext();
When running my tests this gives me the exception "System services not available to activites before onCreate()". Does that method have to be overridden?
final Context context = new IsolatedContext(null, getContext()) gives the same thing.
The reason I am using the Android testing framework and not something like Robolectric is because the class I'm testing gathers hardware information about a device and so I want to run the tests on an actual device. I have looked at the developer docs for AndroidTestCase but can't see what I'm looking for in the examples. I'm not sure the other test case classes will achieve what I want. Any ideas?
My test class:
public class DeviceTest extends AndroidTestCase {
ClassToTest mClassToTest;
#Override
protected void setUp() throws Exception {
final Context context = new IsolatedContext(null, getContext()) {
#Override
public Object getSystemService(final String pName) {
return getContext().getSystemService(pName);
}
};
mClassToTest = new ClassToTest(context);
super.setUp();
}
public void testClassMethod() {
Object mObject;
mObject = mClassToTest.getObject();
assertNotNull(mObject);
}
#Override
protected void tearDown() throws Exception {
mClassToTest = null;
super.tearDown();
}
}
Thanks in advance.
UPDATE: After changing my setup to the following:
#Override
protected void setUp() throws Exception {
super.setUp();
context = this.getContext();
mClassToTest = new ClassToTest(context);
}
I am getting an error that context is null. In what scenarios would AndroidTestCase.getContext() return null? My setup seems to be ok....
From AndroidTestCase you can access directly mContext, or call getContext().
From the context returned by those, you could also call Context.getApplicationContext() if you wanted that one.
You can use mContext from super class (AndroidTestCase). I used it for the testing of the database where context is required.
AndroidTestCase.class
public class AndroidTestCase extends TestCase {
protected Context mContext;
...
}
You would be able to use Context in the inherited class of AndroidTestCase.
TestDb.java
public class TestDb extends AndroidTestCase {
void deleteTheDatabase() {mContext.deleteDatabase(DB_NAME)};
}
There are a few ways around this, you could use a mockcontext as one solution or if you really do not care what the context is just that is valid you can use an InstrumentationTestCase and get the context of the test apk via getInstrumentation().getContext().
I think the reason your context is null is that actually no android context exists at this point, you can get one by creating an application or an activity.
I need a class to get the artists, albums and tracks on the device, which I will then use JNI to call upon.
At the moment, in its barebones, the following causes a crash.
public class AndroidMediaLibray extends Activity {
public void getArtists() {
getContentResolver();
}
}
How do I get this to not crash?
The problem you have, is that you need to call getContentResolver() on a Context. If you call it in an Activity, you automatically call it on the Context of the Activity. But you (probably) never really start AndroidMediaLibrary. Please refer to the documentation of activities. If you want to have the DB call in an extra class, you may have a look at the following code. I have created a class with static methods. I just need to pass the context of my given Activity to that class. In your case that class might look like this:
public class AndroidMediaLibrary {
public static List<String> getArtists(Context context){
ArrayList<String> retVal = new ArrayList<String>();
ContentResolver resolver = context.getContentResolver();
// some more stuff here..
return retVal;
}
}
You may call that function from your MainActivity with:
List<String> myValues = DBUtils.someFunction(MainActivity.this);
Situation: I am trying to export my SQLite Tables to a XML file and have followed this answer as well as a post deleted from here and also this question (apparently both last links from the same author :) )
Update-2: I already have another class named DBAdapter which extends the SQLiteOpenHelper. So I have this:
public DBAdapter(Context ctx) {
this.context = ctx;
DBHelper = new DatabaseHelper(context);
}
private static class DatabaseHelper extends SQLiteOpenHelper {
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
/*...*/
onCreate()
/*...*/
onUpgrade()
/*...*/
}
already in my DBAdapter class file. How can I reuse this?
Also, I tried passing as:
DataXmlExporter dm = new DataXmlExporter(SQLiteDatabase
Database(getReadableDatabase ()));
But still got an error.
Update-1: I used the 2nd Link to implement my solution.
Problem: I am getting a Null Pointer Exception; I guess because I haven't initialized my object correctly. At the time of calling the DataXmlExporter / exportData method what is supplied as parameter? : DataXmlExporter dm = new DataXmlExporter(WHAT_IS_PASSED_HERE?);
Thanks..
looks like you need an SQLiteDatabase.
for example you can get one with getReadableDatabase() or with getWritableDatabase().
If you implemented DatabaseAssistant like in the first link you provided you have as constructor parameter a reference to a SQLiteDatabase....
You need to pass SQLiteDatabase Database ( getReadableDatabase () ):
As per constructor
public DataXmlExporter(final SQLiteDatabase db) {
this.db = db;
}
And as per comments:
Android DataExporter that allows the passed in SQLiteDatabase
to be exported to external storage (SD card) in an XML format
What I did was to extend the SQLiteOpenHelper inside the DatabaseAssistant class and used it.