In my android application I want to send MMS from background service without user interaction, I tried to use SmsManager.sendMultimediaMessage but this method requires API-21 atleast and I am working on API-19 (Android KitKat). So please tell how can I send MMS from background service without user interaction in Android API level 19 (KitKat)?
Use this page.
since i shouldn't answer with just a link. I copied some content from there.
Settings sendSettings = new Settings();
sendSettings.setMmsc(mmsc);
sendSettings.setProxy(proxy);
sendSettings.setPort(port);
you can get them something like (found at Set APN programmatically on Android - answear by vincent091):
Cursor cursor = null;
if (Utils.hasICS()){
cursor =SqliteWrapper.query(activity, activity.getContentResolver(),
Uri.withAppendedPath(Carriers.CONTENT_URI, "current"), APN_PROJECTION, null, null, null);
} else {
cursor = activity.getContentResolver().query(Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current"),
null, null, null, null);
}
cursor.moveToLast();
String type = cursor.getString(cursor.getColumnIndex(Telephony.Carriers.TYPE));
String mmsc = cursor.getString(cursor.getColumnIndex(Telephony.Carriers.MMSC));
String proxy = cursor.getString(cursor.getColumnIndex(Telephony.Carriers.MMSPROXY));
String port = cursor.getString(cursor.getColumnIndex(Telephony.Carriers.MMSPORT));
Related
I am trying to delete content (chanel's program) like:
content://android.media.tv/preview_program/317
with this code:
getContentResolver().delete(TvContractCompat.buildPreviewProgramUri(ALlProgramIDs.get(i)), null, null);
// ALlProgramIDs.get(i) = 317; long type
or this code:
getContentResolver().delete(Uri.parse(ALsProgramIDs.get(i)), null, null);
// ALsProgramIDs.get(i) = content://android.media.tv/preview_program/317
and nothing to be happen. Programs are not deleting.
BUT this code:
getContentResolver().delete(Uri.parse(ALsProgramIDs.get(i).substring(0, ALsProgramIDs.get(i).length() - 3)), null, null);
// LsProgramIDs.get(i).substring(0, ALsProgramIDs.get(i).length() - 3 = content://android.media.tv/preview_program/
works fine - everything from this Uri (or storage) is deleted.
What is wrong with deleting certain IDs?
Seems done like here:
https://developer.android.com/reference/androidx/tvprovider/media/tv/PreviewProgram
Usage example when deleting a preview program:
getContentResolver().delete(TvContractCompat.buildPreviewProgramUri(existingProgram.getId()), null, null);
getContentResolver().delete(TvContractCompat.buildPreviewProgramUri(programId), null, null);
Should work, so you may want to connect the debugger and step through it to verify you're passing the ID you want to delete and that the built URI is correct. An alternative that will make your code more readable is to use the PreviewChannelHelper's deletePreviewProgram method.
PreviewChannelHelper(context).deletePreviewProgram(id);
I'm using the below code to retrieve a message from sms.
private List<String> getEveryLastMessages(){
List<String> listSms = new ArrayList<String>();
ContentResolver contentResolver = getActivity().getContentResolver();
Cursor c = contentResolver.query(Telephony.Sms.Inbox.CONTENT_URI, // Official CONTENT_URI from docs
new String[] { Telephony.Sms.Inbox.BODY }, // Select body text
null,
null,
Telephony.Sms.Inbox.DEFAULT_SORT_ORDER); // Default sort order
int totalSMS = c.getCount();
if (c.moveToFirst()) {
for (int i = 0; i < totalSMS; i++) {
listSms.add(c.getString(0));
listSms.add("\n");
c.moveToNext();
}
} else {
//Do something, no messages
}
c.close();
return listSms;
}
my problem is all of the message was retrieved and except the locked message.
what I'm trying to achieve is retrieve only the last message of
every conversation including the lock messages and populate it into my recyclerview adapater to show it as inbox.
If you want the last message in each conversation, regardless of whether it's sent or received, there's a handy built-in URI that you can use, in lieu of just grabbing everything and filtering it yourself.
Telephony.Sms.Conversations.CONTENT_URI (in the android.provider package) can be used in a ContentResolver query to retrieve a summary of the available conversations. For example:
Cursor c = contentResolver.query(Telephony.Sms.Conversations.CONTENT_URI,
null, null, null, null);
This query will return with three columns:
Telephony.Sms.Conversations.SNIPPET ("snippet")
Telephony.Sms.Conversations.MSG_COUNT ("msg_count")
Telephony.Sms.Conversations.THREAD_ID ("thread_id")
The SNIPPET column will be the most recent available message in that conversation.
Unfortunately, starting with Marshmallow (API level 21), any app that is not the default messaging app has access to only a restricted view of the SMS table. Such an app can only get messages with a Telephony.Sms.TYPE of MESSAGE_TYPE_INBOX or MESSAGE_TYPE_SENT. This means that you won't get MESSAGE_TYPE_FAILED, MESSAGE_TYPE_DRAFT, etc., unless your app is the current default app.
However, the Telephony.Sms.LOCKED column is a completely separate categorization from the TYPE column, and so should not figure into the restricted view. That is, you should be able to get locked messages, as long as they're sent or inbox, no matter if your app is the default or not. Of course, it's possible that a manufacturer has altered any of this described behavior, and you might need to account for that in your app.
I'm trying to implement an AccountPicker in my game, and I've tried using all three versions of newChooseAccountIntent, 2 coming from AccountManager and one from AccountPicker.
my code looks like this
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
intent = AccountManager.newChooseAccountIntent(null, null, new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, null, null, null, null);
} else {
intent = AccountManager.newChooseAccountIntent(null, null, new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, false, null, null, null, null);
}
or the same, but replace AccountManager for AccountPicker
My aim is to have a picker that looks like this
But using AccountManager I get
which is at least Material in colour
or this from AccountPicker (ICS!!)
Any ideas what I'm doing wrong?
I thought it might be that the AccountManager is populating the first field which is selectedAccount, but when I did that, it just selected the radio button against the appropriate account.
You can use Google Api Client document
Someone know if there's a programmatically way to use a specific defined APN on the device which is not the default one?
Thanks.
You can programmatically query and set the preferred APN using the uri content://telephony/carriers/preferapn. To set a new preferred APN you have to pass in the database ID of an existing APN entry. The following function can do this if you pass in the display name of the APN (eg: setPreferredApn(context, "Giffgaff");)
public static final Uri APN_TABLE_URI = Uri.parse("content://telephony/carriers");
public static final Uri APN_PREFER_URI = Uri.parse("content://telephony/carriers/preferapn");
public static boolean setPreferredApn(Context context, String name) {
boolean changed = false;
String columns[] = new String[] { Carriers._ID, Carriers.NAME };
String where = "name = ?";
String wargs[] = new String[] {name};
String sortOrder = null;
Cursor cur = context.getContentResolver().query(APN_TABLE_URI, columns, where, wargs, sortOrder);
if (cur != null) {
if (cur.moveToFirst()) {
ContentValues values = new ContentValues(1);
values.put("apn_id", cur.getLong(0));
if (context.getContentResolver().update(APN_PREFER_URI, values, null, null) == 1)
changed = true;
}
cur.close();
}
return changed;
}
I guess I should add that you need WRITE_APN_SETTINGS permission and need to import android.provider.Telephony and android.provider.Telephony.Carriers
UPDATE FOR 4.0+
This facility became disabled with the release of Android 4.0 (ICS). Enabling the WRITE_APN_SETTINGS permission has no effect on allowing you to set the APN any more. See this question for some relevant links. On the API page it now states explicitly this permission is not for external use and this is enforced internally.
I dont think there is a way, even if there is one, the carrier could wipe it out with a software update. Also, for some carriers like AT&T in US, using a specific APN provides specific functionality, like getting the Subscriber number of that user (its a unique ID, not the phone number). So it may not be a good idea to force this change, as it will impact numerous other apps installed on handset.
I'm attempting to update a calendar's event on my phone from my code, but context.getContentResolver().update keeps returning 0, and of course there are no changes made to the event when I look at it in the Calendar app.
I'm getting the event ID, start time, etc with context.getContentResolver().query, and I'm getting unique numbers like 431, 4, 233, etc, so I'm presuming the event IDs I'm using are real.
I understand the official way to do this is to go through Google's servers instead of using update(), but for my implementation it doesn't make sense to do it that way (or even in general, but I digress).
Am I doing something wrong, or am I trying to do something that Android simply isn't going to allow?
Uri updateEventUri = ContentUris.withAppendedId(Uri.parse("content://com.android.calendar/events"), id);
ContentValues cv = new ContentValues();
begin.set(Calendar.HOUR_OF_DAY, arg0.getCurrentHour()); //begin is a java.util.Calendar object
begin.set(Calendar.MINUTE, arg0.getCurrentMinute());
//cv.put("_id", id);
//cv.put("title", "yeahyeahyeah!");
cv.put("dtstart", begin.getTimeInMillis());
int updatedrowcount = context.getContentResolver().update(updateEventUri, cv, null, null);
System.out.println("updated "+updatedrowcount+" rows with id "+id);
A related question was posted here with no replies https://stackoverflow.com/questions/5636350/update-android-calendar-event
Let me know if I can clarify anything; I would really appreciate any input you guys and dolls could provide!
i had tried a lot and finally ended up with solution (Unreliable though).. but works fine..
public static boolean updateCalendar(Context context,String cal_Id,String eventId)
{
try{
Uri CALENDAR_URI = Uri.parse(CAL_URI+"events");
Cursor c = context.getContentResolver().query(CALENDAR_URI, null, null, null, null);
String[] s = c.getColumnNames();
if (c.moveToFirst())
{
while (c.moveToNext())
{
String _id = c.getString(c.getColumnIndex("_id"));
String CalId = c.getString(c.getColumnIndex("calendar_id"));
if ((_id==null) && (CalId == null))
{
return false;
}
else
{
if (_id.equals(eventId) && CalId.equals(cal_Id))
{
Uri uri = ContentUris.withAppendedId(CALENDAR_URI, Integer.parseInt(_id));
context.getContentResolver().update(uri, null, null, null);// need to give your data here
return true;
}
}
}
}
}
finally
{
return true;
}
}
and finally i'm not sure if it works with every device.
Ok, so, the problem was that I was using different URIs between fetching the events and editing them. I used the code sample from here and was using the URI "content://com.android.calendar/instances/when" to fetch the events and display them on the screen. When I had made a change I was using "content://com.android.calendar/events" to edit by id as in my example above.
What I found, thanks to your response, ntc, was that the ids for events between the two URIs were different, and therefore I couldn't edit the events consistently with the information each was giving me. I was presuming the event ids I was getting were system ids and universal to the phone.
I guess I'll have to do some testing and see what hardware isn't compatible with this method. I am using an HTC Evo for testing and so far so good.
When querying the Instances table, use Instances.EVENT_ID to get the identifier for the event you want to edit, instead of Instances._ID.