diff --git a/README.md b/README.md index 04fcf26..481454c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,6 @@ -#验证码助手 +#验证码助手 SmsCodeHelper -是由原「[贝壳单词](http://www.beikedanci.com)」团队开发的一款新的开源轻App. - -它可以在手机接收到验证码短信的时候,自动浮现验证码,并自动复制验证码到用户的剪切板。当用户接收到短信验证码,只要长按验证码的输入框,粘贴验证码即可。 +在手机接收到验证码短信的时候,自动浮现验证码,并自动复制验证码到用户的剪切板。当用户接收到短信验证码,只要长按验证码的输入框,粘贴验证码即可。 除此之外,还可以让用户批量删除无用验证码短信,帮助用户反向推理出绑定了哪些业务(换号必备啊有木有)。 @@ -16,12 +14,32 @@ screenshot screenshot -#源代码在GPLv3协议下发布 -###我们开源,我们做好设计,我们不乱使用权限,只求你如果喜欢,可以分享给你的朋友们,好东西需要分享才能让其健康成长,每一次分享都是我们的动力,非常感谢! +#源代码在 GPLv3 协议下发布 +###我们开源,做好设计,不乱使用权限,只求你如果喜欢,可以分享给你的朋友们,好东西需要分享才能让其健康成长,每一次分享都是我们的动力,非常感谢! -#下载 +#下载 Download Google Play:https://play.google.com/store/apps/details?id=me.drakeet.inmessage -Fir:http://fir.im/codehelper \ No newline at end of file +Fir:http://fir.im/codehelper + +#English introduction +SmsCodeHelper, is a new open source and light App. + +It can automatically emerge verification code when your phone receives a text message contains a verification code. And automatically copy the code to the user's clipboard. When the user receives the message verification code, just long press the EditText to paste the verification code. + +In addition, it can also allow users to bulk delete unwanted SMS verification code; It can also help users Backward inference out what the business is bound (for a new phone number, it is useful). + +It is very light, but also adhering to the usual good design and user-friendly, since it does not start at leisure, will not take up any memory (unbelievers or concern, welcome to view the source code) . + + +We open source, good design, not indiscriminately use rights. Just hope if you like it, you can share with your friends, because good things need to share with others in order to let it grow, every share is our power, thanks! + +## About me + +I am a student in China, I love reading pure literature, love Japanese culture and Hongkong music. At the same time, I am also obsessed with writing code. If you have any questions or want to make friends with me, you can write to me: drakeet.me@gmail.com + +In addition, my blog: http://drakeet.me + +If you like my open source projects, you can follow me: https://github.com/drakeet diff --git a/app/build.gradle b/app/build.gradle index d41f8f6..2429687 100755 --- a/app/build.gradle +++ b/app/build.gradle @@ -4,6 +4,8 @@ def releaseTime() { return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC")) } +def key = file('s.keystore') + android { compileSdkVersion 22 buildToolsVersion "22.0.1" @@ -11,14 +13,9 @@ android { defaultConfig { applicationId "me.drakeet.inmessage" minSdkVersion 15 - targetSdkVersion 21 - versionCode 4 - versionName "1.0" - } - sourceSets { - main { - jniLibs.srcDirs = ['libs'] - } + targetSdkVersion 22 + versionCode 33 + versionName "1.3.3" } packagingOptions { @@ -44,10 +41,10 @@ android { signingConfigs { app1 { - storeFile file("s.keystore") - storePassword STOREPASS - keyAlias KEYALIAS - keyPassword KEYPASS + storeFile key + storePassword project.hasProperty('STOREPASS') ? STOREPASS : '' + keyAlias project.hasProperty('KEYALIAS') ? KEYALIAS : '' + keyPassword project.hasProperty('KEYPASS') ? KEYPASS : '' } } @@ -57,16 +54,21 @@ android { buildConfigField "boolean", "LOG_DEBUG", "false" debuggable false - minifyEnabled true - shrinkResources true + minifyEnabled false + shrinkResources false proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' - signingConfig signingConfigs.app1 + if (key.exists()) { + println "using drakeet's key" + signingConfig signingConfigs.app1 + } else { + println "no key" + } applicationVariants.all { variant -> variant.outputs.each { output -> def outputFile = output.outputFile if (outputFile != null && outputFile.name.endsWith('.apk')) { - // 输出apk名称为boohee_v1.0_2015-01-15_wandoujia.apk + // 输出apk名称为SmsCodeHelper_v1.0_2015-01-15_wandoujia.apk def fileName = "SmsCodeHelper_v${defaultConfig.versionName}_${releaseTime()}_${variant.productFlavors[0].name}.apk" output.outputFile = new File(outputFile.parent, fileName) } @@ -114,11 +116,10 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:22.2.0' - compile 'com.android.support:recyclerview-v7:22.2.0' + compile 'com.android.support:appcompat-v7:22.2.1' + compile 'com.android.support:recyclerview-v7:22.2.1' + compile 'com.android.support:design:22.2.1' compile 'com.daimajia.numberprogressbar:library:1.2@aar' - compile 'com.getbase:floatingactionbutton:1.4.0' - compile 'com.github.ksoichiro:android-observablescrollview:1.4.0' compile 'com.squareup:otto:1.3.5' compile 'com.jakewharton:butterknife:6.0.0' compile 'com.badoo.mobile:android-weak-handler:1.0' diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 9b41c64..64460bf 100755 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -58,12 +58,9 @@ -keep public class * extends android.os.Binder # Keep the support library --keep class android.support.v4.** { *; } --keep interface android.support.v4.** { *; } +-keep class android.support.** { *; } +-keep interface android.support.** { *; } -# Keep the support library --keep class android.support.v7.** { *; } --keep interface android.support.v7.** { *; } ## GSON 2.2.4 specific rules ## @@ -167,7 +164,7 @@ native ; } --keep class me.drakeet.inmessage.model.** { *;} +-keep class me.drakeet.inmessage.** { *;} -keep class cn.smssdk.** { *;} -keepclasseswithmembernames class * { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 757ec6d..04e3a88 100755 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,15 +1,15 @@ - + - - - + + + - + @@ -18,21 +18,22 @@ android:allowBackup="true" android:icon="@mipmap/ic_incode" android:label="@string/app_name" - android:theme="@style/MaterialTheme" > + android:theme="@style/MaterialTheme"> + android:launchMode="singleTask" + android:label="@string/app_name"> - + - + - - -   - + + +    + @@ -41,15 +42,17 @@ - - - + + + - - + + diff --git a/app/src/main/assets/litepal.xml b/app/src/main/assets/litepal.xml index c6b6fdd..21b5e5b 100755 --- a/app/src/main/assets/litepal.xml +++ b/app/src/main/assets/litepal.xml @@ -1,7 +1,7 @@ - + diff --git a/app/src/main/java/me/drakeet/inmessage/AboutActivity.java b/app/src/main/java/me/drakeet/inmessage/AboutActivity.java index a86594f..c553dee 100644 --- a/app/src/main/java/me/drakeet/inmessage/AboutActivity.java +++ b/app/src/main/java/me/drakeet/inmessage/AboutActivity.java @@ -2,26 +2,30 @@ import android.content.Intent; import android.os.Bundle; +import android.support.design.widget.CollapsingToolbarLayout; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.view.Menu; import android.view.MenuItem; import android.view.View; +import android.widget.TextView; -import com.github.ksoichiro.android.observablescrollview.ObservableScrollView; -import com.github.ksoichiro.android.observablescrollview.ObservableScrollViewCallbacks; -import com.github.ksoichiro.android.observablescrollview.ScrollState; import com.umeng.analytics.MobclickAgent; import butterknife.ButterKnife; import butterknife.InjectView; +/** + * Created by drakeet on 15/6/5. + */ public class AboutActivity extends AppCompatActivity { @InjectView(R.id.toolbar) Toolbar mToolbar; - @InjectView(R.id.sv_about) - ObservableScrollView mScrollView; + @InjectView(R.id.tv_version) + TextView mVersionTextView; + @InjectView(R.id.collapsing_toolbar) + CollapsingToolbarLayout mCollapsingToolbarLayout; @Override protected void onCreate(Bundle savedInstanceState) { @@ -29,9 +33,12 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_about); ButterKnife.inject(this); - final int headerHeight = getResources().getDimensionPixelSize(R.dimen.about_header_height); - mToolbar.setTitle(""); + setUpVersionName(); + + mCollapsingToolbarLayout.setTitle(getString(R.string.app_name)); + setSupportActionBar(mToolbar); + getSupportActionBar().setDisplayHomeAsUpEnabled(true); mToolbar.setNavigationOnClickListener( new View.OnClickListener() { @Override @@ -41,29 +48,10 @@ public void onClick(View v) { } ); - mScrollView.setScrollViewCallbacks( - new ObservableScrollViewCallbacks() { - @Override - public void onScrollChanged(int scrollY, boolean firstScroll, - boolean dragging) { - if (scrollY > headerHeight + 192) { - mScrollView.setBackgroundColor(getResources().getColor(R.color.background)); - } else { - mScrollView.setBackgroundColor(getResources().getColor(R.color.transparent)); - } - } - - @Override - public void onDownMotionEvent() { - - } - - @Override - public void onUpOrCancelMotionEvent(ScrollState scrollState) { + } - } - } - ); + private void setUpVersionName() { + mVersionTextView.setText("Version " + BuildConfig.VERSION_NAME); } @Override @@ -74,9 +62,13 @@ public boolean onCreateOptionsMenu(Menu menu) { @Override public boolean onOptionsItemSelected(MenuItem item) { - int id = item.getItemId(); - if (id == R.id.menu_share) { - onClickShare(); + switch (item.getItemId()) { + case android.R.id.home: + this.finish(); + return true; + case R.id.menu_share: + onClickShare(); + return true; } return super.onOptionsItemSelected(item); } diff --git a/app/src/main/java/me/drakeet/inmessage/MainActivity.java b/app/src/main/java/me/drakeet/inmessage/MainActivity.java index a401b5b..6d10ad6 100755 --- a/app/src/main/java/me/drakeet/inmessage/MainActivity.java +++ b/app/src/main/java/me/drakeet/inmessage/MainActivity.java @@ -9,7 +9,9 @@ import android.os.Bundle; import android.support.v4.view.MenuItemCompat; import android.support.v7.app.AlertDialog; +import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; import android.support.v7.widget.SwitchCompat; import android.support.v7.widget.Toolbar; import android.view.KeyEvent; @@ -22,7 +24,6 @@ import com.badoo.mobile.util.WeakHandler; import com.daimajia.numberprogressbar.NumberProgressBar; -import com.github.ksoichiro.android.observablescrollview.ObservableRecyclerView; import com.umeng.analytics.MobclickAgent; import org.litepal.crud.DataSupport; @@ -42,17 +43,18 @@ import me.drakeet.inmessage.utils.TaskUtils; import me.drakeet.inmessage.utils.ToastUtils; import me.drakeet.inmessage.utils.VersionUtils; +import me.drakeet.inmessage.widget.SeparatorItemDecoration; public class MainActivity extends SwipeRefreshBaseActivity { @InjectView(R.id.message_rv) - ObservableRecyclerView mRecyclerView; + RecyclerView mRecyclerView; - NumberProgressBar mNumberProgressBar; - MainMessageAdapter mMainMessageAdapter; - WeakHandler mHandler; - private int mCurrentCaptchasCount = 0; + private NumberProgressBar mNumberProgressBar; + private MainMessageAdapter mMainMessageAdapter; private List mMessages; + private WeakHandler mHandler; + private int mCurrentCaptchasCount = 0; private boolean mIsRefreshing = false; private boolean mStopDelete; private boolean mShowResult; @@ -67,9 +69,7 @@ protected void onCreate(Bundle savedInstanceState) { mShowResult = false; setupActionBar(); initRecyclerView(); - MobclickAgent.updateOnlineConfig(this); - checkFirstTimeUse(); } @@ -94,6 +94,8 @@ private void initRecyclerView() { LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this); linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL); mRecyclerView.setLayoutManager(linearLayoutManager); + mRecyclerView.addItemDecoration(new SeparatorItemDecoration(this)); + mRecyclerView.setItemAnimator(new DefaultItemAnimator()); mRecyclerView.setOnTouchListener( new View.OnTouchListener() { @Override @@ -105,26 +107,27 @@ public boolean onTouch(View v, MotionEvent event) { } private void setAdapter() { - mMainMessageAdapter = new MainMessageAdapter(this, mMessages); + mMainMessageAdapter = new MainMessageAdapter(mMessages); mMainMessageAdapter.setShowResult(mShowResult); mRecyclerView.setAdapter(mMainMessageAdapter); mMainMessageAdapter.setOnItemClickListener( new OnItemClickListener() { @Override public void onItemClick(View view, int position) { - if (mMessages.get(position).getIsMessage()) { - showDetailSMS(mMessages.get(position)); + if (!mIsRefreshing) { + if (mMessages.get(position).getIsMessage()) { + showDetailSMS(mMessages.get(position)); + } } } } ); } - private void getAllMessage() { setRefreshing(true); mIsRefreshing = true; - TaskUtils.executeAsyncTask( + TaskUtils.execute( new AsyncTask() { @Override protected Object doInBackground(Object... params) { @@ -144,7 +147,13 @@ protected Object doInBackground(Object... params) { @Override protected void onPostExecute(Object o) { super.onPostExecute(o); - setAdapter(); + /* + && mMessages.size() != 0 应该去掉,即使没有验证码短信,也应该更新 + 不然用户从系统收件箱删除短信之后再回到应用点击会崩溃 + */ + if (mMessages != null) { + setAdapter(); + } setRefreshing(false); mIsRefreshing = false; } @@ -166,41 +175,31 @@ private int getMessageCount() { @OnClick(R.id.fab_delete_all) public void deleteAll() { if (VersionUtils.IS_MORE_THAN_LOLLIPOP) { - ToastUtils.showShort("Android 5.0 以上暂不支持清空验证码短信!"); + ToastUtils.showShort(R.string.str_version_morethan_five); } else { showConfirmDialog(); } } private void showConfirmDialog() { - AlertDialog alertDialog = new AlertDialog.Builder(this). - setTitle("清空验证码短信?") - . - setMessage(getString(R.string.str_clear_messages_hint)) - . - setPositiveButton( - "确定", - new DialogInterface.OnClickListener() { - @Override - public void onClick( - DialogInterface dialog, - int which) { - showDeleteDialog(); - } - } - ) - . - setNegativeButton( - "取消", - new DialogInterface.OnClickListener() { - @Override - public void onClick( - DialogInterface dialog, - int which) { - - } - } - ) + AlertDialog alertDialog = new AlertDialog.Builder(this).setTitle(getString(R.string.empty_verification_code)) + .setMessage(getString(R.string.str_clear_messages_hint)) + .setPositiveButton( + android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + showDeleteDialog(); + } + } + ) + .setNegativeButton( + android.R.string.cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + } + } + ) .create(); alertDialog.setCanceledOnTouchOutside(false); alertDialog.show(); @@ -211,24 +210,16 @@ private void showDeleteDialog() { LayoutInflater layoutInflater = LayoutInflater.from(MainActivity.this); View addLayout = layoutInflater.inflate(R.layout.view_delete_messages, null); mNumberProgressBar = (NumberProgressBar) addLayout.findViewById(R.id.number_progress_bar); - AlertDialog deleteDialog = new AlertDialog.Builder(MainActivity.this). - setTitle( - "正在删除验证码短信..." - ) - .setView(addLayout) - . - setNegativeButton( - "停止", - new DialogInterface.OnClickListener() { - @Override - public void onClick( - DialogInterface dialog, - int which) { - mStopDelete = true; - } - } - ) - .create(); + AlertDialog deleteDialog = new AlertDialog.Builder(MainActivity.this).setTitle( + getString(R.string.deleting_verification_code) + ).setView(addLayout).setNegativeButton( + android.R.string.cancel, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + mStopDelete = true; + } + } + ).create(); deleteDialog.setCanceledOnTouchOutside(false); deleteDialog.setOnKeyListener( new DialogInterface.OnKeyListener() { @@ -252,26 +243,19 @@ public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) { private void showBussinessDialog() { - final AlertDialog alertDialog = new AlertDialog.Builder(this). - setTitle(getString(R.string.str_check_bussiness_hint)) - . - setMessage(getString(R.string.str_doing_hint)) - . - setPositiveButton( - "确定", - new DialogInterface.OnClickListener() { - @Override - public void onClick( - DialogInterface dialog, - int which) { - } - } - ) - . - create(); + final AlertDialog alertDialog = new AlertDialog.Builder(this).setTitle(getString(R.string.str_check_bussiness_hint)) + .setMessage(getString(R.string.str_doing_hint)) + .setPositiveButton( + android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + } + } + ) + .create(); alertDialog.setCanceledOnTouchOutside(false); alertDialog.show(); - TaskUtils.executeAsyncTask( + TaskUtils.execute( new AsyncTask() { @Override protected String doInBackground(Object... params) { @@ -329,23 +313,16 @@ private Boolean isExist(String company, List companys) { } private void showDetailSMS(Message message) { - AlertDialog alertDialog = new AlertDialog.Builder(this). - setTitle(message.getSender()) - . - setMessage(message.getContent()) - . - setPositiveButton( - "确定", - new DialogInterface.OnClickListener() { - @Override - public void onClick( - DialogInterface dialog, - int which) { - } - } - ) - . - create(); + AlertDialog alertDialog = new AlertDialog.Builder(this).setTitle(message.getSender()) + .setMessage(message.getContent()) + .setPositiveButton( + android.R.string.ok, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + } + } + ) + .create(); alertDialog.setCanceledOnTouchOutside(false); alertDialog.show(); } @@ -353,7 +330,7 @@ public void onClick( private void deleteAllCaptchasMessage(final AlertDialog deleteDialog) { mStopDelete = false; final SmsUtils smsUtils = new SmsUtils(MainActivity.this); - TaskUtils.executeAsyncTask( + TaskUtils.execute( new AsyncTask() { @Override protected String doInBackground(Object... params) { @@ -382,7 +359,12 @@ protected String doInBackground(Object... params) { protected void onPostExecute(String o) { super.onPostExecute(o); deleteDialog.dismiss(); - ToastUtils.showShort("成功删除" + o + "条验证码短信!"); + ToastUtils.showShort( + String.format( + getString(R.string.successfully_delete_verification_code_numbers), + o + ) + ); getAllMessage(); } @@ -435,7 +417,7 @@ public boolean onCreateOptionsMenu(Menu menu) { public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { if (mIsRefreshing) { switchCompat.setChecked(!isChecked); - ToastUtils.showShort("加载中请勿改变开关状态!"); + ToastUtils.showShort(getString(R.string.do_not_change_the_switch)); } else { SharedPreferences sharedPreferences = getSharedPreferences( "userinfo", Context.MODE_PRIVATE @@ -444,11 +426,11 @@ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { mShowResult = isChecked; if (mMainMessageAdapter != null) { mMainMessageAdapter.setShowResult(isChecked); - mMainMessageAdapter.notifyDataSetChanged(); + mMainMessageAdapter.notifyItemRangeChanged(0, mMessages.size()); if (isChecked) - ToastUtils.showShort("开启验证码内容显示简化"); + ToastUtils.showShort(getString(R.string.open_simplified)); else - ToastUtils.showShort("关闭验证码内容显示简化"); + ToastUtils.showShort(getString(R.string.close_simplified)); } } } @@ -469,9 +451,6 @@ private void initCheckStatus(SwitchCompat switchCompat) { @Override public boolean onOptionsItemSelected(MenuItem item) { - // Handle action bar item clicks here. The action bar will - // automatically handle clicks on the Home/Up button, so long - // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.menu_about) { startActivity(new Intent(this, AboutActivity.class)); @@ -481,7 +460,7 @@ public boolean onOptionsItemSelected(MenuItem item) { if (!mIsRefreshing) { showBussinessDialog(); } else { - ToastUtils.showShort("加载中请勿操作!"); + ToastUtils.showShort(getString(R.string.do_not_operate_in_load)); } } return super.onOptionsItemSelected(item); @@ -493,7 +472,7 @@ public boolean onOptionsItemSelected(MenuItem item) { public void onClickShare() { Intent intent = new Intent(Intent.ACTION_SEND); intent.setType("text/plain"); - intent.putExtra(Intent.EXTRA_SUBJECT, "分享"); + intent.putExtra(Intent.EXTRA_SUBJECT, getString(R.string.share_just)); intent.putExtra(Intent.EXTRA_TEXT, getString(R.string.share_text)); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); startActivity(Intent.createChooser(intent, getTitle())); diff --git a/app/src/main/java/me/drakeet/inmessage/adapter/MainMessageAdapter.java b/app/src/main/java/me/drakeet/inmessage/adapter/MainMessageAdapter.java index 57633f8..2afe16b 100755 --- a/app/src/main/java/me/drakeet/inmessage/adapter/MainMessageAdapter.java +++ b/app/src/main/java/me/drakeet/inmessage/adapter/MainMessageAdapter.java @@ -1,14 +1,10 @@ package me.drakeet.inmessage.adapter; -import android.content.Context; -import android.graphics.Bitmap; -import android.os.AsyncTask; import android.support.v7.widget.RecyclerView; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.ImageView; -import android.widget.LinearLayout; +import android.widget.FrameLayout; import android.widget.TextView; import java.util.List; @@ -16,9 +12,7 @@ import me.drakeet.inmessage.R; import me.drakeet.inmessage.api.OnItemClickListener; import me.drakeet.inmessage.model.Message; -import me.drakeet.inmessage.utils.SmsUtils; -import me.drakeet.inmessage.utils.TaskUtils; -import me.drakeet.inmessage.utils.VersionUtils; +import me.drakeet.inmessage.utils.StringUtils; /** * Created by shengkun on 15/6/5. @@ -31,17 +25,13 @@ public enum ITEM_TYPE { } private List mList; - private Context mContext; - private SmsUtils mSmsUtils; private Boolean mShowResult = false; private OnItemClickListener listener; - public MainMessageAdapter(Context context, List messageList) { + public MainMessageAdapter(List messageList) { mList = messageList; - mSmsUtils = new SmsUtils(context); - mContext = context; } @Override @@ -50,17 +40,16 @@ public MainMessageAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int vi if (viewType == ITEM_TYPE.ITEM_TYPE_DATE.ordinal()) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_separation, parent, false); viewHolder = new ViewHolder(v); - viewHolder.dateTv = (TextView) v.findViewById(R.id.date_message_tv); - viewHolder.shadow = v.findViewById(R.id.ig_shadow); + viewHolder.date = (TextView) v.findViewById(R.id.date_message_tv); } if (viewType == ITEM_TYPE.ITEM_TYPE_MESSAGE.ordinal()) { View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message, parent, false); viewHolder = new ViewHolder(v); - viewHolder.authorTv = (TextView) v.findViewById(R.id.author_message_tv); - viewHolder.contentTv = (TextView) v.findViewById(R.id.content_message_tv); - viewHolder.avatarTv = (TextView) v.findViewById(R.id.avatar_tv); - viewHolder.dateTv = (TextView) v.findViewById(R.id.message_date_tv); - viewHolder.itemLl = (LinearLayout) v.findViewById(R.id.item_message); + viewHolder.author = (TextView) v.findViewById(R.id.author_message_tv); + viewHolder.content = (TextView) v.findViewById(R.id.content_message_tv); + viewHolder.avatar = (TextView) v.findViewById(R.id.avatar_tv); + viewHolder.date = (TextView) v.findViewById(R.id.message_date_tv); + viewHolder.item = (FrameLayout) v.findViewById(R.id.item_message); } return viewHolder; } @@ -68,20 +57,21 @@ public MainMessageAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int vi @Override public void onBindViewHolder(MainMessageAdapter.ViewHolder holder, final int position) { if (holder.getItemViewType() == ITEM_TYPE.ITEM_TYPE_MESSAGE.ordinal()) { - holder.authorTv.setText(mList.get(position).getSender()); + holder.author.setText(mList.get(position).getSender()); if(mShowResult && mList.get(position).getResultContent() != null) { - holder.contentTv.setText(mList.get(position).getResultContent()); + holder.content.setText(mList.get(position).getResultContent()); } else { - holder.contentTv.setText(mList.get(position).getContent()); + holder.content.setText(mList.get(position).getContent()); } if (mList.get(position).getReceiveDate() != null) { - holder.dateTv.setText(mList.get(position).getReceiveDate()); + holder.date.setText(mList.get(position).getReceiveDate()); } - holder.authorTv.setText(mList.get(position).getSender()); + holder.author.setText(mList.get(position).getSender()); if(mList.get(position).getCompanyName() != null) { String showCompanyName = mList.get(position).getCompanyName(); - if(showCompanyName.length() == 4) { + // 中文四个字的名字特别换行 + if(StringUtils.isContainsChinese(showCompanyName) && showCompanyName.length() == 4) { String fourCharsName = ""; for(int u = 0; u < showCompanyName.length();u ++) { if(u == 2) { @@ -91,13 +81,13 @@ public void onBindViewHolder(MainMessageAdapter.ViewHolder holder, final int pos } showCompanyName = fourCharsName; } - holder.avatarTv.setText(showCompanyName); + holder.avatar.setText(showCompanyName); } else { - holder.avatarTv.setText("?"); + holder.avatar.setText("?"); } if (listener != null) { - holder.itemLl.setOnClickListener( + holder.item.setOnClickListener( new View.OnClickListener() { @Override @@ -109,12 +99,7 @@ public void onClick(View v) { } } else { - holder.dateTv.setText(mList.get(position).getReceiveDate()); - if(needShowShadow(position)) { - holder.shadow.setVisibility(View.VISIBLE); - } else { - holder.shadow.setVisibility(View.GONE); - } + holder.date.setText(mList.get(position).getReceiveDate()); } } @@ -124,64 +109,9 @@ public int getItemCount() { return mList.size(); } - private void getAvatar(final String phoneNumber, final ImageView imageView, final TextView textView, final Message message) { - TaskUtils.executeAsyncTask( - new AsyncTask() { - @Override - protected Bitmap doInBackground(Object... params) { - Bitmap bitmap = mSmsUtils.get_people_image(phoneNumber); - return bitmap; - } - - @Override - protected void onPostExecute(Bitmap o) { - super.onPostExecute(o); - if (o != null) { - imageView.setVisibility(View.VISIBLE); - textView.setVisibility(View.GONE); - imageView.setImageBitmap(o); - } else { - textView.setVisibility(View.VISIBLE); - imageView.setVisibility(View.GONE); - } - } - } - ); - } - - private void getName(final String phoneNumber, final TextView textView, final Message message) { - TaskUtils.executeAsyncTask(new AsyncTask() { - @Override - protected String doInBackground(Object... params) { - return mSmsUtils.getContactNameFromPhoneBook(phoneNumber); - } - - @Override - protected void onPostExecute(String s) { - super.onPostExecute(s); - if (s != null) { - textView.setText(s); - message.setAuthor(s); - } - } - }); - } - - private Boolean needShowShadow(int position) { - if (VersionUtils.IS_MORE_THAN_LOLLIPOP) { - return false; - } - if(position == 0) { - return false; - } - else if(mList.get(position - 1).getIsMessage()) { - return true; - } - return false; - } - @Override public int getItemViewType(int position) { + if (mList.size() == 0) return ITEM_TYPE.ITEM_TYPE_DATE.ordinal(); // 解决快速滚动下拉带来的越界异常 return mList.get(position).getIsMessage() ? ITEM_TYPE.ITEM_TYPE_MESSAGE.ordinal() : ITEM_TYPE.ITEM_TYPE_DATE.ordinal(); } @@ -190,26 +120,19 @@ public ViewHolder(View itemView) { super(itemView); } - TextView authorTv; - TextView contentTv; - TextView avatarTv; - TextView dateTv; - View shadow; - LinearLayout itemLl; + TextView author; + TextView content; + TextView avatar; + TextView date; + FrameLayout item; } public void setOnItemClickListener(OnItemClickListener listener) { this.listener = listener; } - - public void setShowResult(Boolean showResult) { + public void setShowResult(boolean showResult) { this.mShowResult = showResult; } - - @Override - public void onViewRecycled(MainMessageAdapter.ViewHolder holder) { - super.onViewRecycled(holder); - } } diff --git a/app/src/main/java/me/drakeet/inmessage/api/SmsCallback.java b/app/src/main/java/me/drakeet/inmessage/api/SmsCallback.java index 1de0a0a..ccd867e 100755 --- a/app/src/main/java/me/drakeet/inmessage/api/SmsCallback.java +++ b/app/src/main/java/me/drakeet/inmessage/api/SmsCallback.java @@ -8,5 +8,5 @@ * Created by shengkun on 15/2/9. */ public interface SmsCallback { - void done(List examples,String errorMessage); + void done(List examples, String errorMessage); } diff --git a/app/src/main/java/me/drakeet/inmessage/constant/StaticObjectInterface.java b/app/src/main/java/me/drakeet/inmessage/constant/StaticObjectInterface.java index ea689fc..773f3be 100644 --- a/app/src/main/java/me/drakeet/inmessage/constant/StaticObjectInterface.java +++ b/app/src/main/java/me/drakeet/inmessage/constant/StaticObjectInterface.java @@ -5,6 +5,9 @@ */ public interface StaticObjectInterface { - String[] CPATCHAS_KEYWORD = {"激活码", "动态码", "校验码", "验证码"}; + String[] CPATCHAS_KEYWORD = {"激活码", "动态码", "校验码", "验证码", "确认码", "检验码", "验证代码", "激活代码", + "校验代码", "动态代码", "检验代码", "确认代码", "短信口令", "动态密码", "交易码", "驗證碼", "激活碼", "動態碼", "校驗碼", "檢驗碼", "驗證代碼", + "激活代碼", "校驗代碼", "確認代碼", "動態代碼", "檢驗代碼", "上网密码"}; + String[] CPATCHAS_KEYWORD_EN = {"CODE", "code"}; String ACTION_CLICK = "me.drakeet.inmessage.intent.action.NotificationClick"; } diff --git a/app/src/main/java/me/drakeet/inmessage/events/BusProvider.java b/app/src/main/java/me/drakeet/inmessage/events/BusProvider.java index 1dc8c17..54720a5 100755 --- a/app/src/main/java/me/drakeet/inmessage/events/BusProvider.java +++ b/app/src/main/java/me/drakeet/inmessage/events/BusProvider.java @@ -6,6 +6,7 @@ * Created by drakeet on 12/1/14. */ public class BusProvider { + private static final Bus BUS = new Bus(); public static Bus getInstance() { diff --git a/app/src/main/java/me/drakeet/inmessage/model/Message.java b/app/src/main/java/me/drakeet/inmessage/model/Message.java index 6b69ca3..d5a1066 100755 --- a/app/src/main/java/me/drakeet/inmessage/model/Message.java +++ b/app/src/main/java/me/drakeet/inmessage/model/Message.java @@ -2,12 +2,13 @@ import org.litepal.crud.DataSupport; +import java.io.Serializable; import java.util.Date; /** * Created by shengkun on 15/6/5. */ -public class Message extends DataSupport { +public class Message extends DataSupport implements Serializable { private String sender; private String content; diff --git a/app/src/main/java/me/drakeet/inmessage/service/DiscernCaptchasService.java b/app/src/main/java/me/drakeet/inmessage/service/DiscernCaptchasService.java index 700f621..e098bc4 100755 --- a/app/src/main/java/me/drakeet/inmessage/service/DiscernCaptchasService.java +++ b/app/src/main/java/me/drakeet/inmessage/service/DiscernCaptchasService.java @@ -2,13 +2,10 @@ import android.app.Service; import android.content.Intent; +import android.os.Bundle; import android.os.IBinder; -import com.squareup.otto.Subscribe; - import me.drakeet.inmessage.R; -import me.drakeet.inmessage.events.BusProvider; -import me.drakeet.inmessage.events.ReceiveMessageEvent; import me.drakeet.inmessage.model.Message; import me.drakeet.inmessage.utils.ClipboardUtils; import me.drakeet.inmessage.utils.NotificationUtils; @@ -19,8 +16,6 @@ */ public class DiscernCaptchasService extends Service { - public static boolean isAlive = false; - @Override public IBinder onBind(Intent intent) { return null; @@ -29,28 +24,22 @@ public IBinder onBind(Intent intent) { @Override public void onCreate() { super.onCreate(); - BusProvider.getInstance().register(this); - isAlive = true; - } - - - @Subscribe - public void onReceiveMessageEvent(ReceiveMessageEvent event) { - Message message = event.message; - if(message.getCaptchas() != null) { - ClipboardUtils.putTextIntoClipboard(DiscernCaptchasService.this, message.getCaptchas()); - // 弹两遍,加长时间。 - ToastUtils.showLong(String.format(getResources().getString(R.string.tip), message.getCaptchas())); - ToastUtils.showLong(String.format(getResources().getString(R.string.tip), message.getCaptchas())); - } - NotificationUtils.showMessageInNotificationBar(DiscernCaptchasService.this, message); - DiscernCaptchasService.this.stopSelf(); } @Override - public void onDestroy() { - super.onDestroy(); - BusProvider.getInstance().unregister(this); - isAlive = false; + public int onStartCommand(Intent intent, int flags, int startId) { + if(intent != null) { + Bundle bundle = intent.getBundleExtra("bundle"); + Message message = (Message) bundle.getSerializable("message"); + + if (message.getCaptchas() != null) { + ClipboardUtils.putTextIntoClipboard(DiscernCaptchasService.this, message.getCaptchas()); + // 弹两遍,加长时间。 + ToastUtils.showLong(String.format(getResources().getString(R.string.tip), message.getCaptchas())); + ToastUtils.showLong(String.format(getResources().getString(R.string.tip), message.getCaptchas())); + NotificationUtils.showMessageInNotificationBar(DiscernCaptchasService.this, message); + } + } + return START_STICKY; } } diff --git a/app/src/main/java/me/drakeet/inmessage/service/SMSBroadcastReceiver.java b/app/src/main/java/me/drakeet/inmessage/service/SMSBroadcastReceiver.java index d4003f3..b0e70ac 100755 --- a/app/src/main/java/me/drakeet/inmessage/service/SMSBroadcastReceiver.java +++ b/app/src/main/java/me/drakeet/inmessage/service/SMSBroadcastReceiver.java @@ -3,6 +3,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; +import android.os.Bundle; import android.telephony.SmsMessage; import com.badoo.mobile.util.WeakHandler; @@ -10,8 +11,6 @@ import java.text.SimpleDateFormat; import java.util.Date; -import me.drakeet.inmessage.events.BusProvider; -import me.drakeet.inmessage.events.ReceiveMessageEvent; import me.drakeet.inmessage.model.Message; import me.drakeet.inmessage.utils.StringUtils; import me.drakeet.inmessage.utils.VersionUtils; @@ -27,6 +26,7 @@ public class SMSBroadcastReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //从Intent中接受信息 + Object[] pdus = (Object[]) intent.getExtras().get("pdus"); for (Object p : pdus) { byte[] sms = (byte[]) p; @@ -36,53 +36,51 @@ public void onReceive(Context context, Intent intent) { //获取发送时间 final Date date = new Date(message.getTimestampMillis()); final String sender = message.getOriginatingAddress(); - if (!StringUtils.isPersonalMoblieNO(sender) && StringUtils.isCaptchasMessage(content) && !StringUtils - .tryToGetCaptchas(content) - .equals("")) { - if (!DiscernCaptchasService.isAlive) { + + if (!StringUtils.isPersonalMoblieNO(sender)) { + boolean isCpatchasMessage = false; + if (!StringUtils.isContainsChinese(content)) { + if (StringUtils.isCaptchasMessageEn(content) && !StringUtils.tryToGetCaptchasEn(content).equals("")) { + isCpatchasMessage = true; + } + } else if (StringUtils.isCaptchasMessage(content) && !StringUtils.tryToGetCaptchas(content).equals("")) { + isCpatchasMessage = true; + } + if (isCpatchasMessage) { + this.abortBroadcast(); + Message smsMessage = new Message(); + smsMessage.setContent(content); + smsMessage.setSender(sender); + smsMessage.setDate(date); + String company = StringUtils.getContentInBracket(content, sender); + if (company != null) { + smsMessage.setCompanyName(company); + } + smsMessage.setIsMessage(true); + //格式化短信日期提示 + SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd hh:mm"); + //获得短信的各项内容 + String date_mms = dateFormat.format(date); + smsMessage.setReceiveDate(date_mms); + smsMessage.setReadStatus(0); + smsMessage.setFromSmsDB(1); + String captchas = StringUtils.tryToGetCaptchas(content); + if (!captchas.equals("")) { + smsMessage.setCaptchas(captchas); + } + String resultContent = StringUtils.getResultText(smsMessage, false); + if (resultContent != null) { + smsMessage.setResultContent(resultContent); + } + if (!VersionUtils.IS_MORE_THAN_LOLLIPOP) { + smsMessage.save(); + } mServiceIntent = new Intent(context, DiscernCaptchasService.class); + Bundle bundle = new Bundle(); + bundle.putSerializable("message", smsMessage); + mServiceIntent.putExtra("bundle", bundle); context.startService(mServiceIntent); } - this.abortBroadcast(); - mHandler = new WeakHandler(); - mHandler.postDelayed(new Runnable() { - @Override - public void run() { - Message smsMessage = new Message(); - smsMessage.setContent(content); - smsMessage.setSender(sender); - smsMessage.setDate(date); - String company = StringUtils.getContentInBracket(content, sender); - if (company != null) { - smsMessage.setCompanyName(company); - } - smsMessage.setIsMessage(true); - //格式化短信日期提示 - SimpleDateFormat sfd = new SimpleDateFormat("MM-dd hh:mm"); - String time = sfd.format(date); - //获得短信的各项内容 - String date_mms = time; - smsMessage.setReceiveDate(date_mms); - smsMessage.setReadStatus(0); - smsMessage.setFromSmsDB(1); - String captchas = StringUtils.tryToGetCaptchas(content); - if(!captchas.equals("")) { - smsMessage.setCaptchas(captchas); - } - String resultContent = StringUtils.getResultText(smsMessage, false); - if(resultContent != null) { - smsMessage.setResultContent(resultContent); - } - if(!VersionUtils.IS_MORE_THAN_LOLLIPOP) { - smsMessage.save(); - } - BusProvider.getInstance().register(this); - BusProvider.getInstance().post(new ReceiveMessageEvent(smsMessage)); - BusProvider.getInstance().unregister(this); - //终止广播 - } - }, 358 - ); } } } diff --git a/app/src/main/java/me/drakeet/inmessage/ui/SwipeRefreshBaseActivity.java b/app/src/main/java/me/drakeet/inmessage/ui/SwipeRefreshBaseActivity.java index 7165c0a..f12e42b 100755 --- a/app/src/main/java/me/drakeet/inmessage/ui/SwipeRefreshBaseActivity.java +++ b/app/src/main/java/me/drakeet/inmessage/ui/SwipeRefreshBaseActivity.java @@ -41,8 +41,6 @@ public void onRefresh() { public void requestDataRefresh() {} - ; - public void setRefreshing(boolean refreshing) { if (mSwipeRefreshLayout == null) { return; diff --git a/app/src/main/java/me/drakeet/inmessage/utils/ClipboardUtils.java b/app/src/main/java/me/drakeet/inmessage/utils/ClipboardUtils.java index 08acec3..3d6034c 100755 --- a/app/src/main/java/me/drakeet/inmessage/utils/ClipboardUtils.java +++ b/app/src/main/java/me/drakeet/inmessage/utils/ClipboardUtils.java @@ -11,8 +11,8 @@ public class ClipboardUtils { public static void putTextIntoClipboard(Context context, String text) { // 得到剪贴板管理器 - ClipboardManager cmb = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText("copy text", text); - cmb.setPrimaryClip(clip); + ClipboardManager clipboardManager = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clipData = ClipData.newPlainText("copy text", text); + clipboardManager.setPrimaryClip(clipData); } } diff --git a/app/src/main/java/me/drakeet/inmessage/utils/NotificationUtils.java b/app/src/main/java/me/drakeet/inmessage/utils/NotificationUtils.java index 70b335c..5d69b00 100755 --- a/app/src/main/java/me/drakeet/inmessage/utils/NotificationUtils.java +++ b/app/src/main/java/me/drakeet/inmessage/utils/NotificationUtils.java @@ -26,7 +26,11 @@ public static void showMessageInNotificationBar(Context context, Message message if (message.getCaptchas() != null) { remoteViews.setTextViewText( - R.id.tv_content, String.format(context.getResources().getString(R.string.notify_msg), message.getCaptchas()) + R.id.tv_content, + String.format( + context.getResources().getString(R.string.notify_msg), + message.getCaptchas() + ) ); } else { remoteViews.setTextViewText(R.id.tv_content, message.getContent()); diff --git a/app/src/main/java/me/drakeet/inmessage/utils/SmsUtils.java b/app/src/main/java/me/drakeet/inmessage/utils/SmsUtils.java index 972a231..fb65084 100755 --- a/app/src/main/java/me/drakeet/inmessage/utils/SmsUtils.java +++ b/app/src/main/java/me/drakeet/inmessage/utils/SmsUtils.java @@ -30,7 +30,8 @@ public SmsUtils(final Context context) { mContext = context; } - public static final Uri MMSSMS_ALL_MESSAGE_URI = Uri.parse("content://sms/"); + //只检查收件箱的验证码信息 + public static final Uri MMSSMS_ALL_MESSAGE_URI = Uri.parse("content://sms/inbox"); public static final Uri ALL_MESSAGE_URI = MMSSMS_ALL_MESSAGE_URI.buildUpon(). appendQueryParameter("simple", "true").build(); @@ -39,68 +40,77 @@ public SmsUtils(final Context context) { "date", "type", "thread_id"}; public List getAllCaptchMessages() { - List dateGroupS = new ArrayList<>(); - ContentResolver cr = mContext.getContentResolver(); - Cursor cursor = cr.query(ALL_MESSAGE_URI, ALL_THREADS_PROJECTION, + List dateGroups = new ArrayList<>(); + ContentResolver contentResolver = mContext.getContentResolver(); + Cursor cursor = contentResolver.query(ALL_MESSAGE_URI, ALL_THREADS_PROJECTION, null, null, "date desc"); List smsMessages = new ArrayList<>(); - int i = 0; while ((cursor.moveToNext())) { - i += 1; - int index_Body = cursor.getColumnIndex("body"); - int index_Address = cursor.getColumnIndex("address"); - int index_ThreadId = cursor.getColumnIndex("thread_id"); - String strbody = cursor.getString(index_Body); - String strAddress = cursor.getString(index_Address); - if (!StringUtils.isPersonalMoblieNO(strAddress) && StringUtils.isCaptchasMessage(strbody) && !StringUtils.tryToGetCaptchas(strbody).equals("")) { - int date = cursor.getColumnIndex("date"); - //格式化短信日期提示 - SimpleDateFormat sfd = new SimpleDateFormat("MM-dd hh:mm"); - Date date_format = new Date(Long.parseLong(cursor.getString(date))); - long thread_id = cursor.getLong(index_ThreadId); - - String time = sfd.format(date_format); - //获得短信的各项内容 - String date_mms = time; - Message message = new Message(); - String company = StringUtils.getContentInBracket(strbody, strAddress); - if (company != null) { - message.setCompanyName(company); - } - String captchas = StringUtils.tryToGetCaptchas(strbody); - if(!captchas.equals("")) { - message.setCaptchas(captchas); + int indexBody = cursor.getColumnIndex("body"); + int indexAddress = cursor.getColumnIndex("address"); + int indexThreadId = cursor.getColumnIndex("thread_id"); + String strbody = cursor.getString(indexBody); + String strAddress = cursor.getString(indexAddress); + if (!StringUtils.isPersonalMoblieNO(strAddress)) { + boolean isCpatchasMessage = false; + if (!StringUtils.isContainsChinese(strbody)) { + if (StringUtils.isCaptchasMessageEn(strbody) && !StringUtils.tryToGetCaptchasEn(strbody).equals("")) { + isCpatchasMessage = true; + } + } else if (StringUtils.isCaptchasMessage(strbody) && !StringUtils.tryToGetCaptchas(strbody).equals("")) { + isCpatchasMessage = true; } - int index_Id = cursor.getColumnIndex("_id"); - String smsId = cursor.getString(index_Id); - message.setIsMessage(true); - message.setDate(date_format); - message.setSender(strAddress); - message.setThreadId(thread_id); - message.setContent(strbody); - message.setSmsId(smsId); - message.setReceiveDate(date_mms); - String resultContent = StringUtils.getResultText(message, false); - if(resultContent != null) { - message.setResultContent(resultContent); + if (isCpatchasMessage) { + int date = cursor.getColumnIndex("date"); + //格式化短信日期提示 + SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd hh:mm"); + Date formatDate = new Date(Long.parseLong(cursor.getString(date))); + long threadId = cursor.getLong(indexThreadId); + + //获得短信的各项内容 + String dateMms = dateFormat.format(formatDate); + Message message = new Message(); + String company = StringUtils.getContentInBracket(strbody, strAddress); + if (company != null) { + message.setCompanyName(company); + } + String captchas = StringUtils.tryToGetCaptchas(strbody); + if (!captchas.equals("")) { + message.setCaptchas(captchas); + } + int columnIndex = cursor.getColumnIndex("_id"); + String smsId = cursor.getString(columnIndex); + message.setIsMessage(true); + message.setDate(formatDate); + message.setSender(strAddress); + message.setThreadId(threadId); + message.setContent(strbody); + message.setSmsId(smsId); + message.setReceiveDate(dateMms); + String resultContent = StringUtils.getResultText(message, false); + if (resultContent != null) { + message.setResultContent(resultContent); + } + //检查收件箱地址把所有的验证码短信放到smsMessages + smsMessages.add(message); } - smsMessages.add(message); } } + List localMessages = DataSupport.where("readStatus = ?", "0").order("date asc").find(Message.class); - for(Message message:localMessages) { - if(message.getDate() != null) { + for (Message message : localMessages) { + if (message.getDate() != null) { message.setIsMessage(true); boolean find = false; - for(int u = 0; u< smsMessages.size();u ++ ) { - if(message.getDate().getTime() > smsMessages.get(u).getDate().getTime()) { + for (int u = 0; u < smsMessages.size(); u++) { + if (message.getDate().getTime() > smsMessages.get(u).getDate().getTime()) { smsMessages.add(u, message); find = true; break; } } - if(!find) { + if (!find) { smsMessages.add(message); } @@ -109,40 +119,37 @@ public List getAllCaptchMessages() { List unionMessages = new ArrayList<>(); - for(Message message: smsMessages) { + for (Message message : smsMessages) { String group = TimeUtils.getInstance().getDateGroup(message.getDate()); - if (dateGroupS.size() == 0) { - dateGroupS.add(group); + if (dateGroups.size() == 0) { + dateGroups.add(group); Message dateMessage = new Message(); dateMessage.setReceiveDate(group); dateMessage.setIsMessage(false); unionMessages.add(dateMessage); } else { - if (!group.equals(dateGroupS.get(dateGroupS.size() - 1))) { - dateGroupS.add(group); + if (!group.equals(dateGroups.get(dateGroups.size() - 1))) { + dateGroups.add(group); Message dateMessage = new Message(); dateMessage.setReceiveDate(group); dateMessage.setIsMessage(false); unionMessages.add(dateMessage); } } + unionMessages.add(message); } - - cursor.close(); return unionMessages; } /** * 删除手机短信 - * - * */ + */ public int deleteSms(String smsId) { final Uri SMS_URI = Uri.parse("content://sms/"); - int result = mContext.getContentResolver().delete(SMS_URI,"_id=?",new String[]{smsId}); - return result; + return mContext.getContentResolver().delete(SMS_URI, "_id=?", new String[]{smsId}); } public String getContactNameFromPhoneBook(String phoneNum) { @@ -169,7 +176,7 @@ public String getContactNameFromPhoneBook(String phoneNum) { } // 根据号码获得联系人头像 - public Bitmap get_people_image(String x_number) { + public Bitmap getPeopleImage(String x_number) { // 获得Uri Uri uriNumber2Contacts = Uri.parse("content://com.android.contacts/" @@ -193,8 +200,7 @@ public Bitmap get_people_image(String x_number) { // 打开头像图片的InputStream InputStream input = ContactsContract.Contacts.openContactPhotoInputStream(mContext.getContentResolver(), uri); // 从InputStream获得bitmap - Bitmap bmp_head = BitmapFactory.decodeStream(input); - return bmp_head; + return BitmapFactory.decodeStream(input); } cursorCantacts.close(); return null; diff --git a/app/src/main/java/me/drakeet/inmessage/utils/StringUtils.java b/app/src/main/java/me/drakeet/inmessage/utils/StringUtils.java index 720fd54..ffba9a5 100755 --- a/app/src/main/java/me/drakeet/inmessage/utils/StringUtils.java +++ b/app/src/main/java/me/drakeet/inmessage/utils/StringUtils.java @@ -9,10 +9,9 @@ /** * Created by Administrator on 2014/12/24 0024. */ -public class StringUtils implements StaticObjectInterface{ +public class StringUtils implements StaticObjectInterface { - private StringUtils() { - } + private StringUtils() {} /** * 判断字符串中子字符串出现次数 @@ -40,7 +39,7 @@ public static String getContentInBracket(String str, String address) { Pattern pattern = Pattern.compile("\\【(.*?)\\】"); Matcher matcher = pattern.matcher(str); while (matcher.find()) { - if(matcher.group(1) != null && matcher.group(1).length() < 10) { + if (matcher.group(1) != null && matcher.group(1).length() < 10) { return analyseSpecialCompany(matcher.group(1), str, address); } @@ -48,7 +47,7 @@ public static String getContentInBracket(String str, String address) { Pattern pattern1 = Pattern.compile("\\[(.*?)\\]"); Matcher matcher1 = pattern1.matcher(str); while (matcher1.find()) { - if(matcher1.group(1) != null && matcher1.group(1).length() < 10) { + if (matcher1.group(1) != null && matcher1.group(1).length() < 10) { return analyseSpecialCompany(matcher1.group(1), str, address); } @@ -56,7 +55,7 @@ public static String getContentInBracket(String str, String address) { Pattern pattern2 = Pattern.compile("\\((.*?)\\)"); Matcher matcher2 = pattern2.matcher(str); while (matcher2.find()) { - if(matcher2.group(1) != null && matcher2.group(1).length() < 10) { + if (matcher2.group(1) != null && matcher2.group(1).length() < 10) { return analyseSpecialCompany(matcher2.group(1), str, address); } @@ -66,72 +65,180 @@ public static String getContentInBracket(String str, String address) { private static String analyseSpecialCompany(String company, String content, String address) { String companyName = company; - if(company.equals("掌淘科技")) { - int index = content.indexOf("的验证码"); - companyName = content.substring(0, index); - companyName = companyName.replaceAll("【掌淘科技】", "").trim(); - } - else { - if(content.contains("贝壳单词的验证码")) { + if (company.equals("掌淘科技")) { + int index = content.indexOf("的验证码"); + companyName = content.substring(0, index); + companyName = companyName.replaceAll("【掌淘科技】", "").trim(); + } else { + if (content.contains("贝壳单词的验证码")) { companyName = "贝壳单词"; } } - if(address.equals("10010")) { + if (address.equals("10010")) { companyName = "中国联通"; } - if(address.equals("10086")) { + if (address.equals("10086")) { companyName = "中国移动"; } - if(address.equals("10000")) { + if (address.equals("10000")) { companyName = "中国电信"; } return companyName; } + /** + * 判断字符串中时否包含中文 + * + * @param str + * @return + */ + public static boolean isContainsChinese(String str) { + String regEx = "[\u4e00-\u9fa5]"; + Pattern pat = Pattern.compile(regEx); + Matcher matcher = pat.matcher(str); + boolean flg = false; + if (matcher.find()) { + flg = true; + } + return flg || str.contains("【") || str.contains("】") || str.contains("。"); + } + public static boolean isPersonalMoblieNO(String mobiles) { - Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$"); - Matcher m = p.matcher(mobiles); - return m.matches(); + if(mobiles != null) { + Pattern p = Pattern.compile("^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$"); + Matcher m = p.matcher(mobiles); + if (m == null) { + return false; + } + else { + return m.matches(); + } + } + return false; } public static String tryToGetCaptchas(String str) { Pattern continuousNumberPattern = Pattern.compile("[a-zA-Z0-9\\.]+"); Matcher m = continuousNumberPattern.matcher(str); + String mostLikelyCaptchas = ""; + int currentLevel = -1; //只有字母相似级别为0, 只有字母和数字可能级别为1, 只有数字可能级别为2. + while (m.find()) { + if (m.group().length() > 3 && m.group().length() < 8 && !m.group().contains(".")) { + if(isNearToKeyWord(m.group(), str)) { + final String strr = m.group(); + if(currentLevel == -1) { + mostLikelyCaptchas = m.group(); + } + final int level = getLikelyLevel(m.group()); + if(level > currentLevel) { + mostLikelyCaptchas = m.group(); + } + currentLevel = level; + } + } + } + return mostLikelyCaptchas; + } + + public static String tryToGetCaptchasEn(String str) { + Pattern continuousNumberPattern = Pattern.compile("[0-9\\.]+"); + Matcher m = continuousNumberPattern.matcher(str); while (m.find()) { if (m.group().length() > 3 && m.group().length() < 8 && !m.group().contains(".")) { - return m.group(); + if(isNearToKeyWordEn(m.group(), str)) { + return m.group(); + } } } return ""; } + private static int getLikelyLevel(String str) { + if(str.matches("^[0-9]*$")) { + return 2; + } else if(str.matches("^[a-zA-Z]*$")) { + return 0; + } else { + return 1; + } + + } + + public static boolean isNearToKeyWordEn(String currentStr, String content) { + int startPosition = 0; + int endPosition = content.length() - 1; + if (content.indexOf(currentStr) > 12) { + startPosition = content.indexOf(currentStr) - 12; + } + if (content.indexOf(currentStr) + currentStr.length() + 12 < content.length() - 1) { + endPosition = content.indexOf(currentStr) + currentStr.length() + 12; + } + Boolean isNearToKeyWord = false; + for (int i = 0; i < CPATCHAS_KEYWORD_EN.length; i++) { + if (content.substring(startPosition, endPosition).contains(CPATCHAS_KEYWORD_EN[i])) { + isNearToKeyWord = true; + break; + } + } + return isNearToKeyWord; + } + + public static boolean isNearToKeyWord(String currentStr, String content) { + int startPosition = 0; + int endPosition = content.length() - 1; + if (content.indexOf(currentStr) > 12) { + startPosition = content.indexOf(currentStr) - 12; + } + if (content.indexOf(currentStr) + currentStr.length() + 12 < content.length() - 1) { + endPosition = content.indexOf(currentStr) + currentStr.length() + 12; + } + Boolean isNearToKeyWord = false; + for (int i = 0; i < CPATCHAS_KEYWORD.length; i++) { + if (content.substring(startPosition, endPosition).contains(CPATCHAS_KEYWORD[i])) { + isNearToKeyWord = true; + break; + } + } + return isNearToKeyWord; + } + public static boolean isCaptchasMessage(String content) { - Boolean isCaptchasMessage = false; - for(int i = 0;i < CPATCHAS_KEYWORD.length;i++) { - if(content.contains(CPATCHAS_KEYWORD[i])) { - isCaptchasMessage = true; - break; - } - } - return isCaptchasMessage; + Boolean isCaptchasMessage = false; + for (int i = 0; i < CPATCHAS_KEYWORD.length; i++) { + if (content.contains(CPATCHAS_KEYWORD[i])) { + isCaptchasMessage = true; + break; + } + } + return isCaptchasMessage; + } + + public static boolean isCaptchasMessageEn(String content) { + Boolean isCaptchasMessage = false; + for (int i = 0; i < CPATCHAS_KEYWORD_EN.length; i++) { + if (content.contains(CPATCHAS_KEYWORD_EN[i])) { + isCaptchasMessage = true; + break; + } + } + return isCaptchasMessage; } /** * 根据短信获取描述文字 + * * @return */ public static String getResultText(Message message, Boolean isNotificationText) { String resultStr = ""; - if(message.getCompanyName() != null && !isNotificationText) { + if (message.getCompanyName() != null && !isNotificationText) { resultStr += "来自" + message.getCompanyName() + "的验证码:"; - } - else { + } else { resultStr += "当前验证码为:"; } - if(message.getCaptchas() != null) { + if (message.getCaptchas() != null) { resultStr += message.getCaptchas(); - } - else { + } else { resultStr += "点击查看详情."; } return resultStr; diff --git a/app/src/main/java/me/drakeet/inmessage/utils/TaskUtils.java b/app/src/main/java/me/drakeet/inmessage/utils/TaskUtils.java index 6ff8256..2334e8e 100755 --- a/app/src/main/java/me/drakeet/inmessage/utils/TaskUtils.java +++ b/app/src/main/java/me/drakeet/inmessage/utils/TaskUtils.java @@ -4,12 +4,13 @@ import android.os.Build; /** - * Created by drak11t on 8/16/14. + * Created by drakeet on 8/16/14. */ public class TaskUtils { - public static void executeAsyncTask( - AsyncTask task, Params... params) { + @SafeVarargs + public static void execute(AsyncTask task, + Params... params) { if (Build.VERSION.SDK_INT >= 11) { task.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR, params); } else { diff --git a/app/src/main/java/me/drakeet/inmessage/utils/TimeUtils.java b/app/src/main/java/me/drakeet/inmessage/utils/TimeUtils.java index 87a5a2d..0e50269 100755 --- a/app/src/main/java/me/drakeet/inmessage/utils/TimeUtils.java +++ b/app/src/main/java/me/drakeet/inmessage/utils/TimeUtils.java @@ -60,7 +60,7 @@ public static long getTimesMorning() { cal.set(Calendar.SECOND, 0); cal.set(Calendar.MINUTE, 0); cal.set(Calendar.MILLISECOND, 0); - return (long) (cal.getTimeInMillis()); + return cal.getTimeInMillis(); } public static Date getDateFromTimestamp(long longTime) { @@ -222,30 +222,26 @@ public String getDateGroup(Date date) { return TODAY; } - if(isSameYear(nowCalendar, cal)) { + if(isSameWeek(nowCalendar, cal)) { + if (isYesterDay(nowCalendar, cal)) { + return YESTERDAY; + } else if (isTheDayBeforeYesterday(nowCalendar, cal)) { + return THE_DAY_BEFORE_YESTERDAY; + } else { + return WEEK; + } + } else { if(isSameMonth(nowCalendar, cal)) { - if(isSameWeek(nowCalendar, cal)) { - if (isYesterDay(nowCalendar, cal)) { - return YESTERDAY; - } else if (isTheDayBeforeYesterday(nowCalendar, cal)) { - return THE_DAY_BEFORE_YESTERDAY; - } else { - return WEEK; - } - } - else { - return MONTH; - } + return MONTH; } - else { + else if(isSameYear(nowCalendar, cal)) { int month = cal.get(Calendar.MONTH) + 1; return month + "月"; + } else { + int month = cal.get(Calendar.MONTH) + 1; + return cal.get(Calendar.YEAR) + "年" + month + "月"; } } - else { - int month = cal.get(Calendar.MONTH) + 1; - return cal.get(Calendar.YEAR) + "年" + month + "月"; - } } diff --git a/app/src/main/java/me/drakeet/inmessage/utils/ToastUtils.java b/app/src/main/java/me/drakeet/inmessage/utils/ToastUtils.java index 74e6870..a463304 100755 --- a/app/src/main/java/me/drakeet/inmessage/utils/ToastUtils.java +++ b/app/src/main/java/me/drakeet/inmessage/utils/ToastUtils.java @@ -1,7 +1,5 @@ package me.drakeet.inmessage.utils; -import android.content.Context; -import android.os.AsyncTask; import android.widget.Toast; import me.drakeet.inmessage.App; @@ -11,19 +9,9 @@ */ public class ToastUtils{ - Context mContext; - private ToastUtils() { } - private static void show(Context context, int resId, int duration) { - Toast.makeText(context, resId, duration).show(); - } - - private static void show(Context context, String message, int duration) { - Toast.makeText(context, message, duration).show(); - } - public static void showShort(int resId) { Toast.makeText(App.getContext(), resId, Toast.LENGTH_SHORT).show(); } @@ -36,21 +24,6 @@ public static void showLong(int resId) { Toast.makeText(App.getContext(), resId, Toast.LENGTH_LONG).show(); } - public static void showToast(final String text) { - TaskUtils.executeAsyncTask(new AsyncTask() { - @Override - protected Object doInBackground(Object... params) { - return null; - } - - @Override - protected void onPostExecute(Object o) { - super.onPostExecute(o); - showShort(text); - } - }); - } - public static void showLong(String message) { Toast.makeText(App.getContext(), message, Toast.LENGTH_LONG).show(); } diff --git a/app/src/main/java/me/drakeet/inmessage/utils/VersionUtils.java b/app/src/main/java/me/drakeet/inmessage/utils/VersionUtils.java index 9c46502..4a916c5 100755 --- a/app/src/main/java/me/drakeet/inmessage/utils/VersionUtils.java +++ b/app/src/main/java/me/drakeet/inmessage/utils/VersionUtils.java @@ -6,9 +6,5 @@ * Created by drakeet on 12/11/14. */ public class VersionUtils { - public static final boolean IS_JBMR2 = Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN_MR2; - public static final boolean IS_ISC = Build.VERSION.SDK_INT == Build.VERSION_CODES.ICE_CREAM_SANDWICH; - public static final boolean IS_GINGERBREAD_MR1 = Build.VERSION.SDK_INT == Build.VERSION_CODES.GINGERBREAD_MR1; - public static final boolean IS_MORE_THAN_16 = Build.VERSION.SDK_INT >= 16; public static final boolean IS_MORE_THAN_LOLLIPOP = Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP; } diff --git a/app/src/main/java/me/drakeet/inmessage/widget/MultiSwipeRefreshLayout.java b/app/src/main/java/me/drakeet/inmessage/widget/MultiSwipeRefreshLayout.java index 9af9e63..6d1fa30 100755 --- a/app/src/main/java/me/drakeet/inmessage/widget/MultiSwipeRefreshLayout.java +++ b/app/src/main/java/me/drakeet/inmessage/widget/MultiSwipeRefreshLayout.java @@ -25,9 +25,11 @@ import me.drakeet.inmessage.R; /** - * Created by drakeet on 1/3/15. + * + * from io 2014 */ public class MultiSwipeRefreshLayout extends SwipeRefreshLayout { + private CanChildScrollUpCallback mCanChildScrollUpCallback; private Drawable mForegroundDrawable; @@ -61,8 +63,8 @@ public void setCanChildScrollUpCallback(CanChildScrollUpCallback canChildScrollU mCanChildScrollUpCallback = canChildScrollUpCallback; } - public static interface CanChildScrollUpCallback { - public boolean canSwipeRefreshChildScrollUp(); + public interface CanChildScrollUpCallback { + boolean canSwipeRefreshChildScrollUp(); } @Override diff --git a/app/src/main/java/me/drakeet/inmessage/widget/SeparatorItemDecoration.java b/app/src/main/java/me/drakeet/inmessage/widget/SeparatorItemDecoration.java new file mode 100644 index 0000000..a10e707 --- /dev/null +++ b/app/src/main/java/me/drakeet/inmessage/widget/SeparatorItemDecoration.java @@ -0,0 +1,79 @@ +package me.drakeet.inmessage.widget; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.drawable.Drawable; +import android.support.v7.widget.RecyclerView; +import android.view.View; + +import me.drakeet.inmessage.R; +import me.drakeet.inmessage.adapter.MainMessageAdapter; +import me.drakeet.inmessage.utils.VersionUtils; + +public class SeparatorItemDecoration extends RecyclerView.ItemDecoration { + + private static final int DIVIDER_SIZE_PX = 1; + + private final Paint mDivider; + + private final Drawable mShadow; + + public SeparatorItemDecoration(Context context) { + mDivider = new Paint(); + mDivider.setColor(context.getResources().getColor(R.color.line_gray)); + mDivider.setStyle(Paint.Style.STROKE); + mDivider.setStrokeWidth(DIVIDER_SIZE_PX); + + mShadow = context.getResources().getDrawable(R.drawable.shadow); + } + + @Override + public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) { + int childCount = parent.getChildCount(); + for (int i = 0; i < childCount; i++) { + View child = parent.getChildAt(i); + + if (shouldDrawDivider(parent, i, childCount)) { + c.drawLine(0, child.getBottom(), c.getWidth(), child.getBottom(), mDivider); + } + + if (shouldDrawShadow(parent, i)) { + mShadow.setBounds(0, child.getTop(), c.getWidth(), child.getTop() + mShadow.getIntrinsicHeight()); + mShadow.draw(c); + } + } + } + + private MainMessageAdapter.ITEM_TYPE getItemType(View child, RecyclerView parent) { + int adapterPosition = parent.getChildAdapterPosition(child); + int itemType = parent.getAdapter().getItemViewType(adapterPosition); + return MainMessageAdapter.ITEM_TYPE.values()[itemType]; + } + + private boolean shouldDrawDivider(RecyclerView parent, int i, int childCount) { + View child = parent.getChildAt(i); + + // 对于 Lollipop 以上,因为 message item 有 elevation,不绘制 date item 底下的分割线 + if (VersionUtils.IS_MORE_THAN_LOLLIPOP && getItemType(child, parent) + == MainMessageAdapter.ITEM_TYPE.ITEM_TYPE_DATE) { + return false; + } + + // 总是不绘制 date item 上一个 message item 底下的分割线,因为有 elevation 或假阴影 + if (i < childCount - 1 && getItemType(parent.getChildAt(i + 1), parent) + == MainMessageAdapter.ITEM_TYPE.ITEM_TYPE_DATE) { + return false; + } + + return true; + } + + private boolean shouldDrawShadow(RecyclerView parent, int i) { + return !VersionUtils.IS_MORE_THAN_LOLLIPOP + && i > 0 + && getItemType(parent.getChildAt(i - 1), parent) == MainMessageAdapter.ITEM_TYPE.ITEM_TYPE_MESSAGE + && getItemType(parent.getChildAt(i), parent) == MainMessageAdapter.ITEM_TYPE.ITEM_TYPE_DATE; + } + +} diff --git a/app/src/main/res/drawable/bg_listview_item.xml b/app/src/main/res/drawable/bg_listview_item.xml deleted file mode 100644 index c54a281..0000000 --- a/app/src/main/res/drawable/bg_listview_item.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/shadow.xml b/app/src/main/res/drawable/shadow.xml new file mode 100644 index 0000000..a7c366e --- /dev/null +++ b/app/src/main/res/drawable/shadow.xml @@ -0,0 +1,12 @@ + + + + + + + + diff --git a/app/src/main/res/layout/activity_about.xml b/app/src/main/res/layout/activity_about.xml index 0b77d71..965de25 100644 --- a/app/src/main/res/layout/activity_about.xml +++ b/app/src/main/res/layout/activity_about.xml @@ -1,69 +1,94 @@ - - - + + + android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> - + - + - - - - + + + + + + + + + + + + + + android:layout_height="match_parent" + app:layout_behavior="@string/appbar_scrolling_view_behavior"> - - @@ -81,7 +106,7 @@ android:layout_height="wrap_content" android:layout_marginBottom="12dp" android:layout_marginTop="12dp" - android:text="开发人员" + android:text="@string/developers" android:textColor="@color/md_grey_600"/> + android:textColor="@color/md_grey_800" + tools:ignore="HardcodedText"/> + android:textColor="@color/md_grey_800" + tools:ignore="HardcodedText"/> @@ -151,7 +182,7 @@ android:layout_height="wrap_content" android:layout_marginBottom="12dp" android:layout_marginTop="12dp" - android:text="开源协议" + android:text="@string/open_source_lis" android:textColor="@color/md_grey_600"/> + android:textColor="@color/md_grey_800" + tools:ignore="HardcodedText"/> + android:textSize="@dimen/open_source_lis_text_size" + tools:ignore="HardcodedText"/> + android:textColor="@color/md_grey_800" + tools:ignore="HardcodedText"/> + android:textSize="@dimen/open_source_lis_text_size" + tools:ignore="HardcodedText"/> + android:layout_marginBottom="16dp" + android:background="@drawable/card"> + android:textColor="@color/md_grey_800" + tools:ignore="HardcodedText"/> + android:textSize="@dimen/open_source_lis_text_size" + tools:ignore="HardcodedText"/> + android:background="@drawable/card"> + android:textColor="@color/md_grey_800" + tools:ignore="HardcodedText"/> - - - - - - - - - - - - - - + android:textSize="@dimen/open_source_lis_text_size" + tools:ignore="HardcodedText"/> - - - + - + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 8a2e66e..f59d122 100755 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,49 +1,45 @@ - + + - + + - - - - - - - - - - - + android:layout_height="match_parent"/> + + + + + + diff --git a/app/src/main/res/layout/item_message.xml b/app/src/main/res/layout/item_message.xml index 5837e54..bb044af 100755 --- a/app/src/main/res/layout/item_message.xml +++ b/app/src/main/res/layout/item_message.xml @@ -1,82 +1,83 @@ - + android:layout_height="wrap_content" + android:background="@color/message_bg_color" + android:elevation="2dp" + android:foreground="?selectableItemBackground"> + android:paddingStart="16dp" + android:paddingTop="12dp"> + android:paddingTop="4dp"> + tools:ignore="SmallSp" + tools:text="I" /> + android:layout_alignTop="@id/avatar_fg" + android:layout_toEndOf="@id/avatar_fg" + android:layout_toRightOf="@id/avatar_fg" + android:textColor="@color/material_text_title" + android:textSize="16sp" + android:textStyle="bold" + tools:text="10086" /> + tools:text="温馨提示,您的可信用额度已不足50元,请尽快充值或去营业厅交费!" /> + android:textSize="13sp" + tools:text="Just now" /> - - - - + diff --git a/app/src/main/res/layout/line.xml b/app/src/main/res/layout/line.xml deleted file mode 100755 index 06efc94..0000000 --- a/app/src/main/res/layout/line.xml +++ /dev/null @@ -1,6 +0,0 @@ - - \ No newline at end of file diff --git a/app/src/main/res/layout/view_separation.xml b/app/src/main/res/layout/view_separation.xml index ec4ea4f..f9f45ed 100755 --- a/app/src/main/res/layout/view_separation.xml +++ b/app/src/main/res/layout/view_separation.xml @@ -1,44 +1,15 @@ - - - - - - - - - - - - - - - \ No newline at end of file + android:background="@color/message_date_grey" + android:paddingBottom="12dp" + android:paddingLeft="16dp" + android:paddingRight="16dp" + android:paddingTop="12dp" + android:textColor="@color/md_grey_600" + android:textSize="14sp" + android:textStyle="bold" + tools:text="今天" /> diff --git a/app/src/main/res/layout/view_switchcompat.xml b/app/src/main/res/layout/view_switchcompat.xml index 342c40c..86a5e04 100644 --- a/app/src/main/res/layout/view_switchcompat.xml +++ b/app/src/main/res/layout/view_switchcompat.xml @@ -1,15 +1,14 @@ - + + android:layout_height="wrap_content" + android:checked="false" + android:shadowColor="@color/black" /> - + diff --git a/app/src/main/res/layout/view_toolbar.xml b/app/src/main/res/layout/view_toolbar.xml index 31e57d9..6e6f404 100755 --- a/app/src/main/res/layout/view_toolbar.xml +++ b/app/src/main/res/layout/view_toolbar.xml @@ -1,10 +1,19 @@ - - + app:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"> + + + + diff --git a/app/src/main/res/menu/menu_about.xml b/app/src/main/res/menu/menu_about.xml index e47a8af..2ccfda2 100644 --- a/app/src/main/res/menu/menu_about.xml +++ b/app/src/main/res/menu/menu_about.xml @@ -1,7 +1,7 @@ + tools:context="me.drakeet.meizhi.ui.AboutActivity"> + 验证码助手 + 关于 + 验证码助手,是由原「贝壳单词」团队开发的一款新的开源轻App.\n\n它可以在手机接收到验证码短信的时候,自动浮现验证码,并自动复制验证码到用户的剪切板。当用户接收到短信验证码,只要长按验证码的输入框,粘贴验证码即可。\n\n除此之外,还可以让用户批量删除无用验证码短信,帮助用户反向推理出绑定了哪些业务(换号必备啊有木有)。\n\n我们做得非常轻,也秉承了一贯的好设计和用户友好,在闲时它不会自启动、不会偷跑流量、不会占用任何内存(不信或担忧的话欢迎查看源代码~)。\n\n开放源代码地址:https://github.com/drakeet/SmsCodeHelper\n\n我们开源,做好设计,不乱使用权限,只求你如果喜欢,可以分享给你的朋友们,好东西需要分享才能让其健康成长,每一次分享都是我们的动力,非常感谢! + 分享给朋友(谢谢QAQ) + 反向推理绑定业务 + 发现了一款非常美观易用的「验证码助手」轻App,开源的,可以在验证码短信来临的时,自动识别验证码,悬浮并且自动复制到剪切板,不用记忆不用输入,只要长按粘贴即可输入验证码。推荐~:http://fir.im/codehelper + 暂未识别绑定任何业务! + 识别中,请稍等 + 反向推理出的绑定业务详情 v0.1 + 操作后将会把短信收件箱中所有的验证码短信清空,但是我们还是会为你保存验证码记录(就算清空我们也还是能够帮你反向推理出绑定的业务)。请仔细检查并确认操作! + Android 5.0 以上暂不支持清空验证码短信! + 识别到验证码:%s,并已复制到剪贴板,长按你的输入框即可粘贴验证码 + 当前验证码:%s(点击可复制) + 验证码助手 - 不用记数字不用输入完成验证 + 开发人员 + 开发者 + + 开源协议 + 介绍与帮助 + 清空验证码短信? + 删除验证码短信中… + 成功删除%s条验证码短信 + 加载中请勿改变开关状态! + 开启验证码内容显示简化 + 关闭验证码内容显示简化 + 加载中请勿操作! + 分享 + diff --git a/app/src/main/res/values-zh-rCN/strings_time.xml b/app/src/main/res/values-zh-rCN/strings_time.xml new file mode 100755 index 0000000..75b8c73 --- /dev/null +++ b/app/src/main/res/values-zh-rCN/strings_time.xml @@ -0,0 +1,14 @@ + + + + 刚刚 + 分钟以前 + 小时以前 + 天以前 + 本月 + 今年 + 今天 + 昨天 + 前天 + 本周 + \ No newline at end of file diff --git a/app/src/main/res/values-zh-rTW/strings.xml b/app/src/main/res/values-zh-rTW/strings.xml new file mode 100755 index 0000000..9d1ff4b --- /dev/null +++ b/app/src/main/res/values-zh-rTW/strings.xml @@ -0,0 +1,29 @@ + + 驗證碼助手 + 關於 + 驗證碼助手,是由原「貝殼單詞」團隊開發的一款新的開源輕App.\n\n它可以在手機接收到驗證碼短信的時候,自動浮現驗證碼,並自動複製驗證碼到用戶的剪切板。當用戶接收到短信驗證碼,只要長按驗證碼的輸入框,粘貼驗證碼即可。 \n\n除此之外,還可以讓用戶批量刪除無用驗證碼短信,幫助用戶反向推理出綁定了哪些業務(換號必備啊有木有)。 \n\n我們做得非常輕,也秉承了一貫的好設計和用戶友好,在閒時它不會自啟動、不會偷跑​​流量、不會佔用任何內存(不信或擔憂的話歡迎查看源代碼~)。 \n\n開放源代碼地址:https://github.com/drakeet/SmsCodeHelper\n\n我們開源,做好設計,不亂使用權限,只求你如果喜歡,可以分享給你的朋友們,好東西需要分享才能讓其健康成長,每一次分享都是我們的動力,非常感謝! + 分享給朋友(謝謝QAQ) + 反向推理綁定業務 + 發現了一款非常美觀易用的「驗證碼助手」輕App,開源的,可以在驗證碼短信來臨的時,自動識別驗證碼,懸浮並且自動複製到剪切板,不用記憶不用輸入,只要長按粘貼即可輸入驗證碼。推薦~:http://fir.im/codehelper + 暫未識別綁定任何業務! + 識別中,請稍等 + 反向推理出的綁定業務詳情 v0.1 + 操作後將會把短信收件箱中所有的驗證碼短信清空,但是我們還是會為你保存驗證碼記錄(就算清空我們也還是能夠幫你反向推理出綁定的業務)。請仔細檢查並確認操作! + Android 5.0 以上暫不支持清空驗證碼短信! + 識別到驗證碼:%s,並已復製到剪貼板,長按你的輸入框即可粘貼驗證碼 + 當前驗證碼:%s(點擊可複制) + 驗證碼助手- 不用記數字不用輸入完成驗證 + 開發人員 + 開發者 + + 開源協議 + 介紹與幫助 + 清空驗證碼簡訊? + 删除驗證碼簡訊中… + 成功删除%s條驗證碼簡訊 + 加载中请勿改变开关状态! + 开启验证码内容显示简化 + 关闭验证码内容显示简化 + 加载中请勿操作! + 分享 + diff --git a/app/src/main/res/values-zh-rTW/strings_time.xml b/app/src/main/res/values-zh-rTW/strings_time.xml new file mode 100755 index 0000000..a08e9f1 --- /dev/null +++ b/app/src/main/res/values-zh-rTW/strings_time.xml @@ -0,0 +1,14 @@ + + + + 剛剛 + 分鐘以前 + 小時以前 + 天以前 + 本月 + 今年 + 今天 + 昨天 + 前天 + 本週 + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index bddf7b5..ae28b34 100755 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -3,15 +3,15 @@ #00bcd4 @color/actionbar_background - #ff2b4d90 + #008196 #00778d #ffffff #000000 #fdd835 - #d9d9d9 + #1f000000 - #eceff1 + #e7e7e7 #e91e63 #808080 #ec407a @@ -24,7 +24,6 @@ #f57c00 #e0e0e0 #cfdbdc - #216b74ff #e91e63 #00b0ff @color/theme_primary @@ -33,4 +32,4 @@ #f1f1f1 #00000000 - \ No newline at end of file + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index f6b0026..ac31262 100755 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -1,19 +1,29 @@ - 验证码助手 - Hello world! - Settings - 关于 - @string/about - 验证码助手,是由原「贝壳单词」团队开发的一款新的开源轻App.\n\n它可以在手机接收到验证码短信的时候,自动浮现验证码,并自动复制验证码到用户的剪切板。当用户接收到短信验证码,只要长按验证码的输入框,粘贴验证码即可。\n\n除此之外,还可以让用户批量删除无用验证码短信,帮助用户反向推理出绑定了哪些业务(换号必备啊有木有)。\n\n我们做得非常轻,也秉承了一贯的好设计和用户友好,在闲时它不会自启动、不会偷跑流量、不会占用任何内存(不信或担忧的话欢迎查看源代码~)。\n\n开放源代码地址:https://github.com/drakeet/SmsCodeHelper\n\n我们开源,我们做好设计,我们不乱使用权限,只求你如果喜欢,可以分享给你的朋友们,好东西需要分享才能让其健康成长,每一次分享都是我们的动力,非常感谢! - 分享给朋友(谢谢QAQ) - 反向推理绑定业务 - 发现了一款非常美观易用的「验证码助手」轻App,开源的,可以在验证码短信来临的时,自动识别验证码,悬浮并且自动复制到剪切板,不用记忆不用输入,只要长按粘贴即可输入验证码。推荐~:http://fir.im/codehelper - 暂未识别绑定任何业务! - 识别中,请稍等 - 反向推理出的绑定业务详情 v0.1 - 操作后将会把短信收件箱中所有的验证码短信清空,但是我们还是会为你保存验证码记录(就算清空我们也还是能够帮你反向推理出绑定的业务)。请仔细检查并确认操作! - Android 5.0 以上暂不支持清空验证码短信! - 识别到验证码:%s,并已复制到剪贴板,长按你的输入框即可粘贴验证码 - 当前验证码:%s(点击可复制) - 删除的会话Id为: + SmsCodeHelper + About + SmsCodeHelper, is a new open source and light App.\n\nIt can automatically emerge verification code when your phone receives a text message contains a verification code. And automatically copy the code to the user\'s clipboard. When the user receives the message verification code, just long press the EditText to paste the verification code.\n\nIn addition, it can also allow users to bulk delete unwanted SMS verification code; It can also help users Backward inference out what the business is bound (for a new phone number, it is useful).\n\nIt is very light, but also adhering to the usual good design and user-friendly, since it does not start at leisure, will not take up any memory (unbelievers or concern, welcome to view the source code) .\n\nOpen source address: https: //github.com/drakeet/SmsCodeHelper\n\nWe open source, good design, not indiscriminately use rights. Just hope if you like it, you can share with your friends, because good things need to share with others in order to let it grow, every share is our power, thanks! + Share to Friends (thank you) + Backward inference of bundled services + Found a very beautiful and easy to use app: SmsCodeHelper (verification code helper), light, open source, it can automatically copy the code to the user\'s clipboard, when the user receives the message verification code. Material Design and open source: http://fir.im/codehelper (or Google Play: SmsCodeHelper) + Temporarily did not find any business is bound. + Being recognized, please wait. + Backward inference of bundled services + All messages contain verification code will be deleted, but we will still save you records (for Backward inference). Please double-check and confirm the operation! + Android 5.0+ does not support emptied verification code text message temporarily. + Verification code: %s, and has been copied to the clipboard, press your input box to paste the code. + Current verification code:%s (Click to copy) + SmsCodeHelper \n- Convenient for Verification code + Developers + Developer + + Open source licenses + Introduction and help + Empty verification code SMS? + Deleting verification code SMS... + Successfully delete %s verification code sms! + Do not change the switch state in the load! + Opened simplified + Closed simplified + Do not operate in load! + Share diff --git a/app/src/main/res/values/strings_time.xml b/app/src/main/res/values/strings_time.xml index 95b49fa..0bff79e 100755 --- a/app/src/main/res/values/strings_time.xml +++ b/app/src/main/res/values/strings_time.xml @@ -1,15 +1,14 @@ - 刚刚 - 分钟以前 - 小时以前 - 天以前 - 本月 - 今年 - 今天 - 今天 - 昨天 - 前天 - 本周 + Just now + minute(s) ago + hour(s) ago + day(s) ago + This month + This year + Today + Yesterday + The day after yesterday + This week \ No newline at end of file diff --git a/app/src/main/res/values/styles.xml b/app/src/main/res/values/styles.xml index faad83d..5edea65 100755 --- a/app/src/main/res/values/styles.xml +++ b/app/src/main/res/values/styles.xml @@ -21,4 +21,9 @@ 16dp + + + diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml index 34c10e0..6cf63ed 100755 --- a/app/src/main/res/values/themes.xml +++ b/app/src/main/res/values/themes.xml @@ -15,7 +15,8 @@ - - + \ No newline at end of file diff --git a/build.gradle b/build.gradle index d3ff69d..1b7886d 100755 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:1.1.0' + classpath 'com.android.tools.build:gradle:1.3.0' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/screenshots/s2.png b/screenshots/s2.png index efa55a4..1638018 100755 Binary files a/screenshots/s2.png and b/screenshots/s2.png differ