From 555f4f68546ac0bf64ae5b6f1fdbedad8a81f747 Mon Sep 17 00:00:00 2001 From: Mygod Date: Wed, 16 Mar 2016 22:31:07 +0800 Subject: [PATCH] Refine #609 --- .../github/shadowsocks/ParserActivity.scala | 37 ++++++-------- .../shadowsocks/ProfileManagerActivity.scala | 50 ++++++++----------- .../github/shadowsocks/database/Profile.scala | 6 +++ .../com/github/shadowsocks/utils/Parser.scala | 5 -- 4 files changed, 43 insertions(+), 55 deletions(-) diff --git a/src/main/scala/com/github/shadowsocks/ParserActivity.scala b/src/main/scala/com/github/shadowsocks/ParserActivity.scala index 25676610..a7f40265 100644 --- a/src/main/scala/com/github/shadowsocks/ParserActivity.scala +++ b/src/main/scala/com/github/shadowsocks/ParserActivity.scala @@ -39,34 +39,27 @@ package com.github.shadowsocks -import android.content.{Intent, DialogInterface} +import android.content.{DialogInterface, Intent} import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.nfc.{NdefMessage, NfcAdapter} -import android.os.{Parcelable, Bundle} -import android.support.v7.app.{AppCompatActivity, AlertDialog} +import android.support.v7.app.{AlertDialog, AppCompatActivity} +import android.text.TextUtils import android.view.WindowManager import com.github.shadowsocks.utils.Parser class ParserActivity extends AppCompatActivity { - override def onCreate(savedInstanceState: Bundle) { - super.onCreate(savedInstanceState) - } - - - override def onResume() { - super.onResume() - var sharedStr = "" - if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent.getAction)) { - val rawMsgs = getIntent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES) - if (rawMsgs != null) { - val msg = rawMsgs(0).asInstanceOf[NdefMessage] - val records = msg.getRecords - sharedStr = new String(records(0).getPayload) - } - } else if (Intent.ACTION_VIEW.equals(getIntent.getAction)) { - sharedStr = getIntent.getData.toString + override def onNewIntent(intent: Intent) { + super.onNewIntent(intent) + val sharedStr = intent.getAction match { + case Intent.ACTION_VIEW => intent.getData.toString + case NfcAdapter.ACTION_NDEF_DISCOVERED => + val rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES) + if (rawMsgs != null && rawMsgs.nonEmpty) + new String(rawMsgs(0).asInstanceOf[NdefMessage].getRecords()(0).getPayload) else null + case _ => null } + if (TextUtils.isEmpty(sharedStr)) return val profiles = Parser.findAll(sharedStr) if (profiles.isEmpty) { finish() @@ -79,9 +72,9 @@ class ParserActivity extends AppCompatActivity { .setPositiveButton(android.R.string.yes, ((_, _) => profiles.foreach(ShadowsocksApplication.profileManager.createProfile)): DialogInterface.OnClickListener) .setNegativeButton(android.R.string.no, null) - .setMessage(sharedStr) + .setMessage(profiles.mkString("\n")) .create() - dialog.setOnDismissListener((dialog: DialogInterface) => finish()) // builder method was added in API 17 + dialog.setOnDismissListener((_: DialogInterface) => finish()) // builder method was added in API 17 dialog.show() } diff --git a/src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala b/src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala index 10b7bbec..03a499df 100644 --- a/src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala +++ b/src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala @@ -3,8 +3,8 @@ package com.github.shadowsocks import java.nio.charset.Charset import android.content._ -import android.nfc.{NdefRecord, NdefMessage, NfcEvent, NfcAdapter} import android.nfc.NfcAdapter.CreateNdefMessageCallback +import android.nfc.{NdefMessage, NdefRecord, NfcAdapter, NfcEvent} import android.os.{Bundle, Handler} import android.support.v7.app.{AlertDialog, AppCompatActivity} import android.support.v7.widget.RecyclerView.ViewHolder @@ -13,7 +13,7 @@ import android.support.v7.widget.helper.ItemTouchHelper import android.support.v7.widget.helper.ItemTouchHelper.SimpleCallback import android.support.v7.widget.{DefaultItemAnimator, LinearLayoutManager, RecyclerView, Toolbar} import android.text.style.TextAppearanceSpan -import android.text.{TextUtils, SpannableStringBuilder, Spanned} +import android.text.{SpannableStringBuilder, Spanned, TextUtils} import android.view.{LayoutInflater, MenuItem, View, ViewGroup} import android.widget.{CheckedTextView, ImageView, LinearLayout, Toast} import com.github.shadowsocks.aidl.IShadowsocksServiceCallback @@ -25,10 +25,8 @@ import net.glxn.qrgen.android.QRCode import scala.collection.mutable.ArrayBuffer -/** - * @author Mygod - */ -class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListener with ServiceBoundContext with CreateNdefMessageCallback{ +class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListener with ServiceBoundContext + with CreateNdefMessageCallback { private class ProfileViewHolder(val view: View) extends RecyclerView.ViewHolder(view) with View.OnClickListener { var item: Profile = _ private val text = itemView.findViewById(android.R.id.text1).asInstanceOf[CheckedTextView] @@ -37,10 +35,10 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe { val shareBtn = itemView.findViewById(R.id.share) shareBtn.setOnClickListener(_ => { - val url = Parser.generate(item) + val url = item.toString if (nfcAdapter != null && nfcAdapter.isEnabled) { - nfcAdapter.setNdefPushMessageCallback(ProfileManagerActivity.this,ProfileManagerActivity.this) - nfcShareItem = url + nfcAdapter.setNdefPushMessageCallback(ProfileManagerActivity.this, ProfileManagerActivity.this) + nfcShareItem = url.getBytes(Charset.forName("UTF-8")) } val image = new ImageView(ProfileManagerActivity.this) image.setLayoutParams(new LinearLayout.LayoutParams(-1, -1)) @@ -58,14 +56,11 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe .setMessage(R.string.share_message) .setTitle(R.string.share) .create() + dialog.setOnDismissListener(_ => if (nfcAdapter != null && nfcAdapter.isEnabled) + nfcAdapter.setNdefPushMessageCallback(null, ProfileManagerActivity.this)) dialog.show() - dialog.setOnDismissListener((dialog : DialogInterface) => { - if (nfcAdapter != null && nfcAdapter.isEnabled) { - nfcAdapter.setNdefPushMessageCallback(null,ProfileManagerActivity.this) - } - }) }) - shareBtn.setOnLongClickListener((v: View) => { + shareBtn.setOnLongClickListener(_ => { Utils.positionToast(Toast.makeText(ProfileManagerActivity.this, R.string.share, Toast.LENGTH_SHORT), shareBtn, getWindow, 0, Utils.dpToPx(ProfileManagerActivity.this, 8)).show true @@ -163,8 +158,8 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe private var undoManager: UndoSnackbarManager[Profile] = _ private lazy val clipboard = getSystemService(Context.CLIPBOARD_SERVICE).asInstanceOf[ClipboardManager] - private var nfcAdapter : NfcAdapter = _ - private var nfcShareItem : String = _ + private var nfcAdapter: NfcAdapter = _ + private var nfcShareItem: Array[Byte] = _ override def onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) @@ -181,9 +176,8 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe toolbar.setOnMenuItemClickListener(this) nfcAdapter = NfcAdapter.getDefaultAdapter(this) - if (nfcAdapter != null && nfcAdapter.isEnabled) { - nfcAdapter.setNdefPushMessageCallback(null,ProfileManagerActivity.this) - } + if (nfcAdapter != null && nfcAdapter.isEnabled) + nfcAdapter.setNdefPushMessageCallback(null, ProfileManagerActivity.this) ShadowsocksApplication.profileManager.setProfileAddedListener(profilesAdapter.add) val profilesList = findViewById(R.id.profilesList).asInstanceOf[RecyclerView] @@ -239,15 +233,15 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe override def onActivityResult(requestCode: Int, resultCode: Int, data: Intent) { val scanResult = IntentIntegrator.parseActivityResult(requestCode, resultCode, data) - if (scanResult != null && !TextUtils.isEmpty(scanResult.getContents)) - Parser.findAll(scanResult.getContents).foreach(ShadowsocksApplication.profileManager.createProfile) + if (scanResult != null) { + val contents = scanResult.getContents + if (!TextUtils.isEmpty(contents)) + Parser.findAll(contents).foreach(ShadowsocksApplication.profileManager.createProfile) + } } - def createNdefMessage(nfcEvent: NfcEvent): NdefMessage = { - val ndefRecord = new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI,nfcShareItem.getBytes(Charset.forName("US-ASCII")),Array[Byte](),nfcShareItem.getBytes(Charset.forName("US-ASCII"))) - val ndefMessage = new NdefMessage(Array[NdefRecord](ndefRecord)) - ndefMessage - } + def createNdefMessage(nfcEvent: NfcEvent) = + new NdefMessage(Array(new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, nfcShareItem, Array[Byte](), nfcShareItem))) def onMenuItemClick(item: MenuItem): Boolean = item.getItemId match { case R.id.scan_qr_code => @@ -276,7 +270,7 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe case R.id.action_export => ShadowsocksApplication.profileManager.getAllProfiles match { case Some(profiles) => - clipboard.setPrimaryClip(ClipData.newPlainText(null, profiles.map(Parser.generate).mkString("\n"))) + clipboard.setPrimaryClip(ClipData.newPlainText(null, profiles.mkString("\n"))) Toast.makeText(this, R.string.action_export_msg, Toast.LENGTH_SHORT).show case _ => Toast.makeText(this, R.string.action_export_err, Toast.LENGTH_SHORT).show } diff --git a/src/main/scala/com/github/shadowsocks/database/Profile.scala b/src/main/scala/com/github/shadowsocks/database/Profile.scala index b7c6ae4e..2472f059 100644 --- a/src/main/scala/com/github/shadowsocks/database/Profile.scala +++ b/src/main/scala/com/github/shadowsocks/database/Profile.scala @@ -39,6 +39,9 @@ package com.github.shadowsocks.database +import java.util.Locale + +import android.util.Base64 import com.j256.ormlite.field.{DataType, DatabaseField} class Profile { @@ -95,4 +98,7 @@ class Profile { @DatabaseField var userOrder: Long = _ + + override def toString = "ss://" + Base64.encodeToString("%s:%s@%s:%d".formatLocal(Locale.ENGLISH, + method, password, host, remotePort).getBytes, Base64.NO_PADDING | Base64.NO_WRAP) } diff --git a/src/main/scala/com/github/shadowsocks/utils/Parser.scala b/src/main/scala/com/github/shadowsocks/utils/Parser.scala index 3784fc8d..f1a38ccd 100644 --- a/src/main/scala/com/github/shadowsocks/utils/Parser.scala +++ b/src/main/scala/com/github/shadowsocks/utils/Parser.scala @@ -39,8 +39,6 @@ package com.github.shadowsocks.utils -import java.util.Locale - import android.util.{Base64, Log} import com.github.shadowsocks.database.Profile @@ -48,9 +46,6 @@ object Parser { val TAG = "ShadowParser" private val pattern = "(?i)ss://([A-Za-z0-9+-/=_]+)".r - def generate (profile: Profile): String = "ss://" + Base64.encodeToString("%s:%s@%s:%d".formatLocal(Locale.ENGLISH, - profile.method, profile.password, profile.host, profile.remotePort).getBytes, Base64.NO_PADDING | Base64.NO_WRAP) - def findAll(data: CharSequence) = pattern.findAllMatchIn(data).map(m => try { val content = new String(Base64.decode(m.group(1), Base64.NO_PADDING), "UTF-8") val methodIdx = content.indexOf(':')