While searching the internet I came across the topic of sending SMS but unfortunately I did not find any example for C ++ Builder. Everything is written in Delphi. I tried to rewrite the instructions in C ++ and got this code:
#include <Androidapi.Helpers.hpp>
#include <Androidapi.JNI.JavaTypes.hpp>
#include <Androidapi.JNI.Telephony.hpp>
#include <Androidapi.JNI.GraphicsContentViewText.hpp>
#include <Androidapi.JNI.App.hpp>
#include <Androidapi.JNI.Net.hpp>
JString* wiadomosc = StringToJString( L"Wiadomość" );
Jnet_Uri* URI;
JString* destAdress;
URI = StrToJURI( "12345678" ); // phone number
_di_JIntent Intent = TJIntent::JavaClass->init( TJIntent::JavaClass->ACTION_VIEW, URI ); //ACTION_VIEW ACTION_SEND
Intent->setType( StringToJString("text/plain") );
//Intent->putExtra( TJIntent::JavaClass->EXTRA_TEXT, wiadomosc ); StringToJString('sms_body')
Intent->putExtra( StringToJString("sms_body"), wiadomosc );
::SharedActivityContext()->startActivity( Intent );
//SharedActivity()->startActivity(Intent);
The program works but not as I've expected. The application selection window appears, and despite permanent SMS set as default I can not send sms without typing a phone number and text message even though that data is present in the code. Please give me a hint how to send sms without using the default program on Android.
Related
when my app was using Android5, I can monitor if the SMS was sent or failed by checking the content://sms/sent and content://sms/failed. Aside from via my app, I can also see the message and its status directly from the SMS app of the phone.
Now that the good old Android5 smartphone is dead, I am upgrading to a newer smartphone base on Android8 (Oreo). However I am facing a problem of detecting the status of the sent sms.
First... I can no longer "see" the sms using the phone's default SMS app.
Second... I cant also find the sms using my app even if I scroll through all messages one by one.
This is the code I use to send the SMS:
smsManager := TJSmsManager.JavaClass.getDefault;
smsTo := StringToJString(targetstr);
smsarray := smsmanager.divideMessage(stringtojstring(bodystr));
smsManager.sendmultiparttextMessage(smsTo, nil,smsarray, nil, nil);
While this is the code I use to scroll through all my messages:
uri := StrToJURI('content://sms');
smscursor := TAndroidHelper.Activity.getContentResolver.query(uri, nil, nil,nil,nil);
id_id := smscursor.getColumnIndex(StringToJstring('_id'));
idaddress := smscursor.getColumnIndex(StringToJstring('address'));
idbody := smscursor.getColumnIndex(StringToJstring('body'));
idstatus := smscursor.getColumnIndex(StringToJstring('status'));
idthread_id := smscursor.getColumnIndex(StringToJstring('thread_id'));
idtype := smscursor.getColumnIndex(StringToJstring('type'));
smscursor.moveToFirst;
** using the repeat until loop to read each and every sms until "islast" is true **
But I cant find the sent SMS irregardless if the SMS was successfully sent or not.
I need to do this detection because the signal strength in my area is very low and around 20% of the time the sms failed, and my app should resend the intended message.
PS: I also tried searching for the SMS from the content://sms/sent and content://sms/failed but to no avail.
Anyway, my questions are:
How to make the send out sms show up inside the phone's default sms app?
How to correctly determine if the send out sms was successful or not?
I read somewhere that the method above is using the API and there is a way to use the phone's sms app instead... But I dont have any idea how to do it.
Thank you.
For the benefit of others who may be in similar situation that requires to:
(A) Able to send an SMS directly from the app without using the Phone's built-in SMS default app
(B) The SMS length can be more than the default 160 characters limit (using sendmultiparttextMessage)
(C) Able to know if the SMS was process or not (base on aResultCode of the onReceive from the PendingIntent)
Known Limitation:
Under multi-sim phone, sms is sent via the default sim
if sending to multiple phone recipients, there is no way to know which ones failed, if any. So I suggest send 1 sms to 1 recipient at a time
Doesnt detect if the intended recipient receive the sms or not as the DeliveryIntent is nil
PS: tested under Delphi Community Edition 10.4.2 and Android Oreo 8.0 and 8.1
What I did:
Create and save a unit for the BroadcastReceiver (I call it BCast.pas) from the 2nd answer from this link How read JPendingIntent in Delphi?
In your main.pas (assuming it is save as main.pas), add the following:
ADD TO PROJECT the unit created in step 1 (in my case bcast.pas)
add BCAST in uses clause
add variable for the TBroadCastReceiver (ie fbroadcast : Tbroadcastreceiver;)
make an OnReceiveBroadcast procedure
in my case:
private
{ Private declarations }
procedure OnReceiveBroadcast(aContext: JContext; aIntent: JIntent; aResultCode: integer);
then under implementation, create the code for the OnReceiveBroadcast:
procedure Tmain.OnReceiveBroadcast(aContext: JContext; aIntent: JIntent; aResultCode: integer);
begin
// ... put in the codes here for the result of the last sms send. //
// ... use the the value of AResultcode to do the checking //
// ... AResultcode=1 means ok, other number means possible error //
end;
initialize the fbroadcast as follows: (i put them under my main's onshow):
fbroadcast := TBroadcastReceiver.Create(OnReceiveBroadcast);
fbroadcast.addactions([StringToJString('xxx')]);
where xxx is any string that will be use to match the intent's action
Add in a procedure to sendsms:
procedure tmain.SendSMSAPI(target,messagestr:string);
var
smsManager: JSmsManager; // Androidapi.JNI.Telephony //
smsTo : JString; // Androidapi.JNI.JavaTypes //
PIntent : JPendingIntent; // Androidapi.JNI.App //
smsarray : jarraylist;
APIntent : JArraylist;
intent : JIntent;
begin
Intent := TJIntent.Create;
Intent.setAction(StringToJString('xxx'));
PIntent := TJPendingIntent.JavaClass.getBroadcast(TAndroidHelper.Context, 0, Intent, 0);
APIntent := Tjarraylist.create;
APIntent.add(PIntent);
smsManager:= TJSmsManager.JavaClass.getDefault;
smsTo := StringToJString(target); // Androidapi.Helpers //
smsarray := smsmanager.divideMessage(stringtojstring(messagestr));
smsManager.sendmultiparttextMessage(smsTo, nil,smsarray, APIntent, nil);
end;
I am new at worknig on android chromium, and I need to print the log msg in it, then how to print the log in android chromium, which interface can be used to print log?
There several ways to print the log in android chromium, and you try the two flowing ways:
1. The first way:
//Add the head file
#include <cutils/log.h>
#define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "Your Tags", __VA_ARGS__)
//use the XLOGC to print the log
XLOGC("Your log message");
2. The second way:
//Add the head file
#include "base/logging.h"
LOG(INFO) << "Your log message";
while looking in android logging frame work -
I checked /dev/log/main |system |event log files. in these log file I dont see time stamp. but at the same time "logcat -v time" display time stamp along with log.
I check Logcat code Its reading androidlog_entry from /dev/log/* buffers and displaying on cmdline.
While tracing android logging code , I could not find at what point we are adding timestamp with our log.
I did trace following flow -
LOGI("pre_alloc_cap_mem_thread_init: inited=%d", obj->mPreAllocCapMemInited);
#define LOGE ALOGE
#define ALOGE(...) ((void)ALOG(LOG_ERROR, LOG_TAG, VA_ARGS))
#define LOG_PRI(priority, tag, ...) \
android_printLog(priority, tag, VA_ARGS)
#define android_printLog(prio, tag, fmt...) \
__android_log_print(prio, tag, fmt)
int __android_log_print(int prio, const char *tag, const char *fmt, ...)
{
va_list ap;
char buf[LOG_BUF_SIZE];
va_start(ap, fmt);
vsnprintf(buf, LOG_BUF_SIZE, fmt, ap);
va_end(ap);
return __android_log_write(prio, tag, buf);
}
and on and on till NR_writev system call .
can somebody please guide me, when Its adding timestamp to android logs.
I appreciate help.. what ever i could get ..
But i have figure out it -
"Android frame work does not add time stamp, threadid etc. to android logs that goes to /dev/log/, but It rather pass it down to kernel to logger driver(check logger.c in kernel code) that further add up the timestamp+PID etc. as prefix to each android log. "
The following video tutorial was a good starting point (using Vibrator as an example rather than DeviceId), but there were a few more details needing attention to transpose to C++.
I'm just getting started with Stack Exchange. Hopefully this question and answer is useful to others; the following code does work as expected.
#include <Androidapi.Helpers.hpp>
#include <Androidapi.JNI.Telephony.hpp>
// Get Device ID (IMEI) from device:
_di_JObject TelephonyServiceObj = SharedActivityContext()->getSystemService(TJContext::JavaClass->TELEPHONY_SERVICE);
_di_JTelephonyManager TelephonyManager = TJTelephonyManager::Wrap(((_di_ILocalObject)TelephonyServiceObj)->GetObjectID());
UnicodeString DeviceId = JStringToString(TelephonyManager->getDeviceId());
I am stuck and am getting an error somewhere within my C code, and I do not know where. I would like to use the simple Log.i( tag, msg ) or Log.e( tag, msg ) commands. I have looked around online and have found two other questions on SO but neither of them deal with exactly what I'm saying.
This method is not what I'm looking for...
And this is exactly what I'm looking for, but in C++, not C
If the syntax in C++/C is the same, I'm sorry but I have little experience in both.
Syntax in C is the same
#include <android/log.h>
#define TAG "MYDEBUG"
#ifdef DEBUG
# define D(x...) __android_log_print(ANDROID_LOG_INFO, TAG , x)
#else
# define D(x...) do {} while (0)
#endif
# define W(x...) __android_log_print(ANDROID_LOG_WARN, TAG , x)
# define E(x...) __android_log_print(ANDROID_LOG_ERROR, TAG , x)
#include <cutils/log.h>
#define LOG_TAG "MYDEBUG"
...
ALOGD("Here we are!");
In older releases the macro was:
LOGD("Here we are!");