服务器参考工程:点击打开链接 注意将clientid改成你自己的clientid
客户端参考工程:点击打开链接
1.引子
最近因为学习和工作需要经常用到远程登录,但是我没有固定IP,所以为了得到IP,出门前都要用cmd看一下,比较麻烦。所以希望能够开发一个小应用能够方便地获得我自己电脑的IP地址。虽然如果开发发送ip地址到自己邮箱的应用可能会简单方便安全很多,但对安卓开发情有独钟的我希望能够在我手机上接受IP地址。思来想去,最后发现可能比较简单地解决方案就是使用推送服务。刚好我也没尝试过,所以就决定开发这样一款小应用。能够实现以下功能:
服务器: 在自己的电脑上开机自启动,没过一段时间检查本机IP,并推送到指定的手机客户端上。
客户端: 接收计算机发送的透传消息,保存并在界面上显示IP地址。
2. 开发步骤
步骤一:
首先是客户端的开发。
为了让客户端能够接收透传消息,需要初始化sdk,具体可以参考我的上上篇文章 安卓开发笔记4——透传服务初体验。也可以查看官方客户端技术文档点击打开链接。
做完初始化,我们在应用的activity中定义和注册接收透传消息的broadcast receiver
package com.tanglikang.ipGiver; import android.os.Bundle; import com.igexin.sdk.Consts; //这两个包需要自己导入 import com.igexin.slavesdk.MessageManager; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.util.Log; import android.view.Menu; import android.widget.TextView; public class MainActivity extends Activity { private static final String ACTIONNAME_STRING="com.igexin.sdk.action.0a6shecpQs9ae01bYTQ9o1"; //这是appid private TextView IP ; private String data="127.0.0.1"; private SharedPreferences sp; private Editor editor; private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Bundle bundle = intent.getExtras(); Log.d("GexinSdkDemo", "onReceive() action=" + bundle.getInt("action")); switch (bundle.getInt(Consts.CMD_ACTION)) { case Consts.GET_MSG_DATA: // 获取透传(payload)数据 byte[] payload = bundle.getByteArray("payload"); if (payload != null) { data = new String(payload); Log.d("GexinSdkDemo", "Got Payload:" + data); editor.putString("IP", data); //将透传消息内容保存到sharedPreference,以便于下次打开时能够查看 editor.commit();//别忘了commit IP.setText(data);//将获得的ip地址在显示在activity中 } break; case Consts.GET_CLIENTID: // 获取ClientID(CID) String cid = bundle.getString("clientid"); Log.d("GexinSdkDemo", "Got ClientID:" + cid); // TODO: /* 第三方应用需要将ClientID上传到第三方服务器,并且将当前用户帐号和ClientID进行关联,以便以后通过用户帐号查找ClientID进行消息推送 有些情况下ClientID可能会发生变化,为保证获取最新的ClientID,请应用程序在每次获取ClientID广播后,都能进行一次关联绑定 */ break; default: break; } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); sp = this.getSharedPreferences("SP", MODE_WORLD_READABLE); //获得sharedPreferences对象。 editor = sp.edit(); //获得sharedPreferences编辑对象 IP = (TextView) findViewById(R.id.tv); MessageManager.getInstance().initialize(this.getApplicationContext()); //初始化sdk registerBroadcastReceiver(); //调用注册broadcast receiver类函数 data = sp.getString("IP", "127.0.0.1"); //获得sharedPreferences中保存的ip IP.setText(data); } void registerBroadcastReceiver(){ //对broadcast进行注册 IntentFilter intentFilter = new IntentFilter(); // intentFilter.addAction(ACTIONNAME_STRING); //消息过滤设置消息类型 registerReceiver(broadcastReceiver, intentFilter); //注册receiver,并添加消息过滤器 } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
步骤二:
然后是服务器端的开发
服务器端开发也需要做个推sdk的初始化,初始化与相关函数可以查看官方技术文档点击打开链接
做完初始化让我们来写服务器
import java.net.InetAddress; import com.gexin.rp.*; //下面这些包需要自己导入 import com.gexin.rp.sdk.base.IPushResult; import com.gexin.rp.sdk.base.impl.SingleMessage; import com.gexin.rp.sdk.base.impl.Target; import com.gexin.rp.sdk.http.IGtPush; import com.gexin.rp.sdk.template.TransmissionTemplate; public class ipGiver { private static final String APPID = "0a6shecpQs9ae01bYTQ9o1"; private static final String APPKEY = "rGjehsZMuq5V46utMwp6x3"; private static final String MASTERSECRET = "ICMQ5vGvFc5URALXIj35v7"; private static final String CLIENTID = "你的clientid";//获得方式可以参考技术文档,我的获取方式,通过真机调试在logcat中查看 private static final String API = "http://sdk.open.api.igexin.com/apiex.htm"; public static void main(String [] args){ while(true){ pushIp(); //向手机推送IP try { Thread.sleep(1000*60*5); //睡眠5分钟再次推送 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void pushIp(){ IGtPush iGtPush = new IGtPush(API, APPKEY, MASTERSECRET); //推送对象 String ip=""; try { InetAddress address = InetAddress.getLocalHost(); //获得本机InetAddress 对象 ip = address.getHostAddress(); //通过InetAddress对象获得本机ip } catch (Exception e) { // TODO: handle exception } try { SingleMessage message = new SingleMessage(); //单推送消息对象,只想指定手机推送消息 TransmissionTemplate template = new TransmissionTemplate(); //推送模板 template.setAppId(APPID); template.setAppkey(APPKEY); template.setTransmissionContent(ip); //设置推送内容 template.setTransmissionType(2); //设置类型: 1:接受消息后自动运行应用 2: 接受消息等待用户运行应用 message.setData(template); //将模板导入message对象 message.setOffline(true); //设置是否用户离线时在服务器保存 message.setOfflineExpireTime(1000*60*60); //设置保存时间 Target target = new Target(); //设置Target对象,定义了向什么地方发送 target.setAppId(APPID); target.setClientId(CLIENTID); IPushResult iResult = iGtPush.pushMessageToSingle(message, target); //单推送消息,并获得推送结果 System.out.println(iResult.toString()); } catch (Exception e) { // TODO: handle exception } } }
步骤三:
做完了以上两步,可以先尝试一下,运行服务器端,手机端是否能够接受消息。如果可以,那让我们进入下一步,让服务器开机自启动,百度了一下,觉得使用批处理文件比较方便,let‘s do it.
首先将服务器工程导出为可执行jar包,创建.bat文件,输入一下内容
F: #你jar包所放路径 IpGiverServer.jar #你jar包的名字
然后再写一个reg文件实现bat文件的开机自启动注册
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run] "IpGiverServer"="C:\\autoRun\\test.bat" # bat文件的路径,注意要用双斜杠在开始运行中regedit,然后倒入上面的reg文件。
3.总结
做完上面就差不多了,基本功能是实现了,美中不足的是没有实现从客户端向服务器端要求发送ip,而是每隔5分钟发送一次,以后改进吧。