IllegalArgumentException: Unknown URL content:// CONTENT - java

IllegalArgumentException: Unknown URL content://
^ Having a nightmare with the above. I've checked my variables and paths but can't see what the issue is? Greatly appreciate any pointers!
Here's my trace.
java.lang.IllegalArgumentException: Unknown URL
content://com.purewowstudio.topmovies.data.FilmProvider/film_data
at android.content.ContentResolver.insert(ContentResolver.java:1203)
at com.purewowstudio.topmovies.data.DatabaseHelper.addFilm(DatabaseHelper.java:52)
at com.purewowstudio.topmovies.fragments.FilmList$getFilms.onPostExecute(FilmList.java:72)
at com.purewowstudio.topmovies.fragments.FilmList$getFilms.onPostExecute(FilmList.java:62)
at android.os.AsyncTask.finish(AsyncTask.java:632)
at android.os.AsyncTask.access$600(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:645)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5262)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:693)
Content Provider
public class FilmProvider extends ContentProvider {
public static final String TABLE_NAME = "film_data";
public static final String AUTHORITY = "com.purewowstudio.topmovies.data.FilmProvider";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + TABLE_NAME);
public static final int FILMS = 1;
public static final int FILMS_ID = 2;
public static final UriMatcher sURIMatcher =
new UriMatcher(UriMatcher.NO_MATCH);
static {
sURIMatcher.addURI(AUTHORITY, TABLE_NAME, FILMS);
sURIMatcher.addURI(AUTHORITY, TABLE_NAME + "/#",
FILMS_ID);
}
private DatabaseHelper mDB;
public boolean onCreate() {
mDB = new DatabaseHelper(getContext(), null, null, 1);
return false;
}
#Override
public String getType(Uri uri) {
return null;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
queryBuilder.setTables(MovieDataContract.TABLE_NAME);
int uriType = sURIMatcher.match(uri);
switch (uriType) {
case FILMS_ID:
queryBuilder.appendWhere(MovieDataContract.FilmEntry._ID + "="
+ uri.getLastPathSegment());
break;
case FILMS:
break;
default:
throw new IllegalArgumentException("Unknown URI");
}
Cursor cursor = queryBuilder.query(mDB.getReadableDatabase(),
projection, selection, selectionArgs, null, null,
sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(),
uri);
return cursor;
}
#Override
public Uri insert(Uri uri, ContentValues values) {
int uriType = sURIMatcher.match(uri);
SQLiteDatabase sqlDB = mDB.getWritableDatabase();
long id = 0;
switch (uriType) {
case FILMS:
id = sqlDB.insert(MovieDataContract.TABLE_NAME,
null, values);
break;
default:
throw new IllegalArgumentException("Unknown URI: "
+ uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return Uri.parse(MovieDataContract.TABLE_NAME + "/" + id);
}
DatabaseHelper Class
public class DatabaseHelper extends SQLiteOpenHelper {
private ContentResolver myCR;
public DatabaseHelper(Context context, String name,
SQLiteDatabase.CursorFactory factory, int version) {
super(context, MovieDataContract.DATABASE_NAME, factory, MovieDataContract.DATABASE_VERSION);
myCR = context.getContentResolver();
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(MovieDataContract.FilmEntry.SQL_CREATE_TABLE);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(MovieDataContract.FilmEntry.DELETE_TABLE);
onCreate(db);
}
public void addFilm(Film film){
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(MovieDataContract.FilmEntry.COLUMN_FILM_TITLE, film.getTitle());
values.put(MovieDataContract.FilmEntry.COLUMN_FILM_RATING, film.getRating());
values.put(MovieDataContract.FilmEntry.COLUMN_FILM_RUNTIME, film.getRuntime());
values.put(MovieDataContract.FilmEntry.COLUMN_FILM_CRITICS, film.getCritics());
values.put(MovieDataContract.FilmEntry.COLUMN_FILM_AUDIENCE, film.getAudience());
values.put(MovieDataContract.FilmEntry.COLUMN_FILM_SYNOPSIS, film.getSynopsis());
values.put(MovieDataContract.FilmEntry.COLUMN_FILM_PROFILE, film.getProfile());
myCR.insert(FilmProvider.CONTENT_URI, values);
db.insert(MovieDataContract.TABLE_NAME,
null,
values);
db.close();
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/TopMoviesTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".DetailFragment"
android:label="#string/title_activity_detail_fragment"
android:parentActivityName=".MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value="com.purewowstudio.topmovies.MainActivity" />
<provider
android:name=".data.filmProvider"
android:authorities="com.purewowstudio.topmovies.data.filmProvider"
android:exported="true">
</provider>
</activity>
</application>
</manifest>

First, move <provider> to be a child of <application>, not <activity>.
Second, change android:exported="true" to android:exported="false", until such time as you secure your ContentProvider. As it stands, once you fix the <provider> element location as noted above, any app can read and write anything in your provider, which is unlikely to be what the user wants.

I have added package name in authorities.that's why I got this issue.I have to add Provider name in authorities.
<provider
android:name="LoginContentProvider"
android:authorities="com.provider.name.team"
android:exported="false" />

Related

Can't get Android ContentProvider to work

I am trying to put together a simple app to help me understand the content provider but I can't get it to work. I want to insert data into a database but I think the problem I have is somewhere with the URI.
** I am trying to follow a similar pattern as shown in the Udacity tutorials
Here is what I have
Android Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.simplecontentprovider">
<provider
android:authorities="com.example.android.simplecontentprovider.app"
android:name=".data.MyContentProvider" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
ContentProvider:
public class MyContentProvider extends ContentProvider {
MyDatabaseHelper mOpenHelper;
private static final int NAME = 1;
// Creates a UriMatcher object.
private static final UriMatcher sUriMatcher = buildUriMatcher();
static UriMatcher buildUriMatcher() {
final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
final String authority = MyDataContract.CONTENT_AUTHORITY; // Value = com.example.android.simplecontentprovider.app
matcher.addURI(authority, MyDataContract.PATH_TABLE, NAME); //PATH_TABLE = tblUserData
//matcher.addURI(authority, MyDataContract.PATH_TABLE + "/*", NAME);
return matcher;
}
#Override
public boolean onCreate() {
mOpenHelper = new MyDatabaseHelper(getContext());
return true;
}
#Override
public Cursor query(Uri uri, String[] strings, String s, String[] strings1, String s1) {
return null;
}
#Override
public String getType(Uri uri) {
int match = sUriMatcher.match(uri);
switch (match){
case NAME:
return MyDataContract.UserDetailsEntry.CONTENT_TYPE;
default:
throw new UnsupportedOperationException("UNKNOWN URI: " + uri);
}
}
#Override
public Uri insert(Uri uri, ContentValues contentValues) {
final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
final int match = sUriMatcher.match(uri);
Uri returnUri;
switch (match) {
case NAME: {
long _id = db.insert(MyDataContract.UserDetailsEntry.TABLE_NAME, null, contentValues);
if ( _id > 0 )
returnUri = MyDataContract.UserDetailsEntry.buildtblUserDetailsUri(_id);
else
throw new android.database.SQLException("Failed to insert row into " + uri);
break;
}
default:
throw new UnsupportedOperationException("Unknown uri: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return returnUri;
}
#Override
public int delete(Uri uri, String s, String[] strings) {
return 0;
}
#Override
public int update(Uri uri, ContentValues contentValues, String s, String[] strings) {
return 0;
}
}
and finally the MainActivity
ContentResolver resolver = getContentResolver();
Uri uri = MyDataContract.UserDetailsEntry.buildtblUserDetailsAll("MyTestName");
Log.e("RESOLVER URI: ", uri.toString());
ContentValues values = new ContentValues();
values.put(MyDataContract.UserDetailsEntry.COLUMN_NAME, "MyTestName");
try {
resolver.insert(uri, values);
}catch (Exception e){
Log.e("RESOLVER INSERT: ", e.toString());
}
When I run it through the debugger I get this message:
java.lang.IllegalArgumentException: Unknown URL content://com.example.android.simplecontentprovider.app/tblUserData/MyTestName
this is the default value for the insert in the content provider. I am not sure if I am missing the authority part
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.android.simplecontentprovider">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:authorities="com.example.android.simplecontentprovider.app"
android:name=".data.MyContentProvider" />
</application>
</manifest>

Class or interface expected - Provider name

I'm trying to declare my content provider class in the manifest but it shows me an error when I type the name of the fully qualified name of the provider class:
The error is Class or Interface expected, what does that mean?
the error was at this line: android:name="com.sns.awesomecharactercreator.CharacterProvider" There is a red line underit and when I hover over it says class or interface expected
Here is the code:
<?xml version="1.0" encoding="utf-8"?>
<!--suppress ALL -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.sns.awesomecharactercreator" >
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".Welcome"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".EditingCharacter"
android:label="#string/title_activity_general_characteristics"
android:parentActivityName=".Notes" >
</activity>
<provider
android:authorities="com.sns.awesomecharactercreator.characterprovider"
android:name="com.sns.awesomecharactercreator.CharacterProvider"
android:exported="false" />
</application>
CharacterProvider class:
package com.sns.awesomecharactercreator;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import DATALAYER.DBHelper;
public class CharacterProvider extends android.content.ContentProvider {
private final static String AUTHORITY = "com.sns.awesomecharactercreator.characterprovider";
private final static String BASE_PATH = "characterattributes";
public final static Uri CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);
private static final int CHARACTERS = 1;
private static final int CHARACTERS_ID = 2;
private static final UriMatcher uriMatcher =
new UriMatcher(UriMatcher.NO_MATCH);
static {
uriMatcher.addURI(AUTHORITY, BASE_PATH, CHARACTERS);
uriMatcher.addURI(AUTHORITY, BASE_PATH + "/#", CHARACTERS_ID);
}
private static final String[] allColumns = {
DBHelper.CHARACTERATTRIBUTES_ID,
DBHelper.CHARACTERATTRIBUTES_NAME,
DBHelper.CHARACTERATTRIBUTES_MEANING,
DBHelper.CHARACTERATTRIBUTES_NICKNAME,
DBHelper.CHARACTERATTRIBUTES_RELIGION,
DBHelper.CHARACTERATTRIBUTES_BIRTHDATE,
DBHelper.CHARACTERATTRIBUTES_BIRTHPLACE,
DBHelper.CHARACTERATTRIBUTES_SIGN,
DBHelper.CHARACTERATTRIBUTES_TALENTS,
DBHelper.CHARACTERATTRIBUTES_MAINSEC,
DBHelper.CHARACTERATTRIBUTES_WEAPONS,
DBHelper.CHARACTERATTRIBUTES_CLASSS,
DBHelper.CHARACTERATTRIBUTES_STRENGTHS,
DBHelper.CHARACTERATTRIBUTES_WEAKNESSES,
DBHelper.CHARACTERATTRIBUTES_ROLE,
DBHelper.CHARACTERATTRIBUTES_VOICE,
DBHelper.CHARACTERATTRIBUTES_SECRETS,
DBHelper.CHARACTERATTRIBUTES_PROFESSION,
DBHelper.CHARACTERATTRIBUTES_QUOTE,
DBHelper.CHARACTERATTRIBUTES_AGE,
DBHelper.CHARACTERATTRIBUTES_BODYTYPE,
DBHelper.CHARACTERATTRIBUTES_HEIGHT,
DBHelper.CHARACTERATTRIBUTES_WEIGHT,
DBHelper.CHARACTERATTRIBUTES_FACESHAPE,
DBHelper.CHARACTERATTRIBUTES_EYECOLOR,
DBHelper.CHARACTERATTRIBUTES_HAIRCOLOR,
DBHelper.CHARACTERATTRIBUTES_HAIRSTYLE,
DBHelper.CHARACTERATTRIBUTES_SPECIALFEATURES,
DBHelper.CHARACTERATTRIBUTES_HEALTH,
DBHelper.CHARACTERATTRIBUTES_DISABILITIES,
DBHelper.CHARACTERATTRIBUTES_SKINTONE,
DBHelper.CHARACTERATTRIBUTES_ACCESORIES,
DBHelper.CHARACTERATTRIBUTES_CLOTHES,
DBHelper.CHARACTERATTRIBUTES_ALOOKALIKE,
DBHelper.CHARACTERATTRIBUTES_ETHNICITY,
DBHelper.CHARACTERATTRIBUTES_IQLEVEL,
DBHelper.CHARACTERATTRIBUTES_EDUCATION,
DBHelper.CHARACTERATTRIBUTES_DOMINANTMOOD,
DBHelper.CHARACTERATTRIBUTES_MORALCODES,
DBHelper.CHARACTERATTRIBUTES_DESIRES,
DBHelper.CHARACTERATTRIBUTES_DISLIKES,
DBHelper.CHARACTERATTRIBUTES_ATTITUDES,
DBHelper.CHARACTERATTRIBUTES_EMOTIONHANDLING,
DBHelper.CHARACTERATTRIBUTES_QUALITIES,
DBHelper.CHARACTERATTRIBUTES_FLAWS,
DBHelper.CHARACTERATTRIBUTES_GOALS,
DBHelper.CHARACTERATTRIBUTES_POPULARITY,
DBHelper.CHARACTERATTRIBUTES_REPUTATION,
DBHelper.CHARACTERATTRIBUTES_CHARISMA,
DBHelper.CHARACTERATTRIBUTES_RELATIVES,
DBHelper.CHARACTERATTRIBUTES_COMPANIONS,
DBHelper.CHARACTERATTRIBUTES_LOVELIFE,
DBHelper.CHARACTERATTRIBUTES_NOTES};
private SQLiteDatabase db;
#Override
public boolean onCreate() {
DBHelper helper = new DBHelper(getContext());
db = helper.getWritableDatabase();
return true;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
return db.query(DBHelper.TABLE_CHARACTERATTRIBUTES, allColumns, selection, null, null, null, null);
}
#Override
public String getType(Uri uri) {
return null;
}
#Override
public Uri insert(Uri uri, ContentValues values) {
long id = db.insert(DBHelper.TABLE_CHARACTERATTRIBUTES, null, values);
return Uri.parse(BASE_PATH + "/#" + id);
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
return db.delete(DBHelper.TABLE_CHARACTERATTRIBUTES, selection, selectionArgs);
}
#Override`enter code here`
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
return db.update(DBHelper.TABLE_CHARACTERATTRIBUTES,values,selection,selectionArgs);
}
}
Could someone be a dear and help me here? I'm stuck for like forever and I'm nearly ripping my hair off.

android: saving json to sqlite

i'm a new bie in android and java i want to save a table from sql server(external database) to sqlite(internal database).
1. my json is not getting stored and every record is same like this "com.example.db_client.DeptTable#b3e4e9e0" when i opens the db file in sqlite browser. I don't understand what is this.
when i run my app i sometimes get this exception and sometimes i don't.
FATAL EXCEPTION: main
Process: com.example.db_client, PID: 1697
java.lang.IllegalArgumentException: Activity DeptActivity does not have a parent activity name specified. (Did you forget to add the android.support.PARENT_ACTIVITY element in your manifest?)
I really need help please look into my problem. thanks in advance.
code of database helper class
public class SqliteDB {
public static final String KEY_ID = "no";
public static final String KEY_NAME = "name";
private static final String TAG = "DBAdapter";
private static final String DATABASE_NAME = "SQLiteDB";
private static final String TABLE_NAME = "Department";
private static final int DATABASE_VERSION = 2;
private static final String CREATE_TABLE =
"create table departmentList (id INTEGER PRIMARY KEY, name TEXT);";
private final Context context;
private DatabaseHelper DBHelper;
private SQLiteDatabase db;
public SqliteDB(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);
}
#Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(CREATE_TABLE);
} catch (SQLException e) {
e.printStackTrace();
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data");
db.execSQL("DROP TABLE IF EXISTS sample");
onCreate(db);
}
}
//---open SQLite DB---
public SqliteDB open() throws SQLException {
db = DBHelper.getWritableDatabase();
return this;
}
//---close SQLite DB---
public void close() {
DBHelper.close();
}
//---insert data into SQLite DB---
public long insert(String name) {
ContentValues initialValues = new ContentValues();
initialValues.put(KEY_NAME, name);
return db.insert(TABLE_NAME, null, initialValues);
}
//---Delete All Data from table in SQLite DB---
public void deleteAll() {
db.delete(TABLE_NAME, null, null);
}
//---Get All Contacts from table in SQLite DB---
public Cursor getAllData() {
return db.query(TABLE_NAME, new String[] {KEY_NAME},
null, null, null, null, null);
}
}
code of activity class
public class DeptActivity extends Activity{
ArrayAdapter<String> adapter;
ListView listv;
Context context;
ArrayList<String> data;
SqliteDB sqlite;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dept);
sqlite = new SqliteDB(DeptActivity.this);
setupActionBar();
data = new ArrayList<String>();
listv = (ListView) findViewById(R.id.lv_dept);
context = this;
adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, data);
listv.setAdapter(adapter);
Toast.makeText(this,"Loading Please Wait..",Toast.LENGTH_SHORT).show();
new AsyncLoadDeptDetails().execute();
}
public class AsyncLoadDeptDetails extends
AsyncTask<Void, JSONObject, ArrayList<DeptTable>> {
ArrayList<DeptTable> deptTable = null;
#Override
public ArrayList<DeptTable> doInBackground(Void... params) {
// TODO Auto-generated method stub
RestAPI api = new RestAPI();
try {
JSONObject jsonObj = api.GetDepartmentDetails();
JSONParser parser = new JSONParser();
Log.i( "department list", jsonObj.toString());
deptTable = parser.parseDepartment(jsonObj);
sqlite();
} catch (Exception e) {
}
return deptTable;
}
private void sqlite() {
// TODO Auto-generated method stub
sqlite.open();
for(int i=0; i<deptTable.size(); i++) {
sqlite.insert(deptTable.get(i).toString());
}
sqlite.close();
}
#Override
protected void onPostExecute(ArrayList<DeptTable> result) {
// TODO Auto-generated method stub
for (int i = 0; i < result.size(); i++) {
data.add(result.get(i).getNo() + " " + result.get(i).getName());
}
adapter.notifyDataSetChanged();
Toast.makeText(context,"Loading Completed",Toast.LENGTH_SHORT).show();
} }
and the table which i want to save in sqlite db looks like this.
no. name
1 engineering
2 finance
3 commerce
public class DeptTable {
int no;
String name;
public DeptTable(int no, String name) {
super();
this.no = no;
this.name = name;
}
code of deptTable Class
public DeptTable() {
super();
this.no=0;
this.name = null;
}
public int getNo() {
return no;
}
public void setNo(int no) {
this.no = no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
code of json parser class
public class JSONParser {
public JSONParser()
{
super();
}
public ArrayList<DeptTable> parseDepartment(JSONObject object)
{
ArrayList<DeptTable> arrayList=new ArrayList<DeptTable>();
try {
JSONArray jsonArray=object.getJSONArray("Value");
JSONObject jsonObj=null;
for(int i=0;i<jsonArray.length();i++)
{
jsonObj =jsonArray.getJSONObject(i);
arrayList.add(new DeptTable(jsonObj.getInt("no"), jsonObj.getString("name")));
}
} catch (JSONException e) {
// TODO Auto-generated catch block
Log.d("JSONParser => parseDepartment", e.getMessage());
}
return arrayList;
}
public boolean parseUserAuth(JSONObject object)
{ boolean userAtuh=false;
try {
userAtuh = object.getBoolean("Value");
} catch (JSONException e) {
// TODO Auto-generated catch block
Log.d("JSONParser => parseUserAuth", e.getMessage());
}
return userAtuh; }
code of manifest
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.db_client.DeptActivity"
android:label="#string/app_name" >
</activity>
</application>
</manifest>
enter code here
If you want to use the toString method the class has to implement the toString method otherwise it will just return the default for object with you find out is not so useful. (This "com.example.db_client.DeptTable#b3e4e9e0"). To implement it just type do like this.
#Override
public String toString() {
//What you want to return here.
}
But I'm guessing you want to add some value to the database so you want to call the getter method of your class like this.
private void sqlite() {
sqlite.open();
for(int i=0; i<deptTable.size(); i++) {
sqlite.insert(deptTable.get(i).getName());
}
sqlite.close();
}
You need to add the android:parentActivityName field to DeptActivity like this.
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.db_client.DeptActivity"
android:label="#string/app_name"
android:parentActivityName=".MainActivity">
</activity>
</application>
</manifest>

Unfortunately, Organitza't (my app) has stopped

I am getting error message when I start another activity named Task. The application have 4 image buttons (the other buttons image open correctly. When I click "TaskViewer"(ImageButton2) appears the error.
The activity that attempts to open: (ViewTask)
public class ViewTask extends Activity {
protected TaskerDbHelper db;
List<Task> list;
MyAdapter adapt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_task);
db = new TaskerDbHelper(this);
list = db.getAllTasks();
adapt = new MyAdapter(this, R.layout.list_inner_view, list);
ListView listTask = (ListView) findViewById(R.id.listView1);
listTask.setAdapter(adapt);
}
public void addTaskNow(View v) {
EditText t = (EditText) findViewById(R.id.editText1);
String s = t.getText().toString();
if (s.equalsIgnoreCase("")) {
Toast.makeText(this, "enter the task description first!!",
Toast.LENGTH_LONG);
} else {
Task task = new Task(s, 0);
db.addTask(task);
Log.d("tasker", "data added");
t.setText("");
adapt.add(task);
adapt.notifyDataSetChanged();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_view_task, menu);
return true;
}
private class MyAdapter extends ArrayAdapter<Task> {
Context context;
List<Task> taskList = new ArrayList<Task>();
int layoutResourceId;
public MyAdapter(Context context, int layoutResourceId,
List<Task> objects) {
super(context, layoutResourceId, objects);
this.layoutResourceId = layoutResourceId;
this.taskList = objects;
this.context = context;
}
/**
* This method will DEFINe what the view inside the list view will
* finally look like Here we are going to code that the checkbox state
* is the status of task and check box text is the task name
*/
#Override
public View getView(int position, View convertView, ViewGroup parent) {
CheckBox chk = null;
if (convertView == null) {
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = inflater.inflate(R.layout.list_inner_view,
parent, false);
chk = (CheckBox) convertView.findViewById(R.id.chkStatus);
convertView.setTag(chk);
chk.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
CheckBox cb = (CheckBox) v;
Task changeTask = (Task) cb.getTag();
changeTask.setStatus(cb.isChecked() == true ? 1 : 0);
db.updateTask(changeTask);
Toast.makeText(
getApplicationContext(),
"Clicked on Checkbox: " + cb.getText() + " is "
+ cb.isChecked(), Toast.LENGTH_LONG)
.show();
}
});
} else {
chk = (CheckBox) convertView.getTag();
}
Task current = taskList.get(position);
chk.setText(current.getTaskName());
chk.setChecked(current.getStatus() == 1 ? true : false);
chk.setTag(current);
Log.d("listener", String.valueOf(current.getId()));
return convertView;
}
}
}
The main activity:
public class MainActivity extends Activity {
private Context activity;
#Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
entrarboton();
}
private void entrarboton() {
ImageButton accionentrar = (ImageButton) findViewById(R.id.imageButton0);
accionentrar.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("com.android.calendar");
startActivity(LaunchIntent);
}
});
ImageButton accionentrar2 = (ImageButton) findViewById(R.id.imageButton3);
accionentrar2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this,Notes.class));
}
});
ImageButton accionentrar3 = (ImageButton) findViewById(R.id.imageButton2);
accionentrar3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this,ViewTask.class));
}
});
ImageButton accionentrar4 = (ImageButton) findViewById(R.id.imageButton4);
accionentrar4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
startActivity(new Intent(MainActivity.this,Altres.class));
}
});
AutoCompleteTextView auto = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
String[] noms = getResources() . getStringArray(R.array.noms_array);
ArrayAdapter<String> adapter;
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, noms);
auto.setThreshold(1);
auto.setAdapter(adapter);
}
}
Android Manifest:
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.dppalvaplicacio.app.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.dppalvaplicacio.app.Calendari"
android:label="#string/title_activity_calendari" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.dppalvaplicacio.app.Notes"
android:label="#string/title_activity_notes" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.dppalvaplicacio.app.ViewTask"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity
android:name="com.dppalvaplicacio.app.Altres"
android:label="#string/title_activity_altres" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
Logcat
Caused by: java.lang.IllegalStateException: attempt to re-open an already-closed object: SQLiteDatabase: /data/data/com.dppalvaplicacio.app/databases/taskerManager
at android.database.sqlite.SQLiteClosable.acquireReference(SQLiteClosable.java:55)
at android.database.sqlite.SQLiteDatabase.endTransaction(SQLiteDatabase.java:520)
at android.database.sqlite.SQLiteOpenHelper.getDatabaseLocked(SQLiteOpenHelper.java:263)
at android.database.sqlite.SQLiteOpenHelper.getWritableDatabase(SQLiteOpenHelper.java:164)
at com.dppalvaplicacio.app.TaskerDbHelper.getAllTasks(TaskerDbHelper.java:70)
at com.dppalvaplicacio.app.ViewTask.onCreate(ViewTask.java:33)
at android.app.Activity.performCreate(Activity.java:5008)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2023)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2084)
at android.app.ActivityThread.access$600(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1195)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
TaskDbHelper
public class TaskerDbHelper extends SQLiteOpenHelper {
private static final int DATABASE_VERSION = 1;
// Database Name
private static final String DATABASE_NAME = "taskerManager";
// tasks table name
private static final String TABLE_TASKS = "tasks";
// tasks Table Columns names
private static final String KEY_ID = "id";
private static final String KEY_TASKNAME = "taskName";
private static final String KEY_STATUS = "status";
public TaskerDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_TASKS + " ( "
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_TASKNAME
+ " TEXT, " + KEY_STATUS + " INTEGER)";
db.execSQL(sql);
db.close();
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldV, int newV) {
// Drop older table if existed
db.execSQL("DROP TABLE IF EXISTS " + TABLE_TASKS);
// Create tables again
onCreate(db);
}
// Adding new task
public void addTask(Task task) {
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_TASKNAME, task.getTaskName()); // task name
// status of task- can be 0 for not done and 1 for done
values.put(KEY_STATUS, task.getStatus());
// Inserting Row
db.insert(TABLE_TASKS, null, values);
db.close(); // Closing database connection
}
public List<Task> getAllTasks() {
List<Task> taskList = new ArrayList<Task>();
// Select All Query
String selectQuery = "SELECT * FROM " + TABLE_TASKS;
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(selectQuery, null);
// looping through all rows and adding to list
if (cursor.moveToFirst()) {
do {
Task task = new Task();
task.setId(cursor.getInt(0));
task.setTaskName(cursor.getString(1));
task.setStatus(cursor.getInt(2));
// Adding contact to list
taskList.add(task);
} while (cursor.moveToNext());
}
// return task list
return taskList;
}
public void updateTask(Task task) {
// updating row
SQLiteDatabase db = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_TASKNAME, task.getTaskName());
values.put(KEY_STATUS, task.getStatus());
db.update(TABLE_TASKS, values, KEY_ID + " = ?",new String[] {String.valueOf(task.getId())});
db.close();
}
}
The problem is in your TaskDBHelper class, and more specifically the onCreate method. This method is called automatically when you try to do work on the database, but the database is not created yet. So it first calls the onCreate method and then the method, that does work on it, in your case - getAllTasks. The problem is that you are closing your db in the onCreate method, preventing any further operations on the database within this class instance. Your method should look like this:
public void onCreate(SQLiteDatabase db) {
String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_TASKS + " ( "
+ KEY_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + KEY_TASKNAME
+ " TEXT, " + KEY_STATUS + " INTEGER)";
db.execSQL(sql);
}

Getting a ClassNotFoundException when creating a custom ContentProvider

I'm creating an Android app in Android Studio which implements a custom ContentProvider. For some reason, whenever I go to compile the app and test it out on an emulator, I'm getting this error message:
11-17 21:12:29.918 1381-1381/com.aiorsoft.encryptic E/AndroidRuntime﹕ FATAL EXCEPTION: main
java.lang.RuntimeException: Unable to get provider com.aiorsoft.encryptic.providers.AccountProvider: java.lang.ClassNotFoundException: Didn't find class "com.aiorsoft.encryptic.providers.AccountProvider" on path: DexPathList[[zip file "/data/app/com.aiorsoft.encryptic-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.aiorsoft.encryptic-2, /system/lib]]
at android.app.ActivityThread.installProvider(ActivityThread.java:4882)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:4485)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4425)
at android.app.ActivityThread.access$1300(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.aiorsoft.encryptic.providers.AccountProvider" on path: DexPathList[[zip file "/data/app/com.aiorsoft.encryptic-2.apk"],nativeLibraryDirectories=[/data/app-lib/com.aiorsoft.encryptic-2, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:53)
at java.lang.ClassLoader.loadClass(ClassLoader.java:501)
at java.lang.ClassLoader.loadClass(ClassLoader.java:461)
at android.app.ActivityThread.installProvider(ActivityThread.java:4867)
            at android.app.ActivityThread.installContentProviders(ActivityThread.java:4485)
            at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4425)
            at android.app.ActivityThread.access$1300(ActivityThread.java:141)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1316)
            at android.os.Handler.dispatchMessage(Handler.java:99)
            at android.os.Looper.loop(Looper.java:137)
            at android.app.ActivityThread.main(ActivityThread.java:5103)
            at java.lang.reflect.Method.invokeNative(Native Method)
            at java.lang.reflect.Method.invoke(Method.java:525)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
            at dalvik.system.NativeStart.main(Native Method)
I've done a bit of background research into this, but have yet to come across a solution to my problem. I'm not using ProGuard in this project, so that rules out anything not being kept by that service. Can anyone help me out with this issue? I may be missing something that's obvious and staring me right in the face, but I can't find it. Thank you for any help! I've included the relevant files below.
Here's my manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.aiorsoft.encryptic"
android:installLocation="preferExternal"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/title_app_name"
android:theme="#style/Theme.Encryptic">
<activity android:name=".activities.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".services.ConnectionService"
android:exported="false" />
<provider
android:name=".providers.AccountProvider"
android:authorities=".providers" />
</application>
</manifest>
And the provider itself:
package com.aiorsoft.encryptic.providers;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.provider.BaseColumns;
import android.text.TextUtils;
public class AccountProvider extends ContentProvider {
private static final String AUTHORITY = "com.aiorsoft.encryptic.providers";
private static final String DATABASE_NAME = "accounts";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + DATABASE_NAME);
private static final int DATABASE_VERSION = 1;
private static final String TABLE_ACCOUNTS = "Account";
private static final int ACCOUNTS_ALL = 1;
private static final int ACCOUNTS_SINGLE = 2;
private interface AccountColumns extends BaseColumns {
public static final String _ID = BaseColumns._ID;
public static final String USERNAME = "username";
public static final String EMAIL = "email";
public static final String TOKEN = "token";
}
private static final String[] ALL_COLUMNS = new String[] {
AccountColumns._ID, AccountColumns.USERNAME, AccountColumns.EMAIL, AccountColumns.TOKEN
};
private static final String CREATE_SQL = "CREATE TABLE "
+ TABLE_ACCOUNTS + " ("
+ AccountColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ AccountColumns.USERNAME + " TEXT NOT NULL, "
+ AccountColumns.EMAIL + " TEXT, "
+ AccountColumns.TOKEN + " TEXT);";
private static final String USERNAME_INDEX_SQL = "CREATE INDEX "
+ AccountColumns.USERNAME + "_idx ON " + TABLE_ACCOUNTS + " ("
+ AccountColumns.USERNAME + " ASC);";
private static UriMatcher uriMatcher;
private DatabaseHelper dbHelper;
static {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(AUTHORITY, DATABASE_NAME, ACCOUNTS_ALL);
uriMatcher.addURI(AUTHORITY, DATABASE_NAME + "/#", ACCOUNTS_SINGLE);
}
#Override
public boolean onCreate() {
dbHelper = new DatabaseHelper(getContext());
return true;
}
#Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case ACCOUNTS_ALL:
return "vnd.android.cursor.dir/vnd." + AUTHORITY + "." + DATABASE_NAME;
case ACCOUNTS_SINGLE:
return "vdn.android.cursor.item/vnd." + AUTHORITY + "." + DATABASE_NAME;
default:
return null;
}
}
#Override
public Uri insert(Uri uri, ContentValues values) {
Uri result = doInsert(uri, values, dbHelper.getWritableDatabase());
return result;
}
#Override
public int bulkInsert(Uri uri, ContentValues[] values) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int count = 0;
try {
db.beginTransaction();
for (ContentValues value : values) {
Uri resultUri = doInsert(uri, value, db);
if (resultUri != null) {
count++;
} else {
count = 0;
throw new SQLException("Error in bulk insert");
}
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
db.close();
return count;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
String sortOrder) {
SQLiteDatabase db = dbHelper.getReadableDatabase();
Cursor query;
// Fix the projection
if (projection == null) {
projection = ALL_COLUMNS;
}
// Fix sort order
if (sortOrder == null) {
sortOrder = AccountColumns._ID;
}
switch (uriMatcher.match(uri)) {
case ACCOUNTS_ALL:
query = db.query(TABLE_ACCOUNTS, projection, selection, selectionArgs, null, null, sortOrder);
db.close();
return query;
case ACCOUNTS_SINGLE:
String accountId = uri.getLastPathSegment();
selection = fixSelectionString(selection);
selectionArgs = fixSelectionArgs(selectionArgs, accountId);
query = db.query(TABLE_ACCOUNTS, projection, selection, selectionArgs, null, null, sortOrder);
db.close();
return query;
default:
throw new IllegalArgumentException("Invalid uri: " + uri);
}
}
#Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
getContext().getContentResolver().notifyChange(uri, null);
SQLiteDatabase db = dbHelper.getWritableDatabase();
int rowsAffected;
switch (uriMatcher.match(uri)) {
case ACCOUNTS_ALL:
rowsAffected = db.update(TABLE_ACCOUNTS, values, selection, selectionArgs);
break;
case ACCOUNTS_SINGLE:
String accountId = uri.getLastPathSegment();
selection = fixSelectionString(selection);
selectionArgs = fixSelectionArgs(selectionArgs, accountId);
rowsAffected = db.update(TABLE_ACCOUNTS, values, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Illegal URI: " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return rowsAffected;
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
int rowsAffected;
switch (uriMatcher.match(uri)) {
case ACCOUNTS_ALL:
rowsAffected = db.delete(TABLE_ACCOUNTS, selection, selectionArgs);
break;
case ACCOUNTS_SINGLE:
String accountId = uri.getLastPathSegment();
selection = fixSelectionString(selection);
selectionArgs = fixSelectionArgs(selectionArgs, accountId);
rowsAffected = db.delete(TABLE_ACCOUNTS, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Illegal URI: " + uri);
}
return rowsAffected;
}
private String[] fixSelectionArgs(String[] selectionArgs, String accountId) {
String[] newSelectionArgs;
if (selectionArgs == null) {
newSelectionArgs = new String[] {accountId};
} else {
newSelectionArgs = new String[selectionArgs.length + 1];
newSelectionArgs[0] = accountId;
System.arraycopy(selectionArgs, 0, newSelectionArgs, 1, selectionArgs.length);
}
return newSelectionArgs;
}
private String fixSelectionString(String selection) {
if (selection == null) {
selection = AccountColumns._ID + " = ?";
} else {
selection = AccountColumns._ID + " = ? AND (" + selection + ")";
}
return selection;
}
private Uri doInsert(Uri uri, ContentValues values, SQLiteDatabase db) {
Uri result = null;
switch (uriMatcher.match(uri)) {
case ACCOUNTS_ALL:
long id = db.insert(TABLE_ACCOUNTS, "", values);
if (id == -1) {
throw new SQLException("Error inserting data");
}
result = Uri.withAppendedPath(uri, String.valueOf(id));
break;
}
db.close();
return result;
}
public class DatabaseHelper extends SQLiteOpenHelper {
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
#Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_SQL);
db.execSQL(USERNAME_INDEX_SQL);
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
}
Well this was stupid... Apparently, in the Android Studio settings, the SDK that I was using wasn't being found, so I had to fix that. Everything works now!

Categories