Compare commits

...

15 Commits
1.1.4 ... 1.2.8

Author SHA1 Message Date
2dust
6577c46a31 Merge pull request #425 from yuhan6665/translation
Fix a traditional Chinese translation
2020-05-31 16:13:35 +08:00
yuhan6665
c6dab001b2 Fix traditional Chinese translation 2020-05-30 12:34:29 -04:00
2dust
c105d84b35 Merge pull request #300 from yuhan6665/master
Fix UI touch issues for Android TV
2020-04-12 10:04:52 +08:00
2dust
3ea04c076c Merge pull request #314 from yuhan6665/chrome-os
Add tags in AndroidManifest to support PlayStore filtering
2020-03-16 16:24:58 +08:00
2dust
98475460bf Merge pull request #313 from yuhan6665/lint-fix
Use annotation to fix lint error
2020-03-16 16:24:08 +08:00
yuhan6665
68ee61a753 Add tags in AndroidManifest to support PlayStore filtering
Google Playstore is using uses-feature and supports-screens
to filter devices.
By setting all screens to true and specifing features as
"not required" should make app compatible with more devices
Particularly it includes Chrome OS devices.
2020-03-14 14:07:31 -04:00
yuhan6665
90ba9ef2b7 Use annotation to fix lint error 2020-03-14 13:03:51 -04:00
yuhan6665
0ec114322e Fix UI touch issues for Android TV 2020-03-08 12:06:44 -04:00
2dust
76f52e7aa7 Merge pull request #287 from yuhan6665/multidex
Fix multidex for Android devices below L
2020-03-03 14:52:19 +08:00
2dust
caa25ce424 Merge pull request #278 from yuhan6665/master
Add delete log button in logcat
2020-03-03 14:52:08 +08:00
yuhan6665
e33d7e9bcf Fix multidex for Android devices below L 2020-02-29 10:51:58 -05:00
yuhan6665
e120fce0b7 Add delete log button in logcat
Also, automatically scroll to bottom of the log if it is too long
2020-02-22 12:01:16 -05:00
2dust
6a90965c7b Update README.md 2019-11-14 13:09:31 +08:00
2dust
0542d913f2 Merge pull request #131 from galvasis193/feature-customediting
Give user the ability to edit/copy/paste custom config for convenience. Fix Import
2019-10-14 08:22:39 +08:00
Annoymous contributor
746254bb7e Give user the ability to edit/copy/paste custom config for convenience.
Fix import for go.Seq
2019-10-13 04:55:00 +00:00
18 changed files with 163 additions and 74 deletions

View File

@@ -3,4 +3,3 @@
<a href="https://play.google.com/store/apps/details?id=com.v2ray.ang">
<img alt="Get it on Google Play" src="https://play.google.com/intl/en_us/badges/images/generic/en_badge_web_generic.png" width="165" height="64" />
</a>

View File

@@ -91,6 +91,7 @@ dependencies {
implementation "com.android.support:cardview-v7:$supportLibVersion"
implementation "com.android.support:preference-v7:$supportLibVersion"
implementation "com.android.support:recyclerview-v7:$supportLibVersion"
implementation "com.android.support:multidex:1.0.3"
// DSL
implementation "org.jetbrains.anko:anko-sdk15:$ankoVersion"
implementation "org.jetbrains.anko:anko-support-v4:$ankoVersion"

View File

@@ -2,6 +2,16 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.v2ray.ang">
<supports-screens
android:anyDensity="true"
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"/>
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET" />

View File

@@ -1,12 +1,12 @@
package com.v2ray.ang
import android.app.Application
//import com.squareup.leakcanary.LeakCanary
import android.support.multidex.MultiDexApplication
import com.v2ray.ang.util.AngConfigManager
import me.dozen.dpreference.DPreference
import org.jetbrains.anko.defaultSharedPreferences
class AngApplication : Application() {
class AngApplication : MultiDexApplication() {
companion object {
const val PREF_LAST_VERSION = "pref_last_version"
}

View File

@@ -28,15 +28,11 @@ import libv2ray.Libv2ray
import libv2ray.V2RayVPNServiceSupportsSet
import rx.Observable
import rx.Subscription
import java.net.InetAddress
import java.io.IOException
import java.io.File
import java.io.FileDescriptor
import java.io.FileInputStream
import java.lang.ref.SoftReference
import android.os.Build
import android.annotation.TargetApi
import android.util.Log
import go.Seq
import org.jetbrains.anko.doAsync
class V2RayVpnService : VpnService() {
@@ -73,25 +69,28 @@ class V2RayVpnService : VpnService() {
*
* Source: https://android.googlesource.com/platform/frameworks/base/+/2df4c7d/services/core/java/com/android/server/ConnectivityService.java#887
*/
@TargetApi(28)
private val defaultNetworkRequest = NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.build()
private val defaultNetworkRequest by lazy @RequiresApi(Build.VERSION_CODES.P) {
NetworkRequest.Builder()
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.build()
}
private val connectivity by lazy { getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager }
@TargetApi(28)
private val defaultNetworkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
setUnderlyingNetworks(arrayOf(network))
}
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities?) {
// it's a good idea to refresh capabilities
setUnderlyingNetworks(arrayOf(network))
}
override fun onLost(network: Network) {
setUnderlyingNetworks(null)
private val defaultNetworkCallback by lazy @RequiresApi(Build.VERSION_CODES.P) {
object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
setUnderlyingNetworks(arrayOf(network))
}
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities?) {
// it's a good idea to refresh capabilities
setUnderlyingNetworks(arrayOf(network))
}
override fun onLost(network: Network) {
setUnderlyingNetworks(null)
}
}
}
private var listeningForDefaultNetwork = false
@@ -175,7 +174,7 @@ class V2RayVpnService : VpnService() {
}
if (Build.VERSION.SDK_INT >= 28) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
connectivity.requestNetwork(defaultNetworkRequest, defaultNetworkCallback)
listeningForDefaultNetwork = true
}
@@ -259,7 +258,7 @@ class V2RayVpnService : VpnService() {
// val emptyInfo = VpnNetworkInfo()
// val info = loadVpnNetworkInfo(configName, emptyInfo)!! + (lastNetworkInfo ?: emptyInfo)
// saveVpnNetworkInfo(configName, info)
if (Build.VERSION.SDK_INT >= 28) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
if (listeningForDefaultNetwork) {
connectivity.unregisterNetworkCallback(defaultNetworkCallback)
listeningForDefaultNetwork = false

View File

@@ -1,6 +1,8 @@
package com.v2ray.ang.ui
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.text.method.ScrollingMovementMethod
import android.view.Menu
import android.view.MenuItem
@@ -24,15 +26,22 @@ class LogcatActivity : BaseActivity() {
title = getString(R.string.title_logcat)
supportActionBar?.setDisplayHomeAsUpEnabled(true)
logcat()
logcat(false)
}
private fun logcat() {
private fun logcat(shouldFlushLog: Boolean) {
try {
pb_waiting.visibility = View.VISIBLE
doAsync {
if (shouldFlushLog) {
val lst = LinkedHashSet<String>()
lst.add("logcat")
lst.add("-c")
val process = Runtime.getRuntime().exec(lst.toTypedArray())
process.waitFor()
}
val lst = LinkedHashSet<String>()
lst.add("logcat")
lst.add("-d")
@@ -49,9 +58,11 @@ class LogcatActivity : BaseActivity() {
tv_logcat.text = allText
tv_logcat.movementMethod = ScrollingMovementMethod()
pb_waiting.visibility = View.GONE
Handler(Looper.getMainLooper()).post { sv_logcat.fullScroll(View.FOCUS_DOWN) }
}
}
} catch (e: IOException) {
e.printStackTrace()
}
}
@@ -66,7 +77,10 @@ class LogcatActivity : BaseActivity() {
toast(R.string.toast_success)
true
}
R.id.delete -> {
logcat(true)
true
}
else -> super.onOptionsItemSelected(item)
}
}

View File

@@ -1,9 +1,11 @@
package com.v2ray.ang.ui
import android.os.Bundle
import android.text.Editable
import android.text.TextUtils
import android.view.Menu
import android.view.MenuItem
import com.google.gson.Gson
import com.v2ray.ang.AppConfig
import com.v2ray.ang.R
import com.v2ray.ang.extension.defaultDPreference
@@ -12,6 +14,7 @@ import com.v2ray.ang.util.AngConfigManager
import com.v2ray.ang.util.Utils
import kotlinx.android.synthetic.main.activity_server2.*
import org.jetbrains.anko.*
import java.lang.Exception
class Server2Activity : BaseActivity() {
@@ -50,7 +53,7 @@ class Server2Activity : BaseActivity() {
*/
fun bindingServer(vmess: AngConfig.VmessBean): Boolean {
et_remarks.text = Utils.getEditable(vmess.remarks)
tv_content.text = defaultDPreference.getPrefString(AppConfig.ANG_CONFIG + edit_guid, "")
tv_content.text = Editable.Factory.getInstance().newEditable(defaultDPreference.getPrefString(AppConfig.ANG_CONFIG + edit_guid, ""))
return true
}
@@ -66,21 +69,40 @@ class Server2Activity : BaseActivity() {
* save server config
*/
fun saveServer(): Boolean {
var saveSuccess: Boolean
val vmess = configs.vmess[edit_index]
vmess.remarks = et_remarks.text.toString()
if (TextUtils.isEmpty(vmess.remarks)) {
toast(R.string.server_lab_remarks)
return false
saveSuccess = false
}
if (AngConfigManager.addCustomServer(vmess, edit_index) == 0) {
toast(R.string.toast_success)
saveSuccess = true
} else {
toast(R.string.toast_failure)
saveSuccess = false
}
try {
Gson().fromJson<Object>(tv_content.text.toString(), Object::class.java)
} catch (e: Exception) {
e.printStackTrace()
toast(R.string.toast_malformed_josn)
saveSuccess = false
}
if (saveSuccess) {
//update config
defaultDPreference.setPrefString(AppConfig.ANG_CONFIG + edit_guid, tv_content.text.toString())
finish()
return true
} else {
toast(R.string.toast_failure)
return false
}
}

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true"
android:drawable="@color/secondary_text" />
<item android:state_focused="true"
android:drawable="@color/secondary_text" />
<item android:state_hovered="true"
android:drawable="@color/secondary_text" />
<item android:drawable="@color/colorPrimary_text" />
</selector>

View File

@@ -54,8 +54,10 @@
android:id="@+id/layout_test"
android:layout_width="match_parent"
android:layout_height="@dimen/connection_test_height"
android:background="@color/colorPrimary_text"
android:gravity="center|left">
android:background="@drawable/background_test_button"
android:gravity="center|left"
android:clickable="true"
android:focusable="true">
<TextView
android:id="@+id/tv_test_state"
@@ -92,6 +94,8 @@
android:layout_marginLeft="16dp"
android:layout_marginTop="16dp"
android:src="@drawable/ic_v_idle"
android:clickable="true"
android:focusable="true"
app:layout_anchorGravity="bottom|right|end" />
</com.github.jorgecastilloprz.FABProgressCircle>

View File

@@ -68,20 +68,15 @@
android:text="@string/server_lab_content"
android:textAppearance="@style/TextAppearance.AppCompat.Subhead" />
<TextView
<EditText
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="@dimen/layout_margin_top_height"
android:text="" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/layout_margin_top_height"
android:layout_marginBottom="@dimen/layout_margin_top_height"
android:orientation="vertical" />
</LinearLayout>
</ScrollView>

View File

@@ -2,7 +2,10 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical">
android:gravity="center_vertical"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true">
<android.support.v7.widget.AppCompatImageView
android:id="@+id/icon"
@@ -40,6 +43,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="false"
android:focusable="false"
android:paddingStart="2dp"
android:paddingLeft="2dp"
android:paddingEnd="6dp"

View File

@@ -9,10 +9,6 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
android:clickable="true"
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="horizontal"
card_view:cardCornerRadius="5dp">
<LinearLayout
@@ -21,7 +17,11 @@
android:layout_height="@dimen/server_height"
android:layout_gravity="center"
android:gravity="center"
android:orientation="horizontal">
android:orientation="horizontal"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:nextFocusRight="@+id/layout_share">
<LinearLayout
android:layout_width="wrap_content"
@@ -111,10 +111,14 @@
<LinearLayout
android:id="@+id/layout_share"
android:layout_width="wrap_content"
android:layout_height="@dimen/server_height"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:paddingEnd="@dimen/layout_margin_right_height">
android:padding="@dimen/layout_margin_spacing"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:nextFocusLeft="@+id/info_container">
<ImageView
android:layout_width="wrap_content"
@@ -126,10 +130,13 @@
<LinearLayout
android:id="@+id/layout_edit"
android:layout_width="wrap_content"
android:layout_height="@dimen/server_height"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:paddingEnd="@dimen/layout_margin_right_height">
android:padding="@dimen/layout_margin_spacing"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true">
<ImageView
android:layout_width="@dimen/png_height"
@@ -141,10 +148,13 @@
<LinearLayout
android:id="@+id/layout_remove"
android:layout_width="wrap_content"
android:layout_height="@dimen/server_height"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical"
android:paddingEnd="@dimen/layout_margin_right_height">
android:padding="@dimen/layout_margin_spacing"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true">
<ImageView
android:layout_width="@dimen/png_height"

View File

@@ -6,6 +6,7 @@
android:gravity="center_vertical">
<android.support.v7.widget.CardView xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/item_cardview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="3dp"
@@ -13,7 +14,8 @@
android:focusable="true"
android:foreground="?android:attr/selectableItemBackground"
android:orientation="horizontal"
card_view:cardCornerRadius="5dp">
card_view:cardCornerRadius="5dp"
android:nextFocusRight="@+id/layout_edit">
<LinearLayout
android:id="@+id/info_container"
@@ -62,11 +64,14 @@
<LinearLayout
android:id="@+id/layout_share"
android:layout_width="wrap_content"
android:layout_height="@dimen/server_height"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:paddingEnd="@dimen/layout_margin_right_height"
android:visibility="invisible">
android:padding="@dimen/layout_margin_spacing"
android:visibility="invisible"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true">
<ImageView
android:layout_width="@dimen/png_height"
@@ -78,10 +83,14 @@
<LinearLayout
android:id="@+id/layout_edit"
android:layout_width="wrap_content"
android:layout_height="@dimen/server_height"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical"
android:paddingEnd="@dimen/layout_margin_right_height">
android:padding="@dimen/layout_margin_spacing"
android:background="?android:attr/selectableItemBackground"
android:clickable="true"
android:focusable="true"
android:nextFocusLeft="@+id/item_cardview">
<ImageView
android:layout_width="@dimen/png_height"

View File

@@ -6,4 +6,9 @@
android:icon="@drawable/ic_copy_white"
android:title="@string/logcat_copy"
app:showAsAction="always" />
<item
android:id="@+id/delete"
android:icon="@drawable/ic_delete_white_24dp"
android:title="@string/logcat_delete"
app:showAsAction="ifRoom" />
</menu>

View File

@@ -135,6 +135,7 @@
<string name="title_logcat">Logcat</string>
<string name="logcat_copy">复制</string>
<string name="logcat_delete">删除</string>
<string name="title_export_all">导出全部配置至剪贴板</string>
<string name="title_sub_setting">订阅设置</string>
<string name="sub_setting_remarks">备注</string>
@@ -184,5 +185,6 @@
<string name="summary_pref_proxy_sharing_enabled">绑定代理入口ip到0.0.0.0</string>
<string name="toast_warning_pref_proxysharing">其他设备可以使用socks/http协议通过您的IP地址连接到代理\nHttp 代理: http://您的ip:10809\nSocks 代理: socks(4/5)://您的ip:10808\n仅在受信任的网络中启用以避免未经授权的连接</string>
<string name="toast_warning_pref_proxysharing_short">代理共享已启用,请确保处于受信网络</string>
<string name="toast_malformed_josn">配置格式错误</string>
</resources>

View File

@@ -17,7 +17,7 @@
<string name="toast_services_failure">啟動服務失敗</string>
<!--ServerActivity-->
<string name="title_server">組態</string>
<string name="title_server">設定檔</string>
<string name="menu_item_add_config">新增組態</string>
<string name="menu_item_save_config">儲存組態</string>
<string name="menu_item_del_config">刪除組態</string>
@@ -57,7 +57,7 @@
<string name="title_file_chooser">選取一個設定檔</string>
<string name="toast_require_file_manager">請安裝檔案總管。</string>
<string name="server_customize_config">自訂組態</string>
<string name="toast_config_file_invalid">無效組態</string>
<string name="toast_config_file_invalid">無效設定檔</string>
<string name="server_lab_content">內容</string>
<string name="toast_none_data_clipboard">剪貼簿內無資料</string>
<string name="toast_invalid_url">網址無效</string>
@@ -104,17 +104,17 @@
<string name="summary_pref_donate">向開發人員捐款</string>
<string name="donate_detail">新增一些實驗性進階功能</string>
<string name="title_pref_remote_dns">遠端DNS (可)</string>
<string name="title_pref_remote_dns">遠端DNS (可)</string>
<string name="summary_pref_remote_dns">DNS</string>
<string name="title_pref_domestic_dns">境内DNS (可僅本地DNS模式下生效)</string>
<string name="title_pref_domestic_dns">境内DNS (可僅本地DNS模式下生效)</string>
<string name="summary_pref_domestic_dns">DNS</string>
<string name="title_pref_socks_port">SOCKS5代理端口</string>
<string name="summary_pref_socks_port">SOCKS5代理端口</string>
<string name="title_pref_socks_port">SOCKS5代理連接埠</string>
<string name="summary_pref_socks_port">SOCKS5代理連接埠</string>
<string name="title_pref_http_port">HTTP代理端口</string>
<string name="summary_pref_http_port">HTTP代理端口</string>
<string name="title_pref_http_port">HTTP代理連接埠</string>
<string name="summary_pref_http_port">HTTP代理連接埠</string>
<string name="title_pref_feedback">回饋</string>
@@ -137,6 +137,7 @@
<string name="title_logcat">Logcat</string>
<string name="logcat_copy">複製</string>
<string name="logcat_delete">刪除</string>
<string name="title_export_all">匯出全部配置至剪貼簿</string>
<string name="title_sub_setting">訂閱設定</string>
<string name="sub_setting_remarks">備註</string>
@@ -153,7 +154,7 @@
<string name="routing_settings_delete">清除</string>
<string name="routing_settings_scan_replace">掃描並取代</string>
<string name="routing_settings_scan_append">掃描並附加</string>
<string name="routing_settings_default_rules">設置默認路由規則</string>
<string name="routing_settings_default_rules">設置預設路由規則</string>
<string name="connection_test_pending">"檢查連線能力"</string>
<string name="connection_test_testing">"測試中……"</string>
@@ -178,12 +179,13 @@
<string-array name="routing_mode">
<item>全球</item>
<item>略過域網</item>
<item>略過域網</item>
<item>略過中國大陸</item>
<item>略過域網及中國大陸</item>
<item>略過域網及中國大陸</item>
</string-array>
<string name="title_pref_proxy_sharing_enabled">代理共享</string>
<string name="summary_pref_proxy_sharing_enabled">綁定代理入口ip到0.0.0.0</string>
<string name="toast_warning_pref_proxysharing">其他設備可以使用socks/http協通過您的IP地址連接到代理\nHttp 代理: http://您的ip:10809\nSocks 代理: socks(4/5)://您的ip:10808\n僅在受信任的網中啟用以避免未經授權的連接</string>
<string name="toast_warning_pref_proxysharing_short">代理共享已啟用,請確保處於受信網</string>
<string name="toast_warning_pref_proxysharing">其他設備可以使用socks/http協通過您的IP地址連接到代理\nHttp 代理: http://您的ip:10809\nSocks 代理: socks(4/5)://您的ip:10808\n僅在受信任的網中啟用以避免未經授權的連接</string>
<string name="toast_warning_pref_proxysharing_short">代理共享已啟用,請確保處於受信網</string>
<string name="toast_malformed_josn">配置格式錯誤</string>
</resources>

View File

@@ -3,6 +3,7 @@
<dimen name="bypass_list_header_height">50dp</dimen>
<dimen name="layout_margin_top_height">16dp</dimen>
<dimen name="layout_margin_right_height">16dp</dimen>
<dimen name="layout_margin_spacing">8dp</dimen>
<dimen name="edit_height">50dp</dimen>
<dimen name="png_height">24dp</dimen>
<dimen name="server_height">72dp</dimen>

View File

@@ -136,6 +136,7 @@
<string name="title_logcat">Logcat</string>
<string name="logcat_copy">Copy</string>
<string name="logcat_delete">Delete</string>
<string name="title_export_all">Export all config to clipboard</string>
<string name="title_sub_setting">Subscription setting</string>
<string name="sub_setting_remarks">remarks</string>
@@ -185,5 +186,6 @@
<string name="summary_pref_proxy_sharing_enabled">Bind inbound to 0.0.0.0</string>
<string name="toast_warning_pref_proxysharing">Other devices can connect to proxy by your ip address through socks/http protocol\nHttp Proxy: http://yourIP:10809\nSocks Proxy: socks(4/5)://yourIP:10808\nOnly enable in trusted network to avoid unauthorized connection</string>
<string name="toast_warning_pref_proxysharing_short">Proxy sharing enabled\nMake sure you are in a trusted network</string>
<string name="toast_malformed_josn">Config malformed</string>
</resources>