send message in background to whatsapp number using external application - java

Tried everything on stackoverflow, now i am being able to take the msg frwd. But the msg is not sent until you actually click a no. from whatsApp contact list ..... Plz help been stuck here for few days....
Thing is that i am trying to build an app, in which when I give a number then msg should be sent to it using whatsapp. With this code msg is being frwded and when I select a number it sends the pre-defined msg to it. But I want that the msg should be directly sent without whatsApp waiting for user to click on a number..
//checks if whats app is installed or not..
private boolean whatsappInstalledOrNot(String uri) {
PackageManager pm = getPackageManager();
boolean app_installed = false;
try {
pm.getPackageInfo(uri, PackageManager.GET_ACTIVITIES);
app_installed = true;
} catch (PackageManager.NameNotFoundException e) {
app_installed = false;
}
return app_installed;
}
//Main Process
boolean isWhatsappInstalled = whatsappInstalledOrNot("com.whatsapp");
if (isWhatsappInstalled) {
String a="91*********0";// the nuber to which msg is to be sent
Uri uri = Uri.parse("smsto:" + a);
Intent sendIntent = new Intent(Intent.ACTION_SEND, uri);
sendIntent.putExtra(Intent.EXTRA_TEXT, "Test message"+a);//msg to be sent
//sendIntent.putExtra("sms_body", "ydyeryyerf");
sendIntent.setType("text/plain");// type of msg->text
sendIntent.putExtra("chat",true);
sendIntent.setPackage("com.whatsapp");// picks whats app
// startActivity(sendIntent);
startActivity(Intent.createChooser(sendIntent, a));//starts whats app
} else {
// should redriect to play store to download whatsApp
Toast.makeText(getApplicationContext(), "WhatsApp not Installed",
Toast.LENGTH_SHORT).show();
Uri uri = Uri.parse("market://details?id=com.whatsapp");
Intent playStore = new Intent(Intent.ACTION_VIEW, uri);
startActivity(playStore);
}

Instead of using Uri uri = Uri.parse("smsto:" + a);
use sendIntent.putExtra("jid", + number + "#s.whatsapp.net")
"number" should be the actual number with no leading +

Short answer: This is not possible.
You can not do this unless you build your own implementation for whatsapp api and in this case you will need sender phone number and password and this can not be done pragmatically. Long steps to do this will be as follow :
1 - bring rooted mobile phone and put sender sim card in
2 - get the files that whatsapp stores password in and get the password
3 - implement whatsapp mini client that, using this user name and password, send your message.

Related

SpeechRecognizer can not hear me on some devices, the onRmsChanged() method is called only once

I need some help solving a problem with SpeechRecognizer.
Background
My task is to implement a voice memo feature: the user can record a short audio, save it, and then listen to it. If the user does not have the opportunity to listen to the audio, he can tap on the special "Aa" button and get a transcript of his voice note as text.
Since I did not find a suitable way to recognize prerecorded audio, I decided to implement speech recognition using SpeechRecognizer at the same time as recording audio. The recognition results are stored in a string, and when the user taps the "Aa" button, this string is displayed on the screen.
Source
In the Activity, I declare a SpeechRecognizer and an Intent for it, as well as a string to store the recognized text, and a special variable isStoppedByUser. It is needed so that recognition stops only when the user himself stops recording (if the user pauses during speaking, recognition may stop automatically, but I do not need this).
private SpeechRecognizer speechRecognizer;
private Intent speechRecognizerIntent;
private String recognizedMessage = "";
private boolean isStoppedByUser = false;
I initialize the SpeechRecognizer in a separate method that is called from onCreate().
private void initSpeechRecognizer() {
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(this);
speechRecognizerIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, RecognizerIntent.LANGUAGE_MODEL_FREE_FORM);
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_MAX_RESULTS, 5);
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_CALLING_PACKAGE, getClass().getPackage().getName());
speechRecognizerIntent.putExtra(RecognizerIntent.EXTRA_LANGUAGE, Locale.getDefault());
boolean isRecognitionAvailable = SpeechRecognizer.isRecognitionAvailable(this);
Toast.makeText(this, "isRecognitionAvailable = " + isRecognitionAvailable, Toast.LENGTH_SHORT).show();
Log.i(TAG, "isRecognitionAvailable: " + isRecognitionAvailable);
speechRecognizer.setRecognitionListener(new RecognitionListener() {
#Override
public void onRmsChanged(float rmsdB) {
Log.d(TAG, "onRmsChanged() called with: rmsdB = [" + rmsdB + "]");
}
#Override
public void onResults(Bundle results) {
Log.d(TAG, "onResults() called with: results = [" + results + "]");
ArrayList<String> data = results.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION);
recognizedMessage += " " + data.get(0);
Log.d(TAG, "onResults(): recognizedMessage = " + recognizedMessage);
// If recognition stops by itself (as a result of a pause in speaking), we start recognition again
if (!isStoppedByUser) {
speechRecognizer.startListening(speechRecognizerIntent);
}
}
#Override
public void onError(int error) {
Log.d(TAG, "onError() called with: error = [" + error + "]");
if (!isStoppedByUser) {
speechRecognizer.startListening(speechRecognizerIntent);
}
}
// Other callback methods. They have nothing but logging
// ...
});
}
The user starts recording:
startRecording();
isStoppedByUser = false;
recognizedMessage = "";
speechRecognizer.startListening(speechRecognizerIntent);
The user stops recording:
isStoppedByUser = true;
speechRecognizer.stopListening();
// Further processing of recorded audio
// ...
Problem
I tested this functionality on two devices: Xiaomi 9T and Realme 8i.
Everything works fine on Xiaomi: as I speak, the onRmsChanged() method is called several times per second with different rmsdB values, I can clearly see this in the logs. That is, the sound level changes. Then other callback methods are called, and the string is successfully formed.
But on Realme, the onRmsChanged() method is called only once, at the very beginning, with a value of -2.0. Nothing else happens while I'm speaking, and when I stop recording, the onError() method is called with code 7 (ERROR_NO_MATCH).
It's as if the SpeechRecognizer can't hear me, but there are no problems with the microphone, and the RECORD_AUDIO permission is also granted: the audio itself is successfully recorded and can be listened to.
If I open the Google app and enter a voice request, everything also works fine.
I will be very grateful if you recommend what other parameters can be set to solve this problem. Thank you!
The problem turned out to be that it is impossible to use the microphone API for both recording and speech recognition at the same time. Therefore, the fact that everything works fine on Xiaomi turned out to be just a happy accident.

Android code to dial or calll a string containing alphabets *123*abc# instead of numbers (*123#)?

I’m unable to dial or call a string containing alphabets in android.
For Example:
I want to dial a string *123*abcd#.
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:"+"*123*abcd#")); //This string is not getting dialed
try
{
startActivity(callIntent);
}
catch (android.content.ActivityNotFoundException ex)
{
Toast.makeText(getApplicationContext(),"yourActivity is not founded",Toast.LENGTH_SHORT).show();
}
String *123*abcd# is not getting dialed or called. Please help to solve the same.
String s = "*123*abcd#";
if ((s.startsWith("*")) && (s.endsWith("#"))) {
callstring = s.substring(0, s.length() - 1);
callstring = callstring + Uri.encode("#");
}
Intent i = new Intent(android.content.Intent.ACTION_CALL, Uri.parse("tel:" + callstring));
startActivity(i);
your need to encode the # before using it above code will do the trick.
To use Intent.ACTION_CALL you need to add Permission
<uses-permission android:name="android.permission.CALL_PHONE"/> and since its a Dangerous permission you need to handle it Runtime for Android 6 and above.
You can rather use Intent.ACTION_DIAL which doesnt require any permission and will open the Phone app with the given number typed already, the user has to initiate the call.
Here is how to achieve this.
Intent intent = new Intent(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel:*123*abcd#"));
startActivity(intent);

Android - Send email with image attachment returning 0KB size

I created an app with action click to send email with image attachment file, I was think the code is working right, after I found the image size of attachment is 0kb, and when I clicked it, it said "Unable find the item", here is the code I use for
public void SendEmailWithAttachment(final String imageUrl){
String path = "file:///android_asset".concat(File.separator).concat(getString(R.string.sa_books_directory)).concat(File.separator); // Get the path file from my asset folder
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.setType("image/jpeg");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, "");
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "This is subject");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "This is email body");
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(path + "IndividualVillas/pages/" + imageUrl + ".jpg"));
startActivity(emailIntent);
}
I don't know where is the problem, I had tried to change the setType but it doesn't help me also. Any kind help will much appreciate :)
Sorry for my bad English
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("image/jpeg");
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
//emailIntent.putExtra(android.content.Intent.EXTRA_TEXT,body);
emailIntent.putExtra(Intent.EXTRA_TEXT, Html.fromHtml(new StringBuilder()
.append("I think you'll like this ")
.append(wineName).append(".")
.append("<br /><br />Scanned it with the ")
.append(bottleRating+tastingNote)
emailIntent.putExtra(Intent.EXTRA_STREAM,Uri.parse("file://"+winePic));
final PackageManager pm = ShareWineActivity.this.getPackageManager();
final List<ResolveInfo> matches = pm.queryIntentActivities(emailIntent, 0);
ResolveInfo best = null;
for (final ResolveInfo info : matches)
if (info.activityInfo.packageName.endsWith(".gm")|| info.activityInfo.name.toLowerCase().contains("gmail"))
best = info;
if (best != null)
emailIntent.setClassName(best.activityInfo.packageName,best.activityInfo.name);
startActivityForResult(emailIntent, 2015);
Is the path correct? If you have double checked that then:
The problem here are privileges. If you want to make some private file accessible for other application then probably you want to use this simple, nice and clean solution: https://developer.android.com/reference/android/support/v4/content/FileProvider.html

Android SMS intent stuck with the same body and same recepient

So my android application detects when location changes and then it notifies the user and makes him take action either call a number or send SMS.
The SMS is sent to a saved number and its body is "I'm at " + fullAddress
private NotificationCompat.Builder buildNormal(CharSequence pTitle,String fullAddress) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(
this);
Intent in = new Intent(this,MainActivity.class);
PendingIntent pMainIntent = PendingIntent.getActivity(this, 0,
in, 0);
if(getSavedDataString("gNumber")!=null)
{
String url = getSavedDataString("gNumber");
Intent intent = new Intent(Intent.ACTION_CALL, Uri.parse(url));
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
//Intent smsIntent = new Intent(Intent.ACTION_SENDTO,Uri.parse("smsto:"
//+ Uri.encode(getSavedDataString("gNumber").substring(4))));
//intent.setData());
//startActivity(intent);
Intent smsIntent = new Intent(Intent.ACTION_VIEW);
//smsIntent.setType("vnd.android-dir/mms-sms");
smsIntent.putExtra("address", getSavedDataString("gNumber").substring(4));
smsIntent.putExtra("sms_body","I'm at " + fullAddress);
smsIntent.setData(Uri.parse("smsto:"
+ Uri.encode(getSavedDataString("gNumber").substring(4))));
PendingIntent psmsIntent = PendingIntent.getActivity(this, 0,
smsIntent, 0);
builder.addAction(android.R.drawable.ic_menu_call, "Call", pIntent);
builder.addAction(android.R.drawable.sym_action_email, "Send SMS", psmsIntent);
}
else
{
builder.addAction(0, "Choose Guardian", pMainIntent);
}
builder.setAutoCancel(true).setDefaults(Notification.DEFAULT_ALL);
// set the shown date
builder.setWhen(System.currentTimeMillis());
// the title of the notification
builder.setContentTitle(pTitle);
// set the text for pre API 16 devices
builder.setContentText(pTitle);
// set the action for clicking the notification
builder.setContentIntent(pMainIntent);
// set the notifications icon
builder.setSmallIcon(R.drawable.ic_home);
//builder.setSound(android.)
// set the small ticker text which runs in the tray for a few seconds
builder.setTicker("Location Change Alert");
// set the priority for API 16 devices
//builder.setVibrate(pattern)
builder.setPriority(Notification.PRIORITY_DEFAULT);
return builder;
}
it shows here that the notification that shows to the user contains 2 actions to call or to send message and it sends it to the presaved number gNumber
The problem is after i press the action to send sms and then discard that message without sending it also deleting it from draft and all that.
and then the app detects another location change so it sends a different notification with different fullAddress the intent is still stuck at the same text body!!
I also tried to change the recipient and it gets stuck on the old recipient too. I have to either restart the device or send the message I once discarded.
I also tried to change from ACTION_VIEW to ACTION_SEND or ACTION_SENDTO but all in vain.
I want to know if there's a solution to this intent getting stuck on the same body and recipient other than changing this intent totally and using SMSManager
Help please.
When your app requests a PendingIntent, the system keeps a token on behalf of your app to perform an action as though your app is actually doing it. It is done this way so that, even if your app is killed, whatever process receives the PendingIntent can still follow through with it.
When these tokens are created, certain info is recorded, e.g. the operation, the the action, etc. If your app were to request another PendingIntent with the same info, the same token will be returned. Now, the info used to determine if they are the same or different does not include the extras that the Intent itself carries. So when your app requests the same SMS operation with only different Intent extras, you're going to get the same token with the original extras over and over again, unless you pass a flag to indicate differently.
As for the difference between the flags: FLAG_CANCEL_CURRENT "ensures that only entities given the new data will be able to launch it. If this assurance is not an issue, consider FLAG_UPDATE_CURRENT." In your case, I don't think this is an issue, so FLAG_UPDATE_CURRENT should be sufficient. If it is a concern, use FLAG_CANCEL_CURRENT.
The quoted is directly from the docs here.

when i invoke gmail to send some advice the bluetooth come out, too

this is my code to invoke gmail.
private void sendMail() {
// Device model
String PhoneModel = android.os.Build.MODEL;
// Android version
String AndroidVersion = android.os.Build.VERSION.RELEASE;
final Intent emailIntent = new Intent(
android.content.Intent.ACTION_SEND);
emailIntent.setType("plain/text");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
new String[] { "****#gmail.com"});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
"'some feedbace...");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "—— phoneModel:"
+ PhoneModel + ";ROM:" + AndroidVersion);
startActivity(Intent.createChooser(emailIntent, "Sending mail..."));
}
when i click the menu to invoke the gmail to send feedback,the bluetooth come out too,with the gmail,and waiting for me to select one.but i just want to invoke the gmail app.what's wrong with my code .anybody help please!
You can try this:
emailIntent.setType("application/octet-stream");
Or alternatively you can use PackageManager to build a more limited set of Intents, and show your own dialog for the user to select their email app.
but actually you are swimming against the tide of Android with what you're doing. Android is designed to allow for a message to be "Sent" and to show all apps that accept that intent, so be careful you don't remove options the user may actually want.
You can try using android.content.Intent.ACTION_SENDTO instead of ACTION_SEND. If you have multiple email clients installed it will still prompt you to choose one though.
Have a look at this question for more info.
If you absolutely have to use Gmail and not have android prompt the user you can try what is suggested in this answer (Note: I haven't tried this):
If you specifically want GMail, you have to be a bit cleverer. (Note
that the correct MIME type is actually "text/plain", not "plain/text".
Do to an implementation oddity, GMail seems to be the only activity
which responds to the latter, but this isn't a behavior I would count
on.)
private void sendMail() {
String body = "\n 机型:" + android.os.Build.MODEL + ";ROM:"
+ android.os.Build.VERSION.RELEASE;
Uri mailUri = Uri.parse("mailto:byirain#gmail.com");
Intent emailIntent = new Intent(Intent.ACTION_SENDTO, mailUri);
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "'易学堂'问题反馈与建议");
emailIntent.putExtra(Intent.EXTRA_TEXT, body);
startActivity(emailIntent);
}
I finally finished it, though the uri, like before

Categories

Resources