I found out a message sent via AnswerInlineQuery can be edited by EditMessageText() in "supergroup" chats only.
The created group by default has the "group" type, but after changing any settings, it changes to "supergroup" (I read this from the documentation).
Next, I changed the chat where I couldn't edit the message sent via AnswerInlineQuery to "supergroup" and it worked. There is no information about the group type in the telegram client itself.
Also, the message sent via AnswerInlineQuery to the "private" type chat is not editable too. Haven't tried channels.
And messages sent via SendMessage() are edited without problems in any chat type, the main thing is to catch the messageID.
Is it library limitation, or it's not possible for API in common?
private final TelegramBot bot = new TelegramBot(System.getenv("TG_BOT_TOKEN"));
long chatID;
int messageID;
public void listen() {
this.bot.setUpdatesListener(updates -> {
updates.forEach(this::process);
return UpdatesListener.CONFIRMED_UPDATES_ALL;
});
}
#SuppressWarnings("unchecked")
private void process(Update update) {
Message message = update.message();
InlineQuery inlineQuery = update.inlineQuery();
BaseRequest request = null;
if (message != null && message.viaBot() != null) {
chatID = message.chat().id();
messageID = message.messageId();
request = new EditMessageText(chatID, messageID, String.valueOf(update.message().messageId()));
}
if (inlineQuery != null) request = new AnswerInlineQuery(inlineQuery.id(), new InlineQueryResultArticle("id", "title", "text"));
if (request != null) bot.execute(request);
}
}```
Related
Question: It is possible to request data in gRPC similar with a http request with params?
Details: I work on a maven java project with gRPC. Below is a simplified code of my .proto file.
syntax = "proto3";
service BookService{
rpc getBooks(Empty) returns (stream Book);
/* Other functions */
}
message Book {
int32 id = 1;
string title = 2;
int32 total_pages = 3;
string publisher = 4;
string authors = 5;
}
message Empty {
/* EMPTY */
}
On JavaFX Client I receive the data ( a list of books ) and print it in a ListView (image of GUI below)
As you can see, I show only the title, but when I request the data, I receive all information.
Now I did something like this:
stub.getBooks(BookOuterClass.Empty.newBuilder().build(), new StreamObserver<BookOuterClass.Book>() {
#Override
/* Receive the stream of data from the server */
public void onNext(BookOuterClass.Book currentBook) {
publishProgress(currentBook.getTitle().toString(), loadingBooksCounter);
loadingBooksCounter++;
}
#Override
public void onError(Throwable throwable) {
System.out.println("Error : " + throwable.getMessage());
}
#Override
public void onCompleted() {
controller.getBooksListViewLoadingBar().setVisible(false);
}
});
Obs: publishProgress - show the data dynamically as I receive it in ListView and load a progress bar below it.
What I want to try:
GetBooks with a message request like this:
message Params {
bool with_id = 1;
bool with_title = 2;
bool with_total_pages = 3;
bool with_publisher = 4;
bool with_authors = 5;
}
Two problems:
All values will be false by default.
The response is still an object with all that fields, let's say I request with field with_title set true, now I got a Book with all fields (id, title, total_pages etc.), but only the title does not have a default value.
Make multiple Book messages with different fields.
That are called by different rpc fucntions, ex:
service BookService {
rpc getBookTitles(Empty) returns (stream BookTitle);
rpc getBookIdTitles(Empty) returns (stream BookIdTitle);
}
Problems:
For each new combination of fields another function, and most probably another message too.
Make a Params message request and a Book message response which can be any Book message:
import "google/protobuf/any.proto";
service BookService {
rpc getBooks(Params) returns (stream Book);
}
message Book {
google.protobuf.Any book_type = 1;
}
message BookTitle {
string title = 1;
}
message BookIdTitle {
int32 id = 1;
string title = 2;
}
Still I have a lot of messages...
So the option 3 is somewhere between opt. 1 and opt. 2.
When I try to send a message using Microsoft Graph Java API, It's state is Draft.
Authentication.initialize(appId);
final String accessToken = Authentication.getUserAccessToken(appScopes);
authProvider = new SimpleAuthProvider(accessToken);
// Create default logger to only log errors
DefaultLogger logger = new DefaultLogger();
logger.setLoggingLevel(LoggerLevel.DEBUG);
// Build a Graph client
graphClient = GraphServiceClient.builder()
.authenticationProvider(authProvider)
.logger(logger)
.buildClient();
IMailFolderDeltaCollectionPage mailFolderCollectionPage = graphClient.me().mailFolders().delta()
.buildRequest().get();
AtomicReference<String> inBoxFolderId = new AtomicReference<>("");
while (mailFolderCollectionPage.getNextPage() != null) {
List<MailFolder> mailFolders = mailFolderCollectionPage.getCurrentPage();
mailFolders.forEach(m -> {
if (m.displayName.equals("Inbox")) {
inBoxFolderId.set(m.id);
}
});
mailFolderCollectionPage = mailFolderCollectionPage.getNextPage().buildRequest().get();
}
IMessageDeltaCollectionPage messageCollectionPage = graphClient.me().mailFolders("Inbox")
.messages().delta().buildRequest().get();
Message backedMessaged = null;
while (messageCollectionPage.getNextPage() != null) {
System.out.println("messageCollectionPage = " + messageCollectionPage);
List<Message> messageList = messageCollectionPage.getCurrentPage();
backedMessaged = messageList.get(0);
break;
}
graphClient.me().mailFolders("Inbox").messages().buildRequest().post(backedMessaged);
When you create an Outlook message, its state will remain as draft until you send it. You should use the send request to send your message. It will then not be marked as draft anymore.
Look here for more informations : https://learn.microsoft.com/fr-fr/graph/api/message-send?view=graph-rest-1.0&tabs=http
Play 2.5 Highlights states
Better control over WebSocket frames
The Play 2.5 WebSocket API gives you direct control over WebSocket frames. You can now send and receive binary, text, ping, pong and close frames. If you don’t want to worry about this level of detail, Play will still automatically convert your JSON or XML data into the right kind of frame.
However
https://www.playframework.com/documentation/2.5.x/JavaWebSockets has examples around LegacyWebSocket which is deprecated
What is the recommended API/pattern for Java WebSockets? Is using
LegacyWebSocket the only option for java websockets?
Are there any examples using new Message types ping/pong to implement a heartbeat?
The official documentation on this is disappointingly very sparse. Perhaps in Play 2.6 we'll see an update to this. However, I will provide an example below on how to configure a chat websocket in Play 2.5, just to help out those in need.
Setup
AController.java
#Inject
private Materializer materializer;
private ActorRef chatSocketRouter;
#Inject
public AController(#Named("chatSocketRouter") ActorRef chatInjectedActor) {
this.chatSocketRouter = chatInjectedActor;
}
// Make a chat websocket for a user
public WebSocket chatSocket() {
return WebSocket.Json.acceptOrResult(request -> {
String authToken = getAuthToken();
// Checking of token
if (authToken == null) {
return forbiddenResult("No [authToken] supplied.");
}
// Could we find the token in the database?
final AuthToken token = AuthToken.findByToken(authToken);
if (token == null) {
return forbiddenResult("Could not find [authToken] in DB. Login again.");
}
User user = token.getUser();
if (user == null) {
return forbiddenResult("You are not logged in to view this stream.");
}
Long userId = user.getId();
// Create a function to be run when we initialise a flow.
// A flow basically links actors together.
AbstractFunction1<ActorRef, Props> getWebSocketActor = new AbstractFunction1<ActorRef, Props>() {
#Override
public Props apply(ActorRef connectionProperties) {
// We use the ActorRef provided in the param above to make some properties.
// An ActorRef is a fancy word for thread reference.
// The WebSocketActor manages the web socket connection for one user.
// WebSocketActor.props() means "make one thread (from the WebSocketActor) and return the properties on how to reference it".
// The resulting Props basically state how to construct that thread.
Props properties = ChatSocketActor.props(connectionProperties, chatSocketRouter, userId);
// We can have many connections per user. So we need many ActorRefs (threads) per user. As you can see from the code below, we do exactly that. We have an object called
// chatSocketRouter which holds a Map of userIds -> connectionsThreads and we "tell"
// it a lightweight object (UserMessage) that is made up of this connecting user's ID and the connection.
// As stated above, Props are basically a way of describing an Actor, or dumbed-down, a thread.
// In this line, we are using the Props above to
// reference the ActorRef we've just created above
ActorRef anotherUserDevice = actorSystem.actorOf(properties);
// Create a lightweight object...
UserMessage routeThisUser = new UserMessage(userId, anotherUserDevice);
// ... to tell the thread that has our Map that we have a new connection
// from a user.
chatSocketRouter.tell(routeThisUser, ActorRef.noSender());
// We return the properties to the thread that will be managing this user's connection
return properties;
}
};
final Flow<JsonNode, JsonNode, ?> jsonNodeFlow =
ActorFlow.<JsonNode, JsonNode>actorRef(getWebSocketActor,
100,
OverflowStrategy.dropTail(),
actorSystem,
materializer).asJava();
final F.Either<Result, Flow<JsonNode, JsonNode, ?>> right = F.Either.Right(jsonNodeFlow);
return CompletableFuture.completedFuture(right);
});
}
// Return this whenever we want to reject a
// user from connecting to a websocket
private CompletionStage<F.Either<Result, Flow<JsonNode, JsonNode, ?>>> forbiddenResult(String msg) {
final Result forbidden = Results.forbidden(msg);
final F.Either<Result, Flow<JsonNode, JsonNode, ?>> left = F.Either.Left(forbidden);
return CompletableFuture.completedFuture(left);
}
ChatSocketActor.java
public class ChatSocketActor extends UntypedActor {
private final ActorRef out;
private final Long userId;
private ActorRef chatSocketRouter;
public ChatSocketActor(ActorRef out, ActorRef chatSocketRouter, Long userId) {
this.out = out;
this.userId = userId;
this.chatSocketRouter = chatSocketRouter;
}
public static Props props(ActorRef out, ActorRef chatSocketRouter, Long userId) {
return Props.create(ChatSocketActor.class, out, chatSocketRouter, userId);
}
// Add methods here handling each chat connection...
}
ChatSocketRouter.java
public class ChatSocketRouter extends UntypedActor {
public ChatSocketRouter() {}
// Stores userIds to websockets
private final HashMap<Long, List<ActorRef>> senders = new HashMap<>();
private void addSender(Long userId, ActorRef actorRef){
if (senders.containsKey(userId)) {
final List<ActorRef> actors = senders.get(userId);
actors.add(actorRef);
senders.replace(userId, actors);
} else {
List<ActorRef> l = new ArrayList<>();
l.add(actorRef);
senders.put(userId, l);
}
}
private void removeSender(ActorRef actorRef){
for (List<ActorRef> refs : senders.values()) {
refs.remove(actorRef);
}
}
#Override
public void onReceive(Object message) throws Exception {
ActorRef sender = getSender();
// Handle messages sent to this 'router' here
if (message instanceof UserMessage) {
UserMessage userMessage = (UserMessage) message;
addSender(userMessage.userId, userMessage.actorRef);
// Watch sender so we can detect when they die.
getContext().watch(sender);
} else if (message instanceof Terminated) {
// One of our watched senders has died.
removeSender(sender);
} else {
unhandled(message);
}
}
}
Example
Now whenever you want to send a client with a websocket connection a message you can do something like:
ChatSenderController.java
private ActorRef chatSocketRouter;
#Inject
public ChatSenderController(#Named("chatSocketRouter") ActorRef chatInjectedActor) {
this.chatSocketRouter = chatInjectedActor;
}
public static void sendMessage(Long sendToId) {
// E.g. send the chat router a message that says hi
chatSocketRouter.tell(new Message(sendToId, "Hi"));
}
ChatSocketRouter.java
#Override
public void onReceive(Object message) throws Exception {
// ...
if (message instanceof Message) {
Message messageToSend = (Message) message;
// Loop through the list above and send the message to
// each connection. For example...
for (ActorRef wsConnection : senders.get(messageToSend.getSendToId())) {
// Send "Hi" to each of the other client's
// connected sessions
wsConnection.tell(messageToSend.getMessage());
}
}
// ...
}
Again, I wrote the above to help out those in need. After scouring the web I could not find a reasonable and simple example. There is an open issue for this exact topic. There are also some examples online but none of them were easy to follow. Akka has some great documentation but mixing it in with Play was a tough mental task.
Please help improve this answer if you see anything that is amiss.
It's a quite specific question but after days stuck in the same place and not getting any response in the Alljoyn forum, I decided to post it here. Maybe someone worked with this framework.
I am doing a project and I need the use of the signal mechanish that Alljoyn framework provides. However, I do need the signals inside a session and the example provides in the api core is sessionless.
In my case I need the service (server) to raise a signal and the client to receive it, but I am getting this error. Following the api samples, I managed to create a simple app that exchange messages through the methods defined in the interface, so I know that the communication is working. In this case, the service waits until the client connects and the send the signal. The client joins the session and right after register the signal and I am getting the BUS_NO_SUCH_INTERFACE error. I tried also to register after and before sending the signal, same problem. I think that for some reason the client does not find the bussignalhandler but I don't know why. I also put it in an external class and it didn't work.
I'm following the example in the core api guide:
https://allseenalliance.org/developers/develop/api-guide/core/android
This is the part where the service register and emit the signal:
SignalEmitter emitter = new SignalEmitter(mySignalInterface, joinerName,
sessionId,
SignalEmitter.GlobalBroadcast.Off);
myInterface = emitter.getInterface(SampleInterface.class);
// Emitting signals myInterface.buttonClicked(1);
myInterface.playerPosition(12, 1, -24);
However, in that example, I can't see a definition for myInterface. and I know it is not a mistake and they meant mySignalInterface because the method getInterface asks for an interface object and mySignalInterface is a class which implements that interface.
I put here the example I created and I'll upload the files in case someone wants to try them.
#BusInterface(name = "org.alljoyn.bus.samples.simple.SimpleInterface")
public interface SimpleInterface {
#BusMethod
String Ping(String inStr) throws BusException;
#BusSignal
public void playerPosition(int x, int y, int z) throws BusException;
}
Service:
Class inside the service to implement the signal and method
class SimpleService implements SimpleInterface, BusObject {
public String Ping(String inStr) {
mHandler.sendMessage(mHandler.obtainMessage(MESSAGE_PING, inStr));
return inStr;
}
public void playerPosition(int x, int y, int z) { /* no implementation needed here*/}
}
Here part of the code that makes the connection in the service:
case CONNECT: {
org.alljoyn.bus.alljoyn.DaemonInit.PrepareDaemon(getApplicationContext());
mBus = new BusAttachment(getPackageName(), BusAttachment.RemoteMessage.Receive);
mBus.registerBusListener(new BusListener());
Status status = mBus.registerBusObject(mSimpleService, "/SimpleService");
if (status != Status.OK) {...}
status = mBus.connect();
logStatus("BusAttachment.connect()", status);
if (status != Status.OK) {...}
int flag = 0;
status = mBus.requestName(SERVICE_NAME, flag);
logStatus(String.format("BusAttachment.requestName(%s, 0x%08x)", SERVICE_NAME, flag), status);
if (status == Status.OK) {
status = mBus.advertiseName(SERVICE_NAME, SessionOpts.TRANSPORT_ANY);
logStatus(String.format("BusAttachement.advertiseName(%s)", SERVICE_NAME), status);
if (status != Status.OK) {...}
}
Mutable.ShortValue contactPort = new Mutable.ShortValue(CONTACT_PORT);
SessionOpts sessionOpts = new SessionOpts();
sessionOpts.traffic = SessionOpts.TRAFFIC_MESSAGES;
sessionOpts.isMultipoint = false;
sessionOpts.proximity = SessionOpts.PROXIMITY_ANY;
sessionOpts.transports = SessionOpts.TRANSPORT_ANY + SessionOpts.TRANSPORT_WFD;
status = mBus.bindSessionPort(contactPort, sessionOpts, new SessionPortListener() {
#Override
public boolean acceptSessionJoiner(short sessionPort, String joiner, SessionOpts sessionOpts) {
return sessionPort == CONTACT_PORT;
}
#Override
public void sessionJoined(short port, int id, String s) {
sessionId = id; joinerName = s; sessionEstablished = true;
}
});
logStatus(String.format("BusAttachment.bindSessionPort(%d, %s)",
contactPort.value, sessionOpts.toString()), status);
if (status != Status.OK) {...}
try {
while (!sessionEstablished) {
Thread.sleep(10);
}
SignalEmitter emitter = new SignalEmitter(mSimpleService, joinerName, sessionId, SignalEmitter.GlobalBroadcast.Off);
SimpleInterface myInterface = emitter.getInterface(SimpleInterface.class);
myInterface.playerPosition(12,1,1);
}
catch (BusException ex) {... }
}
Client:
/*On create of the activity which has a button and a text view to send text to the server */
mEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_NULL
&& event.getAction() == KeyEvent.ACTION_UP) {
/* Call the remote object's Ping method. */
Message msg = mBusHandler.obtainMessage(BusHandler.PING,
view.getText().toString());
mBusHandler.sendMessage(msg);
}
return true;
}
});
private static final String SERVICE_NAME = "org.alljoyn.bus.samples.simple";
private static final short CONTACT_PORT=42;
private BusAttachment mBus;
private ProxyBusObject mProxyObj;
private SimpleInterface mSimpleInterface;
case CONNECT: {
org.alljoyn.bus.alljoyn.DaemonInit.PrepareDaemon(getApplicationContext());
mBus = new BusAttachment(getPackageName(), BusAttachment.RemoteMessage.Receive);
mBus.registerBusListener(new BusListener() {
#Override
public void foundAdvertisedName(String name, short transport, String namePrefix) {
if(!mIsConnected) {
Message msg = obtainMessage(JOIN_SESSION);
msg.arg1 = transport;
msg.obj = name;
sendMessage(msg);
}
}
});
Status status = mBus.connect();
logStatus("BusAttachment.connect()", status);
if (Status.OK != status) {...}
status = mBus.findAdvertisedName(SERVICE_NAME);
logStatus(String.format("BusAttachement.findAdvertisedName(%s)", SERVICE_NAME), status);
if (Status.OK != status) {...}
break;
}
case (JOIN_SESSION): {
if (mIsStoppingDiscovery) {
break;
}
short contactPort = CONTACT_PORT;
SessionOpts sessionOpts = new SessionOpts();
sessionOpts.transports = (short)msg.arg1;
Mutable.IntegerValue sessionId = new Mutable.IntegerValue();
Status status = mBus.joinSession((String) msg.obj, contactPort, sessionId, sessionOpts, new SessionListener() {
#Override
public void sessionLost(int sessionId, int reason) {
mIsConnected = false;
logInfo(String.format("MyBusListener.sessionLost(sessionId = %d, reason = %d)", sessionId,reason));
mHandler.sendEmptyMessage(MESSAGE_START_PROGRESS_DIALOG);
}
});
if (status == Status.OK) {
mProxyObj = mBus.getProxyBusObject(SERVICE_NAME,
"/SimpleService",
sessionId.value,
new Class<?>[] { SimpleInterface.class });
mSimpleInterface = mProxyObj.getInterface(SimpleInterface.class);
mSessionId = sessionId.value;
mIsConnected = true;
mHandler.sendEmptyMessage(MESSAGE_STOP_PROGRESS_DIALOG);
}
break;
status = mBus.registerSignalHandlers(this);
if (status != Status.OK) {...}
}
case PING: {
try {
if (mSimpleInterface != null) {
sendUiMessage(MESSAGE_PING, msg.obj);
String reply = mSimpleInterface.Ping((String) msg.obj);
sendUiMessage(MESSAGE_PING_REPLY, reply);
} catch {...}
}
...here some more code...
#BusSignalHandler(iface="org.alljoyn.bus.samples.simple.SimpleInterface", signal="playerPosition")
public void playerPosition(int x, int y, int z) {
sendUiMessage(MESSAGE_POST_TOAST, "Signal captured");
}
In this example, I have my client which has a textview where I can add text and send a ping to the server. This is working if I get rid of the registering signal part. I tried to do it as the api core says, with the Thread.sleep but doesn't work either.
Here I add the code of both of my applications (client & server) based on the samples that are in the alljoyn api.
https://github.com/JavierT/Alljoyn_signal_sample
Please let me know if you have some doubts, it was hard to put all the information in one post.
Thank you in advance.
I think this should solve your problem
Alljoyn BusSignalHandler
either of the following may be used to annotate a signal handler:
#BusSignalHandler(iface = "org.sample.MyInterface", signal = "MySignal")
public void handleSignal(String str)
{
}
#BusSignalHandler(iface = "org.myapp.IMyInterface", signal = "EmitMySignal")
public void handleSignal(String str)
{
}
The first example may be used succesfully when IMyInterface is known to the BusAttachment via a previous call to BusAttachment.registerBusObject(BusObject, String) or BusAttachment.getProxyBusObject(String, String, int, Class[]).
The second example may be used succesfully when IMyInterface is unknown to the BusAttachment.
using the second example should solve your problem.
Also, in your Client program as per the link provided above,
#BusSignalHandler(iface="org.alljoyn.bus.samples.simple.SimpleInterface", signal="playerPosition")
should be replaced with
#BusSignalHandler(iface="org.alljoyn.bus.samples.simpleclient.SimpleInterface", signal="playerPosition")
When you call registerSignalHandlers you must pass an object that implements the interface SimpleInterface and the method playerPosition will be called in that object when you receives a signal.
I believe (I've read the code quickly, I hope I'm not wrong) that you pass your BusHandler object, which does not implements SimpleInterface.
Please change :
private static final String SERVICE_NAME = "org.alljoyn.bus.samples.simple";
to
"org.alljoyn.bus.samples.simple.SimpleInterface" as you have interface name ,
both should be same . as when the Get method of BusObject is called the interface names does not match.
I want to send MMS from my application to a specific number. I've searched and found this code but I have no idea if this code what I need or not.
My Questions is :
-can anyone explain this code to me.i am beginner in MMS.
-also, i thought this code is let the user send MMS from my application without move it to the native Messaging inbox (and this is what i want) Am i right?
-also i have a problem ,i do not know how can i put this code in my project.
this is what i found
MMS is just a http-post request. You should perform the request using extra network feature :
final ConnectivityManager connMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
final int result = connMgr.startUsingNetworkFeature( ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_MMS);
If you get back the result with Phone.APN_REQUEST_STARTED value, you have to wait for proper state. Register BroadCastReciver and wait until Phone.APN_ALREADY_ACTIVE appears:
final IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(reciver, filter);
If background connection is ready, then build content and perform request. If you want to do that using android's internal code, please use this:
final SendReq sendRequest = new SendReq();
final EncodedStringValue[] sub = EncodedStringValue.extract(subject);
if (sub != null && sub.length > 0) {
sendRequest.setSubject(sub[0]);
}
final EncodedStringValue[] phoneNumbers = EncodedStringValue.extract(recipient);
if (phoneNumbers != null && phoneNumbers.length > 0) {
sendRequest.addTo(phoneNumbers[0]);
}
final PduBody pduBody = new PduBody();
if (parts != null) {
for (MMSPart part : parts) {
final PduPart partPdu = new PduPart();
partPdu.setName(part.Name.getBytes());
partPdu.setContentType(part.MimeType.getBytes());
partPdu.setData(part.Data);
pduBody.addPart(partPdu);
}
}
sendRequest.setBody(pduBody);
final PduComposer composer = new PduComposer(this.context, sendRequest);
final byte[] bytesToSend = composer.make();
HttpUtils.httpConnection(context, 4444L, MMSCenterUrl, bytesToSendFromPDU, HttpUtils.HTTP_POST_METHOD, !TextUtils.isEmpty(MMSProxy), MMSProxy, port);
MMSCenterUrl: url from MMS-APNs,
MMSProxy: proxy from MMS-APNs,
port: port from MMS-APNs
Note that some classes are from internal packages. Download from android git is required.
The request should be done with url from user's apn-space code:
public class APNHelper {
public class APN {
public String MMSCenterUrl = "";
public String MMSPort = "";
public String MMSProxy = "";
}
public APNHelper(final Context context) {
this.context = context;
}
public List<APN> getMMSApns() {
final Cursor apnCursor = this.context.getContentResolver().query(Uri.withAppendedPath(Telephony.Carriers.CONTENT_URI, "current"), null, null, null, null);
if ( apnCursor == null ) {
return Collections.EMPTY_LIST;
} else {
final List<APN> results = new ArrayList<APN>();
while ( apnCursor.moveToNext() ) {
final String type = apnCursor.getString(apnCursor.getColumnIndex(Telephony.Carriers.TYPE));
if ( !TextUtils.isEmpty(type) && ( type.equalsIgnoreCase(Phone.APN_TYPE_ALL) || type.equalsIgnoreCase(Phone.APN_TYPE_MMS) ) ) {
final String mmsc = apnCursor.getString(apnCursor.getColumnIndex(Telephony.Carriers.MMSC));
final String mmsProxy = apnCursor.getString(apnCursor.getColumnIndex(Telephony.Carriers.MMSPROXY));
final String port = apnCursor.getString(apnCursor.getColumnIndex(Telephony.Carriers.MMSPORT));
final APN apn = new APN();
apn.MMSCenterUrl = mmsc;
apn.MMSProxy = mmsProxy;
apn.MMSPort = port;
results.add(apn);
}
}
apnCursor.close();
return results;
}
Please help me
why don't you use the android system functions:
Please have a look on
https://developer.android.com/guide/components/intents-common.html
public void composeMmsMessage(String message, Uri attachment) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setData(Uri.parse("smsto:")); // This ensures only SMS apps respond
intent.putExtra("sms_body", message);
intent.putExtra(Intent.EXTRA_STREAM, attachment);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent); }
}
Cheers
Tom
I found a link in an other thread to a github project that works 100% https://github.com/klinker41/android-smsmms
Notice, that obligatory settings are only
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));