Unity获取安卓手机运营商,电量,wifi信号强度,本地Toast,获取已安装apk,调用第三方应用,强制自动重启本应用
2017-03-18 20:19 wuzhang 阅读(11660) 评论(62) 编辑 收藏 举报一个完整的游戏项目上线需要不断的完善优化,但是到了后期的开发不再仅仅是游戏了,它的复杂度远远大于纯粹的应用开发。首先必须要考虑的就是集成第三方SDK,支付这块渠道商已经帮你我们做好了,只需要按照文档对接就好。其次是各种各样的功能需求,例如社交中的语音聊天,我们游戏使用的云娃的SDK,支持语音翻译文字,推送使用的是极光。对接SDK这块说简单吧有时也不简单,需要有一定的java基础和安卓开发基础。说实话我是没有一点安卓开发基础的,大二假期里看了几天java基础从入门到放弃,之后再没碰过java。我对java的了解仅限语法层面,该语言的特性不是很了解。好在对接SDK,他们都提供开发者文档,老老实实一步一步的照着抄就行了。再遇到搞不定的疑难杂症千万不要去钻牛角尖,解决办法有很多.一,找SDk技术支持。二,度娘,谷哥。三,周围的朋友,强大的社区!上来啰嗦了这么多,还不知道楼主到底想干嘛呢?扯远了吧?
言归正传,虽然我是个游戏开发者但是我对安卓还是比较感兴趣的,自己对sdk这块了解了点,在Unity项目里接过支付宝,微信支付,搞过BmobSMS的SDK做过手机号短信验证,还接过联通SDk的短信道具内购,使用过Mob的shareSDK和ShareRec,朋友项目有个圈子的社交功能,由于用户绑定的是手机号,那么官方推出的免费的MobileAPI就用的上了,做了手机号码归属地的查询。对了,这个项目还有一个第三方登陆的功能,使用Mob的第三方登陆搞定了QQ和微信的一键登录,当时微信登陆没有成功是因为要签名的。在大学期间还做过有米sdk的接入,这些东西也不是游戏必须的一款好的游戏其实完全可以没有这些,这些仅仅是锦上添花罢了。
今天周末,在家没事,看到了之前玩的小东西,虽然上传到了git,但是还是想写下来。今天这些不是第三方SDK的对接,而是安卓原生本地的一些API的调用。例如:获取手机的硬件信息,在内测时是非常有必要的,在统计游戏的兼容性和机型适配上有很大帮助的,例如这么一个需求,玩家离线挂机获得了很多道具和经验,这时是不是要告诉玩家这些可领取的信息,怎么搞定呢?这是就想到了Jpush了,推送啊!怎么做到,精准推送呢,获取用户的设备唯一标识啊!听说IOS现在比较坑,官方不公开这些信息了,我们可以获取GPU的型号生成Md5什么的,实在不行,我们可以写入本地的一个唯一标识。是不是硬件信息也有很多用呢!游戏过程中我们看不到时间和电量了怎么办,做啊!可以获取到底层的各种信息,显示出来不就行了。那么这些信息如何获取呢???
1,打开Eclipse建一个安卓库工程,注意是库工程,是Libiary哦!
2,继续
3,勾选库工程,继续
4,Icon显示方式选择
5,选择一个空的Activity,在安卓开发里每一个界面默认是一个Activity。在这里我们是调用逻辑代码,不需要GUI,如果想做地图什么的那就需要了。
6,安卓Activity名称,默认,Finish即可。
7,工程建好了,可以开始撸代码了吧? 莫着急,还差一步就可以愉快的撸代码!要做安卓和Unity的交互,安卓又不认识Unity,总得有个介绍人吧!这个介绍人是谁呢?没错,就是你Classes.jar,不管三七二十几,直接拖到工程的Lib下。
将这个jar文件添加到本工程,以后给Uniiy回掉数据全靠它了啊!
8,准备工作结束,可以贴代码了!
1 package com.wuzhang.testandroid; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import com.unity3d.player.UnityPlayer; 7 import com.unity3d.player.UnityPlayerActivity; 8 9 import android.app.Notification; 10 import android.app.NotificationManager; 11 import android.app.PendingIntent; 12 import android.app.ProgressDialog; 13 import android.app.Service; 14 import android.appwidget.AppWidgetManager; 15 import android.appwidget.AppWidgetProviderInfo; 16 import android.content.BroadcastReceiver; 17 import android.content.Context; 18 import android.content.Intent; 19 import android.content.IntentFilter; 20 import android.content.pm.ApplicationInfo; 21 import android.content.pm.PackageInfo; 22 import android.content.pm.PackageManager; 23 import android.net.wifi.WifiInfo; 24 import android.net.wifi.WifiManager; 25 import android.os.BatteryManager; 26 import android.os.Bundle; 27 import android.os.Handler; 28 import android.os.Vibrator; 29 import android.telephony.TelephonyManager; 30 import android.text.format.Formatter; 31 import android.util.Log; 32 import android.widget.Toast; 33 34 public class MainActivity extends UnityPlayerActivity { 35 private Vibrator mVibrator01;//声明一个振动器对象 36 private static Context instance; 37 private String TAG = "log"; 38 39 @Override 40 protected void onCreate(Bundle savedInstanceState) { 41 super.onCreate(savedInstanceState); 42 instance = getApplicationContext(); 43 CreateToast("默认的初始化"); 44 45 onCoderReturn("pid:"+android.os.Process.myPid() +" "+getBaseContext().getPackageName());//显示进程id和包名 46 } 47 48 public static Context getContext() 49 { 50 return instance; 51 } 52 53 /* 54 * 求和 55 */ 56 public int Sum(int a,int b) 57 { 58 int sum = a+b; 59 onCoderReturn(String.format("%s + %s = %s", a,b,sum)); 60 return sum; 61 } 62 63 /* 64 * 震动 65 */ 66 public void ClickShake() 67 { 68 mVibrator01 = (Vibrator)getApplication().getSystemService(Service.VIBRATOR_SERVICE); 69 mVibrator01.vibrate(new long[]{100,10,100,1000},-1);//自定义整栋模式,只震动一次 70 } 71 72 /* 73 * 状态返回Unity 74 */ 75 public void onCoderReturn(String state ) 76 { 77 String gameObjectName = "Main Camera"; 78 String methodName = "OnCoderReturn"; 79 String arg0 = state; 80 UnityPlayer.UnitySendMessage(gameObjectName, methodName, arg0); 81 } 82 83 /***********************调用Android Toast***************************/ 84 85 /* 86 * Unity调用安卓的Toast 87 */ 88 public void UnityCallAndroidToast(final String toast ) 89 { 90 runOnUiThread(new Runnable(){ 91 @Override 92 public void run() { 93 //onCoderReturn("Android:UnityCallAndroidToast()"); 94 /* 95 * 第一个参数:当前上下午的环境。可用getApplicationContext()或this 96 * 第二个参数:要显示的字符串 97 * 第三个参数:显示时间的长短。Toast有默认的两个LENGTH_SHORT(短)和LENGTH_LONG(长),也可以使用毫秒2000ms 98 * */ 99 Toast.makeText(MainActivity.this,toast,Toast.LENGTH_SHORT).show(); 100 } 101 }); 102 103 } 104 105 /* 106 * 创建Toast 107 */ 108 public void CreateToast(final String toast) 109 { 110 runOnUiThread(new Runnable(){ 111 @Override 112 public void run() { 113 //onCoderReturn("CreateToast()"); 114 Toast.makeText( 115 MainActivity.this, 116 toast,Toast.LENGTH_LONG).show(); 117 } 118 }); 119 } 120 121 122 /*************************************重启应用*************************************/ 123 124 /* 125 * 重新启动应用 126 */ 127 public void RestartApplication(){ 128 CreateToast("应用重启中..."); 129 130 Intent launch=getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName()); 131 launch.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 132 startActivity(launch); 133 } 134 135 /* 136 * UI 线程重启应用 137 */ 138 public void RestartApplicationOnUIThread(){ 139 CreateToast("3s后应用重启..."); 140 new Thread(){ 141 public void run(){ 142 Intent launch=getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName()); 143 launch.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 144 startActivity(launch); 145 android.os.Process.killProcess(android.os.Process.myPid()); 146 onCoderReturn("pid:"+android.os.Process.myPid()); 147 } 148 }.start(); 149 finish(); 150 } 151 152 /* 153 * 立即重启应用 ok 154 */ 155 public void RestartApplication1(){ 156 new Thread(){ 157 public void run(){ 158 Intent launch=getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName()); 159 launch.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 160 startActivity(launch); 161 android.os.Process.killProcess(android.os.Process.myPid()); 162 } 163 }.start(); 164 finish(); 165 } 166 167 /* 168 * 延迟5s重启应用 ok 169 */ 170 public void RestartApplication2(){ 171 ProgressDialog progressDialog = new ProgressDialog(MainActivity.this); 172 progressDialog.setMessage("5s后自动重启…"); 173 progressDialog.show(); 174 175 new Handler().postDelayed(new Runnable(){ 176 public void run() { 177 Intent launch=getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName()); 178 launch.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); 179 startActivity(launch); 180 android.os.Process.killProcess(android.os.Process.myPid()); 181 } 182 }, 5000); 183 } 184 185 /************************调用第三方app *****************************/ 186 187 public void CallThirdApp(String packageName)//packageName 188 { 189 Intent intent = getPackageManager().getLaunchIntentForPackage(packageName); 190 startActivity(intent); 191 onCoderReturn(packageName); 192 } 193 194 /* 195 * 获取所有安装包名和apk名字 196 */ 197 public void GetAllPackageName() 198 { 199 PackageManager packageManager = null; 200 packageManager = getPackageManager(); 201 List<PackageInfo> mAllPackages=new ArrayList<PackageInfo>(); 202 mAllPackages = packageManager.getInstalledPackages(0); 203 for(int i = 0; i < mAllPackages.size(); i ++) 204 { 205 PackageInfo packageInfo = mAllPackages.get(i); 206 Log.i("package path", packageInfo.applicationInfo.sourceDir); 207 Log.i("apk name", (String) packageInfo.applicationInfo.loadLabel(packageManager) ); 208 onCoderReturn("sourceDir:"+packageInfo.applicationInfo.sourceDir+" apkName:"+packageInfo.applicationInfo.loadLabel(packageManager)); 209 } 210 211 } 212 213 /* 214 * 个人安卓的额第三方App ok 215 */ 216 public void GetInstalledPackageName() 217 { 218 PackageManager packageManager = null; 219 packageManager = getPackageManager(); 220 List<PackageInfo> mAllPackages=new ArrayList<PackageInfo>(); 221 mAllPackages = packageManager.getInstalledPackages(0); 222 for(int i = 0; i < mAllPackages.size(); i ++) 223 { 224 PackageInfo packageInfo = mAllPackages.get(i); 225 if((packageInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)<= 0) 226 { 227 onCoderReturn("apkName:"+packageInfo.applicationInfo.loadLabel(packageManager)+"package path:"+packageInfo.applicationInfo.packageName); 228 } 229 else 230 { 231 onCoderReturn("sys apkName:"+packageInfo.applicationInfo.loadLabel(packageManager)); 232 } 233 } 234 } 235 236 /* 237 * 获取安装包 238 */ 239 public void GetAllWidget() 240 { 241 List<AppWidgetProviderInfo> widgetProviderInfos = AppWidgetManager.getInstance(this).getInstalledProviders(); 242 Log.d("widget", "allWidgetSize = " + widgetProviderInfos.size()); 243 for (int i = 0; i < widgetProviderInfos.size(); i++) { 244 AppWidgetProviderInfo info = widgetProviderInfos.get(i); 245 String packageName = info.provider.getPackageName(); //获取包名 246 String className = info.provider.getClassName(); //获取类名 247 Log.d("widget", "packageName: " + packageName); 248 Log.d("widget", "className: " + className); 249 onCoderReturn("packageName:"+packageName); 250 } 251 } 252 253 /**************************安卓本地推送通知***********************************/ 254 /* 255 * 安卓本地推送 256 */ 257 @SuppressWarnings("deprecation") 258 public void SendNotification(String title,String content) 259 { 260 NotificationManager nm=(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); 261 //1.实例化一个通知,指定图标、概要、时间 262 Notification n=new Notification(R.drawable.ic_launcher,content,3000); 263 //2.指定通知的标题、内容和intent 264 Intent intent = new Intent(this, MainActivity.class); 265 //设置跳转到的页面 ,时间等内容 266 PendingIntent pi= PendingIntent.getActivity(this, 0, intent, 1000); 267 n.setLatestEventInfo(this, title, content, pi); 268 n.flags |= Notification.FLAG_AUTO_CANCEL; // FLAG_AUTO_CANCEL表明当通知被用户点击时,通知将被清除。 269 //3.指定声音 270 n.defaults = Notification.DEFAULT_SOUND; 271 n.when = System.currentTimeMillis(); // 立即发生此通知 272 //4.发送通知 273 nm.notify(1, n); 274 } 275 276 /**************************************************************/ 277 /** 278 * 1.获取手机电池电量 2.检查手机是否充电 279 * */ 280 public String MonitorBatteryState() { 281 UnityCallAndroidToast("获取电池信息中..."); 282 IntentFilter ifilter=new IntentFilter(Intent.ACTION_BATTERY_CHANGED); 283 Intent intent=instance.registerReceiver(null,ifilter); 284 int rawlevel = intent.getIntExtra("level", 0);//获得当前电量 285 int scale = intent.getIntExtra("scale", 0);//获得总电量 286 int status = intent.getIntExtra("status", 0);//电池充电状态 287 int health = intent.getIntExtra("health", 0);//电池健康状况 288 int batteryV = intent.getIntExtra("voltage", 0); //电池电压(mv) 289 int temperature = intent.getIntExtra("temperature", 0); //电池温度(数值) 290 double T = temperature/10.0; //电池摄氏温度,默认获取的非摄氏温度值,需做一下运算转换 291 String targetStr=""; 292 int level = -1; 293 if (rawlevel > 0 && scale > 0) 294 { 295 level = (rawlevel * 100) / scale; 296 CreateToast("剩余电量:"+level+"%"); 297 Log.v(TAG,"现在的电量是:"+level+"%" ); 298 targetStr = level+"|"+scale+"|"+status; 299 onCoderReturn("当前电量:"+level+"|总容量:"+scale+"|充电状态:"+status+"|电压:"+batteryV+"电池健康状态:"+health+"温度:"+T+" 现在的电量是:"+level+"%"); 300 UnityPlayer.UnitySendMessage("Main Canera", "OnBatteryDataReturn", targetStr); 301 } 302 else 303 { 304 onCoderReturn("获取不到电池信息!"); 305 } 306 307 if(health == BatteryManager.BATTERY_HEALTH_GOOD ) 308 { 309 Log.v(TAG, "电池状态很好"); 310 } 311 if(status==BatteryManager.BATTERY_STATUS_CHARGING)//充电标记2 312 { 313 UnityCallAndroidToast("电池充电中..."); 314 } 315 else 316 { 317 UnityCallAndroidToast("电池放电中..."); 318 } 319 //notifyBattery(level,scale,status); 320 321 return targetStr ; 322 } 323 324 //获取详细电量信息 返回电量|是否充电中 325 public String notifyBattery(int level,int scale,int status) 326 { 327 String batteryStatue = ""; 328 int per = scale/5; 329 if(level<=per) 330 { 331 Log.v(TAG, "手机电量低于1/5"); 332 batteryStatue+= "0.2|"; 333 } 334 else if(level>per && level<=per*2) 335 { 336 Log.v(TAG, "手机电量低于2/5"); 337 batteryStatue+= "0.4|"; 338 } 339 else if(level>2*per && level<=per*3) 340 { 341 Log.v(TAG, "手机电量低于3/5"); 342 batteryStatue+= "0.6|"; 343 } 344 else if(level>3*per && level<=per*4) 345 { 346 Log.v(TAG, "手机电量低于4/5"); 347 batteryStatue+= "0.8|"; 348 } 349 else 350 { 351 Log.v(TAG, "手机电量充足"); 352 batteryStatue+= "1|"; 353 } 354 if(status==BatteryManager.BATTERY_STATUS_CHARGING)//充电标记2 355 { 356 Log.v(TAG,"充电中,电量背景为animation"); 357 batteryStatue+="2"; 358 UnityCallAndroidToast("电池充电中..."); 359 } 360 else 361 { 362 if(status == BatteryManager.BATTERY_STATUS_FULL)//5 363 { 364 Log.v(TAG, "满电量"); 365 CreateToast("电池电量充足"); 366 } 367 else if(status == BatteryManager.BATTERY_STATUS_NOT_CHARGING)//4 368 { 369 Log.v(TAG,"未充电"); 370 } 371 else if(status == BatteryManager.BATTERY_STATUS_DISCHARGING)//3 372 { 373 Log.v(TAG,"放电中"); 374 CreateToast("电池放电中"); 375 } 376 if(status == BatteryManager.BATTERY_STATUS_UNKNOWN)//1 377 { 378 Log.v(TAG,"状态未知"); 379 } 380 batteryStatue+="0"; 381 } 382 CreateToast(batteryStatue); 383 //电量信息格式:剩余百分比|是否充电中 384 return batteryStatue; 385 } 386 387 //获取wifi信号强度 388 //wifiinfo.getRssi();获取RSSI,RSSI就是接受信号强度指示。 389 //这里得到信号强度就靠wifiinfo.getRssi()这个方法。 390 //得到的值是一个0到-100的区间值,是一个int型数据,其中0到-50表示信号最好, 391 //-50到-70表示信号偏差,小于-70表示最差, 392 //有可能连接不上或者掉线,一般Wifi已断则值为-200。 393 @SuppressWarnings("deprecation") 394 private String ObtainWifiInfo() { 395 // Wifi的连接速度及信号强度: 396 String result=""; 397 WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE); 398 WifiInfo info = wifiManager.getConnectionInfo(); 399 if (info.getBSSID() != null) { 400 // 链接信号强度 401 int strength = WifiManager.calculateSignalLevel(info.getRssi(), 5); 402 // 链接速度 403 int speed = info.getLinkSpeed(); 404 // 链接速度单位 405 String units = WifiInfo.LINK_SPEED_UNITS; 406 // Wifi源名称 407 String ssid = info.getSSID(); 408 int ip = info.getIpAddress(); 409 String mac = info.getMacAddress(); 410 result = strength+"|"+intToIp(ip)+"|"+mac+"|"+ssid; 411 } 412 UnityPlayer.UnitySendMessage("Main Canera", "OnWifiDataReturn", result); 413 UnityCallAndroidToast(result); 414 return result; 415 } 416 //转换IP地址 417 private String intToIp(int paramInt) { 418 return (paramInt & 0xFF) + "." + (0xFF & paramInt >> 8) + "." + (0xFF & paramInt >> 16) + "." 419 + (0xFF & paramInt >> 24); 420 } 421 /************************检测运营商*******************************/ 422 /* 423 * 检测SIM卡类型 424 */ 425 public String CheckSIM(){ 426 String SIMTypeString = ""; 427 TelephonyManager telManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE); 428 String operator = telManager.getSimOperator(); 429 if (operator != null){ 430 if (operator.equals("46000") || operator.equals("46002")){ 431 CreateToast("此卡属于(中国移动)"); 432 SIMTypeString = "中国移动"; 433 } else if (operator.equals("46001")){ 434 CreateToast("此卡属于(中国联通)"); 435 SIMTypeString = "中国联通"; 436 437 } else if (operator.equals("46003")){ 438 CreateToast("此卡属于(中国电信)"); 439 SIMTypeString = "中国电信"; 440 } 441 } 442 return SIMTypeString; 443 } 444 }
基本上每个功能都有注释,我相信你能看懂得,因为我也是个小菜鸟!接下来导出jar文件,在Unity中测试。
导出时重要的一步,选这几个就可以了!
8,见一个Unity工程,首先建一个Plugins/Android的文件夹,顾名思义,这个文件夹就是存放安卓插件的。将Libs,Res,AndroidMainFest.xml拷贝到该目录下。如下:
9,添加我们的测试代码:
using UnityEngine; using System.Collections; using UnityEngine.UI; public class Test : MonoBehaviour {
public Text log;
string batteryData; string wifiData; private void OnGUI() { if (GUI.Button(new Rect(10, 10, 140, 40), "发送通知")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); jo.Call("UnityCallAndroidToast", "这是Unity调用Android的Toast!"); } if (GUI.Button(new Rect(10, 70, 140, 40), "求和")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); int sum = jo.Call<int>("Sum",new object[] { 10, 20 }); log.text = ""; jo.Call("ClickShake");//调用安卓震动 } if (GUI.Button(new Rect(10, 130, 140, 40), "Toast"))//创建安卓 Toast { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); jo.Call("CreateToast","初始化中..."); } if (GUI.Button(new Rect(10, 190, 140, 40), "立即重启应用")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); jo.Call("RestartApplication"); } if (GUI.Button(new Rect(10, 250, 140, 40), "UI线程重启应用")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); jo.Call("RestartApplicationOnUIThread"); } if (GUI.Button(new Rect(10, 310, 140, 40), "重启应用")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); jo.Call("RestartApplication1"); } if (GUI.Button(new Rect(10, 370, 140, 40), "5s重启应用")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); jo.Call("RestartApplication2"); } if (GUI.Button(new Rect(10, 430, 140, 40), "获取安装apk")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); jo.Call("GetAllPackageName"); } if (GUI.Button(new Rect(10, 490, 140, 40), "调用APP")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); jo.Call("CallThirdApp","com.tencent.mm"); } if (GUI.Button(new Rect(10, 550, 140, 40), "Unity本地推送")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); jo.Call("SendNotification",new string[] {"奇迹:最强者", "勇士们 魔龙讨伐即将开始" }); } if (GUI.Button(new Rect(10, 610, 140, 40), "获取所有App")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); jo.Call("GetAllWidget"); } if (GUI.Button(new Rect(10, 670, 140, 40), "获取已安装的App")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); jo.Call("GetInstalledPackageName"); } if (GUI.Button(new Rect(10, 730, 140, 40), "获取电池信息")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); batteryData = jo.Call<string>("MonitorBatteryState"); OnBatteryDataBack(batteryData); } if (GUI.Button(new Rect(10, 790, 140, 40), "获取wifi强度")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); wifiData = jo.Call<string>("ObtainWifiInfo"); OnWifiDataBack(wifiData); } if (GUI.Button(new Rect(10, 850, 140, 40), "获取运营商名称")) { AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); string simType = jo.Call<string>("CheckSIM"); log.text = simType; } if (Input.GetKeyDown(KeyCode.Escape) || Input.GetKeyDown(KeyCode.Home)) { Application.Quit(); } } void GetBatteryAnWifiData() { batteryData = ""; wifiData = ""; AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity"); batteryData = jo.Call<string>("MonitorBatteryState"); log.text = batteryData; AndroidJavaClass jc1 = new AndroidJavaClass("com.unity3d.player.UnityPlayer"); AndroidJavaObject jo1 = jc.GetStatic<AndroidJavaObject>("currentActivity"); wifiData = jo1.Call<string>("ObtainWifiInfo"); log.text += wifiData; OnBatteryDataBack(batteryData); OnWifiDataBack(wifiData); } void OnBatteryDataBack(string batteryData)//level+"|"+scale+"|"+status; { string[] args = batteryData.Split('|'); if (args[2] == "2") { log.text += "电池充电中"; } else { log.text += "电池放电中"; } float percent = int.Parse(args[0])/float.Parse(args[1]); log.text += (Mathf.CeilToInt(percent)+"%").ToString(); } void OnWifiDataBack(string wifiData)//strength+"|"+intToIp(ip)+"|"+mac+"|"+ssid; { //分析wifi信号强度 //获取RSSI,RSSI就是接受信号强度指示。 //得到的值是一个0到-100的区间值,是一个int型数据,其中0到-50表示信号最好, //-50到-70表示信号偏差,小于-70表示最差, //有可能连接不上或者掉线,一般Wifi已断则值为-200。 log.text += wifiData; string[] args = wifiData.Split('|'); if (int.Parse(args[0]) > -50 && int.Parse(args[0]) < 0) { log.text += "Wifi信号强度很棒"; } else if (int.Parse(args[0]) > -70 && int.Parse(args[0]) < -50) { log.text += "Wifi信号强度一般"; } else if (int.Parse(args[0]) > -150 && int.Parse(args[0]) < -70) { log.text += "Wifi信号强度很弱"; } else if (int.Parse(args[0]) < -200) { log.text += "Wifi信号JJ了"; } string ip = "IP:" + args[1]; string mac = "MAC:" + args[2]; string ssid = "Wifi Name:" + args[3]; log.text += ip; log.text += mac; log.text += ssid; } /// <summary> /// 安卓日志 /// </summary> /// <param name="str"></param> void OnCoderReturn(string str) { log.text += str; } void OnBatteryDataReturn(string batteryData) { string[] args = batteryData.Split('|'); if (args[2] == "2") { log.text += "电池充电中"; } else { log.text += "电池放电中"; } log.text += (args[0] + "%").ToString(); } void OnWifiDataReturn(string wifiData) { log.text += wifiData; string[] args = wifiData.Split('|'); if (int.Parse(args[0]) > -50 && int.Parse(args[0]) <100) { log.text += "Wifi信号强度很棒"; } else if (int.Parse(args[0]) > -70 && int.Parse(args[0]) < -50) { log.text += "Wifi信号强度一般"; } else if (int.Parse(args[0]) > -150 && int.Parse(args[0]) < -70) { log.text += "Wifi信号强度很弱"; } else if (int.Parse(args[0]) < -200) { log.text += "Wifi信号JJ了"; } string ip = "IP:" + args[1]; string mac = "MAC:" + args[2]; string ssid = "Wifi Name:" + args[3]; log.text += ip; log.text += mac; log.text += ssid; } }
过程中会遇到几个问题,获取电量和Wifi信息后我们怎么去取得我们想要的数据,电池相关:
Intent intent=instance.registerReceiver(null,ifilter);
int rawlevel = intent.getIntExtra("level", 0);//获得当前电量
int scale = intent.getIntExtra("scale", 0);//获得总电量
int status = intent.getIntExtra("status", 0);//电池充电状态
int health = intent.getIntExtra("health", 0);//电池健康状况
int batteryV = intent.getIntExtra("voltage", 0); //电池电压(mv)
int temperature = intent.getIntExtra("temperature", 0); //电池温度(数值)
double T = temperature/10.0; //电池摄氏温度,默认获取的非摄氏温度值,需做一下运算转换
//分析wifi信号强度
//获取RSSI,RSSI就是接受信号强度指示。
//得到的值是一个0到-100的区间值,是一个int型数据,其中0到-50表示信号最好,
//-50到-70表示信号偏差,小于-70表示最差,
//有可能连接不上或者掉线,一般Wifi已断则值为-200。
这些度娘都知道,如果数据还不够,自己去查API了啊!
打包后,真机测试,看看效果图:
Android 工程:git@git.oschina.net:wuzhang/TestAndroid.git
Unity工程:git@git.oschina.net:wuzhang/UnityCallAndroidAPI.git如果你觉得有什么问题,大家共同交流,一起学习,以后有时间把第三方SDK的对接及合并写一些。