I built an app. (The app can save favourite items using SQLite Database). I tried running it on Android Nougat and there is no error. When I tried running it on Android Marshmallow, the app won't open (Force close) and when I check the error it says unable to open database. After that, I tried running it on Android Lollipop and there is no error found.
I trace the error and found on the Marshmallow, the database is not created. (I used DB debugger to check the DB). I already add these user permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
and nothing happened. Anyone else knows about this??
**NEW EDIT
this is the syntax to check if the db already created or not
public DataHeper(Context context) {
// TODO Auto-generated constructor stub
this.mContext = context;
databasePath = "data/data/"+context.getPackageName()+"/databases/data.sqlite";
databaseFile = new File(databasePath);
if(!databaseFile.exists())
try {
deployDataBase(databaseName, databasePath);
} catch (IOException e) {
e.printStackTrace();
}
}
public int getTotalQuotesNoFilter(){
int i =0;
String query="";
Cursor cursor;
//This is the line that produce error (On Marshmallow only).
//I trace it and found out the db not created, thats why opendatabase produce error
database = SQLiteDatabase.openDatabase(databasePath, null, SQLiteDatabase.OPEN_READWRITE);
query = "SELECT count(quotes._id) FROM quotes;";
WriteLog.d("ThangTB", "query: "+query);
try {
cursor = database.rawQuery(query, null);
if (cursor != null){
boolean bool = cursor.moveToFirst();
int j = cursor.getInt(0);
i = j;
}
if (cursor!=null) {
cursor.close();
}
} catch (Exception e) {
// TODO: handle exception
}finally{
database.close();
}
return i;
}
SQLite Db needs no user permission. So I guess there is some other issue. Post your code.
From Android M onwards, permissions needs to obtained from User while he/she is using the app, solely mentioning in Manifest wont do.
It is super easy to implement it using this library.
https://github.com/googlesamples/easypermissions
From Marshmallow you need to request permission from user at run time, I also had the same problem check this link, it will help you.
https://www.androidhive.info/2016/11/android-working-marshmallow-m-runtime-permissions/
Related
Everyone.
I'm developing the android app that send the data what was stored in sqlite database to server now.
For storing the data to sqlite, I used the insertOrThrow().
What I wanna know is, if it happen the occur to fail to send the data, I'm afraid of the data is not exist. After sending the data, the android app shows the message "OK". In other words, there are no the record at server database.
I'll share my code.
public long insertSubmitRecord(int type, String data, String picPath, String vdoPath, String devicesId, String bugDesc) {
try {
ContentValues values = new ContentValues();
values.put(SQLHelper.DATA, data);
values.put(SQLHelper.TYPE, type);
values.put(SQLHelper.PIC_PATH, picPath);
values.put(SQLHelper.VDO_PATH, vdoPath);
values.put(SQLHelper.DEVICES_ID, devicesId);
values.put(SQLHelper.BUG_DESC, bugDesc);
values.put(SQLHelper.UPLOADERROR, 200);
values.put(SQLHelper.UPLOADERRORINFO, "");
return db.insertOrThrow(SQLHelper.TABLE_SUBMIT_RECORD, null, values);
} catch (SQLException e) {
e.printStackTrace();
Log.e("ERROR", "Failed to insert row into database");
return -1;
}
}
How come that is not stored? Attention: insertOrThrow().
Please help me.
I'm trying to connect to another database on an Android App, and can't seem to see if I've successfully init the secondary database.
How I'm instantiating the second one.
public void initFirebase() {
//init the default db;
FirebaseApp.initializeApp(this);
//init the second db;
FirebaseOptions.Builder builder = new FirebaseOptions.Builder();
builder.setApplicationId("id");
builder.setApiKey("key");
builder.setDatabaseUrl("https://second-db.firebaseio.com");
try {
FirebaseApp.initializeApp(this, builder.build(), "second-db");
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
Then I try to read something here.
public static DatabaseReference getSecondDbRef(String child) {
FirebaseApp app = FirebaseApp.getInstance("second-db");
return FirebaseDatabase.getInstance(app).getReference(child);
}
Then this fails with some: Listen at /child/child/child/teams failed: DatabaseError: Permission denied, though I've allowed access at this location and can confirm with the rules simulator that this node can be read.
Is there a way to have this log: Listen to second-db/child/child/child/teams failed ..., notice the prefix second-db.
Is it possible to change default sms application on Android 4.4 without user knowledge? I'm trying to do it on a ROOTED Galaxy S5 using reflection and invoking system methods, so here is what I done so far:
Created small app that implements all things needed for app to be a SMS manager (as per http://android-developers.blogspot.in/2013/10/getting-your-sms-apps-ready-for-kitkat.html) and I can make it default sms app but Android asks me to confirm that in dialog. Now I'm exploring android source code and I found something in this class:
https://github.com/android/platform_packages_apps_settings/blob/2abbacb7d46657e5863eb2ef0035521ffc41a0a8/src/com/android/settings/SmsDefaultDialog.java
So I'm trying to invoke internal method:
SmsApplication.setDefaultApplication(mNewSmsApplicationData.mPackageName, this);
via reflection and here is how I done it so far:
Class[] params = new Class[2];
params[0]=String.class;
params[1]=Context.class;
Class cls = null;
try {
cls = Class.forName("com.android.internal.telephony.SmsApplication");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Method method = null;
try {
method = cls.getDeclaredMethod("getSmsApplicationData", params);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
try {
Object[] params2 = new Object[2];
params2[0]=getPackageName();
params2[1]=getApplicationContext();
Log.d("Current package", getPackageName());
method.invoke(null, params2);
} catch (InvocationTargetException e) {
e.printStackTrace();
}
And I made this app system app and put it into folder /system/priv-app, rebooted phone and started it successfully with adb, but when I click on the button that executes code above, nothing happens. No errors, no log output, but default app is still Messaging (com.android.mms).
Is there any way to do this?
This information contained in file /data/system/users/0/settings_secure.xml. For example, default application for SMS stored by key sms_default_application.
<setting id="85" name="sms_default_application" value="com.google.android.talk" package="com.android.settings" />
More info you can find in this class: https://android.googlesource.com/platform/frameworks/base/+/master/core/java/android/provider/Settings.java#6067
Accordingly, if you have ROOT permissions, you can edit this file.
When I sign in on my application and try to get the size from the datastore's table, it is empty. But after I restart the application, it works as it should and gives back the size of the datastore's table.
In my case, there are two activities. The activity, and in-turn the fragment, SettingsFragment.java has the sign-in part. The activity MainActivity.java has the part with getting the datastore's table size.
SettingsFragment.java (Sign-in).
// Dropbox Signin
mAccountManager = DbxAccountManager.getInstance(getActivity().getApplicationContext(), APP_KEY, SECRET_KEY);
mDropBoxPreference = findPreference("preference_sync_dbx");
mDropBoxPreference.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
public boolean onPreferenceClick(Preference preference) {
if (mAccountManager.hasLinkedAccount()) {
mAccountManager.unlink();
} else {
mAccountManager.startLink(getActivity(), REQUEST_LINK_TO_DBX);
}
return true;
}
});
MainActivity.java (Get datastore size).
// Dropbox Get Datastore Size
mAccountManager = DbxAccountManager.getInstance(getApplicationContext(), APP_KEY, SECRET_KEY);
if (mAccountManager.hasLinkedAccount()) {
DbxAccount mDbxAccount = mAccountManager.getLinkedAccount();
try {
mDbxStore = DbxDatastore.openDefault(mDbxAccount);
mDbxNotesTable = mDbxStore.getTable("notes");
mDbxNotesCount = mDbxNotesTable.query().count();
Log.e("mDbxNotesCount", Integer.toString(mDbxNotesCount));
} catch (DbxException e) {
e.printStackTrace();
}
}
Let's say there are 3 records in the datastore.
After I sign in, this shows up from the Logcat.
E/mDbxNotesCount﹕ 0
Once I restart it, this shows up from the Logcat.
E/mDbxNotesCount﹕ 3
What's causing it to work like this?
Edit: Added listener after using smarx's answer, and it works! Here is what I did.
mDbxStore.addSyncStatusListener(new DbxDatastore.SyncStatusListener() {
#Override
public void onDatastoreStatusChange(DbxDatastore dbxDatastore) {
if (!dbxDatastore.getSyncStatus().isDownloading) {
try {
mDbxStore.sync();
mDbxNotesCount = mDbxNotesTable.query().count();
} catch (DbxException e) {
e.printStackTrace();
}
Log.e("mDbxNotesCount", Integer.toString(mDbxNotesCount));
}
}
});
It looks like you're trying to read the contents of the datastore before it's had a chance to sync. You'll need to wait until the initial sync is completed. I think one way to do that would be to add a listener via addSyncStatusListener and wait for store.getSyncStatus().isDownloading to be false.
But typically the pattern you'll want to follow is to always show the current information... so set up a listener and update your UI any time it changes. That way whether it's the initial sync bringing in new records or updates from a different device, your app will respond appropriately when the information changes.
This is my method in DBMethods class:
public void getResult(EditText keyWord2){
EditText keyWord = null;
String SQL ="localSearch.php?query="+keyWord.getText();
mDb.rawQuery(SQL, null);
}
And this is my method in which I am opening Database and all that in webServices class.
public void startSearch(View v){
keyWord = (EditText)findViewById(R.id.searchField);
String data = null;
DBMethods mDbHelper = new DBMethods(this);
mDbHelper.createDatabase();
mDbHelper.open();
mDbHelper.getResult(keyWord);
mDbHelper.close();
}
When I try to fetch data from the database by entering some keyword in the search bar, a force close error occurs.
EditText keyWord = null;
String SQL ="localSearch.php?query="+keyWord.getText();
Keyword is null, this will give null pointer exception.
I think your SQL variable must be
localSearch.php?query="+**keyWord2**.getText();
Make sure that you uninstall the already installed same application in your Emulator. Because once we Run our app that Sqlite DB installed in our Emulator and can't be edited. So uninstall your app and then Run again your app after changing .