From c1437e56a722ec0983cb2def15dd012454939dd2 Mon Sep 17 00:00:00 2001 From: liuguijing <123456> Date: Tue, 7 May 2024 20:13:49 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9F=AD=E4=BF=A1=E7=9B=91=E5=90=AC=E8=BF=90?= =?UTF-8?q?=E7=BB=B4=E5=92=8CGPS=E5=AE=9A=E4=BD=8D=E8=8E=B7=E5=8F=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- mpmaster/src/main/AndroidManifest.xml | 14 +- .../com/xypower/mpmaster/LocationUtil.java | 282 ++++++++++++++++ .../com/xypower/mpmaster/MainActivity.java | 66 +++- .../com/xypower/mpmaster/MpMasterService.java | 21 +- .../com/xypower/mpmaster/SmsReceiver.java | 62 ---- .../xypower/mpmaster/sms/ModelSlotAndSub.java | 11 + .../com/xypower/mpmaster/sms/SimUtil.java | 308 ++++++++++++++++++ .../xypower/mpmaster/sms/SmsMessageModel.java | 48 +++ .../com/xypower/mpmaster/sms/SmsReceiver.java | 20 ++ .../xypower/mpmaster/sms/SmsSendReceiver.java | 30 ++ .../com/xypower/mpmaster/sms/SmsTypeEnum.java | 49 +++ .../src/main/res/layout/activity_main.xml | 10 +- 12 files changed, 827 insertions(+), 94 deletions(-) create mode 100644 mpmaster/src/main/java/com/xypower/mpmaster/LocationUtil.java delete mode 100644 mpmaster/src/main/java/com/xypower/mpmaster/SmsReceiver.java create mode 100644 mpmaster/src/main/java/com/xypower/mpmaster/sms/ModelSlotAndSub.java create mode 100644 mpmaster/src/main/java/com/xypower/mpmaster/sms/SimUtil.java create mode 100644 mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsMessageModel.java create mode 100644 mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsReceiver.java create mode 100644 mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsSendReceiver.java create mode 100644 mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsTypeEnum.java diff --git a/mpmaster/src/main/AndroidManifest.xml b/mpmaster/src/main/AndroidManifest.xml index 4889cf59..7c9581af 100644 --- a/mpmaster/src/main/AndroidManifest.xml +++ b/mpmaster/src/main/AndroidManifest.xml @@ -3,6 +3,8 @@ xmlns:tools="http://schemas.android.com/tools" package="com.xypower.mpmaster"> + + @@ -10,9 +12,10 @@ - - + @@ -66,7 +69,6 @@ - + android:exported="true" + android:process=":hotspot"> - + diff --git a/mpmaster/src/main/java/com/xypower/mpmaster/LocationUtil.java b/mpmaster/src/main/java/com/xypower/mpmaster/LocationUtil.java new file mode 100644 index 00000000..9ddce61c --- /dev/null +++ b/mpmaster/src/main/java/com/xypower/mpmaster/LocationUtil.java @@ -0,0 +1,282 @@ +package com.xypower.mpmaster; + +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.location.Address; +import android.location.Criteria; +import android.location.Geocoder; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.location.LocationProvider; +import android.os.Bundle; +import android.provider.Settings; +import android.util.Log; +import android.widget.Toast; + +import androidx.core.app.ActivityCompat; + +import java.io.IOException; +import java.util.List; +import java.util.Locale; + +public class LocationUtil { + private static OnLocationChangeListener mListener; + + private static MyLocationListener myLocationListener; + + private static LocationManager mLocationManager; + + private LocationUtil() { + throw new UnsupportedOperationException("u can't instantiate me..."); + } + + /** + * 判断Gps是否可用 + * + * @return {@code true}: 是
{@code false}: 否 + */ + public static boolean isGpsEnabled(Context context) { + LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + return lm.isProviderEnabled(LocationManager.GPS_PROVIDER); + } + + /** + * 判断定位是否可用 + * + * @return {@code true}: 是
{@code false}: 否 + */ + public static boolean isLocationEnabled(Context context) { + LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + return lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER) || lm.isProviderEnabled(LocationManager.GPS_PROVIDER); + } + + /** + * 打开Gps设置界面 + */ + public static void openGpsSettings(Context context) { + Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + + /** + * 注册 + *

使用完记得调用{@link #unregister()}

+ *

需添加权限 {@code }

+ *

需添加权限 {@code }

+ *

需添加权限 {@code }

+ *

如果{@code minDistance}为0,则通过{@code minTime}来定时更新;

+ *

{@code minDistance}不为0,则以{@code minDistance}为准;

+ *

两者都为0,则随时刷新。

+ * + * @param minTime 位置信息更新周期(单位:毫秒) + * @param minDistance 位置变化最小距离:当位置距离变化超过此值时,将更新位置信息(单位:米) + * @param listener 位置刷新的回调接口 + * @return {@code true}: 初始化成功
{@code false}: 初始化失败 + */ + public static boolean register(Context context, long minTime, long minDistance, OnLocationChangeListener listener) { + if (listener == null) return false; + mLocationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); + mListener = listener; + if (!isLocationEnabled(context)) { + Toast.makeText(context, "无法定位,请打开定位服务", Toast.LENGTH_SHORT).show(); + return false; + } +// String provider = mLocationManager.getBestProvider(getCriteria(), true); + String provider = LocationManager.GPS_PROVIDER; + if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + // TODO: Consider calling + // ActivityCompat#requestPermissions + // here to request the missing permissions, and then overriding + // public void onRequestPermissionsResult(int requestCode, String[] permissions, + // int[] grantResults) + // to handle the case where the user grants the permission. See the documentation + // for ActivityCompat#requestPermissions for more details. + return false; + } + Location location = mLocationManager.getLastKnownLocation(provider); + + if (location != null) listener.getLastKnownLocation(location); + if (myLocationListener == null) myLocationListener = new MyLocationListener(); + mLocationManager.requestLocationUpdates(provider, minTime, minDistance, myLocationListener); + return true; + } + + + /** + * 注销 + */ + public static void unregister() { + if (mLocationManager != null) { + if (myLocationListener != null) { + mLocationManager.removeUpdates(myLocationListener); + myLocationListener = null; + } + mLocationManager = null; + } + } + + /** + * 设置定位参数 + * + * @return {@link Criteria} + */ + private static Criteria getCriteria() { + Criteria criteria = new Criteria(); + //设置定位精确度 Criteria.ACCURACY_COARSE比较粗略,Criteria.ACCURACY_FINE则比较精细 + criteria.setAccuracy(Criteria.ACCURACY_FINE); + //设置是否要求速度 + criteria.setSpeedRequired(false); + // 设置是否允许运营商收费 + criteria.setCostAllowed(false); + //设置是否需要方位信息 + criteria.setBearingRequired(false); + //设置是否需要海拔信息 + criteria.setAltitudeRequired(false); + // 设置对电源的需求 + criteria.setPowerRequirement(Criteria.POWER_LOW); + return criteria; + } + + /** + * 根据经纬度获取地理位置 + * + * @param context 上下文 + * @param latitude 纬度 + * @param longitude 经度 + * @return {@link Address} + */ + public static Address getAddress(Context context, double latitude, double longitude) { + Geocoder geocoder = new Geocoder(context, Locale.getDefault()); + try { + List
addresses = geocoder.getFromLocation(latitude, longitude, 1); + if (addresses.size() > 0) return addresses.get(0); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + /** + * 根据经纬度获取所在国家 + * + * @param context 上下文 + * @param latitude 纬度 + * @param longitude 经度 + * @return 所在国家 + */ + public static String getCountryName(Context context, double latitude, double longitude) { + Address address = getAddress(context, latitude, longitude); + return address == null ? "unknown" : address.getCountryName(); + } + + /** + * 根据经纬度获取所在地 + * + * @param context 上下文 + * @param latitude 纬度 + * @param longitude 经度 + * @return 所在地 + */ + public static String getLocality(Context context, double latitude, double longitude) { + Address address = getAddress(context, latitude, longitude); + return address == null ? "unknown" : address.getLocality(); + } + + /** + * 根据经纬度获取所在街道 + * + * @param context 上下文 + * @param latitude 纬度 + * @param longitude 经度 + * @return 所在街道 + */ + public static String getStreet(Context context, double latitude, double longitude) { + Address address = getAddress(context, latitude, longitude); + return address == null ? "unknown" : address.getAddressLine(0); + } + + private static class MyLocationListener implements LocationListener { + /** + * 当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发 + * + * @param location 坐标 + */ + @Override + public void onLocationChanged(Location location) { + if (mListener != null) { + mListener.onLocationChanged(location); + } + } + + /** + * provider的在可用、暂时不可用和无服务三个状态直接切换时触发此函数 + * + * @param provider 提供者 + * @param status 状态 + * @param extras provider可选包 + */ + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + if (mListener != null) { + mListener.onStatusChanged(provider, status, extras); + } + switch (status) { + case LocationProvider.AVAILABLE: + Log.e("onStatusChanged", "当前GPS状态为可见状态"); + break; + case LocationProvider.OUT_OF_SERVICE: + Log.e("onStatusChanged", "当前GPS状态为服务区外状态"); + break; + case LocationProvider.TEMPORARILY_UNAVAILABLE: + Log.e("onStatusChanged", "当前GPS状态为暂停服务状态"); + break; + } + } + + /** + * provider被enable时触发此函数,比如GPS被打开 + */ + @Override + public void onProviderEnabled(String provider) { + System.out.println("dsaf"); + } + + /** + * provider被disable时触发此函数,比如GPS被关闭 + */ + @Override + public void onProviderDisabled(String provider) { + System.out.println("dsaf"); + } + } + + public interface OnLocationChangeListener { + + /** + * 获取最后一次保留的坐标 + * + * @param location 坐标 + */ + void getLastKnownLocation(Location location); + + /** + * 当坐标改变时触发此函数,如果Provider传进相同的坐标,它就不会被触发 + * + * @param location 坐标 + */ + void onLocationChanged(Location location); + + /** + * provider的在可用、暂时不可用和无服务三个状态直接切换时触发此函数 + * + * @param provider 提供者 + * @param status 状态 + * @param extras provider可选包 + */ + void onStatusChanged(String provider, int status, Bundle extras);//位置状态发生改变 + } +} diff --git a/mpmaster/src/main/java/com/xypower/mpmaster/MainActivity.java b/mpmaster/src/main/java/com/xypower/mpmaster/MainActivity.java index 9cbe0e81..9c596e9c 100644 --- a/mpmaster/src/main/java/com/xypower/mpmaster/MainActivity.java +++ b/mpmaster/src/main/java/com/xypower/mpmaster/MainActivity.java @@ -8,12 +8,13 @@ import android.Manifest; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; -import android.net.ConnectivityManager; +import android.location.Location; import android.os.Build; import android.os.Bundle; import android.os.Handler; import android.os.StrictMode; import android.text.TextUtils; +import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.widget.Switch; @@ -33,6 +34,7 @@ public class MainActivity extends AppCompatActivity { private static int MY_PERMISSIONS_REQUEST_FOREGROUND_SERVICE = 100; private Handler mHandler; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -41,12 +43,11 @@ public class MainActivity extends AppCompatActivity { ActionBar actionBar = getSupportActionBar(); mHandler = new Handler(); - mHandler.postDelayed( - new Runnable() { - public void run() { - requestPermissions(); - } - }, 100); + mHandler.postDelayed(new Runnable() { + public void run() { + requestPermissions(); + } + }, 100); // String buildTime = BuildConfig.BUILD_ Date date = new Date(BuildConfig.BUILD_TIMESTAMP); @@ -58,7 +59,7 @@ public class MainActivity extends AppCompatActivity { StrictMode.setThreadPolicy(policy); MicroPhotoContext.AppConfig appConfig = MicroPhotoContext.getMpAppConfig(getApplicationContext()); - ((TextView)findViewById((R.id.cmdid))).setText(TextUtils.isEmpty(appConfig.cmdid) ? "" : appConfig.cmdid); + ((TextView) findViewById((R.id.cmdid))).setText(TextUtils.isEmpty(appConfig.cmdid) ? "" : appConfig.cmdid); findViewById(R.id.btnEnableCam3V3).setOnClickListener(new View.OnClickListener() { @Override @@ -94,7 +95,6 @@ public class MainActivity extends AppCompatActivity { // SysApi.enableApp(v.getContext(), "abcd1234"); - } }); @@ -114,12 +114,12 @@ public class MainActivity extends AppCompatActivity { } }); - Switch sw = (Switch)findViewById(R.id.btn485ReadMode); + Switch sw = (Switch) findViewById(R.id.btn485ReadMode); sw.setChecked(true); findViewById(R.id.btn485ReadMode).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - Switch sw = (Switch)view; + Switch sw = (Switch) view; if (sw.isChecked()) { SysApi.set485ReadMode(); } else { @@ -128,13 +128,47 @@ public class MainActivity extends AppCompatActivity { } }); + findViewById(R.id.sendsms).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { +// boolean gpsEnabled = LocationUtil.isGpsEnabled(MainActivity.this); +// System.out.printf("g" + gpsEnabled); + LocationUtil.register(MainActivity.this, 0, 0, new LocationUtil.OnLocationChangeListener() { + @Override + public void getLastKnownLocation(Location location) { + Log.e("xyh", "onLocationChanged: " + location.getLatitude()); + } + + @Override + public void onLocationChanged(Location location) { + //位置信息变化时触发 + Log.e("xyh", "定位方式:" + location.getProvider()); + Log.e("xyh", "纬度:" + location.getLatitude()); + Log.e("xyh", "经度:" + location.getLongitude()); + Log.e("xyh", "海拔:" + location.getAltitude()); + Log.e("xyh", "时间:" + location.getTime()); + Log.e("xyh", "国家:" + LocationUtil.getCountryName(MainActivity.this, location.getLatitude(), location.getLongitude())); + Log.e("xyh", "获取地理位置:" + LocationUtil.getAddress(MainActivity.this, location.getLatitude(), location.getLongitude())); + Log.e("xyh", "所在地:" + LocationUtil.getLocality(MainActivity.this, location.getLatitude(), location.getLongitude())); + Log.e("xyh", "所在街道:" + LocationUtil.getStreet(MainActivity.this, location.getLatitude(), location.getLongitude())); + LocationUtil.unregister(); - mHandler.postDelayed( - new Runnable() { - public void run() { - HotspotManager.enableHotspot(getApplicationContext(), false); } - }, 5000); + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + System.out.println("dfsad"); + } + }); + } + }); + + + mHandler.postDelayed(new Runnable() { + public void run() { + HotspotManager.enableHotspot(getApplicationContext(), false); + } + }, 5000); startMicroPhotoService(getApplicationContext()); } diff --git a/mpmaster/src/main/java/com/xypower/mpmaster/MpMasterService.java b/mpmaster/src/main/java/com/xypower/mpmaster/MpMasterService.java index c02ef15d..86f6286f 100644 --- a/mpmaster/src/main/java/com/xypower/mpmaster/MpMasterService.java +++ b/mpmaster/src/main/java/com/xypower/mpmaster/MpMasterService.java @@ -7,7 +7,6 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.app.Service; import android.content.BroadcastReceiver; -import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; @@ -20,13 +19,11 @@ import android.os.Environment; import android.os.Handler; import android.os.IBinder; import android.os.Message; -import android.os.Messenger; import android.os.PowerManager; import android.os.SystemClock; import android.telephony.SignalStrength; import android.telephony.TelephonyManager; import android.text.TextUtils; -import android.text.format.DateFormat; import android.util.Log; import android.widget.RemoteViews; import android.widget.Toast; @@ -35,18 +32,14 @@ import androidx.core.app.NotificationCompat; import com.dev.devapi.api.SysApi; import com.xypower.common.FileDownloader; -import com.xypower.common.InetAddressUtils; import com.xypower.common.JSONUtils; import com.xypower.common.MicroPhotoContext; +import com.xypower.mpmaster.sms.SimUtil; +import com.xypower.mpmaster.sms.SmsSendReceiver; import org.json.JSONObject; import java.io.File; -import java.net.InetAddress; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; import java.util.logging.FileHandler; import java.util.logging.Level; import java.util.logging.Logger; @@ -81,6 +74,8 @@ public class MpMasterService extends Service { private static final String EXTRA_PARAM_SCHEDULE = "Schedule_"; private static final String EXTRA_PARAM_TIME = "Time"; private static final String FOREGROUND_CHANNEL_ID = "foreground_channel_id"; + private SmsSendReceiver mSmsSnedReceiver; + public static class STATE_SERVICE { public static final int CONNECTED = 10; public static final int NOT_CONNECTED = 0; @@ -218,6 +213,13 @@ public class MpMasterService extends Service { registerReceiver(mUpdateReceiver, intentFilter); } + //自定义发送短信广播接收器 + mSmsSnedReceiver = new SmsSendReceiver(); + IntentFilter intentFilter; + intentFilter = new IntentFilter(SimUtil.SMS_SEND_ACTION); + registerReceiver(mSmsSnedReceiver,intentFilter); + + // AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); startMaster(); @@ -236,6 +238,7 @@ public class MpMasterService extends Service { unregisterReceiver(mAlarmReceiver); unregisterReceiver(mScreenaAtionReceiver); unregisterReceiver(mUpdateReceiver); + unregisterReceiver(mSmsSnedReceiver); super.onDestroy(); } diff --git a/mpmaster/src/main/java/com/xypower/mpmaster/SmsReceiver.java b/mpmaster/src/main/java/com/xypower/mpmaster/SmsReceiver.java deleted file mode 100644 index 40b5533f..00000000 --- a/mpmaster/src/main/java/com/xypower/mpmaster/SmsReceiver.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.xypower.mpmaster; - -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.telephony.SmsMessage; -import android.util.Log; - -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.TimeZone; - -/** - * 短信监听的广播 - * - * @author jingjing - */ -public class SmsReceiver extends BroadcastReceiver { - - private static final String TAG = "MPLOG"; - private Context mContext; - public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED"; - public static final String SMS_DELIVER_ACTION = "android.provider.Telephony.SMS_DELIVER"; - - @Override - public void onReceive(Context context, Intent intent) { - this.mContext = context; - - Log.e(TAG, "Recv SMS"); - String action = intent.getAction(); - if (SMS_RECEIVED_ACTION.equals(action) || SMS_DELIVER_ACTION.equals(action)) { - - // Log.e("日志:onReceive。。。", "开始接收短信....."); - Bundle bundle = intent.getExtras(); - if (bundle != null) { - Object[] pdus = (Object[]) bundle.get("pdus"); - if (pdus != null && pdus.length > 0) { - SmsMessage[] messages = new SmsMessage[pdus.length]; - for (int i = 0; i < pdus.length; i++) { - byte[] pdu = (byte[]) pdus[i]; - messages[i] = SmsMessage.createFromPdu(pdu); - } - for (SmsMessage message : messages) { - String content = message.getMessageBody();// 得到短信内容 - String sender = message.getOriginatingAddress();// 得到发信息的号码 - Date date = new Date(message.getTimestampMillis()); - SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); - format.setTimeZone(TimeZone.getTimeZone("GMT+08:00")); - String dateContent = format.format(date); - - -// this.abortBroadcast();// 中止 - - } - } - - } - } - } - -} \ No newline at end of file diff --git a/mpmaster/src/main/java/com/xypower/mpmaster/sms/ModelSlotAndSub.java b/mpmaster/src/main/java/com/xypower/mpmaster/sms/ModelSlotAndSub.java new file mode 100644 index 00000000..96ca656b --- /dev/null +++ b/mpmaster/src/main/java/com/xypower/mpmaster/sms/ModelSlotAndSub.java @@ -0,0 +1,11 @@ +package com.xypower.mpmaster.sms; + + +/* +sim卡信息类 +*/ +public class ModelSlotAndSub { + public String subId; + public String simSlot; + public String iccid; +} diff --git a/mpmaster/src/main/java/com/xypower/mpmaster/sms/SimUtil.java b/mpmaster/src/main/java/com/xypower/mpmaster/sms/SimUtil.java new file mode 100644 index 00000000..801bede1 --- /dev/null +++ b/mpmaster/src/main/java/com/xypower/mpmaster/sms/SimUtil.java @@ -0,0 +1,308 @@ +package com.xypower.mpmaster.sms; + +import android.Manifest; +import android.app.Activity; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.os.Build; +import android.os.Bundle; +import android.telephony.SmsManager; +import android.telephony.SmsMessage; +import android.telephony.SubscriptionInfo; +import android.telephony.SubscriptionManager; +import android.text.TextUtils; + +import androidx.core.app.ActivityCompat; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Set; +import java.util.TimeZone; + + +/* + * 短信接收类 + * + * */ +public class SimUtil { + public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED"; + public static final String SMS_DELIVER_ACTION = "android.provider.Telephony.SMS_DELIVER"; + + //自定义ACTION常数 作为广播的IntentFilter识别常数 + public static String SMS_SEND_ACTION = "com.xypower.mpmaster.SMS_SEND_ACTION"; + public static String SMSTYPE = "smstype"; + + //短信解析 + public static SmsMessageModel analysisSMSInfo(Intent intent, Context context) { + SmsMessageModel smsInfo = getSMSInfo(intent); + if (smsInfo != null) { + String content = smsInfo.getContent(); + int slot = smsInfo.getSlot(); + String sender = smsInfo.getSender(); + String sendmessage = ""; + String sendtype = ""; + if (content.contains(SmsTypeEnum.REBOOT1.value())) { + sendmessage = content + " OK"; + sendtype = SmsTypeEnum.REBOOT1.value(); + } else if (content.contains(SmsTypeEnum.REBOOT2.value())) { + sendmessage = content + " OK"; + sendtype = SmsTypeEnum.REBOOT2.value(); + } + sendSms(context, slot, sender, sendmessage, sendtype); + } + return smsInfo; + } + + //短信解析 + public static SmsMessageModel getSMSInfo(Intent intent) { + SmsMessageModel smsMessageModel = new SmsMessageModel(); + String action = intent.getAction(); + if (SMS_RECEIVED_ACTION.equals(action) || SMS_DELIVER_ACTION.equals(action)) { + Bundle bundle = intent.getExtras(); + if (bundle != null) { + String content = ""; + String sender = ""; + String dateContent = ""; + Object[] pdus = (Object[]) bundle.get("pdus"); + if (pdus != null && pdus.length > 0) { + SmsMessage[] messages = new SmsMessage[pdus.length]; + for (int i = 0; i < pdus.length; i++) { + byte[] pdu = (byte[]) pdus[i]; + messages[i] = SmsMessage.createFromPdu(pdu); + } + for (SmsMessage message : messages) { + content = message.getMessageBody();// 得到短信内容 + // 得到发信息的号码 + sender = message.getOriginatingAddress(); + Date date = new Date(message.getTimestampMillis()); + SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + format.setTimeZone(TimeZone.getTimeZone("GMT+08:00")); + dateContent = format.format(date); + } + int smsSlot = getSmsSlot(bundle); + smsMessageModel.setContent(content); + smsMessageModel.setSender(sender); + smsMessageModel.setDateContent(dateContent); + smsMessageModel.setSlot(smsSlot); + } + } + } + return smsMessageModel; + } + + //获取是哪个sim卡收到短信 + private static int getSmsSlot(Bundle bundle) { + int slot = -1; + Set keySet = bundle.keySet(); + for (String key : keySet) { + switch (key) { + case "slot": + slot = bundle.getInt("slot", -1); + break; + case "simId": + slot = bundle.getInt("simId", -1); + break; + case "simSlot": + slot = bundle.getInt("simSlot", -1); + break; + case "slot_id": + slot = bundle.getInt("slot_id", -1); + break; + case "simnum": + slot = bundle.getInt("simnum", -1); + break; + case "slotId": + slot = bundle.getInt("slotId", -1); + break; + case "slotIdx": + slot = bundle.getInt("slotIdx", -1); + break; + default: + if (key.toLowerCase().contains("slot") | key.toLowerCase().contains("sim")) { + String value = bundle.getString(key, "-1"); + if (value.equals("0") | value.equals("1") | value.equals("2")) { + slot = bundle.getInt(key, -1); + } + } + } + } + return slot; + } + + //指定sim卡位置发送短信 + public static void sendSms(Context mContext, int slot, String sender, String message, String value) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { + SubscriptionManager localSubscriptionManager = SubscriptionManager.from(mContext); + if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { + return; + } + if (localSubscriptionManager.getActiveSubscriptionInfoCount() > 1) { + List localList = localSubscriptionManager.getActiveSubscriptionInfoList(); + + SubscriptionInfo simInfo1 = (SubscriptionInfo) localList.get(0); + SubscriptionInfo simInfo2 = (SubscriptionInfo) localList.get(1); + SubscriptionInfo simInfoAnother; + if (slot == 0) { + simInfoAnother = simInfo1; + } else { + simInfoAnother = simInfo2; + } + Intent itSend = new Intent(SMS_SEND_ACTION); + itSend.putExtra(SMSTYPE, value); + //sendIntent参数为传送后接受的广播信息PendingIntent + PendingIntent sendPI = PendingIntent.getBroadcast(mContext, 0, itSend, 0); + +// Intent itDeliver = new Intent(SMS_DELIVERED_ACTION); + //deliveryIntent参数为传送后接受的广播信息PendingIntent +// PendingIntent deliverPI = PendingIntent.getBroadcast(mContext,0,itDeliver,0); + SmsManager.getSmsManagerForSubscriptionId(simInfoAnother.getSubscriptionId()).sendTextMessage(sender, null, message, sendPI, null); + } + } + } + + + //判断是否是双卡 + public static boolean isDoubleSim(Context mContext) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { + SubscriptionManager manager = SubscriptionManager.from(mContext); + if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { + return false; + } + int count = manager.getActiveSubscriptionInfoCount(); + if (count == 2) { + return true; + } + } + return false; + } + + //通过卡槽id获取sim卡的信息0代码卡槽1,1代表卡槽2 + public static String getSlotIdInfo(Context mContext, int slotId) { + String info = ""; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { + SubscriptionManager manager = SubscriptionManager.from(mContext); + if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { + return ""; + } + SubscriptionInfo subInfo = manager.getActiveSubscriptionInfoForSimSlotIndex(slotId); + if (subInfo != null) { + info = subInfo.getCarrierName().toString(); + } + } + return info; + } + + //判断手机中是否装了双卡 + public static boolean isHasDoubleSim(Context mContext) { + try { + if (isDoubleSim(mContext)) { + List slotAndSubs = getModelSlot(mContext); + if (slotAndSubs != null && slotAndSubs.size() == 2) { + return true; + } else { + return false; + } + } else { + return false; + } + } catch (Exception e) { + e.printStackTrace(); + return false; + } + } + + + //判断是否拥有该权限 + public static boolean IsHasPermission(Context mContext, String permission) { + if (mContext != null) { + if (ActivityCompat.checkSelfPermission(mContext, permission) != PackageManager.PERMISSION_GRANTED) { + return false; + } + } else { + return false; + } + return true; + } + + + //申请该权限 + public static void requestOnePermission(Activity activity, String permission, int permissionCode) { + if (activity != null) { + activity.requestPermissions(new String[]{permission}, permissionCode); + } + } + + + //获取icc用来判断 + public static int getIcc(String iccid, List slotAndSubs) { + int icc = 0; + if (slotAndSubs != null && slotAndSubs.size() >= 2 && !TextUtils.isEmpty(iccid)) { + if (iccid.startsWith(slotAndSubs.get(0).iccid)) { + icc = 1; + } else if (iccid.startsWith(slotAndSubs.get(1).iccid)) { + icc = 2; + } else { + if (iccid.equals(slotAndSubs.get(0).subId)) { + icc = 1; + } else if (iccid.equals(slotAndSubs.get(1).subId)) { + icc = 2; + } else { + icc = 0; + } + } + } + return icc; + } + + /** + * 获取来自那张卡 即卡1 还是卡2 + * + * @param mContext + * @param subID + * @return + */ + public static int getSlot(Context mContext, String subID) { + return getIcc(subID, getModelSlot(mContext)); + } + + //获取对应的卡槽ID和iccID 关联 + private static List getModelSlot(Context mContext) { + List data = new ArrayList<>(); + ModelSlotAndSub modelSlotAndSub = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) { + SubscriptionManager subscriptionManager = SubscriptionManager.from(mContext); + if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) { + List mSubcriptionInfos = subscriptionManager.getActiveSubscriptionInfoList(); + if (mSubcriptionInfos != null) { + for (int i = 0; i < mSubcriptionInfos.size(); i++) { + SubscriptionInfo info = mSubcriptionInfos.get(i); + if (info != null) { + modelSlotAndSub = new ModelSlotAndSub(); + modelSlotAndSub.subId = info.getSubscriptionId() + ""; + modelSlotAndSub.simSlot = info.getSimSlotIndex() + 1 + ""; + modelSlotAndSub.iccid = info.getIccId(); + data.add(modelSlotAndSub); + } + } + if (data != null && data.size() == 2) { + if (!TextUtils.isEmpty(data.get(0).simSlot) && !TextUtils.isEmpty(data.get(1).simSlot)) { + int simSlot1 = Integer.valueOf(data.get(0).simSlot); + int simSlot2 = Integer.valueOf(data.get(1).simSlot); + if (simSlot1 > simSlot2) { + ModelSlotAndSub modelSlotAndSub1 = data.get(1); + data.remove(data.get(1)); + data.add(0, modelSlotAndSub1); + } + } + } + } + } + } + return data; + } + +} \ No newline at end of file diff --git a/mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsMessageModel.java b/mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsMessageModel.java new file mode 100644 index 00000000..382526ca --- /dev/null +++ b/mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsMessageModel.java @@ -0,0 +1,48 @@ +package com.xypower.mpmaster.sms; + +//收到的短信信息模型 +public class SmsMessageModel { + //短信内容 + private String content; + + //发送的短信号码 + private String sender; + + //收到短信的sim卡位置 + private int slot; + + //短信收到的时间 + private String dateContent; + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + public String getSender() { + return sender; + } + + public void setSender(String sender) { + this.sender = sender; + } + + public int getSlot() { + return slot; + } + + public void setSlot(int slot) { + this.slot = slot; + } + + public String getDateContent() { + return dateContent; + } + + public void setDateContent(String dateContent) { + this.dateContent = dateContent; + } +} diff --git a/mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsReceiver.java b/mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsReceiver.java new file mode 100644 index 00000000..72f2208b --- /dev/null +++ b/mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsReceiver.java @@ -0,0 +1,20 @@ +package com.xypower.mpmaster.sms; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +/** + * 短信接收的监听的广播 + * + * @author jingjing + */ +public class SmsReceiver extends BroadcastReceiver { + + @Override + public void onReceive(Context context, Intent intent) { + SimUtil.analysisSMSInfo(intent,context); + } + + +} \ No newline at end of file diff --git a/mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsSendReceiver.java b/mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsSendReceiver.java new file mode 100644 index 00000000..c376045a --- /dev/null +++ b/mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsSendReceiver.java @@ -0,0 +1,30 @@ +package com.xypower.mpmaster.sms; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; + +import com.dev.devapi.api.SysApi; + + +/** + * 短信发送的监听广播 + * 从Android 4.4(API 19)开始,由于安全和隐私原因,不再允许应用程序静态注册监听短信发送状态的广播。 + * + * @author jingjing + */ +public class SmsSendReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (SimUtil.SMS_SEND_ACTION.equals(action)) { + String type = intent.getStringExtra(SimUtil.SMSTYPE); + if (type.contains(SmsTypeEnum.REBOOT1.value())) { + SysApi.reboot(context); + } + } + } + + +} \ No newline at end of file diff --git a/mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsTypeEnum.java b/mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsTypeEnum.java new file mode 100644 index 00000000..6b409ebd --- /dev/null +++ b/mpmaster/src/main/java/com/xypower/mpmaster/sms/SmsTypeEnum.java @@ -0,0 +1,49 @@ +package com.xypower.mpmaster.sms; + +public enum SmsTypeEnum { + REBOOT1("yw+at+stw21"), REBOOT2("at+stw21"), //重启命令 + YW_SCHEDULE("yw+at+stw51"), //拍照时间表设置 + OPERATE("yw+at+stw52"), //运维开关 + OPERATE_URL("yw+at+stw53"), //运维地址 + ADB("yw+at+ds"), //开关adb + UPDATE("yw+at+update"), //远程升级 + READ_CMDID("at+str01"), //读取设备编号 + SET_CMDID("at+stw01"), //设置设备编号 + SET_IP("at+stw05"), //设置主站IP + READ_IP("at+str05"), //读取主站IP端口 + SET_AI("yw+at+stw61"), //设置ai识别是否可用 0是不启用,1是启用 + GET_AI("yw+at+stw62"), //查询ai识别是否可用 0是不启用,1是启用 + SET_AI_BOARD("yw+at+stw63"), //设置ai画框是否可用 0是不启用,1是启用 + GET_AI_BOARD("yw+at+stw64"), //查询ai画框是否可用 0是不启用,1是启用 + GET_OSD("yw+at+str65"), //查询水印 + SET_OSD("yw+at+stw66"), //设置水印 + SET_PHOTO_SCHEDULE_LIST("at+stw37"), //拍照时间表设置 + GET_PHOTO_SCHEDULE_LIST("at+str37"), //拍照时间表查询 + SET_PHOTO_SCHEDULE("at+stw07"), //拍照时间表单独设置 + GET_PHOTO_SCHEDULE("at+str07"), //拍照时间表查询 + SET_RESOLUTION("at+stw38"), //分辨率设置 + GET_RESOLUTION("at+str38"), //查询分辨率 + TAKE_PHOTO("at+stw39"), //手动拍照/短视频并上传 + SET_HEART("yw+at+setHB"), //设置心跳间隔 + GET_HEART("yw+at+getHB"), //获取心跳间隔 + SET_TP("yw+at+setTP"), //设置传输协议 + GET_TP("yw+at+getTP"), //获取传输协议 + SET_PACKAGE("yw+at+setPackage"), //设置分包大小 + GET_PACKAGE("yw+at+getPackage"),//获取分包大小 + CLEAR_PHOTO("yw+at+clearPhoto"), //清除历史图片及视频 + CLEAR_LOG("yw+at+clearLog"), //删除日志 + CLEAR_ALL("yw+at+clearAll"), //清除图片、视频、日志 + RESTORE("yw+at+Restore"), //恢复出厂设置 + GET_GPS("yw+at+getGPS");//GPS数据获取 + + + private String name; + + SmsTypeEnum(String name) { + this.name = name; + } + + public String value() { + return this.name; + } +} diff --git a/mpmaster/src/main/res/layout/activity_main.xml b/mpmaster/src/main/res/layout/activity_main.xml index 148ed406..b9e5b13b 100644 --- a/mpmaster/src/main/res/layout/activity_main.xml +++ b/mpmaster/src/main/res/layout/activity_main.xml @@ -83,6 +83,7 @@ app:layout_constraintStart_toEndOf="@+id/btnTurn485On" app:layout_constraintTop_toTopOf="@+id/btnTurn485On" /> + - +