Это работает для меня:
vertical_line.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<solid android:color="@android:color/transparent"/>
<stroke
android:width="1px"
android:color="#60000000"
android:dashGap="5px"
android:dashWidth="5px" />
</shape>
В макете:
<View
android:layout_width="1dp"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:background="@drawable/vertical_line" />
Мы используем 3 метода, в которых я работаю
Удачи. Вы правы в том, что намного легче отлаживать, если у вас есть трассировка стека и, возможно, даже экран того, что делал старый бедный пользователь.
Я бы посоветовал НЕ отправлять все (весь аудит вашего приложения).
Но только если пользователь этого хочет (кнопка «Отзыв») или если есть явное исключение, фатальная ошибка, состояние проблемы в приложении.
Мы использовали как веб-службы, так и электронную почту (SMTPClient). Мои мысли об этих
веб-сервисах
ХОРОШО
ПЛОХО
SMTPClient
ХОРОШО
BAD
Вы можете написать это сами или использовать что-то вроде log4net , он позаботится о регистрации исключений за вас ...
Каким-то образом сообщить пользователю, что вы собираетесь это сделать. Попросите у них прокси, попросите у них почтовый сервер или что-то в этом роде.
Заинтересованные в безопасности будут очень нервничать, если обнаружат, что вы открываете сокет или что-то в этом роде и отправляете данные без уведомления.
] И это правильно.
Мне нравится получать подобные вещи по электронной почте на специальный почтовый ящик. Таким образом, я могу легко заархивировать его, выполнить поиск или проигнорировать.
На стороне клиента / отправителя, я думаю, хорошей идеей будет всплывающее окно с предложением отправить журналы. Если окна, вы можете использовать MAPI для отправки электронной почты. В системе unix проблема «почты» работает в большинстве систем.
Вы можете запросить у пользователя адрес электронной почты в подтверждающем сообщении и, возможно, предложить несколько вариантов того, как его отправить (включая копирование / вставку в почтовый клиент по их выбору).
Вы должны НЕ отправлять информацию без разрешения пользователя.
Если вы не ожидаете, что за один день будет отправлено так много отчетов ... вы можете создать учетную запись gmail и использовать ее для отправки писем, чтобы обойти необходимость принуждения пользователя для настройки SMTP-сервера. Не знаю, каковы условия использования Gmail для этого.
Вот класс, который я написал, который отправляет электронное письмо с использованием учетной записи Gmail ...
Очевидно, здесь есть некоторые проблемы с безопасностью, например, кто-то потенциально может получить доступ к вашей учетной записи Gmail. Итак, примите это во внимание.
В этом классе есть методы для синхронной или асинхронной отправки электронной почты.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Collections;
using System.Text;
using System.Net;
using System.Net.Mail;
using System.Net.Mime;
//Mime is Not necerrary if you dont change the msgview and
//if you dont add custom/extra headers
using System.Threading;
using System.IO;
using System.Windows.Forms; // needed for MessageBox only.
namespace BR.Util
{
public class Gmailer
{
SmtpClient client = new SmtpClient();
static String mDefaultToAddress = "yourToAddress@yourdomain.com";
static String mDefaultFromAddress = "anonymous@gmail.com";
static String mDefaultFromDisplayName = "Anonymous";
String mGmailLogin = "someaccount@gmail.com";
String mGmailPassword = "yourpassword";
public Gmailer()
{
client.Credentials = new System.Net.NetworkCredential(mGmailLogin, mGmailPassword);
client.Port = 587;
client.Host = "smtp.gmail.com";
client.EnableSsl = true;
client.SendCompleted += new SendCompletedEventHandler(Gmailer_DefaultAsyncSendCompletedHandler);
}
public void setSendCompletedHandler(SendCompletedEventHandler pHandler)
{
client.SendCompleted -= Gmailer_DefaultAsyncSendCompletedHandler;
client.SendCompleted += pHandler;
}
/// <summary>
/// Static method which sends an email synchronously.
/// It uses a hardcoded from email.
/// </summary>
/// <returns></returns>
public static bool quickSend(String toEmailAddress, String subject, String body)
{
return Gmailer.quickSend(toEmailAddress, mDefaultFromAddress, mDefaultFromDisplayName, subject, body);
}
/// <summary>
/// Static method which sends an email synchronously.
/// It uses the hardcoded email address.
/// </summary>
/// <returns>true if successful, false if an error occurred.</returns>
public static bool quickSend(String toEmailAddress, String fromEmailAddress,
String fromDisplayName, String subject, String body)
{
try
{
Gmailer gmailer = new Gmailer();
System.Net.Mail.MailMessage mailMsg = gmailer.createMailMessage(toEmailAddress, fromEmailAddress, fromDisplayName, subject, body);
gmailer.send(mailMsg);
}
catch (Exception ex)
{
return false;
}
return true;
}
// <summary> creates a MailMessage object initialized with the default values.</summary>
public System.Net.Mail.MailMessage createMailMessage()
{
return createMailMessage(mDefaultToAddress, mDefaultFromAddress, mDefaultFromDisplayName, mDefaultEmailSubject, mDefaultEmailBody);
}
public System.Net.Mail.MailMessage createMailMessage(String toEmailAddress, String fromEmailAddress,
String fromDisplayName, String subject, String body)
{
//Build The MSG
System.Net.Mail.MailMessage msg = new System.Net.Mail.MailMessage();
msg.To.Add(toEmailAddress);
msg.From = new MailAddress(fromEmailAddress, fromDisplayName, System.Text.Encoding.UTF8);
msg.Subject = subject;
msg.SubjectEncoding = System.Text.Encoding.UTF8;
msg.Body = body;
msg.BodyEncoding = System.Text.Encoding.UTF8;
msg.IsBodyHtml = false;
msg.Priority = MailPriority.High;
return msg;
}
public System.Net.Mail.MailMessage addAttachmentToMailMessage(System.Net.Mail.MailMessage msg, String attachmentPath)
{
msg.Attachments.Add(new Attachment(attachmentPath));
return msg;
}
// <summary> method which blocks until the MailMessage has been sent. Throws
// System.Net.Mail.SmtpException if error occurs.</summary>
public void send(System.Net.Mail.MailMessage pMailMessage)
{
//try {
client.Send(pMailMessage);
//}
//catch (System.Net.Mail.SmtpException ex)
//{
// MessageBox.Show(ex.Message, "Send Mail Error");
//}
}
//
public void sendAsync(System.Net.Mail.MailMessage pMailMessage)
{
object userState = pMailMessage;
try
{
MailSent = false;
client.SendAsync(pMailMessage, userState);
}
catch (System.Net.Mail.SmtpException ex)
{
MessageBox.Show(ex.Message, "Send Mail Error");
}
}
// <summary>
// Provides a default SendComplete handler which is activated when an AsyncCompletedEvent
// is triggered by the private client variable. This is useful for debugging etc.
// Use the method setSendCompletedHandler to define your own application specific handler.
// That method also turns this handler off.
// </summary>
public void Gmailer_DefaultAsyncSendCompletedHandler(object sender, AsyncCompletedEventArgs e)
{
MailMessage mail = (MailMessage)e.UserState;
string subject = mail.Subject;
if (e.Cancelled)
{
string cancelled = string.Format("[{0}] Send canceled.", subject);
MessageBox.Show(cancelled);
}
if (e.Error != null)
{
string error = String.Format("[{0}] {1}", subject, e.Error.ToString());
MessageBox.Show(error);
}
else
{
MessageBox.Show("Message sent.");
}
MailSent = true;
}
private bool _MailSent = false;
/// <summary>
/// Set to false when an async send operation is started and is set to true when finished.
/// </summary>
public bool MailSent
{
set
{
_MailSent = value;
}
get
{
return _MailSent;
}
}
}
}