diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml index 26e4a77e..d97358c9 100644 --- a/src/main/AndroidManifest.xml +++ b/src/main/AndroidManifest.xml @@ -51,7 +51,7 @@ android:theme="@style/PopupTheme" android:excludeFromRecents="true" android:taskAffinity="" - android:launchMode="singleInstance"> + android:launchMode="singleTask"> diff --git a/src/main/res/values-zh/strings.xml b/src/main/res/values-zh/strings.xml index e7dd2411..77e64d3e 100755 --- a/src/main/res/values-zh/strings.xml +++ b/src/main/res/values-zh/strings.xml @@ -62,6 +62,9 @@ 刷新中…… 分享 扫描二维码或者使用 NFC(Android Beam) + 扫描二维码 + 扫描二维码,NFC(Android Beam)被禁用 + 打开 NFC & Android Beam 添加配置文件 NAT 模式 (仅限调试) diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 9f69e76c..7a204a3b 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -93,6 +93,9 @@ Shadowsocks %s Share Scan QRCode or Use NFC (Android Beam) + Scan QRCode + Scan QRCode, NFC (Android Beam) is disabled + Turn on NFC & Android Beam Flush DNS cache Only useful in NAT mode Only useful in NAT mode. Requires ROOT permission. diff --git a/src/main/scala/com/github/shadowsocks/ParserActivity.scala b/src/main/scala/com/github/shadowsocks/ParserActivity.scala index a7f40265..d99178d4 100644 --- a/src/main/scala/com/github/shadowsocks/ParserActivity.scala +++ b/src/main/scala/com/github/shadowsocks/ParserActivity.scala @@ -43,24 +43,38 @@ import android.content.{DialogInterface, Intent} import android.graphics.Color import android.graphics.drawable.ColorDrawable import android.nfc.{NdefMessage, NfcAdapter} +import android.os.Bundle 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) + handledSharedIntent() + } + override def onNewIntent(intent: Intent) { super.onNewIntent(intent) + setIntent(intent) + handledSharedIntent() + } + + def handledSharedIntent() { + val intent = getIntent() 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 + new String(rawMsgs(0).asInstanceOf[NdefMessage].getRecords()(0).getPayload) + else null case _ => null } if (TextUtils.isEmpty(sharedStr)) return - val profiles = Parser.findAll(sharedStr) + val profiles = Parser.findAll(sharedStr).toList if (profiles.isEmpty) { finish() return diff --git a/src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala b/src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala index 03a499df..36d8b84d 100644 --- a/src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala +++ b/src/main/scala/com/github/shadowsocks/ProfileManagerActivity.scala @@ -5,7 +5,8 @@ import java.nio.charset.Charset import android.content._ import android.nfc.NfcAdapter.CreateNdefMessageCallback import android.nfc.{NdefMessage, NdefRecord, NfcAdapter, NfcEvent} -import android.os.{Bundle, Handler} +import android.os.{Build, Bundle, Handler} +import android.provider.Settings import android.support.v7.app.{AlertDialog, AppCompatActivity} import android.support.v7.widget.RecyclerView.ViewHolder import android.support.v7.widget.Toolbar.OnMenuItemClickListener @@ -36,8 +37,8 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe val shareBtn = itemView.findViewById(R.id.share) shareBtn.setOnClickListener(_ => { val url = item.toString - if (nfcAdapter != null && nfcAdapter.isEnabled) { - nfcAdapter.setNdefPushMessageCallback(ProfileManagerActivity.this, ProfileManagerActivity.this) + if (nfcBeamEnable) { + nfcAdapter.setNdefPushMessageCallback(ProfileManagerActivity.this,ProfileManagerActivity.this) nfcShareItem = url.getBytes(Charset.forName("UTF-8")) } val image = new ImageView(ProfileManagerActivity.this) @@ -53,11 +54,26 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe .setNegativeButton(R.string.copy_url, ((_, _) => clipboard.setPrimaryClip(ClipData.newPlainText(null, url))): DialogInterface.OnClickListener) .setView(image) - .setMessage(R.string.share_message) .setTitle(R.string.share) .create() - dialog.setOnDismissListener(_ => if (nfcAdapter != null && nfcAdapter.isEnabled) - nfcAdapter.setNdefPushMessageCallback(null, ProfileManagerActivity.this)) + if (!nfcAvailable){ + dialog.setMessage(getString(R.string.share_message_without_nfc)) + } else { + if (!nfcBeamEnable) { + dialog.setMessage(getString(R.string.share_message_nfc_disabled)) + dialog.setButton(DialogInterface.BUTTON_NEUTRAL, getString(R.string.turn_on_nfc), ((_, _) => + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + startActivity(new Intent(Settings.ACTION_NFC_SETTINGS)) + } else { + startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS)) + } + ): DialogInterface.OnClickListener) + } else { + dialog.setMessage(getString(R.string.share_message)) + dialog.setOnDismissListener(_ => + nfcAdapter.setNdefPushMessageCallback(null, ProfileManagerActivity.this)) + } + } dialog.show() }) shareBtn.setOnLongClickListener(_ => { @@ -158,8 +174,12 @@ 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 nfcAdapter : NfcAdapter = _ private var nfcShareItem: Array[Byte] = _ + private var nfcAvailable = false + private var nfcEnable = false + private var nfcBeamEnable = false override def onCreate(savedInstanceState: Bundle) { super.onCreate(savedInstanceState) @@ -175,10 +195,6 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe toolbar.inflateMenu(R.menu.profile_manager_menu) toolbar.setOnMenuItemClickListener(this) - nfcAdapter = NfcAdapter.getDefaultAdapter(this) - if (nfcAdapter != null && nfcAdapter.isEnabled) - nfcAdapter.setNdefPushMessageCallback(null, ProfileManagerActivity.this) - ShadowsocksApplication.profileManager.setProfileAddedListener(profilesAdapter.add) val profilesList = findViewById(R.id.profilesList).asInstanceOf[RecyclerView] val layoutManager = new LinearLayoutManager(this) @@ -215,6 +231,31 @@ class ProfileManagerActivity extends AppCompatActivity with OnMenuItemClickListe } } + + override def onResume() { + super.onResume() + nfcAdapter = NfcAdapter.getDefaultAdapter(this) + if (nfcAdapter != null){ + nfcAvailable = true + if (nfcAdapter.isEnabled) { + nfcEnable = true + if (nfcAdapter.isNdefPushEnabled) { + nfcBeamEnable = true + nfcAdapter.setNdefPushMessageCallback(null, ProfileManagerActivity.this) + } else { + nfcBeamEnable = false + } + } else{ + nfcEnable = false + nfcBeamEnable = false + } + } else { + nfcAvailable = false + nfcEnable = false + nfcBeamEnable = false + } + } + override def onStart() { super.onStart() registerCallback