youngstar

    前段时间,我自己部署的个人网站要用到短信发送功能,当时想到的是在网上找个收费的短信群发平台,结果几乎所有的平台都是千元以上起卖,但是我是自己使用不了太多也不想一次性买这么多短信,怎么办呢?于是我又在网上搜索是否有免费的开源平台用于自己搭建,但是几乎在网上没搜索相关的内容,所以我决定自己用php+android搭建平台。

  该平台其实就是android端作为短信发送端,php作为短信管理推送服务端。那么android端就需要开发一个短信发送功能的应用,作为一个phper几乎没接触过android开发,所以只有在网上搜,但是都没有适合的、完整的开源应用,那么又只有自己一边学习一边开发了。之前学习过一点安卓开发的基础知识,对安卓应用的结构有一定了解。于是开始我的发送端的开发:

  既然是短信发送端,首先得先做短信发送功能(因为是android菜鸟所以要先确定短信功能是否能实现才能考虑后面的问题),在网上搜索不少关于短信发送的代码段,经过修改测试后代码如下:

 1     public void sendsms(String tels,String contents)
 2     {
 3         //String tel = "135******73";
 4         SmsManager smsManager = SmsManager.getDefault();
 5         PendingIntent sentIntent = PendingIntent.getBroadcast(ServicesSMS.this, 0, new Intent(), 0);
 6         
 7         if(contents.length() >= 70)
 8         {
 9             //将短信分成多条发送
10             List<String> ms = smsManager.divideMessage(contents);
11         
12             for(String str : ms )
13             {
14                 smsManager.sendTextMessage(tels, null, str, sentIntent, null);
15             }
16         }
17         else
18         {
19             //单条发送
20             smsManager.sendTextMessage(tels, null, contents, sentIntent, null);
21         }
22         num++;//记录短信发送条数
23     }

   发送短信成功了,那么就该考虑获取服务端数据库里的待发送短信数据,那么连接服务器该用什么协议和包呢,因为我是做web的所以使用http协议来实现与服务器通讯获取数据(用的是HttpPost包):

  1 Runnable runnable = new Runnable(){
  2         @Override
  3         public void run() {
  4             //
  5             // TODO: http request.
  6             //
  7             
  8                 while(auto)
  9                 {
 10                     if(checkNetworkState())//检查网路是否可用
 11                     {
 12                         requestHttp();    
 13                         try {
 14                             Thread.sleep(30000);//循环请求服务器,5分钟一次,可以根据需要自行设定
 15                         } catch (InterruptedException e) {
 16                             // TODO Auto-generated catch block
 17                             e.printStackTrace();
 18                         }
 19                     }
 20                 }
 21                 
 22                 //handler.postDelayed(requestHttp(), 1000);
 23             
 24         }
 25         public void requestHttp()
 26         {
 27             
 28             // http地址  
 29             //String httpUrl = "http://domain/public/api/getsms.php";
 30             String httpUrl = urlpass;
 31             if(httpUrl.equals(""))
 32             {
 33                 Toast.makeText(ServicesSMS.this, "url地址异常!", Toast.LENGTH_LONG).show();
 34                 try {
 35                     Thread.sleep(3000);
 36                 } catch (InterruptedException e) {
 37                     // TODO Auto-generated catch block
 38                     e.printStackTrace();
 39                 }
 40                 onDestroy();//停止服务,后面用到
 41             }
 42             //HttpPost连接对象  
 43             HttpPost httpRequest = new HttpPost(httpUrl);  
 44             //使用NameValuePair来保存要传递的Post参数  
 45             List<NameValuePair> params = new ArrayList<NameValuePair>();  
 46             //添加要传递的参数  
 47             params.add(new BasicNameValuePair("par", "HttpClient_android_Post"));  
 48             //设置字符集  
 49                 HttpEntity httpentity = null;
 50                 try {
 51                     httpentity = new UrlEncodedFormEntity(params, "utf-8");
 52                 } catch (UnsupportedEncodingException e) {
 53                     // TODO Auto-generated catch block
 54                     e.printStackTrace();
 55                 }  
 56                 //请求httpRequest  
 57                 httpRequest.setEntity(httpentity);  
 58                 //取得默认的HttpClient  
 59                 HttpClient httpclient = new DefaultHttpClient();  
 60                 //取得HttpResponse  
 61                 HttpResponse httpResponse = null;
 62                 try {
 63                     httpResponse = httpclient.execute(httpRequest);
 64                 } catch (ClientProtocolException e) {
 65                     // TODO Auto-generated catch block
 66                     e.printStackTrace();
 67                 } catch (IOException e) {
 68                     // TODO Auto-generated catch block
 69                     e.printStackTrace();
 70                 }  
 71                 //Object mTextView;
 72                 //HttpStatus.SC_OK表示连接成功  
 73                 String strResult = null;
 74                 if (httpResponse.getStatusLine().getStatusCode() == HttpStatus.SC_OK)  
 75                 {  
 76                     //取得返回的字符串  
 77                    
 78                     try {
 79                         strResult = EntityUtils.toString(httpResponse.getEntity());
 80                     } catch (ParseException e) {
 81                         // TODO Auto-generated catch block
 82                         e.printStackTrace();
 83                     } catch (IOException e) {
 84                         // TODO Auto-generated catch block
 85                         e.printStackTrace();
 86                     }  
 87                     System.out.print(strResult);  
 88                 }  
 89                 else 
 90                 {  
 91                     System.out.print("请求错误!"); 
 92                 }  
 93                 Message msg = new Message();
 94                 Bundle data = new Bundle();
 95                 data.putString("value",strResult);//获取到的数据
 96                 msg.setData(data);
 97                 handler.sendMessage(msg);
 98                 
 99                 //return runnable;
100         }
101     };

  获取到服务器的数据后,就是处理分析数据,然后发送了:

 1 Handler handler = new Handler(){
 2         @Override
 3         public void handleMessage(Message msg) {
 4             super.handleMessage(msg);
 5             Bundle data = msg.getData(); 6             String val = data.getString("value");//获取的服务器数据
 7             
 8             
 9             if(!val.equals("{}"))//“{}”代表服务器没有待发送数据,可以自行定义
10             {
11                 JSONObject jsonObject = null;//服务器返回的是json数据,所以需要处理
12                 try {
13                     jsonObject = new JSONObject(val.toString()).getJSONObject("sms");
14                 } catch (JSONException e) {
15                     // TODO Auto-generated catch block
16                     e.printStackTrace();
17                 }
18                 /*{
19                  * \'a\':
20                  *     {\'b\':
21                  *         [
22                  *             {\'c\':1},
23                  *             {\'d\',2}
24                  *         ]
25                  *     }
26                 * }
27                 * 该格式的json数组需要将[]中的转化为JSONArray*/
28                 
29                 JSONArray jsonArray = null;
30                 try {
31                     jsonArray = jsonObject.getJSONArray("list");
32                 } catch (JSONException e1) {
33                     // TODO Auto-generated catch block
34                     e1.printStackTrace();
35                 } 
36                 for(int i=0;i<jsonArray.length();i++){ 
37                     //JSONObject jsonObject2 = (JSONObject)jsonArray.opt(i);  
38                     JSONObject oj = null;
39                     try {
40                         oj = jsonArray.getJSONObject(i);
41                     } catch (JSONException e) {
42                         // TODO Auto-generated catch block
43                         e.printStackTrace();
44                     }  
45                     //aa = aa + oj.getString("name")+"|"; 
46                     try {
47                         tel=oj.getString("tel");
48                     } catch (JSONException e) {
49                         // TODO Auto-generated catch block
50                         e.printStackTrace();
51                     }
52                     try {
53                         content=oj.getString("content");
54                     } catch (JSONException e) {
55                         // TODO Auto-generated catch block
56                         e.printStackTrace();
57                     }
58                     sendsms(tel,content);//调用前面提到的发送方法
59                 }                
60                 //String State; 
61                 if(num>0)
62                 {
63                     Toast.makeText(ServicesSMS.this, "发送成功,共"+num+"条!", Toast.LENGTH_LONG).show();
64                 }
65             }       
66         };
67     };

  到这里,一个具有基本的短信群发功能就实现了,实现过程中也遇到一些问题,其中遇到一个关于线程的问题耽误不少时间:含有http协议请求的功能不能放在主线程中(即需要开辟一个activity或service)。开始不晓得这个,在网上搜索了很久才找到原因。虽然实现了基本功能,但是有些地方还不尽人意,比如不能后台运行,不能自定义服务器地址等。所以我添加了后台运行功能和自定义服务器地址功能,手动开始停止程序功能:

  在AndroidManifest.xml中添加服务(解决了http请求不能在主线程中的问题)

1 <service android:name=".ServicesSMS" >    
2              <intent-filter> 
3                 <action android:name="android.intent.action.MAIN" /> 
4                 <category android:name="android.intent.category.LAUNCHER" /> 
5             </intent-filter> 
6 </service>

将上面实现功能的放到ServicesSMS.java文件中,其详细过程不再赘述,后面有完整源码地址。

  最后就是服务器端程序了:

<?php
//读取数据库数据,伪代码
//为了加强安全性,可以加入防伪检验功能
$data=getDataFromDataBase();
if($data==\'\')
    echo \'{}\';//根据自己需要,定义待发送短信为空的表现方式
else
    echo json_encode($data);

 

小弟第一次写博客,不足之处请见谅。附安卓源码地址:http://pan.baidu.com/s/1dDrdoRZ

 

分类:

技术点:

相关文章: