Email not sending in unity android? - android

I have looked many source and question but I am still not clear to how this code of sending email through unity is not working in android build. It works fine in windows build but doesn't work in android. Can someone help me. Here is the code -
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Net;
using System.Net.Mail;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;
using UnityEngine;
public class EmailUnity
{
public static string SenderEmail;
public static string SenderPassword;
public static string SmtpClient;
public static int SmtpPort;
public static void SendEmail(string to, string subject, string body, bool isHtml, string[] attachmentPaths,
Action<object, AsyncCompletedEventArgs> callback = null)
{
try
{
SmtpClient emailServer = new SmtpClient(SmtpClient, SmtpPort);
emailServer.EnableSsl = true;
emailServer.Credentials = (ICredentialsByHost) new NetworkCredential(SenderEmail, SenderPassword);
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
MailMessage message = new MailMessage(SenderEmail, to);
message.Subject = subject;
message.Body = body;
message.IsBodyHtml = isHtml;
foreach (string path in attachmentPaths)
{
if (!string.IsNullOrEmpty(path) && File.Exists(path))
{
message.Attachments.Add(new Attachment(path));
}
}
if (callback == null)
{
callback = SampleCallback;
}
emailServer.SendCompleted += new SendCompletedEventHandler(callback);
emailServer.SendAsync(message, "");
Debug.Log("Email sending");
}
catch (Exception ex)
{
Debug.Log("Error: " + ex.Message);
callback("", new AsyncCompletedEventArgs(ex, true, "Exception occured"));
}
}
private static void SampleCallback(object sender, AsyncCompletedEventArgs e)
{
if (e.Cancelled || e.Error != null)
{
Debug.Log("Error: " + e.Error.Message);
}
else
{
Debug.Log("Email sent");
}
}
}

These are the things to try if SmtpClient is not working on Android.
Go to File --> Build Settings... --> Select Android. Now, click on Player Settings.
1.On the Internet Access, change it from Auto to Require.
2.Make sure that API Compatible Level is set to .NET 2.0 not .NET 2.0 Subset.
3.Make sure that Stripping Level is set to Disabled.
4.Go to Player settings --> Android and change Internet Access from Auto to Require

Related

How do I send data from an android wearable device to a phone in the form of a a simple text file containing data?

I have a wearable app. The app after it finishes has data like time/date, UUID, Geo location, parameters selected displayed in front of me like a Data Report or Log in several TextViews underneath each other. Like a list. I want this data to be transferred from my wearable device to my android phone.
Now I have to ask does the WearOS app the pairs the phone with the watch enables such a thing? Like can the data be sent through it? OR what exactly can I do? I read about Sync data items with the Data Layer API in the documentation, but I'm not sure if the code snippets provided would help achieve what I want.
public class MainActivity extends Activity {
private static final String COUNT_KEY = "com.example.key.count";
private DataClient dataClient;
private int count = 0;
...
// Create a data map and put data in it
private void increaseCounter() {
PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
putDataMapReq.getDataMap().putInt(COUNT_KEY, count++);
PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
Task<DataItem> putDataTask = dataClient.putDataItem(putDataReq);
}
...
}
The data I display in the textviews are called through methods that I call things like: getLocation, getUUID, getDateTime, getSelections, etc... when I click a button I call them in the setOnClickListener. I want this data in the TextViews to be placed in a file or something like that and send them over to the mobile phone from the watch when they're generated.
private void getDateTime()
{
SimpleDateFormat sdf_date = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat sdf_time = new SimpleDateFormat("HH:mm:ss z");
String currentDate= sdf_date.format(new Date());
String currentTime= sdf_time.format(new Date());
textView_date_time.setText("Date: "+currentDate+"\n"+"Time: "+currentTime);
}
#SuppressLint("SetTextI18n")
private void getUUID()
{
// Retrieving the value using its keys the file name
// must be same in both saving and retrieving the data
#SuppressLint("WrongConstant") SharedPreferences sh = getSharedPreferences("UUID_File", MODE_APPEND);
// The value will be default as empty string because for
// the very first time when the app is opened, there is nothing to show
String theUUID = sh.getString(PREF_UNIQUE_ID, uniqueID);
// We can then use the data
textView_UUID.setText("UUID: "+theUUID);
}
#SuppressLint("SetTextI18n")
private void getSelections()
{
textView_data_selected.setText("Tool No.: "+c.getToolNo()+
"\nTool Size: " +c.getToolSizeStr()+
"\nFrom Mode: " +c.getCurrentModeStr()+
"\nGoto Mode: " +c.getModeStr()+
"\nMethod: " +c.getMethodStr()+
"\nBit Duration: " +c.getBitDuration()+
"\nUpper bound" +c.getUpStageValue()+
"\nLower bound: "+c.getDownStageValue());
}
The above are examples of the methods I use to get the data. then I call them here:
gps_btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (Build.VERSION.SDK_INT >= 26) {
getLocation();
getDateTime();
getUUID();
getSelections();
}
else
{
//ActivityCompat.requestPermissions(get_location.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
Toast.makeText(get_location.this,"Build SDK too low",Toast.LENGTH_SHORT);
}
}
});
Now how do I take all this and send it over from my device to the the phone?
Note: The data report I want to send as a file, I want it done subtly like something done in the background. I don't know what else to do or where to look.
You have two options if you want to use the Data Layer, one is to use the MessageClient API to bundle your data up in a message and send it directly to the handheld. The easiest here would be to create an arbitrary JSONObject and serialize your data as a JSON string you can stuff into a message. For example:
try {
final JSONObject object = new JSONObject();
object.put("heart_rate", (int) event.values[0]);
object.put("timestamp", Instant.now().toString());
new MessageSender("/MessageChannel", object.toString(), getApplicationContext()).start();
} catch (JSONException e) {
Log.e(TAG, "Failed to create JSON object");
}
In my case, I do this in my onSensorChanged implementation, but you can insert this wherever you are updating your text.
MessageSender is just a threaded wrapper around the MessageClient:
import java.util.List;
class MessageSender extends Thread {
private static final String TAG = "MessageSender";
String path;
String message;
Context context;
MessageSender(String path, String message, Context context) {
this.path = path;
this.message = message;
this.context = context;
}
public void run() {
try {
Task<List<Node>> nodeListTask = Wearable.getNodeClient(context.getApplicationContext()).getConnectedNodes();
List<Node> nodes = Tasks.await(nodeListTask);
byte[] payload = message.getBytes();
for (Node node : nodes) {
String nodeId = node.getId();
Task<Integer> sendMessageTask = Wearable.getMessageClient(context).sendMessage(nodeId, this.path, payload);
try {
Tasks.await(sendMessageTask);
} catch (Exception exception) {
// TODO: Implement exception handling
Log.e(TAG, "Exception thrown");
}
}
} catch (Exception exception) {
Log.e(TAG, exception.getMessage());
}
}
}
The other option is to create a nested hierarchy of data items in the Data Layer and implement DataClient.OnDataChangedListener on both sides, such that changes that are written in on one side are automatically synchronized with the other. You can find a good walkthrough on how to do that here.
For your specific case, just packing it in a JSON object would probably be the simplest. The writing out to your preferred file format you can then implement on the handheld side without needing to involve the wear side.

Pusher for Android Implementation

I'm trying to implement a pusher service in my Android app, doesn't have access to the server just copying from an iOS app previous implementation. Everything works fine in connection process but when subscribe to a private channel the authentication fails with:
"com.pusher.client.AuthorizationFailureException: java.io.FileNotFoundException: https://authorization_url"
The implementation goes like this:
HttpAuthorizer authorizer = new HttpAuthorizer(PUSHER_AUTH_URL);
PusherOptions options = new PusherOptions().setEncrypted(true).setWssPort(443).setAuthorizer(authorizer);
pusher = new Pusher(PUSHER_KEY, options);
pusher.connect(new com.pusher.client.connection.ConnectionEventListener() {
#Override
public void onConnectionStateChange(ConnectionStateChange change) {
if (change.getCurrentState() == ConnectionState.CONNECTED) {
Channel channel = pusher.subscribePrivate(PUSH_CHANNEL, new PrivateChannelEventListener() {
#Override
public void onAuthenticationFailure(String s, Exception e) {
Log.w("PUSHER", "Channel subscription authorization failed");
}
#Override
public void onSubscriptionSucceeded(String s) {
Log.w("PUSHER", "Channel subscription authorization succeeded");
}
#Override
public void onEvent(String s, String s2, String s3) {
Log.w("PUSHER", "An event with name " + s2 + " was delivered!!");
}
}, "my-event");
}
}
#Override
public void onError(String message, String code, Exception e) {
Log.w("PUSHER", "There was a problem connecting with code " + code + " and message " + message);
}
}, ConnectionState.ALL);
UPDATE
I'm sure that the problem is with the authentication, there is a function call in iOS version that set some headers to the channel subscription or something like that:
(void)pusher:(PTPusher *)pusher willAuthorizeChannel:(PTPusherChannel *)channel withRequest:(NSMutableURLRequest *)request;
{
[request addAuthorizationHeadersForUser:self.credentials.user];
}
Im trying to figure out where to add the headers in android, try to add it to the authorizer but nothing change:
authorizer.setHeaders(addMapAuthorizationHeaders());
Any idea of what is the equivalent in Android of that iOS function: willAuthorizeChannel??
Ok solved, it was what I thought, the HttpAuthorizer needed a set of headers that you can set directly when creating it like:
HttpAuthorizer authorizer = new HttpAuthorizer(PUSHER_AUTH_URL);
authorizer.setHeaders(MY_AUTH_HEADERS); //a HashMap with the headers
PusherOptions options = new PusherOptions().setEncrypted(true).setWssPort(443).setAuthorizer(authorizer);
pusher = new Pusher(PUSHER_KEY, options);
And with that works fine, in case somebody have a similar problem.
EDIT:
this is how to set the authorization headers. It's a Map set to "Key" "Value" pair for example:
public static HashMap<String, String> getMapAuthorizationHeaders() {
try {
HashMap<String, String> authHeader = new HashMap<>();
authHeader.put("HeaderKey1", "HeaderValue1");
authHeader.put("HeaderKey2", "HeaderValue2");
return authHeader;
} catch (Exception e) {
return null;
}
}
So the pusher config will be like:
authorizer.setHeaders(getMapAuthorizationHeaders());
I've been struggling with this as well... the solution is simple.
First check this out: https://github.com/pusher/pusher-websocket-java/blob/master/src/main/java/com/pusher/client/util/HttpAuthorizer.java
Then implement the abstract interface Authorizer and override the authorize method with your own code and that's it, you get the same thing as on the iOS.
Some snippet to get you started (with a custom constructor):
CustomSocketHttpAuthorizer authorizer = new CustomSocketHttpAuthorizer(ServerComm.API_MAIN_LINK + ServerComm.API_LINK_PUSHER_AUTH, pusherServerAuthTimeStamp, MessageActivity.this);
PusherOptions options = new PusherOptions().setAuthorizer(authorizer).setEncrypted(true);;
clientPusher = new Pusher(ServerComm.PUSHER_CLIENT_KEY, options);
clientPusher.connect(new ConnectionEventListener() .....

how to connect apigee proxy (Oauth verify) by using apigee android sdk?

i would like to use apigee android sdk in android app. By using android sdk, I would like to connect apigee end point proxy but api proxy has got Oauth 2.0 verification. How to access our proxy?
//Create client entity
String ORGNAME = "your-org";
String APPNAME = "your-app";
ApigeeClient apigeeClient = new ApigeeClient(ORGNAME,APPNAME);
DataClient dataClient = apigeeClient.getDataClient();
String type = "item"; //entity type to be retrieved
Map queryString = null; //we don't need any additional query parameters, in this case
//call getCollectionAsync to initiate the asynchronous API call
dataClient.getCollectionAsync(type, queryString, new ApiResponseCallback() {
//If getEntitiesAsync fails, catch the error
#Override
public void onException(Exception e) {
// Error
}
//If getCollectionAsync is successful, handle the response object
#Override
public void onResponse(ApiResponse response) {
try {
if (response != null) {
// Success
}
} catch (Exception e) { //The API request returned an error
// Fail
}
}
});
There is currently no support for OAuth in the Android SDK.

I can't see my Layout (Monodroid + MS Visual Studio 2010)

I'm making a very simple software with a TCP Listener that (until now) only receives a message from a TCP Client codified in ASCII and I'll have to do something with the UI that I still don't know, but by now, I'm just trying to show an AlertDialog with this message on Samsung Galaxy Tab.
The problem is that, I believe that for some reason the setContentView is not working. I have one .axml (layout) file with an AbsoluteLayout, and I'm calling this AbsoluteLayout on code, changing its color, and trying to show this AbsoluteLayout (with its color changed) on the screen, but the problem is that I just see the regular black screen.
I started debugging the code, and I can see the all the Console.Writeline commands on the output of the MS VS 2010, even the message sent from the client. But I can't see the layout and the AlertDialog.
Can anybody help me? Thanks in advance.
using System;
using Android.App;
using Android.Content;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Android.Graphics.Drawables;
using System.Drawing;
namespace Gafisa.Automacao.VideoWall.Listener
{
[Activity(Label = "Listener", MainLauncher = true, Icon = "#drawable/icon")]
public class Activity1 : Activity
{
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
AbsoluteLayout abs = FindViewById<AbsoluteLayout>(Resource.Id.abslayout);
abs.SetBackgroundColor(new Android.Graphics.Color(125,125,125,125));
//ImageButton btn = new ImageButton(this);
//var lp = new AbsoluteLayout.LayoutParams(50, 50, 200, 200);
//btn.LayoutParameters = lp;
//BitmapDrawable dd = new BitmapDrawable("/mnt/sdcard/1.png");
//btn.SetBackgroundDrawable(dd);
//abs.AddView(btn);
System.Net.Sockets.TcpListener listener = null;
byte[] rcvBuffer = new byte[40];
int bytesRcvd;
try
{
listener = new System.Net.Sockets.TcpListener(IPAddress.Any, 13000);
listener.Start();
Console.WriteLine("Listener iniciado");
}
catch (SocketException se)
{
Console.WriteLine("Erro ao iniciar o listener: " + se.Message);
}
for (;;)
{
TcpClient client = null;
NetworkStream netStream = null;
try
{
client = listener.AcceptTcpClient();
netStream = client.GetStream();
int totalBytesEchoed = 0;
while ((bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0)
{
netStream.Write(rcvBuffer, 0, bytesRcvd);
totalBytesEchoed += bytesRcvd;
}
string recebido = System.Text.Encoding.ASCII.GetString(rcvBuffer);
Console.WriteLine(recebido);
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetMessage(recebido);
alert.SetTitle("Mensagem Recebida");
alert.Show();
Console.WriteLine("echoed {0} bytes.", totalBytesEchoed);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine("Erro no LOOP");
}
finally
{
netStream.Close();
client.Close();
}
}
}
}
}
By running an infinite loop in this OnCreate function, you prevents the UI framework from finishing rendering. That's why what you see is only the black screen.
You are supposed to run non-UI code asynchronously (in a separate thread).
Change it to
Task.Factory.StartNew(() =>
{
for (;;)
{
TcpClient client = null;
NetworkStream netStream = null;
try
{
client = listener.AcceptTcpClient();
netStream = client.GetStream();
int totalBytesEchoed = 0;
while ((bytesRcvd = netStream.Read(rcvBuffer, 0, rcvBuffer.Length)) > 0)
{
netStream.Write(rcvBuffer, 0, bytesRcvd);
totalBytesEchoed += bytesRcvd;
}
string recebido = System.Text.Encoding.ASCII.GetString(rcvBuffer);
Console.WriteLine(recebido);
RunOnUiThread(() =>
{
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetMessage(recebido);
alert.SetTitle("Mensagem Recebida");
alert.Show();
}
Console.WriteLine("echoed {0} bytes.", totalBytesEchoed);
}
catch (Exception e)
{
Console.WriteLine(e.Message);
Console.WriteLine("Erro no LOOP");
}
finally
{
netStream.Close();
client.Close();
}
}
}
Also with Mono for Android (Xamarin.Android) you should use Log.Info(string tag, string message) where tag is the name of calling class. Don't use Console.WriteLine(string). You can also use Log.Warn(string, string) and Log.Error(string, string)

How to access database using phone gap

I am new to android phonegap. i am storing and retrieving data using native application. i dont know how to display the retrieved data from native to phonegap(HTML)page.
can anyone pls guide me how to access sqlite with phonegap.?
Thanks in advance.
You need to first create a Android plugin for Phonegap through which you will be able to access the native code and hence the native DB like this
public class SqlitePlugin extends Plugin {
private static final String TAG = "SqlitePlugin";
private static final String CREATE_DB_ACTION = "createDatabase";
private static final String SHOW_DB_VALUES_ACTION = "showValues";
#Override
public PluginResult execute(String action, JSONArray data, String callbackId) {
Log.i(TAG, "Plugin Called");
PluginResult result = null;
if (CREATE_DB_ACTION.equals(action)) {
Log.d(TAG, "CREATE_DB_ACTION");
DB _db = new DB(ctx);
_db.insertValues();
}
else if (SHOW_DB_VALUES_ACTION.equals(action)) {
Log.d(TAG, "SHOW_DB_VALUES_ACTION");
JSONObject DBInfo = null;
try {
DBInfo = getDBValuesListing();
} catch (JSONException e) {
e.printStackTrace();
}
result = new PluginResult(Status.OK, DBInfo);
}
else {
result = new PluginResult(Status.INVALID_ACTION);
Log.d(TAG, "Invalid action : " + action + " passed");
}
return result;
}
}
After that Create a sqlite.js file like this
function SqlitePlugin() {
};
SqlitePlugin.prototype.createDatabase = function(successCallback, failCallback) {
return PhoneGap.exec(successCallback, failCallback, "SqlitePlugin",
"createDatabase", [ null ]);
};
SqlitePlugin.prototype.showValues = function(params, successCallback, failCallback) {
return PhoneGap.exec(successCallback, failCallback, 'SqlitePlugin', 'showValues',
[ params ]);
};
PhoneGap.addConstructor(function() {
PhoneGap.addPlugin("SqlitePlugin", new SqlitePlugin());
});
Import this sqlite.js in your page(index.html) and then finally use the plugin like this
function showValues() {
window.plugins.SqlitePlugin.showValues('showValues',
showValuesSuccessCallBack, showValuesFailCallBack);
}
function showValuesSuccessCallBack(e) {
if (e.Rows.length > 0) {
alert("Success");
for (i = 0; i < e.Rows.length; i++) {
alert("Id = " + e.Rows[i].id);
alert("Number = " + e.Rows[i].number);
}
} else {
alert("No values in Database");
}
}
function showValuesFailCallBack(f) {
alert("Failure");
}
Let me know if this worked out for you
Write an phonegap plugin to pass the data from native side to html (js)
http://wiki.phonegap.com/w/page/36753494/How%20to%20Create%20a%20PhoneGap%20Plugin%20for%20Android
Well, you probably should use the HTML5 functions to store and retrieve data from a sqlite DB. However, if you are set on doing it with native code you should look at our implementation which was used for older Android devices that don't support sqlite.
https://github.com/cordova/cordova-android/blob/master/framework/assets/js/storage.js
https://github.com/cordova/cordova-android/blob/master/framework/src/com/phonegap/Storage.java

Categories

Resources