├── .gitignore ├── .idea ├── compiler.xml ├── copyright │ └── profiles_settings.xml ├── gradle.xml ├── misc.xml ├── modules.xml └── runConfigurations.xml ├── ExcelDataExample.xls ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── libs │ └── jxl.jar ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── java │ └── com │ │ └── ccccat │ │ └── www │ │ └── msgs │ │ ├── MainActivity.java │ │ ├── Person.java │ │ └── SimUtil.java │ └── res │ ├── drawable │ ├── bg_input.xml │ ├── btn_main.xml │ ├── btn_main_enable.xml │ ├── btn_main_selector.xml │ ├── rb_left_enable.xml │ ├── rb_left_main.xml │ ├── rb_left_selector.xml │ ├── rb_right_enable.xml │ ├── rb_right_main.xml │ └── rb_right_selector.xml │ ├── layout │ ├── activity_main.xml │ └── item_person.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-w820dp │ └── dimens.xml │ └── values │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── build.gradle ├── demo ├── Msgs.apk ├── pic0.png └── pic1.png ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | -------------------------------------------------------------------------------- /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 17 | 18 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 19 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Abstraction issuesJava 39 | 40 | 41 | Android > Lint > Correctness 42 | 43 | 44 | Android > Lint > Security 45 | 46 | 47 | Concurrency annotation issuesJava 48 | 49 | 50 | Initialization issuesJava 51 | 52 | 53 | Java 54 | 55 | 56 | Probable bugsJava 57 | 58 | 59 | Security issuesJava 60 | 61 | 62 | Threading issuesJava 63 | 64 | 65 | 66 | 67 | Android 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 89 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /ExcelDataExample.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GHBlade/Msgs/b673a7995982d7b20a48dd69f5f4c280891a95ff/ExcelDataExample.xls -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Skyline 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #### Msgs 2 | 3 | * 短信群发,支持单卡/双卡,发送短信 4 | 5 | * 群发仅支持 .xls 后缀格式表格数据 分三列 :`用户名` | `电话号码` | `短信内容` 6 | * 格式可参考 [**ExcelDataExample.xls**](./ExcelDataExample.xls) 7 | 8 | * [**示例APK**](./demo/Msgs.apk) 9 | 10 | #### 示例图片:
11 | 12 | ![示例1](./demo/pic0.png) 13 | ![示例2](./demo/pic1.png) 14 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 24 5 | buildToolsVersion "25.0.0" 6 | defaultConfig { 7 | applicationId "com.ccccat.www.msgs" 8 | minSdkVersion 19 9 | targetSdkVersion 22 10 | versionCode 1 11 | versionName "1.0" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | compile fileTree(dir: 'libs', include: ['*.jar']) 23 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { 24 | exclude group: 'com.android.support', module: 'support-annotations' 25 | }) 26 | compile 'com.android.support:appcompat-v7:24.2.1' 27 | compile 'com.jude:easyrecyclerview:4.0.2' 28 | compile files('libs/jxl.jar') 29 | } 30 | -------------------------------------------------------------------------------- /app/libs/jxl.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GHBlade/Msgs/b673a7995982d7b20a48dd69f5f4c280891a95ff/app/libs/jxl.jar -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in E:\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/java/com/ccccat/www/msgs/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.ccccat.www.msgs; 2 | 3 | import android.app.Activity; 4 | import android.app.ProgressDialog; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.content.res.AssetManager; 8 | import android.net.Uri; 9 | import android.os.AsyncTask; 10 | import android.os.Build; 11 | import android.support.annotation.RequiresApi; 12 | import android.support.v7.app.AppCompatActivity; 13 | import android.os.Bundle; 14 | import android.support.v7.widget.DefaultItemAnimator; 15 | import android.support.v7.widget.LinearLayoutManager; 16 | import android.support.v7.widget.RecyclerView; 17 | import android.telephony.SmsManager; 18 | import android.telephony.SubscriptionInfo; 19 | import android.telephony.SubscriptionManager; 20 | import android.text.TextUtils; 21 | import android.util.Log; 22 | import android.view.LayoutInflater; 23 | import android.view.View; 24 | import android.view.ViewGroup; 25 | import android.widget.Button; 26 | import android.widget.EditText; 27 | import android.widget.LinearLayout; 28 | import android.widget.RadioGroup; 29 | import android.widget.TextView; 30 | import android.widget.Toast; 31 | import com.jude.easyrecyclerview.EasyRecyclerView; 32 | import java.io.FileInputStream; 33 | import java.io.InputStream; 34 | import java.util.ArrayList; 35 | import java.util.List; 36 | import jxl.Sheet; 37 | import jxl.Workbook; 38 | 39 | public class MainActivity extends AppCompatActivity implements View.OnClickListener, RadioGroup.OnCheckedChangeListener { 40 | public static String TAG = "SMSMANAGER"; 41 | private Button btn_send, btn_improt, btn_send_more; 42 | private EditText phoneEt, contextEt; 43 | private EasyRecyclerView rv_list; 44 | private ProgressDialog progressDialog; 45 | private List personList; 46 | private PersonAdapter mAdapter; 47 | private TextView tips; 48 | private RadioGroup rg_all; 49 | private int IDs = 0; 50 | 51 | @Override 52 | public void onCreate(Bundle savedInstanceState) { 53 | super.onCreate(savedInstanceState); 54 | setContentView(R.layout.activity_main); 55 | init(); 56 | } 57 | 58 | private void init() { 59 | personList = new ArrayList<>(); 60 | mAdapter = new PersonAdapter(); 61 | btn_send = (Button) this.findViewById(R.id.btn_send); 62 | tips = (TextView) this.findViewById(R.id.tips); 63 | btn_send_more = (Button) this.findViewById(R.id.btn_send_more); 64 | btn_improt = (Button) this.findViewById(R.id.btn_improt); 65 | phoneEt = (EditText) this.findViewById(R.id.phoneNumberEt); 66 | contextEt = (EditText) this.findViewById(R.id.contextEt); 67 | rg_all = (RadioGroup) this.findViewById(R.id.rg_all); 68 | rv_list = (EasyRecyclerView) this.findViewById(R.id.rv_list); 69 | progressDialog = new ProgressDialog(this); 70 | btn_send.setOnClickListener(this); 71 | btn_improt.setOnClickListener(this); 72 | btn_send_more.setOnClickListener(this); 73 | LinearLayoutManager mLayoutManager = new LinearLayoutManager(this); 74 | rv_list.setLayoutManager(mLayoutManager); 75 | rv_list.setItemAnimator(new DefaultItemAnimator()); 76 | rv_list.setAdapter(mAdapter); 77 | rg_all.setOnCheckedChangeListener(this); 78 | } 79 | 80 | /** 81 | * 获取 excel 表格中的数据,不能在主线程中调用 82 | */ 83 | private ArrayList getXlsData(String filePath, int index) { 84 | ArrayList persons = new ArrayList<>(); 85 | try { 86 | InputStream is = new FileInputStream(filePath); 87 | Workbook workbook = Workbook.getWorkbook(is); 88 | Sheet sheet = workbook.getSheet(index); 89 | int sheetRows = sheet.getRows(); 90 | for (int i = 0; i < sheetRows; i++) { 91 | Person person = new Person(); 92 | person.setUserName(sheet.getCell(0, i).getContents()); 93 | person.setPhoneNumber(sheet.getCell(1, i).getContents()); 94 | person.setMsgContent(sheet.getCell(2, i).getContents()); 95 | persons.add(person); 96 | } 97 | workbook.close(); 98 | } catch (Exception e) { 99 | Log.d(TAG, "数据读取错误=" + e); 100 | } 101 | return persons; 102 | } 103 | 104 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1) 105 | @Override 106 | public void onClick(View v) { 107 | switch (v.getId()) { 108 | // 导入Excel表格 109 | case R.id.btn_improt: 110 | Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 111 | intent.setType("*/*"); 112 | intent.addCategory(Intent.CATEGORY_OPENABLE); 113 | startActivityForResult(intent,1); 114 | break; 115 | // 发送 116 | case R.id.btn_send: 117 | String phone = phoneEt.getText().toString().trim(); 118 | String context = contextEt.getText().toString().trim(); 119 | 120 | if (TextUtils.isEmpty(phone) || TextUtils.isEmpty(context)) { 121 | Toast.makeText(MainActivity.this, "号码或内容不能为空!", Toast.LENGTH_SHORT); 122 | return; 123 | } 124 | sendSms(IDs,phone,context); 125 | 126 | phoneEt.setText(""); 127 | contextEt.setText(""); 128 | Toast.makeText(getApplicationContext(), "发送完毕", Toast.LENGTH_SHORT).show(); 129 | break; 130 | // 批量发送 131 | case R.id.btn_send_more: 132 | for (Person item : personList){ 133 | sendSms(IDs,item.getPhoneNumber(),item.getMsgContent()); 134 | // 停顿1s 135 | } 136 | Toast.makeText(getApplicationContext(), "正在发送,请稍后...", Toast.LENGTH_SHORT).show(); 137 | break; 138 | } 139 | } 140 | 141 | private void setupData(List persons) { 142 | personList.clear(); 143 | personList.addAll(persons); 144 | mAdapter.notifyDataSetChanged(); 145 | } 146 | 147 | @Override 148 | public void onCheckedChanged(RadioGroup group, int checkedId) { 149 | switch (checkedId) { 150 | case R.id.rb_one: 151 | IDs = 0; 152 | break; 153 | case R.id.rb_two: 154 | IDs = 1; 155 | break; 156 | } 157 | } 158 | 159 | // 异步获取Excel数据信息 160 | private class ExcelDataLoader extends AsyncTask> { 161 | @Override 162 | protected void onPreExecute() { 163 | progressDialog.setMessage("Excel数据导入中,请稍后......"); 164 | progressDialog.setCanceledOnTouchOutside(false); 165 | progressDialog.show(); 166 | } 167 | 168 | @Override 169 | protected ArrayList doInBackground(String... params) { 170 | return getXlsData(params[0], 0); 171 | } 172 | 173 | @Override 174 | protected void onPostExecute(ArrayList persons) { 175 | if (progressDialog.isShowing()) { 176 | progressDialog.dismiss(); 177 | } 178 | if (persons != null && persons.size() > 0) { 179 | // 列表显示数据 180 | setupData(persons); 181 | } else { 182 | // 加载失败 183 | Toast.makeText(MainActivity.this, "数据加载失败!", Toast.LENGTH_SHORT); 184 | } 185 | } 186 | } 187 | 188 | private class PersonAdapter extends RecyclerView.Adapter { 189 | 190 | class TextViewHolder extends RecyclerView.ViewHolder { 191 | TextView tv_name, tv_number, tv_content; 192 | LinearLayout ll_index; 193 | 194 | public TextViewHolder(View itemView) { 195 | super(itemView); 196 | tv_name = (TextView) itemView.findViewById(R.id.tv_name); 197 | tv_number = (TextView) itemView.findViewById(R.id.tv_number); 198 | tv_content = (TextView) itemView.findViewById(R.id.tv_content); 199 | ll_index = (LinearLayout) itemView.findViewById(R.id.ll_index); 200 | } 201 | } 202 | 203 | @Override 204 | public TextViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 205 | return new TextViewHolder(LayoutInflater.from(parent.getContext()) 206 | .inflate(R.layout.item_person, parent, false)); 207 | } 208 | 209 | @Override 210 | public void onBindViewHolder(final RecyclerView.ViewHolder holder, final int position) { 211 | if (holder instanceof TextViewHolder) { 212 | ((TextViewHolder) holder).tv_name.setText(personList.get(position).getUserName()); 213 | ((TextViewHolder) holder).tv_number.setText(personList.get(position).getPhoneNumber()); 214 | ((TextViewHolder) holder).tv_content.setText(personList.get(position).getMsgContent()); 215 | ((TextViewHolder) holder).ll_index.setOnClickListener(new View.OnClickListener() { 216 | @Override 217 | public void onClick(View v) { 218 | phoneEt.setText(personList.get(position).getPhoneNumber()); 219 | contextEt.setText(personList.get(position).getMsgContent()); 220 | } 221 | }); 222 | } 223 | } 224 | 225 | @Override 226 | public int getItemCount() { 227 | return personList.size(); 228 | } 229 | } 230 | 231 | // 获取本地Excel信息 232 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 233 | if (resultCode == Activity.RESULT_OK) { 234 | if (requestCode == 1) { 235 | Uri uri = data.getData(); 236 | String path = uri.getPath().toString(); 237 | tips.setText(path); 238 | 239 | // 执行Excel数据导入 240 | new ExcelDataLoader().execute(path.trim()); 241 | } 242 | } 243 | } 244 | 245 | @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP_MR1) 246 | private void sendSms(final int which,String phone,String context) { 247 | SubscriptionInfo sInfo = null; 248 | 249 | final SubscriptionManager sManager = (SubscriptionManager) getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); 250 | 251 | List list = sManager.getActiveSubscriptionInfoList(); 252 | 253 | if (list.size() == 2) { 254 | // 双卡 255 | sInfo = list.get(which); 256 | } else { 257 | // 单卡 258 | sInfo = list.get(0); 259 | } 260 | 261 | if (sInfo != null) { 262 | int subId = sInfo.getSubscriptionId(); 263 | SmsManager manager = SmsManager.getSmsManagerForSubscriptionId(subId); 264 | 265 | if (!TextUtils.isEmpty(phone)) { 266 | ArrayList messageList =manager.divideMessage(context); 267 | for(String text:messageList){ 268 | manager.sendTextMessage(phone, null, text, null, null); 269 | } 270 | Toast.makeText(this, "信息正在发送,请稍候", Toast.LENGTH_SHORT) 271 | .show(); 272 | } else { 273 | Toast.makeText(this, "无法正确的获取SIM卡信息,请稍候重试", 274 | Toast.LENGTH_SHORT).show(); 275 | } 276 | } 277 | } 278 | } -------------------------------------------------------------------------------- /app/src/main/java/com/ccccat/www/msgs/Person.java: -------------------------------------------------------------------------------- 1 | package com.ccccat.www.msgs; 2 | 3 | public class Person { 4 | private String userName; 5 | private String phoneNumber; 6 | private String msgContent; 7 | 8 | public String getUserName() { 9 | return userName; 10 | } 11 | 12 | public void setUserName(String userName) { 13 | this.userName = userName; 14 | } 15 | 16 | public String getPhoneNumber() { 17 | return phoneNumber; 18 | } 19 | 20 | public void setPhoneNumber(String phoneNumber) { 21 | this.phoneNumber = phoneNumber; 22 | } 23 | 24 | public String getMsgContent() { 25 | return msgContent; 26 | } 27 | 28 | public void setMsgContent(String msgContent) { 29 | this.msgContent = msgContent; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/com/ccccat/www/msgs/SimUtil.java: -------------------------------------------------------------------------------- 1 | package com.ccccat.www.msgs; 2 | 3 | import android.app.PendingIntent; 4 | import android.content.Context; 5 | import android.os.Build; 6 | import android.os.IBinder; 7 | import android.util.Log; 8 | 9 | import java.lang.reflect.InvocationTargetException; 10 | import java.lang.reflect.Method; 11 | import java.util.ArrayList; 12 | import java.util.List; 13 | 14 | public class SimUtil { 15 | public static boolean sendSMS(Context ctx, int simID, String toNum, String centerNum, String smsText, PendingIntent sentIntent, PendingIntent deliveryIntent) { 16 | String name; 17 | 18 | try { 19 | if (simID == 0) { 20 | name = "isms"; 21 | // for model : "Philips T939" name = "isms0" 22 | } else if (simID == 1) { 23 | name = "isms2"; 24 | } else { 25 | throw new Exception("can not get service which for sim '" + simID + "', only 0,1 accepted as values"); 26 | } 27 | Method method = Class.forName("android.os.ServiceManager").getDeclaredMethod("getService", String.class); 28 | method.setAccessible(true); 29 | Object param = method.invoke(null, name); 30 | 31 | method = Class.forName("com.android.internal.telephony.ISms$Stub").getDeclaredMethod("asInterface", IBinder.class); 32 | method.setAccessible(true); 33 | Object stubObj = method.invoke(null, param); 34 | if (Build.VERSION.SDK_INT < 18) { 35 | method = stubObj.getClass().getMethod("sendText", String.class, String.class, String.class, PendingIntent.class, PendingIntent.class); 36 | method.invoke(stubObj, toNum, centerNum, smsText, sentIntent, deliveryIntent); 37 | } else { 38 | method = stubObj.getClass().getMethod("sendText", String.class, String.class, String.class, String.class, PendingIntent.class, PendingIntent.class); 39 | method.invoke(stubObj, ctx.getPackageName(), toNum, centerNum, smsText, sentIntent, deliveryIntent); 40 | } 41 | 42 | return true; 43 | } catch (ClassNotFoundException e) { 44 | Log.e("apipas", "ClassNotFoundException:" + e.getMessage()); 45 | } catch (NoSuchMethodException e) { 46 | Log.e("apipas", "NoSuchMethodException:" + e.getMessage()); 47 | } catch (InvocationTargetException e) { 48 | Log.e("apipas", "InvocationTargetException:" + e.getMessage()); 49 | } catch (IllegalAccessException e) { 50 | Log.e("apipas", "IllegalAccessException:" + e.getMessage()); 51 | } catch (Exception e) { 52 | Log.e("apipas", "Exception:" + e.getMessage()); 53 | } 54 | return false; 55 | } 56 | 57 | public static boolean sendMultipartTextSMS(Context ctx, int simID, String toNum, String centerNum, ArrayList smsTextlist, ArrayList sentIntentList, ArrayList deliveryIntentList) { 58 | String name; 59 | try { 60 | if (simID == 0) { 61 | name = "isms"; 62 | } else if (simID == 1) { 63 | name = "isms2"; 64 | } else { 65 | throw new Exception("can not get service which for sim '" + simID + "', only 0,1 accepted as values"); 66 | } 67 | Method method = Class.forName("android.os.ServiceManager").getDeclaredMethod("getService", String.class); 68 | method.setAccessible(true); 69 | Object param = method.invoke(null, name); 70 | 71 | method = Class.forName("com.android.internal.telephony.ISms$Stub").getDeclaredMethod("asInterface", IBinder.class); 72 | method.setAccessible(true); 73 | Object stubObj = method.invoke(null, param); 74 | if (Build.VERSION.SDK_INT < 18) { 75 | method = stubObj.getClass().getMethod("sendMultipartText", String.class, String.class, List.class, List.class, List.class); 76 | method.invoke(stubObj, toNum, centerNum, smsTextlist, sentIntentList, deliveryIntentList); 77 | } else { 78 | method = stubObj.getClass().getMethod("sendMultipartText", String.class, String.class, String.class, List.class, List.class, List.class); 79 | method.invoke(stubObj, ctx.getPackageName(), toNum, centerNum, smsTextlist, sentIntentList, deliveryIntentList); 80 | } 81 | return true; 82 | } catch (ClassNotFoundException e) { 83 | Log.e("apipas", "ClassNotFoundException:" + e.getMessage()); 84 | } catch (NoSuchMethodException e) { 85 | Log.e("apipas", "NoSuchMethodException:" + e.getMessage()); 86 | } catch (InvocationTargetException e) { 87 | Log.e("apipas", "InvocationTargetException:" + e.getMessage()); 88 | } catch (IllegalAccessException e) { 89 | Log.e("apipas", "IllegalAccessException:" + e.getMessage()); 90 | } catch (Exception e) { 91 | Log.e("apipas", "Exception:" + e.getMessage()); 92 | } 93 | return false; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_input.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_main_enable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/btn_main_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/rb_left_enable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/rb_left_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/rb_left_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/rb_right_enable.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/rb_right_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/rb_right_selector.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 18 | 24 |