2017-02-25 105 views
0

我正在开发一个Android应用程序,它将读取任何收到的短信并将它们发布到在线数据库中。我希望所有这些都发生在后台,因此不涉及UI。只是一个接收器和一个意向服务。用Xamarin和C导入到数据库的短信阅读器#

因此,我尝试的是创建一个广播接收器,它将查找接收到的短信,一旦发现它将启动一个将短信发送到数据库的服务。我设法让这个与用另一个代码打开的UI一起工作。但我希望这可以不必打开我的应用程序。

这是我现在的代码。有什么问题吗?有一点要提到的是,如果我打开应用程序并收到消息,那么应用程序崩溃!如果有人能帮助我,我会很感激!

SmsReciever(我知道我写的接收器错误)

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using Android.App; 
using Android.Content; 
using Android.OS; 
using Android.Runtime; 
using Android.Views; 
using Android.Widget; 
using Android.Telephony; 
using Android.Provider; 

namespace Services_Log 
{ 
    [BroadcastReceiver(Enabled = true, Label = "SMS Receiver")] 
    [IntentFilter(new[] { "android.provider.Telephony.SMS_RECEIVED" })] 
    public class SmsReciever : BroadcastReceiver 
    { 
     private const string Tag = "SMSBroadcastReceiver"; 
     private const string IntentAction = "android.provider.Telephony.SMS_RECEIVED"; 
     public override void OnReceive(Context context, Intent intent) 
     { 
      try 
      { 
       Intent smsIntent = new Intent(context, typeof(SmsService)); 
       if (intent.Action != IntentAction) return; 
       SmsMessage[] messages = Telephony.Sms.Intents.GetMessagesFromIntent(intent); 
       for (int i=0; i<messages.Length; i++) 
       { 
        smsIntent.PutExtra("sms_number", messages[i].OriginatingAddress); 
        smsIntent.PutExtra("sms_body", messages[i].MessageBody); 
        context.StartService(smsIntent); 
       } 
      } 
      catch (Exception ex) 
      { 
       Toast.MakeText(context, ex.Message, ToastLength.Long).Show(); 
      } 
     } 
    } 
} 

SmsService

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

using Android.App; 
using Android.Content; 
using Android.OS; 
using Android.Runtime; 
using Android.Views; 
using Android.Widget; 
using MySql.Data.MySqlClient; 
using System.Data; 
using Android.Service; 

namespace Services_Log 
{ 
    [Service] 
    public class SmsService : IntentService 
    { 
     public SmsService() : base("SmsService") 
     { 

     } 

     protected override void OnHandleIntent(Intent intent) 
     { 
      Context context = this; 
      Toast.MakeText(context,"Service Started", ToastLength.Long).Show(); 
      MySqlConnection con = new MySqlConnection("Server=db4free.net;Port=3306;database=testdbs;User Id=venoom;Password=takefree1;charset=utf8"); 

      string smsNumber = intent.GetStringExtra("sms_number"); 
      string smsBody = intent.GetStringExtra("sms_body"); 

      try 
      { 
       con.Open(); 
       MySqlCommand cmd = new MySqlCommand("INSERT INTO tableTest(number,message) VALUES(@number,@message)"); 
       cmd.Connection = con; 
       cmd.Parameters.AddWithValue("@number",smsNumber); 
       cmd.Parameters.AddWithValue("@message", smsBody); 
       Toast.MakeText(context, "Succsesfully uploaded to database!", ToastLength.Long).Show(); 
       cmd.ExecuteNonQuery(); 
      } 
      catch (MySqlException ex) 
      { 
       Toast.MakeText(context, ex.Message, ToastLength.Long).Show(); 
      } 
      finally 
      { 
       con.Close(); 
      } 
     } 
    } 
} 

MainActivity(留空)

using Android.App; 
using Android.Widget; 
using Android.OS; 

namespace Services_Log 
{ 
    [Activity(Label = "Services_Log", MainLauncher = true, Icon = "@drawable/icon")] 
    public class MainActivity : Activity 
    { 
     protected override void OnCreate(Bundle bundle) 
     { 
      base.OnCreate(bundle); 

      // Set our view from the "main" layout resource 
      // SetContentView (Resource.Layout.Main); 
     } 
    } 
} 

AndroidManifest

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="Services_Log.Services_Log" android:versionCode="1" android:versionName="1.0" android:installLocation="auto"> 
    <uses-sdk android:minSdkVersion="16" /> 
    <uses-permission android:name="android.permission.SEND_SMS" /> 
    <uses-permission android:name="android.permission.RECEIVE_SMS" /> 
    <uses-permission android:name="android.permission.READ_SMS" /> 
    <uses-permission android:name="android.permission.BROADCAST_SMS" /> 
    <application android:label="Services Log" android:icon="@drawable/Icon"> 
     <receiver android:name="SmsReciever"> 
      <intent-filter> 
       <action android:name="android.provider.Telephony.SMS_RECEIVED" /> 
      </intent-filter> 
     </receiver> 
    <receiver android:name=".SmsReciever"> 
     <intent-filter> 
     <action android:name="android.provider.Telephony.SMS_RECEIVED" /> 
     </intent-filter> 
    </receiver> 
    </application> 
</manifest> 

回答

2

是的,你正在做的事情是错误的。

接收机

没有手动的服务让您AndroidManifest.xml补充。通过使用BroadcastReceiver,IntentFilterServices属性,您可以告诉xamarin编译器为AndroidManifest中的这些接收器,服务,活动...生成条目。您可以通过openening所产生的AndroidManifest.xml中obj\Debug\android

<receiver android:enabled="true" android:label="SMS Receiver" android:name="md563471986402eafe51037cbcf251950c3.SmsReciever"> 
    <intent-filter> 
    <action android:name="android.provider.Telephony.SMS_RECEIVED" /> 
    </intent-filter> 
</receiver> 
    <receiver android:name="mono.android.Seppuku"> 
    <intent-filter> 
    <action android:name="mono.android.intent.action.SEPPUKU" /> 
    <category android:name="mono.android.intent.category.SEPPUKU.SmsApp.SmsApp" /> 
    </intent-filter> 
</receiver> 
<service android:name="md563471986402eafe51037cbcf251950c3.SmsService" /> 

验证这一点,并在UI线程中运行你的用户界面的东西。

var handler = new Handler(Looper.MainLooper); 
handler.Post(() => 
{ 
    Toast.MakeText(context, $"{smsNumber}: {smsBody}", ToastLength.Long).Show(); 
}); 

数据库

从不连接到远程数据库直接。您通过发布您的应用程序来泄露数据库密码!最佳做法是:始终在两者之间使用web服务。