Android Studio: Delete sent and recieved sms by particular number - java

I'd like to know how to delete sent and received SMS by a particular number. My app is connecting with the GSM module with other device and it sends and receives SMS messages. I'd like to delete these SMS. Below is my code:
#Override
public void onReceive(Context context, Intent intent) {
if (Objects.equals(intent.getAction(), SMS_RECEIVED)) {
String smsSender = "";
String smsBody = "";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
StringBuilder smsBodyBuilder = new StringBuilder();
for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
smsSender = smsMessage.getDisplayOriginatingAddress();
smsBodyBuilder.append(smsMessage.getMessageBody());
}
smsBody = smsBodyBuilder.toString();
} else {
Bundle smsBundle = intent.getExtras();
if (smsBundle != null) {
Object[] pdus = (Object[]) smsBundle.get("pdus");
if (pdus == null) {
// Display some error to the user
return;
}
SmsMessage[] messages = new SmsMessage[pdus.length];
StringBuilder smsBodyBuilder = new StringBuilder();
for (int i = 0; i < messages.length; i++) {
messages[i] = SmsMessage.createFromPdu((byte[]) pdus[i]);
smsBodyBuilder.append(messages[i].getMessageBody());
}
smsBody = smsBodyBuilder.toString();
smsSender = messages[0].getOriginatingAddress();
}
}
if (smsSender != null) {
if (smsSender.equals(serviceProviderNumber) && smsBody.startsWith(serviceProviderSmsCondition)) {
this.pdCanceller.removeCallbacks(this.progressRunnable);
this.message = smsBody;
context.unregisterReceiver(broadcastReceiver);
progressDialog.cancel();
SmsReceiverDialog smsReceiverDialog = new SmsReceiverDialog(this.activity, this.context, this.message);
checkCommand(smsBody, smsReceiverDialog); // call correctly function from list
context.getContentResolver().delete(Uri.parse("content://sms/"), "address=?", new String[]{smsSender});
}
}
}
}
The source code is catching SMS messages. I have a problem with where clause. Deleting SMS doesn't work.

Credits to the answer of "Maksim Dmitriev" from deleting-android-sms-programmatically
Please consider that you can't delete SMS messages on devices with Android 4.4.
Also, the system now allows only the default app to write message data to the provider, although other apps can read at any time.
http://developer.android.com/about/versions/kitkat.html
No exception will be thrown if you try; nothing will be deleted.

Related

How to open new Activity for Vcard and how to open Google Maps app?

I am making a qr code scanner app and I can't complete two things. The first one is to pass information about Vcard to a new Activity. Here is the code I wrote:
#Override
public void handleResult(Result rawResult) {
processRawResult(rawResult.getText());
}
private void processRawResult(String text){
if (text.startsWith("BEGIN:")) {
String[] tokens = text.split("\n");
QRVcardModel qrVcardModel = new QRVcardModel();
for (int i = 0; i < tokens.length; i++) {
if (tokens[i].startsWith("BEGIN:")) {
qrVcardModel.setType(tokens[i].substring("BEGIN:".length()));
} else if (tokens[i].startsWith("N:")) {
qrVcardModel.setName(tokens[i].substring("N:".length()));
} else if (tokens[i].startsWith("ORG:")) {
qrVcardModel.setOrg(tokens[i].substring("ORG:".length()));
} else if (tokens[i].startsWith("TEL:")) {
qrVcardModel.setTel(tokens[i].substring("TEL:".length()));
} else if (tokens[i].startsWith("URl:")) {
qrVcardModel.setUrl(tokens[i].substring("URL:".length()));
} else if (tokens[i].startsWith("EMAIL:")) {
qrVcardModel.setEmail(tokens[i].substring("EMAIL:".length()));
} else if (tokens[i].startsWith("ADR:")) {
qrVcardModel.setAddress(tokens[i].substring("ADR:".length()));
} else if (tokens[i].startsWith("NOTE:")) {
qrVcardModel.setNote(tokens[i].substring("NOTE:".length()));
} else if (tokens[i].startsWith("SUMMARY:")) {
qrVcardModel.setSummary(tokens[i].substring("SUMMARY:".length()));
} else if (tokens[i].startsWith("DTSTART:")) {
qrVcardModel.setDtstart(tokens[i].substring("DTSTART:".length()));
} else if (tokens[i].startsWith("DTEND:")) {
qrVcardModel.setDtend(tokens[i].substring("DTEND:".length()));
}
}
Intent intentVcard = new Intent(MainActivity.this, VcardActivity.class);
startActivity(intentVcard);
}
The second problem I face is that I can't open Google Maps app when I scan the Geoqrcode. Here is the code:
else if (text.startsWith("geo:"))
{
QRGeoModel qrGeoModel = new QRGeoModel();
String delims = "[ , ?q= ]+";
String tokens[] = text.split(delims);
for (int i=0;i<tokens.length;i++)
{
if (tokens[i].startsWith(" geo:"))
{
qrGeoModel.setLat(tokens[i].substring("geo:".length()));
}
}
qrGeoModel.setLat(tokens[0].substring("geo:".length()));
qrGeoModel.setLng(tokens[1]);
qrGeoModel.setGeo_place(tokens[2]);
Uri gmmIntentUri = Uri.parse("qrGeoModel.getLat(),qrGeoModel.getLng()");
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
}
Do you know how can I do that two?
You can pass values in Intent like this :
intentVcard.putExtra("value_name" , value);
value can be String, int, boolean, long and more (you can check in your ide what you can pass).
On the recieving activity you can get the value like this :
getIntent.getStrinExtra("value_name");
Be sure to replace it by your value name, for String it is like this, however for boolean it will be :
getIntent.getBooleanExtra("value_name" , defualt_value);
About the Google Maps problem, look at this line
Uri gmmIntentUri = Uri.parse("qrGeoModel.getLat(),qrGeoModel.getLng()");
you don't need " there, that way you will pass it all as a string and not the actual value of qrGeoModel.getLat(), insted write this line like that :
Uri gmmIntentUri = Uri.parse(qrGeoModel.getLat() + "," + qrGeoModel.getLng());

Best way to display an email (JavaMail Message) in android

I am building an android email client app. I managed to display the emails headers/senders in a RecylerView. Next, I want to start a new activity that will display the email content/attachments when the user chooses a specific mail.
I have a hard time doing this through intents. I am able to get the contents of the email (text, inline images, attachments) but I can't figure out a way to display them as close to the original format as possible. I thought of putting the text in a StringBuilder and sending it through an intent in order to display the text, but this way I can't display the inline images in the right place and there are also formatting problems.
Any kind of guidance towards the way I should approach this is much appreciated.
The class that displays the list of the available mails and gets the content of the specific mail to send it another activity for displaying it. I know the code is a little hazardous, I tried many approaches and it is far from the final form.
public class CheckMail extends Activity {
static List<Message> messages = new ArrayList<>();
String[] sender;
String[] date;
String[] subject;
boolean[] seen;
Context context = null;
ListView listView;
Intent intent;
Store store;
StringBuilder content = new StringBuilder();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_check_mail);
if (android.os.Build.VERSION.SDK_INT > 9)
{
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}
context = this;
ReadEmails task = new ReadEmails();
task.execute();
}
public void writePart(Part p) throws Exception {
if (p instanceof Message)
this.writeEnvelope((Message) p);
//check if the content is plain text
if (p.isMimeType("text/plain")) {
content.append(p.getContent().toString());
}
//check if the content has attachment
else if (p.isMimeType("multipart/*")) {
System.out.println("This is a Multipart");
System.out.println("---------------------------");
Multipart mp = (Multipart) p.getContent();
int count = mp.getCount();
for (int i = 0; i < count; i++)
writePart(mp.getBodyPart(i));
}
//check if the content is a nested message
else if (p.isMimeType("message/rfc822")) {
System.out.println("This is a Nested Message");
System.out.println("---------------------------");
writePart((Part) p.getContent());
}
/*
//check if the content is an inline image
else if (p.isMimeType("image/jpeg")) {
System.out.println("--------> image/jpeg");
Object o = p.getContent();
InputStream x = (InputStream) o;
// Construct the required byte array
System.out.println("x.length = " + x.available());
while ((i = (int) ((InputStream) x).available()) > 0) {
int result = (int) (((InputStream) x).read(bArray));
if (result == -1)
int i = 0;
byte[] bArray = new byte[x.available()];
break;
}
FileOutputStream f2 = new FileOutputStream("/tmp/image.jpg");
f2.write(bArray);
}
else if (p.getContentType().contains("image/")) {
System.out.println("content type" + p.getContentType());
File f = new File("image" + new Date().getTime() + ".jpg");
DataOutputStream output = new DataOutputStream(
new BufferedOutputStream(new FileOutputStream(f)));
com.sun.mail.util.BASE64DecoderStream test =
(com.sun.mail.util.BASE64DecoderStream) p
.getContent();
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = test.read(buffer)) != -1) {
output.write(buffer, 0, bytesRead);
}
}
else {
Object o = p.getContent();
if (o instanceof String) {
System.out.println("This is a string");
System.out.println("---------------------------");
System.out.println((String) o);
}
else if (o instanceof InputStream) {
System.out.println("This is just an input stream");
System.out.println("---------------------------");
InputStream is = (InputStream) o;
is = (InputStream) o;
int c;
while ((c = is.read()) != -1)
System.out.write(c);
}
else {
System.out.println("This is an unknown type");
System.out.println("---------------------------");
System.out.println(o.toString());
}
}
*/
}
public void writeEnvelope(Message m) throws Exception {
System.out.println("This is the message envelope");
System.out.println("---------------------------");
Address[] a;
StringBuilder sender = new StringBuilder();
StringBuilder recipients = new StringBuilder();
String subject = "";
// FROM
if ((a = m.getFrom()) != null) {
for (int j = 0; j < a.length; j++)
sender.append(a[j].toString());
}
// TO
if ((a = m.getRecipients(Message.RecipientType.TO)) != null) {
for (int j = 0; j < a.length; j++)
recipients.append(a[j].toString());
}
// SUBJECT
if (m.getSubject() != null)
subject = m.getSubject();
intent.putExtra("Sender", sender.toString());
intent.putExtra("Recipients", recipients.toString());
intent.putExtra("Message", subject);
intent.putExtra("Date", m.getReceivedDate().toString());
}
class ReadEmails extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
// Create all the needed properties - empty!
Properties connectionProperties = new Properties();
// Create the session
Session session = Session.getDefaultInstance(connectionProperties, null);
try {
System.out.print("Connecting to the IMAP server...");
// Connecting to the server
// Set the store depending on the parameter flag value
store = session.getStore("imaps");
// Set the server depending on the parameter flag value
String server = "imap.gmail.com";
store.connect(server, "....#gmail.com", "password");
System.out.println("done!");
// Get the Inbox folder
Folder inbox = store.getFolder("Inbox");
// Set the mode to the read-only mode
inbox.open(Folder.READ_ONLY);
// Get messages
CheckMail.messages = Arrays.asList(inbox.getMessages());
System.out.println("Reading messages...");
sender = new String[messages.size()];
date = new String[messages.size()];
subject = new String[messages.size()];
seen = new boolean[messages.size()];
for (int i = 0; i < messages.size(); i++) {
try {
Address[] froms = messages.get(i).getFrom();
String email = froms == null ? null : ((InternetAddress) froms[0]).getAddress();
sender[i] = email;
date[i] = messages.get(i).getReceivedDate().toString();
subject[i] = messages.get(i).getSubject();
Flags flags = messages.get(i).getFlags();
Flags.Flag[] sf = flags.getSystemFlags();
for (int j = 0; j < sf.length; j++) {
if (sf[j] == Flags.Flag.SEEN)
seen[i] = true;
else
seen[i] = false;
}
} catch (MessagingException e) {
e.printStackTrace();
}
}
System.out.println("Done reading...");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
CustomListAdapter whatever = new CustomListAdapter((Activity) context, sender, date, subject, seen);
listView = (ListView) findViewById(R.id.listviewID);
listView.setAdapter(whatever);
listView.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
try {
content.delete(0, content.length());
intent = new Intent(context, OpenMail.class);
writePart(messages.get(position));
intent.putExtra("Content", content.toString());
startActivity(intent);
}
catch (Exception e)
{e.printStackTrace();}
}
});
}
}
}
Since no one answered...I display emails via Javamail in some of my apps.
I think you're on the right track, having separate activities for the list and viewer is a good approach. [Or separate fragments because on a tablet you may want to display the list and the body on the same screen, side by side]
Couple issues that might come up:
I would be cautious about putting the email content in an extra to start the activity and/or committing it to saved instance state in the viewer activity because there are size limits [For example, 1MB for saved instance state on Android 7+]
Downloading the email in a ASyncTask in the activity might not be the best approach. I don't know the full purpose of the app, but I assume that is something that should succeed whether the user waits or not? The ASyncTask will continue to run if they task away, but it will hold on to the activity context causing a so called 'temporary memory leak'. It is probably best to put it in a service and download it in a separate thread. However, doing it in the activity as a proof of concept is perfectly reasonable...
I don't think that walking the message structure in the email list activity is the best approach. In my apps, I download email in a background service and commit the data to an SQL-DB via a ContentProvider. On the message viewer screen the email body is retrieved from the ContentProvider/SQL-DB using a component called the CursorLoader. It handles all the loading in the background so that the UI remains responsive whilst loading large mails. But in any event, I avoid passing the message body between activities.
A lot of emails have HTML parts (multipart/alternative: text/plain & text/html) so the viewer was implemented as a WebView. The WebView produced good looking emails with minimal effort.
Couple miscellaneous gotchas, when retrieving the mail, take care to call setPeek(true). It will stop the the READ flag being set. It is not an issue for GMail, but some IMAP servers will set this flag. Users will complain if any app other than their primary email app changes the READ flag. Also don't assume that any of the headers are present, SPAM emails are notorious for leaving out the message ID, subject and other fields. Finally, it might be worth considering implementing authentication via OAuth2 which will enable your app to connect to a user's GMail account via Javamail without needing their password.
I'm not sure that any of that really helps because it is a pretty big job, but one step at a time...Cheers!

Parse chat not getting received messages

We are implementing a chat in our android application. We have an userlist and of you click on one of the users, you start a chat with that user. We can send messages to the database with the sender and receiver and we can load these messages everytime we open that specific chat. We cannot, however, get the messages that are sent to the user from the database. This is how our Parse chat colums look like
This is our code for loading the conversation list:
private void loadConversationList()
{
final ParseQuery<ParseObject> q = ParseQuery.getQuery("Chat");
if (convList.size() == 0)
{
// load all messages...
ArrayList<String> al = new ArrayList<String>();
al.add(buddy);
al.add(UserList.user.getUsername());
q.whereContainedIn("sender", al);
q.whereContainedIn("receiver", al);
}
else
{
// load only newly received message..
if (li != null && li.size() > 0)
q.whereGreaterThan("createdAt", lastMsgDate);
q.whereEqualTo("sender", buddy);
q.whereEqualTo("receiver", UserList.user.getUsername());
}
q.orderByDescending("createdAt");
q.setLimit(30);
q.findInBackground(new FindCallback<ParseObject>()
{
#Override
public void done(List<ParseObject> li, ParseException e)
{
if (li != null && li.size() > 0)
{
for (int i = li.size() - 1; i >= 0; i--)
{
ParseObject po = li.get(i);
Conversation c = new Conversation(po
.getString("message"), po.getCreatedAt(), po.getString("sender"));
convList.add(c);
f = li.size();
if (lastMsgDate == null
|| lastMsgDate.before(c.getDate()))
lastMsgDate = c.getDate();
adp.notifyDataSetChanged();
}
}
handler.postDelayed(new Runnable() {
#Override
public void run()
{
if (isRunning)
loadConversationList();
}
}, 1000);
}
});
}
The conversation list is used to fill the screen with te messages. In SendMessage we also update the conversation list, only with the send messages of course. The problem is that the conversation list doesn't update the received messages

Android Service-Activity 2 way communication

in my team's Android application I have a service running from boot which communicates with a server to perform operations such as logging in, registering, chatting between phones and updating the phone database.
I need to make my service communicate with the activity bi-directionally: for example I am working on the login activity at the moment and the username and passwords are Strings taken from a text field on the app screen and I have been able to pass them to the service for it to send an authorisation command to the server.
public void loginPressed(View v){
usernameStr = usernameField.getText().toString();
passwordStr = passwordField.getText().toString();
if (!bound) return;
Bundle b = new Bundle();
Message msg = Message.obtain(null, ChatService.LOGIN);
try {
b.putString("username", usernameStr);
b.putString("password", passwordStr);
msg.setData(b);
messenger.send(msg);
}
catch (RemoteException e) {
}
This works as I would have expected. When the server responds with a message saying whether or not the login was sucessful, I need it to pass a message back to the activity so that I can start the main activity if succesful or prompt for re-entry if not.
I tried to use the msg.replyTo field to get the return messenger to send the information back, but when I run the app it force closes with a null pointer exception and I have no idea why this is happening. Here is the code that seems to be the culprit:
private class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch(msg.what) {
case LOGIN:
Bundle b = msg.getData();
String username = b.getString("username");
String password = b.getString("password");
String loginMessage = TCPCall.login(username, password);
connection.sendMessage(loginMessage);
String loginReturn = connection.retrieveMessage();
Message m;
Scanner s = new Scanner(loginReturn);
s.useDelimiter(",");
String c = s.next();
String status = s.next();
String message = s.next();
if (status.equals("OK")) {
m = Message.obtain(null, LoginActivity.OK);
try {
msg.replyTo.send(m);
} catch (RemoteException e) {}
}
else {
m = Message.obtain(null, LoginActivity.ERR);
try {
msg.replyTo.send(m);
} catch (RemoteException e) {}
}
break;
The null pointer seems to be coming from the
msg.replyTo.send(m);
line of code in both cases (login succesful and login failed)
Any help to fix this problem would be greatly appreciated :)
As Gregg points out in the comments. You need to set msg.replyTo = messenger; int he place where you send the original message.
An example can be found here: http://www.survivingwithandroid.com/2014/01/android-bound-service-ipc-with-messenger.html
I think you forgot to send response to Login Activity by bundle from Service.
So, i made some changes in Messenger Service
define one global variable and made some changes in Incoming Handler
static final int LOGIN_STATUS = 1;
private class IncomingHandler extends Handler {
#Override
public void handleMessage(Message msg) {
switch(msg.what) {
case LOGIN:
Bundle b = msg.getData();
String username = b.getString("username");
String password = b.getString("password");
String loginMessage = TCPCall.login(username, password);
connection.sendMessage(loginMessage);
String loginReturn = connection.retrieveMessage();
Message m = Message.obtain(null, LOGIN_STATUS);
Scanner s = new Scanner(loginReturn);
s.useDelimiter(",");
String c = s.next();
String status = s.next();
String message = s.next();
if (status.equals("OK")) {
b.putString("responseC",c);
b.putString("responseStatus",status);
b.putString("responseMessage",message)
m.setData(b);
try {
msg.replyTo.send(m);
} catch (RemoteException e) {}
}
else {
/*if something is wrong with username and password you can put
a toast*/
}
break;
Now we have to catch this response in our LoginActivity and
take IncomingHandler in Login Activity also
class IncomingHandler extends Handler{
#Override
public void handleMessage(Message msg) {
switch (msg.what){
case ChatService.LOGIN_STATUS:
String C = msg.getData().getString("responseC");
String Status = msg.getData().getString("responseStatus");
String Message = msg.getData().getString("responseMessage");
//Here is your response in LoginActivity, enjoy!!!
break;
default:
super.handleMessage(msg);
}
}
}
final Messenger mMessenger = new Messenger(new IncomingHandler());
public void loginPressed(View v){
usernameStr = usernameField.getText().toString();
passwordStr = passwordField.getText().toString();
if (!bound) return;
Bundle b = new Bundle();
Message msg = Message.obtain(null, ChatService.LOGIN_SATUS,0,0);
try {
b.putString("username", usernameStr);
b.putString("password", passwordStr);
msg.setData(b);
msg.replyTo = mMessenger;
messenger.send(msg);
}
catch (RemoteException e) {
// In this case the service has crashed before we could even
// do anything with it; we can count on soon being
// disconnected (and then reconnected if it can be restarted)
// so there is no need to do anything here.
}
This code is working perfectly, hope it will help you,
Thanks

Import .class file in android java

is there any other way to import another Java class from the same package in android?
I'm trying to import store.class to SMSreceiver.class
in SMSreceiver.class, i type in this code, store storingKey = new store();
but still cannot call the methods in store.class
this will be my store.class coding.
public class store extends Activity{
public store(){
}
public void saveToFile(String filename, String sms) throws NoSuchAlgorithmException, InvalidKeySpecException, IOException{
OutputStreamWriter out = new OutputStreamWriter(openFileOutput(filename, Context.MODE_APPEND));
out.write(sms);
out.close();
}
is there any problem with my coding?
any help?
Rob, this is my another class
public class storePubKey extends BroadcastReceiver
{
Activity ac = new Activity();
store sk = new store();
public void onReceive(Context context, Intent intent)
{
//---get the SMS message passed in---
Bundle bundle = intent.getExtras();
SmsMessage[] msgs = null;
String str = "";
if (bundle != null)
{
try{
//---retrieve the SMS message received---
Object[] pdus = (Object[]) bundle.get("pdus");
msgs = new SmsMessage[pdus.length];
for (int i=0; i<msgs.length; i++){
msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);
str = msgs[i].getMessageBody().toString();
Toast.makeText(context, "f", Toast.LENGTH_SHORT).show();
sk.saveToFile("public.key", str);
Toast.makeText(context,("public.keyasd"), Toast.LENGTH_SHORT).show();
}
}catch(Exception e){}
}
//---display the new SMS message---
try {
//Toast.makeText(context,str, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
EDIT: Try this
To call a non-static method in another class, you need a reference to that class.
store storeRef = new store(); // create new instance and set reference
storeRef.saveToFile(); // call the method
If you already have a reference to that class, you don't need to create it. A reference can be passed in a method call:
public void calledMethod(store storeRef) {
storeRef.saveToFile();
UPDATE
Change
storeKey sk = new storeKey();
to
store sk = new store();
Since store is your original class name, not storeKey.
You also may need to declare that withing the method you are trying to use it in.

Categories

Resources