I have a task in which I have to send E-Mail each day once.
I used Service triggered by AlarmManager to achieve this. It's working properly. But the problem is the mail gets send only if the mobile data is available. So I tried to turn on the data connection and send mail. Mobile data is enabled but, Mail not sending. I have posted here what I've tried. Someone please suggest a method to wait until the user turn on mobile data and send mail. Thank you.
cm=(ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
ni=cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
isConnected=ni!=null&&ni.isConnected();
Mail m=new Mail("xxxxxxxxx#gmail.com","xxxxxxx");
String[] strTo={"xxxxxxxxx#gmail.com"};
m.setTo(strTo);
m.setFrom("xxxxxxxxxx#gmail.com");
m.setSubject("Subject");
m.setBody("Please find the attachment");
try{
m.addAttachment(Environment.getExternalStorageDirectory() + "/xxxxx/xxxxxx.xx");
if (isConnected){
m.send();
}else {
ConnectivityManager dataManager;
dataManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
Method dataMtd = null;
try {
dataMtd = ConnectivityManager.class.getDeclaredMethod("setMobileDataEnabled", boolean.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
dataMtd.setAccessible(true);
try {
dataMtd.invoke(dataManager, true);
} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
NetworkInfo netInfo=dataManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
boolean isOnline=netInfo!=null&&netInfo.isConnected();
if(isOnline){
if (m.send()){
ConnectivityManager dataManager1;
dataManager1 = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
Method dataMtd1 = null;
try {
dataMtd1 = ConnectivityManager.class.getDeclaredMethod("setMobileDataEnabled", boolean.class);
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
dataMtd1.setAccessible(false);
try {
dataMtd1.invoke(dataManager1, false);
} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
}catch (final Exception e){
e.printStackTrace();
Log.v("My_Service",e.toString());
}
You need to have BroadcastReceiver listening to change in data connectivity. Refer to - http://developer.android.com/reference/android/content/BroadcastReceiver.html
Check this for reference specific to network connectivity - Check INTENT internet connection
Don't relay on Google shit api... Info to the user to enable data + post delayed eg time task :) u can not handle all problems by enabling data.. But u can check for most : There could by a firewall issue , DNS issue, TTL issue when theter etc
You can register a BroadcastReceiver to be notified when a Mobile data is enabled.
Register the BroadcastReceiver:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION));
registerReceiver(broadcastReceiver, intentFilter);
And then in your BroadcastReceiver do something like this:
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION))) {
if (intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false)){
// data connection was lost
} else {
// do your stuff
}
}
}
For more info, see the documentation for BroadcastReceiver
You can use below link to send mail :
How to send mail without user interaction from another application
Related
I am making a chat application with smack library and openfire as a server but everytime i exit the chat conversation activity between two users and come back, the whole chat gets erased. I have already enabled archive settings to store one to one messages in the server but i do not know how to implement it in the app.
I want to show chats history in recyclerview by the sender and the receiver in the recyclerview.
currently i have implemented this function which caused error
private void setChatHistory(String entityBareId) {
EntityBareJid jid = null;
try {
jid = JidCreate.entityBareFrom(entityBareId);
} catch (XmppStringprepException e) {
e.printStackTrace();
}
MamManager manager = MamManager.getInstanceFor(mConnection);
MamManager.MamQueryResult r = null;
try {
try {
r = manager.mostRecentPage(jid, 10);
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotLoggedInException e) {
e.printStackTrace();
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
}
if (r.forwardedMessages.size() >= 1) //printing first of them
{
Message message = (Message) r.forwardedMessages.get(0).getForwardedStanza();
Log.i("mam", "message received" + message.getBody());
MessagesData data = new MessagesData("send",message.getBody());
mMessagesData.add(data);
mAdapter = new ConversationAdapter(mMessagesData);
recyclerView.setAdapter(mAdapter);
}
}
Error was
Attempt to read from field 'java.util.List org.jivesoftware.smackx.mam.MamManager$MamQueryResult.forwardedMessages' on a null object reference
At r.forwardedmessages.size()>=1.
Thanks in advance
If you want to keep history of conversation, you must save them in database. MAM just for fetching old conversation from server like when you uninstall or logout the app and decide to reinstall and get old messages.
For getting messages from server be sure you already enabled it, then forwarded messages shouldnt be null. here is a guide to enable it.
I am new to Openfire and smack, therefore I have questions regarding pubsub feature. Actually, I have created a node with setAccessModel as authorize, shown below.
PubSubManager mgr = new PubSubManager(xmpp.getConnection());
try {
LeafNode leaf = mgr.createNode("testNode");
ConfigureForm form = new ConfigureForm(DataForm.Type.submit);
form.setAccessModel(AccessModel.authorize);
form.setDeliverPayloads(true);
form.setNotifyRetract(true);
form.setPersistentItems(true);
form.setPublishModel(PublishModel.open);
leaf.sendConfigurationForm(form);
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
My question is that when somebody wants to subscribe to above node, how the owner of this node can handle the subscription request? Subscription part is as follows:
PubSubManager mgr = new PubSubManager(xmpp.getConnection());
// Get the node
LeafNode node = null;
try {
node = mgr.getNode("testNode");
node.addItemEventListener(new ItemEventCoordinator());
node.subscribe(senderUser+"#desi.loc");
} catch (SmackException.NoResponseException e) {
e.printStackTrace();
} catch (XMPPException.XMPPErrorException e) {
e.printStackTrace();
} catch (SmackException.NotConnectedException e) {
e.printStackTrace();
}
class ItemEventCoordinator implements ItemEventListener {
#Override
public void handlePublishedItems(ItemPublishEvent items) {
final ItemPublishEvent itemstemp=items;
runOnUiThread(new Runnable() {
#Override
public void run() {
//stuff that updates ui
dspySub.setText("Item: " + itemstemp.getItems());
}
});
}
}
When I set form.setAccessModel(AccessModel.open) every thing works fine. Users can publish and subscribe easily but when its AccessModel is authorize, owner don't listen, or might be I don't know how to handle subscription request at owner side with above piece of code. Kindly guide me.
Jawad, I've just replied another guy' question about listening subscription requests. Please take a look:
How can i listen incoming subscription request in smack openfire android
I really hope that it can help you.
Good luck!
PS.: Sorry, but I haven't enough reputation to do a comment :(
I have gone through some of the NFC related topics. But I did not find a clear and simple way to work with it or using NFC?
Another question is How can we recognize the device supports NFC or not,
Is there any code for that?
what makes it different from bluetooth?
All suggestions will be appreciated.
To check if device support NFC :
NfcManager manager = (NfcManager) context.getSystemService(Context.NFC_SERVICE);
NfcAdapter adapter = manager.getDefaultAdapter();
if (adapter != null && adapter.isEnabled()) {
//Yes NFC available
}else{
//Your device doesn't support NFC
}
And here is all for NFC : https://developer.android.com/guide/topics/connectivity/nfc/index.html
If you have rooted device you can easily toggle NFC mode:
public static boolean powerNfc(boolean isOn, Context context) {
boolean success = false;
NfcAdapter nfcAdapter = NfcAdapter.getDefaultAdapter(context);
if (nfcAdapter != null) {
Class<?> NfcManagerClass;
Method setNfcEnabled;
try {
NfcManagerClass = Class.forName(nfcAdapter.getClass().getName());
setNfcEnabled = NfcManagerClass.getDeclaredMethod(isOn ? "enable" : "disable");
setNfcEnabled.setAccessible(true);
success = (Boolean) setNfcEnabled.invoke(nfcAdapter);
} catch (ClassNotFoundException e) {
} catch (NoSuchMethodException e) {
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {
}
}
return success;
}
You also need to add permission write secure settings.
It's already tested.
I want to pair two android bluetooth devices (Kitkat) without any popup for passkey exchange. I tried setpin() and cancelPairingUserInput() methods inside the broadcast receiver for PAIRING_REQUEST intent using reflection, but got no results. Can anyone help me with that ?
if(BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)){
BluetoothDevice localBluetoothDevice = (BluetoothDevice)intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE");
try {
Log.d("setPin()", "Try to set the PIN");
Method m = localBluetoothDevice.getClass().getMethod("setPin", byte[].class);
m.invoke(localBluetoothDevice, ByteBuffer.allocate(4).putInt(1234).array());
Log.d("setPin()", "Success to add the PIN.");
} catch (Exception e) {
Log.e("setPin()", e.getMessage());
}
Class localClass = localBluetoothDevice.getClass();
Class[] arrayOfClass = new Class[0];
try {
localClass.getMethod("setPairingConfirmation", boolean.class).invoke(localBluetoothDevice, true);
localClass.getMethod("cancelPairingUserInput", arrayOfClass).invoke(localBluetoothDevice, null);
} catch (IllegalAccessException | IllegalArgumentException
| InvocationTargetException | NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Did you try calling createBond() through reflection?
This works for me, with device being a BluetoothDevice:
Method m = device.getClass().getMethod("createBond", (Class[]) null);
m.invoke(device, (Object[]) null);
Get the device and the PIN (or the pairing key) from the given Intent
if the given PIN is not -1, set it in the device
invoke the device's .setPairingConfirmation() method
My code (which achieves this) in the .bluetoothEventReceived() callback method, looks something like this:
private void bluetoothEventRecieved(Context context, Intent intent)
{
if (BluetoothDevice.ACTION_PAIRING_REQUEST.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int pin = intent.getIntExtra(BluetoothDevice.EXTRA_PAIRING_KEY, -1);
if (pin != -1) {
byte[] pinBytes = String.format(Locale.US, "%04d", pin).getBytes();
device.setPin(pinBytes);
}
device.setPairingConfirmation(true);
}
}
I am writing an application which sends data to bluetooth printer. Can anyone help me ? how can I use android Bluetooth Stack for printing? or is there any external api or sdk to use?
Here is my code for searching bluetooth...
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
registerReceiver(ActionFoundReceiver,
new IntentFilter(BluetoothDevice.ACTION_FOUND));
private final BroadcastReceiver ActionFoundReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
btArrayAdapter.add(device.getName() + "\n"
+ device.getAddress());
btArrayAdapter.notifyDataSetChanged();
}
}
};
and here is my code for sending data to printer..
BluetoothDevice mDevice = bluetoothAdapter.getRemoteDevice("00:15:FF:F2:56:A4");
Method m = mDevice.getClass().getMethod("createRfcommSocket",
new Class[] { int.class });
mBTsocket = (BluetoothSocket) m.invoke(mDevice, 1);
System.out.println("Connecting.....");
mBTsocket.connect();
System.out.println("Connected");
OutputStream os = mBTsocket.getOutputStream();
os.flush();
os.write(Receipt.getBytes());
// mBTsocket.close();
When I write socket.close() , data is not getting print to printer as socket connection getting closed before printing data..and if I didn't write socket.close() then data is getting printed only once.. I would not be able to print data second time until I restart bluetooth of my phone.
can any one have solution for it??? or is there any other way to get rid of this printing??
I got the solution of my problem...
if i want to print data more than one time then you dont need to create new Socket Connection with the device... instead call outputstream.write(bytes) method.
and in the end if you want to disconnect device then call mBTScoket.close() method to disconnect device.
You can use printooth library for any printer, printooth is simple and well documented,
https://github.com/mazenrashed/Printooth
var printables = ArrayList<Printable>()
var printable = Printable.PrintableBuilder()
.setText("Hello World") //The text you want to print
.setAlignment(DefaultPrinter.ALLIGMENT_CENTER)
.setEmphasizedMode(DefaultPrinter.EMPHASISED_MODE_BOLD) //Bold or normal
.setFontSize(DefaultPrinter.FONT_SIZE_NORMAL)
.setUnderlined(DefaultPrinter.UNDELINED_MODE_ON) // Underline on/off
.setCharacterCode(DefaultPrinter.CHARACTER_CODE_USA_CP437) // Character code to support languages
.setLineSpacing(DefaultPrinter.LINE_SPACING_60)
.setNewLinesAfter(1) // To provide n lines after sentence
.build()
printables.add(printable)
BluetoothPrinter.printer().print(printables)
If you have made connection to the devices and paired it.
So for printing, printer wants the byte. SO I have createed a mothod.
Simply call this method and pass the String inside it to get printed.
String str = new String("This is the text sending to the printer");
private void printData() {
// TODO Auto-generated method stub
String newline = "\n";
try {
out.write(str.getBytes(),0,str.getBytes().length);
Log.i("Log", "One line printed");
} catch (IOException e) {
Toast.makeText(BluetoothDemo.this, "catch 1", Toast.LENGTH_LONG).show();
e.printStackTrace();
Log.i("Log", "unable to write ");
flagCheck = false;
}
try {
out.write(newline.getBytes(),0,newline.getBytes().length);
} catch (IOException e) {
Log.i("Log", "Unable to write the new line::");
e.printStackTrace();
flagCheck = false;
}
flagCheck = true;
}