Unity获取安卓手机运营商,电量,wifi信号强度,本地Toast,获取已安装apk,调用第三方应用,强制自动重启本应用
2017-03-18 20:19 wuzhang 阅读(11730) 评论(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,添加我们的测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 | using UnityEngine; using System.Collections; using UnityEngine.UI; public class Test : MonoBehaviour {<br> public Text log;<br> 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的对接及合并写一些。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步