I'm new to android programming. I tried to update a task in my database with the ContentResolver. But instead of updating and/or showing the toast message, the app seems to process for a while (screen is white for a few seconds) and the item remains the same.
Other operations on ContentResolver works (e.g. inserting)
I tried to debug, but I can't find an error in the debugging window. Obviously all values and Uri seems to be correct... Error must be in following line:
int rowsAffected = getContentResolver().update(mCurrentTaskUri, values, null, null);
if (rowsAffected == 0) {
Toast.makeText(this, getString(R.string.aufgabe_bearbeiten_fehlgeschlagen), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, getString(R.string.aufgabe_bearbeiten_erfolgreich), Toast.LENGTH_SHORT).show();
}
Related
I know similar question has been asked before,
my code was working before, and now it does not, my app is the default dialer and is also a system app,
the canCurrentUserBlockNumbers(this) returns true, however always an empty cursor is returned now,
any suggestion?
Thank you
if (canCurrentUserBlockNumbers(this))
Toast.makeText(this, "ok", Toast.LENGTH_SHORT).show(); // I see this "OK" Toast
else
Toast.makeText(this, "KO", Toast.LENGTH_SHORT).show();
Cursor c = getContentResolver().query(BlockedNumberContract.BlockedNumbers.CONTENT_URI,
new String[]{BlockedNumberContract.BlockedNumbers.COLUMN_ID, BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER,
BlockedNumberContract.BlockedNumbers.COLUMN_E164_NUMBER}, null, null, null);
TextView tv = findViewById(R.id.textviewblockednumbers);
tv.setText("ciao");
//int numElements=(c.getColumnCount();
while (c.moveToNext()) {
String name = c.getString(c.getColumnIndexOrThrow(BlockedNumberContract.BlockedNumbers.COLUMN_ORIGINAL_NUMBER));
tv.append(name);
tv.append(",");
c.close();
}
}
update for everyone interested,
with another phone of the same brand (Xiaomi) the cursor is not empty and I can read blocked numbers,
looks like a platform trouble
I use below code to clear missed calls after I launch my app. In this I get rows affeted is 1. But when i get next missed call, at that time android's stock phone app adds a new notification as "2 new missed calls". Means they are not counting my clear. Am I missing something.
Note: If i launch the stock phone app once, the counter is reset to 0 again.
public boolean markMissedCallsAsRead() {
ContentValues values = new ContentValues();
values.put(CallLog.Calls.NEW, Integer.valueOf(0));
values.put(CallLog.Calls.IS_READ, Integer.valueOf(1));
StringBuilder where = new StringBuilder();
where.append(CallLog.Calls.NEW);
where.append(" = 1 AND ");
//where.append(CallLog.Calls.IS_READ).append(" = 0");
//where.append(" AND ");
where.append(CallLog.Calls.TYPE).append(" = ").append(CallLog.Calls.MISSED_TYPE);
int rows = context.getContentResolver().update(CallLog.Calls.CONTENT_URI, values, where.toString(),
null);
Utilities.writeToLogFile(Constants.LOG_ERROR_LEVEL, "cleared call logs " + rows);
return true;
}
I'm facing the same problem. There is a similar question here:
https://stackoverflow.com/a/26564121/6433463
I'm starting to think (as stated in that thread) that the only way to achieve that is by opening the stock call log (I hope I'm wrong, but couldn't find anything else).
I am writing an app that takes two user inputs and matches them to data stored in a database and displays the corresponding data(row) from the user inputs in a textview.
The if statement works perfectly alone if d condition is true. It however stops working if I add the else statement.
The else statement is executed if d statement is true or false
String name = Jasonobject.getString("name");
String name1 = Jasonobject.getString("name1");
String db_detail = "";
// match user input with database and display corresponding row in
// "detail" textfield
if (et.getText().toString().equalsIgnoreCase(name)
&& et1.getText().toString().equalsIgnoreCase(name1)) {
db_detail = Jasonobject.getString("detail");
text.setText(db_detail);
break;
} else {
Context context = getApplicationContext();
CharSequence text = "NOT AVAILABLE";
int duration = Toast.LENGTH_LONG;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
break;
}
The else statement cannot run if the if statement is true at any cost.
Try to clean your project and re-compile it. Also are you executing this code in an loop, if not then you should get a misplace break error.
i am trying to retrieve alarm information from content provider using following code
final String tag_alarm = "tag_alarm";
Uri uri = Uri.parse("content://com.android.deskclock/alarm")
Cursor c = getContentResolver().query(uri, null, null, null, null);
Log.i(tag_alarm, "no of records are" + c.getCount());
Log.i(tag_alarm, "no of columns are" + c.getColumnCount());
if (c != null) {
String names[] = c.getColumnNames();
for (String temp : names) {
System.out.println(temp);
}
if (c.moveToFirst()) {
do {
for (int j = 0; j < c.getColumnCount(); j++) {
Log.i(tag_alarm, c.getColumnName(j);
+ " which has value " + c.getString(j));
}
} while (c.moveToNext());
}
}
it is giving me error permission denial i copied this code from curious answer from query Get alarm infomation
in the Nguyen's comment he pointed a solution "If i embed this code in Android source code and run image file, it can pass "permission denied" error and retrieve alarm information. Anyway, thanks your tip :) " how to embed a code in android source code and run image file ?? please explain i always create a project in eclipse and then code and run it as run application.please explain this trick
In my opinion, because of each manufacturer had implemented their own Clock App,
So default AlarmClockApp of Android will be replaced depend on each manufacturer, that makes your code can not be run successful if Android Os had been modified by Manufacturers.
So I think we can not handle all the devices in this case, instead of that, we should handler it by manufacturer of devices.
With Samsung devices, it's ClockPackage and in androidManifest :
<provider
android:name=".alarm.AlarmProvider"
android:authorities="com.samsung.sec.android.clockpackage"
android:exported="true"
android:readPermission="com.sec.android.app.clockpackage.permission.READ_ALARM"
android:writePermission="com.sec.android.app.clockpackage.permission.WRITE_ALARM" >
</provider>
So we can read data of alarm in Samsung devices by :
add permission in manifest:
<uses-permission android:name="com.sec.android.app.clockpackage.permission.READ_ALARM" />
then get Uri by below :
Uri uri = Uri.parse("content://com.samsung.sec.android.clockpackage/alarm");
Use Uri :
Cursor c = getContentResolver().query(uri, null, null, null, null);
if (c == null) { // that mean devices is not belong to Samsung manufacturer,
// we should use an other uri (don't for get to add permission)
AlarmLog.w("Can not read cursor");
}
AlarmLog.i(tag_alarm, "no of records are " + c.getCount());
AlarmLog.i(tag_alarm, "no of columns are " + c.getColumnCount());
if (c != null) {
String names[] = c.getColumnNames();
for (String temp : names) {
AlarmLog.d(tag_alarm, temp);
}
if (c.moveToFirst()) {
do {
for (int j = 0; j < c.getColumnCount(); j++) {
AlarmLog.i(tag_alarm, c.getColumnName(j)
+ " which has value " + c.getString(j));
}
} while (c.moveToNext());
}
}
Hope it's helpful and receive code for others manufactures.
Look at the definition of the content provider in AndroidManifest.xml
<provider android:name="AlarmProvider"
android:authorities="com.android.deskclock"
android:exported="false" />
The exported is false, which means a 3rd-party app cannot access it. Permission denial as a result.
how to embed a code in android source code and run image file
It means you modify the Android source(Provided by google). I don't think it's useful in your case.
You can do that in a rooted device, by directly modify the contents in sqlite database. I don't think there is a solution to work on all existing Android platforms.
In general, sqlite database files are under /data/data/app-package-name/databases/database-name, so in this example, it should be /data/data/com.android.deskclock/databases/com.android.deskclock or something similar. You can pull the file out by adb pull and open it using SqliteExplorer to check whether it is what you want.
For how to modify this db file, check Using your own SQLite database in Android applications
As said there's no way to do this without root, but you can monitor when the next alarm is and when the value changes with the following value:
Settings.System.getUriFor(Settings.System.NEXT_ALARM_FORMATTED).toString()
This will give you a string with the next alarm.
Why doesnt my Android Cursor go all the way to the end of the original "promise"??
My cursor.getCount() differs from my last cursor.getPosition(). Check my while loop! It is all I do with it!
Notes:
1. it is about querying the Contacts content provider (android api >5)
2. I display only the esential code
Cursor cursor = mContext.getContentResolver().query(mUri, mProjections, null, null, null);
Logger.d(TAG, "*** cursor.getCount(): "+cursor.getCount());
while (cursor.moveToNext()) {
Logger.d(TAG, "| position: "+cursor.getPosition());
processMainCursor(serializer, cursor);
}
cursor.close();
processMainCursor() will display data from cursor + do another queries: one 4 phones, one 4 emails, one 4 IM accounts:
void processMainCursor(XmlSerializer serializer, Cursor main_cursor) {
writeCursorData(serializer, main_cursor); //writes cursor data, column by column
writePhoneEntities(serializer, main_cursor);
writeEmailEntities(serializer, main_cursor);
writeIMEntities(serializer, main_cursor);
}
In none of my writeXXX methods do i close my main_cursor or move next!!!..have to trust me on that.. i just do a new query, print data & close that cursor
So statistics:
cursor.getCount() = 695 (always)
commenting writePhoneEntities, writeEmailEntities, writeIMEntities: cursor.getCount() =
last cursor.getPosition() = 695 (so correct!)
leaving one/two/all of my writeXEntities shows randomness; example: leaving them all:
last cursor.getPosition() sometimes displays 254, 257, 253, etc; leaving just phone & IM: 514, 510, 511, etc (so different RUN -> different last cursor.getPosition() VALUE)
So oppinions.. Why is that? Is it memory related?
Update:
Leaving any of my writeXEntities displays at the end in logcat:
Removing dead content provider: contacts
Update 2
Adding cursor.moveToFirst(); & doing loop like
do {
//do whatever you want
} while (cursor.moveToNext());
didn't do the job..
So maybe the answer is in this logcat entries:
05-21 23:29:30.209: I/ActivityThread(7085): Removing dead content provider: contacts
05-21 23:29:30.209: I/ActivityThread(7085): Removing dead content provider: com.android.contacts
SAMPLE OF a writeXEntity REMOVED
SOLUTION .. i wasnt closing the cursors from writeXEntity corectly (probably leaving quite a lot of open cursor after main while)
in reality i was closing like this
if(phone_cursor!=null && phone_cursor.getCount() > 0)
{
//... stuff
phone_cursor.close();
}
i should have closed after if
if(phone_cursor!=null && phone_cursor.getCount() > 0)
{
//... stuff
}
phone_cursor.close();
I guess leaving a basilion cursor open ..was the answer?!?
You need to move the cursor to the first row. Try adding cur.moveToFirst() before the while loop.
You might also consider using a do-while loop. This will ensure that you never skip over the first row in the cursor:
if (cursor.moveToFirst()) {
do {
//do whatever you want
} while (cursor.moveToNext());
}
cursor.close();
Well, they won't be the same number as the getCount is the number of items, and the position is the position, ( the first one being 0). So the final position should always be one less than the count.
If it's something other than that, I guess I'm not understanding your question properly.
Use cursor as shown below:
if(cursor.getCount() == 0)
{
//No entry found
}
else {
cursor.moveToFirst();
do {
//do whatever you want
} while (cursor.moveToNext());
cursor.close();
After reading the answer you already found (problem with closing cursors) I think that the best way to ensure you close them all is with this code:
Cursor c = null;
try {
c = <your query>;
if (c.moveToFirst()) { // No point in doing more if empty.
do {
<process this cursor row>
} while (c.moveToNext());
}
}
finally {
if (c != null) c.close(); // Not sure the check needed, maybe if query was really wrong.
}