解决思路: 新建一个安卓apk然后,把验证码获取到,最后传入需要的服务端中转
下面是测试apk的地址有需要可以下载来试试
百度网盘apk地址
链接: https://pan.baidu.com/s/1zDkdNM-_QWICOuVmdqfwUQ 提取码: fktr 复制这段内容后打开百度网盘手机App,操作更方便哦
额外啰嗦:
某些手机需要在短信-设置 里面关闭 验证码安全保护
如我的华为手机,安装时授权了,还需要关闭短信里面的安全保护

1.项目截图

项目中有依赖包直接安装就行
直接上代码
buid.gradle配置
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "com.bb.myapplication"
minSdkVersion 19
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.0'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
implementation 'com.squareup.okio:okio:2.9.0'
implementation 'com.squareup.okhttp3:okhttp-android-support:3.13.1'
}
AndroidManifest.xml 配置
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bb.myapplication">
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ergou"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:networkSecurityConfig="@xml/network_security_config"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".MYSMS"
android:enabled="true"
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>
<provider
android:authorities="com.bb.myapplication.College"
android:name=".Target_Url_Provider"></provider>
</application>
</manifest>
network_security_config.xml 这个文件解决安装9访问网络的权限

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true" />
</network-security-config>
MainActivity.java
package com.bb.myapplication;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import java.io.IOException;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final TextView viewById = findViewById(R.id.setx);
viewById.setText("┏ (゜ω゜)=☞");
final EditText saveEditText=findViewById(R.id.httpurl);
saveEditText.setText((query_url()=="")?"请输入验证码需要发送url地址":query_url());
Button save_and_update_httpurl=findViewById(R.id.save_and_update);
save_and_update_httpurl.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
save_url();
}
});
// https://www.runoob.com/android/android-content-providers.html 内容提供者
}
public void save_url(){
EditText editText=findViewById(R.id.httpurl);
String editText_str=editText.getText().toString();
if(query_url()==""){
ContentValues values=new ContentValues();
values.put(Target_Url_Provider.CODE_URL,editText_str);
Uri uri=getContentResolver().insert(Target_Url_Provider.CONTENT_URI,values);
// Toast.makeText(MainActivity.this,"uri= "+uri,Toast.LENGTH_LONG).show();
Toast.makeText(MainActivity.this,"创建一条新数据",Toast.LENGTH_LONG).show();
}else {
String URLs = "content://com.bb.myapplication.College/target_url/1";
Uri target=Uri.parse(URLs);
ContentValues contentValues=new ContentValues();
contentValues.put(Target_Url_Provider.CODE_URL,editText_str);
int count=getContentResolver().update(target,contentValues,null,null);
Toast.makeText(MainActivity.this,"更新了"+count+"条数据",Toast.LENGTH_SHORT).show();
}
}
public String query_url(){
String URL = "content://com.bb.myapplication.College/target_url/1";
String save_value="";
Uri target_url=Uri.parse(URL);
Cursor c=getContentResolver().query(target_url,null,null,null,"_id");
if(c.moveToFirst()){
// Toast.makeText(MainActivity.this,c.getString(c.getColumnIndex(Target_Url_Provider._ID))+" , "+
// c.getString(c.getColumnIndex(Target_Url_Provider.CODE_URL)),Toast.LENGTH_SHORT).show();
save_value=c.getString(c.getColumnIndex(Target_Url_Provider.CODE_URL));
}else {
// Toast.makeText(MainActivity.this," 没有获取到",Toast.LENGTH_LONG).show();
save_value="";
}
c.close();
return save_value;
}
/**
@Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
getMenuInflater().inflate(R.menu.menu_main,menu);
return true;
}
public void onClickAddName(View view){
/* ContentValues 和HashTable类似都是一种存储的机制 但是两者最大的区别就在于,contenvalues只能存储基本类型的数据,
像string,int之类的,不能存储对象这种东西,而HashTable却可以存储对象。
在忘数据库中插入数据的时候,首先应该有一个ContentValues的对象所以
ContentValues values=new ContentValues();
values.put(StudentsProvider.Name,((EditText)findViewById(R.id.editText2)).getText().toString());
values.put(StudentsProvider.GRADE,((EditText)findViewById(R.id.editText3)).getText().toString());
Uri uri=getContentResolver().insert(StudentsProvider.CONTENT_URI,values);
Toast.makeText(getBaseContext(),uri.toString(),Toast.LENGTH_LONG).show();
}
public void onClickRetrieveStudents(View view){
// 取回数据
String URL="content://com.example.provider.College/students";
Uri students=Uri.parse(URL);
// 获取一个 数据库游标
Cursor c= getContentResolver().query(students, null, null, null, "name");
if(c.moveToFirst()){
do{
Toast.makeText(this,c.getString(c.getColumnIndex(StudentsProvider._ID))+
", "+c.getString(c.getColumnIndex(StudentsProvider.NAME))+
", "+c.getString(c.getColumnIndex(StudentsProvider.GRADE)),
Toast.LENGTH_LONG).show();
}while (c.moveToNext());
}
}
*/
}
MYSMS.java
package com.bb.myapplication;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.nfc.Tag;
import android.os.Bundle;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
public class MYSMS extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Toast.makeText(context,"收到短信",Toast.LENGTH_LONG).show();
// context.getApplicationContext().getContentResolver()
String url="http://172.18.129.173:8000/auto_interface/v1/code";
String URL = "content://com.bb.myapplication.College/target_url/1";
Uri target_url=Uri.parse(URL);
Cursor c=context.getContentResolver().query(target_url,null,null,null,"_id");
if(c.moveToFirst()){
url=c.getString(c.getColumnIndex(Target_Url_Provider.CODE_URL));
}else {
Toast.makeText(context," 不知道把验证码发到哪里,告辞",Toast.LENGTH_LONG).show();
}
c.close();
String msg_body = "";
String msg_phone = "";
Object[] objs=(Object[]) intent.getExtras().get("pdus");
for (Object obj:objs){
SmsMessage msg=SmsMessage.createFromPdu((byte[]) obj);
msg_body=msg.getMessageBody();
msg_phone=msg.getOriginatingAddress();
// Toast.makeText(context,msg_phone+msg_body,Toast.LENGTH_LONG).show();
Log.i("xxx", "广播收到短信: "+msg_phone+msg_body);
}
MyThread myThread=new MyThread();
myThread.setTarget_url(url);
// myThread.setTarget_url(GOLABL_VAR.getTarget_URL());
myThread.setPhone(msg_phone);
myThread.setMsg_body(msg_body);
Thread thread=new Thread(myThread);
thread.start();
// 获取数据库的url 链接
}
}
MyThread.java
package com.bb.myapplication;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
public class MyThread implements Runnable {
private String target_url;
private String phone;
private String msg_body;
public String getMsg_body() {
return msg_body;
}
public void setMsg_body(String msg_body) {
this.msg_body = msg_body;
}
public String getTarget_url() {
return target_url;
}
public void setTarget_url(String target_url) {
this.target_url = target_url;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public void run() {
OkHttpClient okHttpClient=new OkHttpClient.Builder().build();
FormBody formBody=new FormBody.Builder()
.add("body",this.msg_body)
.add("phone",this.phone)
.build();
Request request=new Request.Builder()
.url(this.target_url)
.post(formBody)
.build();
try {
Response response=okHttpClient.newCall(request).execute();
// Looper.prepare();
// Toast.makeText(getBaseContext(),"我是子线程的toast",Toast.LENGTH_LONG).show();
// Looper.loop();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Target_Url_Provider.java
package com.bb.myapplication;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import java.util.HashMap;
public class Target_Url_Provider extends ContentProvider {
// 内容提供者名字
static final String PROVIDER_NAME="com.bb.myapplication.College";
static final String URL="content://" + PROVIDER_NAME + "/target_url";
static final Uri CONTENT_URI=Uri.parse(URL);
static final String _ID="_id";
// 验证码请求地址
static final String CODE_URL="post_target_url";
private static HashMap<String,String> CODE_URL_PROJECTION_MAP;
static final int TAGETURLS=1;
static final int TAGETURL_ID=2;
static final UriMatcher uriMatcher ;
static {
uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);
uriMatcher.addURI(PROVIDER_NAME,"target_url",TAGETURLS);
uriMatcher.addURI(PROVIDER_NAME,"target_url/#",TAGETURL_ID);
}
/**
* 数据库特定常量申明
* @return
*/
private SQLiteDatabase db;
static final String DATABASE_NAME="College";
static final String TARGETURL_TABLE_NAME="target_url";
static final int DATABASE_VERSION=1;
static final String CREATE_DB_TABLE=
" CREATE TABLE "+TARGETURL_TABLE_NAME+
"(_id INTEGER PRIMARY KEY AUTOINCREMENT, "+
"post_target_url TEXT NOT NULL);";
/**
* 创建和管理提供者内部数据源的帮助类。
* @return
*/
private static class DatabaseHelper extends SQLiteOpenHelper{
DatabaseHelper(Context context){
super(context,DATABASE_NAME,null,DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_DB_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS "+TARGETURL_TABLE_NAME);
onCreate(db);
}
}
@Override
public boolean onCreate() {
Context context=getContext();
DatabaseHelper dbHelper=new DatabaseHelper(context);
/**
* 如果不存在 则创建一个可写的
*/
db=dbHelper.getReadableDatabase();
return (db==null)? false:true;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) {
SQLiteQueryBuilder qb=new SQLiteQueryBuilder();
qb.setTables(TARGETURL_TABLE_NAME);
switch (uriMatcher.match(uri)){
case TAGETURLS:
qb.setProjectionMap(CODE_URL_PROJECTION_MAP);
break;
case TAGETURL_ID:
qb.appendWhere(_ID+"="+uri.getPathSegments().get(1));
break;
default:
throw new IllegalArgumentException(" 查询时 url没有匹配的 "+uri);
}
if(sortOrder==null|| sortOrder==""){
sortOrder=CODE_URL;
}
Cursor c=qb.query(db,projection,selection,selectionArgs,null,null,sortOrder);
/**
* 注册内容URI变化的监听器
*/
c.setNotificationUri(getContext().getContentResolver(),uri);
return c;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
switch (uriMatcher.match(uri)){
case TAGETURLS:
return "vnd.android.cursor.dir/vnd.example.students";
case TAGETURL_ID:
return "vnd.android.cursor.item/vnd.example.students";
default:
throw new IllegalArgumentException(" gettype 不支持的uri "+uri);
}
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
/**
* 添加url地址
*/
long rowID=db.insert(TARGETURL_TABLE_NAME,"",values);
/**
* 如果添加成功
*/
if (rowID>0){
Uri _uri= ContentUris.withAppendedId(CONTENT_URI,rowID);
getContext().getContentResolver().notifyChange(_uri,null);
return _uri;
}
throw new SQLException("添加记录失败 "+uri);
}
@Override
public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
int count=0;
switch (uriMatcher.match(uri)){
case TAGETURLS:
count=db.delete(TARGETURL_TABLE_NAME,selection,selectionArgs);
case TAGETURL_ID:
String id=uri.getPathSegments().get(1);
count=db.delete(TARGETURL_TABLE_NAME,_ID+" = "+id+
(!TextUtils.isEmpty(selection)?" AND ("+selection+")":""),selectionArgs);
break;
default:
throw new IllegalArgumentException(" 删除报错 "+uri);
}
return count;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
int count=0;
switch (uriMatcher.match(uri)){
case TAGETURLS:
count=db.update(TARGETURL_TABLE_NAME,values,selection,selectionArgs);
break;
case TAGETURL_ID:
count=db.update(TARGETURL_TABLE_NAME,values,_ID+" = "+uri.getPathSegments().get(1)+
(!TextUtils.isEmpty(selection)?" AND ("+selection+")":""),selectionArgs);
break;
default:
throw new IllegalArgumentException(" 更新失败,没有匹配到"+uri);
}
getContext().getContentResolver().notifyChange(uri,null);
return count;
}
}
GOLABL_VAR.java(项目中没有使用这个)
package com.bb.myapplication;
public class GOLABL_VAR {
private static String Target_URL ;
public static String getTarget_URL() {
return Target_URL;
}
public static void setTarget_URL(String target_URL) {
Target_URL = target_URL;
}
}
网友评论