I followed this to Delete SMS..
So here I am using these
mContext.getContentResolver().delete(Uri.parse("content://sms/"), null, null);
I have a SMS sending app It sends more than 1k messages every hour
Now the problem is that In new/big phone its working fine, But when I installed same in a basic android phone with less internal memory / less SMS storage, I am facing NO_PDU error
So I want to delete it programmatically, but with LIMIT 500 sms or past 1 day sms or past 1 hr SMS.
mContext.getContentResolver().delete(Uri.parse("content://sms/"), null, null);
The above code will delete all the sms present in SmsProvider . To delete specific sms query SmsProvider and do your operation on selected rows.
Refer below example-
if (values.getAsInteger(Sms.TYPE) == Sms.MESSAGE_TYPE_DRAFT) {
SqliteDatabase.delete(TABLE_SMS, "thread_id=? AND type=?",
new String[] { values.getAsString(Sms.THREAD_ID),
Integer.toString(Sms.MESSAGE_TYPE_DRAFT) });
}
Related
I am developing an app which dials some USSD and waits for SMS related to them. It uses both SIM slots in a dual-SIM phone. I need to identify which SIM (e.g. slot index) received a particular SMS. I can get it when received SMS using BroadcastReceiver. But in case I miss some broadcasts (e.g. user uninstalled the app -> SMS received -> app re-installed. In this scenario I must recheck messages after every start-up of my application process.
I am reading SMS using ContentProvider:
val cursor = resolver.query(Uri.parse("content://sms/inbox"), null, null, null, null)
In android docs, there is a column named sub_id (i.e. Telephony.TextBasedSmsColumns.SUBSCRIPTION_ID). But I cannot obtain that column from my testing device Xiaomi Redmi 5 Plus, MIUI Global 11.0.2, Android 8.1.0. It throws exception when I try to get that column using cursor.getString(c.getColumnIndexOrThrow(Telephony.TextBasedSmsColumns.SUBSCRIPTION_ID)) saying that only available columns are: [_id, thread_id, address, person, date, date_sent, protocol, read, status, type, reply_path_present, subject, body, service_center, locked, error_code, seen, timed, deleted, sync_state, marker, source, bind_id, mx_status, mx_id, mx_id_v2, out_time, account, sim_id, block_type, advanced_seen, b2c_ttl, b2c_numbers, fake_cell_type, url_risky_type, creator, favorite_date].
EDIT: Note that sim_id gives me larger values like 11, 13, 14 etc. I cannot map them to sim slots anyway.
I got it finally, sim_id is equivalent to the documented sub_id column. Therefore, we need to be careful when using android Telephony API.
fun findSlotFromSubId(sm: SubscriptionManager, subId: Int): Int {
try {
for (s in sm.activeSubscriptionInfoList) {
if (s.subscriptionId == subId) {
return s.simSlotIndex
}
}
} catch (e: SecurityException) {
e.printStackTrace()
}
return -1
}
We have an Android app where we are trying to read all the messages available in the phone. We are using READ_SMS permission but we are not able to read service messages in this way. By service mesaage I mean the messages obtained from different companies. For example I have messages in my phone from Amazon and Paytm but I am not able to load these while loading messages. I don't understand the issue. Is there any default filter that android is applying when the SMS get loaded or is there any issue with the code?
I use the following code to load all SMS:
private ArrayList load_sms(){
ContentResolver contentResolver = getContentResolver();
ArrayList<String> smsList = new ArrayList<>();
Cursor smsInboxCursor =
contentResolver.query(Uri.parse("content://sms/inbox"),
null,null,null,null);
int indexBody = smsInboxCursor.getColumnIndex("body");
int indexAddress = smsInboxCursor.getColumnIndex("address");
if(indexBody < 0 || !smsInboxCursor.moveToFirst())
return null;
do{
smsList.add("SMS From: " +
smsInboxCursor.getString(indexAddress) + " \nMessage: "
+ smsInboxCursor.getString(indexBody));
}while (smsInboxCursor.moveToNext());
return smsList;
}
So, the solution was quite vague. I have a MI phone and found that MI blocks service messages. To view those SMS' I had to give the permission manually from settings as given in this link: Can't read service messages in Redmi Note 3
When I ran my app on some other phone like in Samsung, I was able to view all the messages.
With the new Android 2.2+ operating systems deployed on Samsung phones, the call log has been replaced with a special super log. The super log contains also the information about sent sms. How I can delete this type of log? Can I use a particular Uri (content://...) to delete it? I read that Samsung uses the LogsProvider.apk to manage logs, is there the open source code of it?
Thanks.
Denis.
You can try to delete the calls using this:
context.getContentResolver().delete(android.provider.CallLog.Calls.CONTENT_URI,
null, null);
I don't think **LogsProvider** app Samsung is open source.
Uri to be used for deleting Samsung log is "content://logs/historys".
Use this Uri to delete all the sms log of a particular number.
String smsLogUri = "content://logs/historys";
Context.getContentResolver().delete(Uri.parse(smsLogUri), " logtype = 300 and number like ?", new String[]{phoneNumber});
logtype= 300 is used to delete only sms log.
If you want to delete sms log of all numbers then use:
Context.getContentResolver().delete(Uri.parse(smsLogUri), " logtype = 300 ", null);
I am working on a simple app for the HTC EVO that blinks the alternate notification LED when a new text message is received. I have this part working great via a Broadcast Receiver but I need some way to turn the LED off when the user has read the message(s) using their default SMS app. I'm not sure if it is best to do this in the receiver or in a background service. I found this, which might be what I am looking for, but I have no idea on how to use it as I could not find any instructions or tutorials.
Alright, I have worked out the following code which I think will meet my needs.
private int getUnreadSMSCount()
{
int count = 0;
Uri smsURI = Uri.parse("content://sms");
ContentResolver contentResolver = this.getContentResolver();
Cursor cursor = contentResolver.query(smsURI, null, "read=0", null, null);
if (cursor != null)
{
try
{
count = cursor.getCount();
}
finally
{
cursor.close();
}
}
return count;
}
Unfortunately I do not believe there is a way to do this.
When your BroadcastReceiver receives the Intent it is a copy of the Intent, same with the default SMS app. So you each have copies of the message independent of eachother.
You can set your own copy of the message to read, but you will be unable to see its status in the default SMS app. Also, the default app does not send out a broadcast that the message has been read, all that data is kept locally.
The only way you would be able to implement this would be to write a full replacement of the Messaging app.
Sorry, I hope this helps, let me know if you have any other questions.
I have a app, which sends a lot of SMS messages to a central server. Each user will probably send ~300 txts/day. SMS messages are being used as a networking layer, because SMS is almost everywhere and mobile internet is not. The app is intended for use in a lot of 3rd world countries where mobile internet is not ubiquitous.
When I hit a limit of 100 messages, I get a prompt for each message sent. The prompt says "A large number of SMS messages are being sent". This is not ok for the user to get prompted each time to ask if the app can send a text message. The user doesn't want to get 30 consecutive prompts.
I found this android source file with google. It could be out of date, I can't tell. It looks like there is a limit of 100 sms messages every 3600000ms(1 day) for each application.
http://www.netmite.com/android/mydroid/frameworks/base/telephony/java/com/android/internal/telephony/gsm/SMSDispatcher.java
/** Default checking period for SMS sent without uesr permit */
private static final int DEFAULT_SMS_CHECK_PERIOD = 3600000;
/** Default number of SMS sent in checking period without uesr permit */
private static final int DEFAULT_SMS_MAX_ALLOWED = 100;
and
/**
* Implement the per-application based SMS control, which only allows
* a limit on the number of SMS/MMS messages an app can send in checking
* period.
*/
private class SmsCounter {
private int mCheckPeriod;
private int mMaxAllowed;
private HashMap<String, ArrayList<Long>> mSmsStamp;
/**
* Create SmsCounter
* #param mMax is the number of SMS allowed without user permit
* #param mPeriod is the checking period
*/
SmsCounter(int mMax, int mPeriod) {
mMaxAllowed = mMax;
mCheckPeriod = mPeriod;
mSmsStamp = new HashMap<String, ArrayList<Long>> ();
}
boolean check(String appName) {
if (!mSmsStamp.containsKey(appName)) {
mSmsStamp.put(appName, new ArrayList<Long>());
}
return isUnderLimit(mSmsStamp.get(appName));
}
private boolean isUnderLimit(ArrayList<Long> sent) {
Long ct = System.currentTimeMillis();
Log.d(TAG, "SMS send size=" + sent.size() + "time=" + ct);
while (sent.size() > 0 && (ct - sent.get(0)) > mCheckPeriod ) {
sent.remove(0);
}
if (sent.size() < mMaxAllowed) {
sent.add(ct);
return true;
}
return false;
}
}
Is this even the real android code? It looks like it is in the package "com.android.internal.telephony.gsm", I can't find this package on the android website.
How can I disable/modify this limit? I've been googling for solutions, but I haven't found anything.
So I was looking at the link that commonsware.com posted, and I found that the source had actually changed. And so I might still have a shot.
int check_period = Settings.Gservices.getInt(mResolver,
Settings.Gservices.SMS_OUTGOING_CEHCK_INTERVAL_MS,
DEFAULT_SMS_CHECK_PERIOD);
int max_count = Settings.Gservices.getInt(mResolver,
Settings.Gservices.SMS_OUTGOING_CEHCK_MAX_COUNT,
DEFAULT_SMS_MAX_COUNT);
mCounter = new SmsCounter(max_count, check_period);
This is getting checkPeriod and maxCount from a settings table. But I don't seem to have access to the same table. That source should be Android 1.1, which is the same I'm using. When I try to import android.provider.Settings.Gservices, I get an error saying that the import can't be resolved.
What is going on?
Did you try using "import android.provider.Settings;" instead of "import android.provider.Settings.GServices"? (see line 36 of SMSDispatcher.java)
Also, not sure how much difference it makes, but 3600000 ms is one hour not one day.
Unfortunately I think you only have a few options
1) Get root access and alter the settings table directly by doing:
sqlite3 /data/data/com.android.providers.settings/databases/settings.db
sqlite> INSERT INTO gservices (name, value) VALUES
('sms_outgoing_check_interval_ms', 0);
2) Use multiple apps since it's a per app limit
3) Perhaps take out the battery after you reach the limit? It looks like the limit is stored in memory. I haven't tried this yet though.
This appears to be built into the Android source tree, so the only way to push this change down to the users would be the build your own ROM and have them install it.
As for ideas on getting around it, why not check for network connectivity first rather than just assuming it doesn't exist. Even if it is not present on a significant majority of devices today, that certainly won't always be the case. Let SMS be the fall back mechanism. If it is the fall back mechanism, you can then prompt the user letting them know that they will be prompted to confirm the level of SMS activity every 100 messages or so. Who knows, they may roam into a Wifi hotspot and have connectivity part of the day too.
Otherwise, you will get into a game of installing a bunch of other Activities+Intents that can act as silent SMS proxies to get around the limit. Of course, this has its own certain set of undesirable qualities as well and I can hardly believe I just typed/suggested something that evil.