diff --git a/app/build.gradle b/app/build.gradle index c2d5123ef97bb02b929c90d76f4ff2dfd0de7428..176191d02eac7936b4cc073148d764564702d954 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -72,5 +72,6 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.3.0' implementation 'com.github.bumptech.glide:glide:4.13.0' annotationProcessor 'com.github.bumptech.glide:compiler:4.14.0' + implementation 'com.hyman:flowlayout-lib:1.1.2' implementation project(':cloudphone') } diff --git a/app/src/main/java/com/huawei/cloudapp/common/CasHistory.java b/app/src/main/java/com/huawei/cloudapp/common/CasHistory.java new file mode 100644 index 0000000000000000000000000000000000000000..1e38528b9bf1560dae39585aa7cd40c01e7f6904 --- /dev/null +++ b/app/src/main/java/com/huawei/cloudapp/common/CasHistory.java @@ -0,0 +1,46 @@ +package com.huawei.cloudapp.common; + +import static android.content.Context.MODE_PRIVATE; + +import android.content.SharedPreferences; + +import java.util.Arrays; + +public class CasHistory { + + private SharedPreferences mPreferences; + + public CasHistory(SharedPreferences preferences) { + mPreferences = preferences; + } + + public String[] getHistory(String key) { + String[] keyHistoryList = {}; + String keyHistoryListStr = mPreferences.getString(key, ""); + if (!keyHistoryListStr.isEmpty()) { + keyHistoryList = keyHistoryListStr.split(","); + } + if (keyHistoryList.length > 10) { + String[] newArrays = new String[10]; + System.arraycopy(keyHistoryList, 0, newArrays, 0, 10); + keyHistoryList = newArrays; + } + return keyHistoryList; + } + + public void setHistory(String key, String value) { + String[] keyHistoryList = mPreferences.getString(key, "").split(","); + if (keyHistoryList.length > 10) { + String[] newArrays = new String[10]; + System.arraycopy(keyHistoryList, 0, newArrays, 0, 10); + keyHistoryList = newArrays; + } + if (!Arrays.asList(keyHistoryList).contains(value)) { + String keyHistoryListStr = Arrays.toString(keyHistoryList); + StringBuilder sb = new StringBuilder(keyHistoryListStr.substring(1, keyHistoryListStr.length() - 1)); + sb.insert(0, value + ","); + mPreferences.edit().putString(key, sb.toString()).apply(); + } + } + +} diff --git a/app/src/main/java/com/huawei/cloudapp/ui/CasCloudMainActivity.java b/app/src/main/java/com/huawei/cloudapp/ui/CasCloudMainActivity.java index 5ed6ad500a9f19fb419dca883dbe5bd7c2e59573..973f1b82647bcb9fd90adbcdc37e2fdf08e6d30f 100644 --- a/app/src/main/java/com/huawei/cloudapp/ui/CasCloudMainActivity.java +++ b/app/src/main/java/com/huawei/cloudapp/ui/CasCloudMainActivity.java @@ -24,18 +24,30 @@ import static com.huawei.cloudapp.utils.CasConstantsUtil.REMOTE_SCHEDULING_ELB_P import android.app.Activity; import android.content.Intent; +import android.content.SharedPreferences; import android.os.Bundle; +import android.text.InputFilter; +import android.text.Spanned; import android.text.TextUtils; +import android.util.Log; import android.view.View; +import android.widget.ArrayAdapter; +import android.widget.AutoCompleteTextView; import android.widget.EditText; import android.widget.LinearLayout; import android.widget.RadioGroup; +import android.widget.TextView; import com.huawei.cloudapp.R; import com.huawei.cloudapp.common.CASLog; import com.huawei.cloudapp.common.CasConnectInfo; +import com.huawei.cloudapp.common.CasHistory; +import com.zhy.view.flowlayout.FlowLayout; +import com.zhy.view.flowlayout.TagAdapter; +import com.zhy.view.flowlayout.TagFlowLayout; import java.io.Serializable; +import java.util.Arrays; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -43,8 +55,8 @@ import java.util.UUID; public class CasCloudMainActivity extends Activity { private static final String TAG = "CasCloudMainActivity"; - private EditText mCloudPhoneId; - private EditText mCloudPhonePort; + private AutoCompleteTextView mCloudPhoneIp; + private AutoCompleteTextView mCloudPhonePort; private RadioGroup mEncodeTypeGroup; private int mEncodeType = 0; private String mFrameType = "h264"; @@ -53,23 +65,30 @@ public class CasCloudMainActivity extends Activity { private EditText mRemoteEncodeServerIp; private EditText mRemoteEncodeServerPort; private RadioGroup mFrameTypeGroup; + private TagFlowLayout mFlowLayout; + private CasHistory mCasHistory; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_cas_cloud_main); + mCasHistory = new CasHistory(getSharedPreferences("input_history", MODE_PRIVATE)); initView(); } private void initView() { - mCloudPhoneId = findViewById(R.id.cloud_phone_id); + mCloudPhoneIp = findViewById(R.id.cloud_phone_ip); + initAutoCompleteTextView("ip", mCloudPhoneIp); mCloudPhonePort = findViewById(R.id.cloud_phone_port); + initAutoCompleteTextView("port", mCloudPhonePort); mEncodeTypeGroup = findViewById(R.id.encodeTypeRadioButtonGroup); mFrameTypeGroup = findViewById(R.id.frameTypeRadioButtonGroup); mRemoteEncodeServerIpLayout = findViewById(R.id.remote_ip_view_layout); mRemoteEncodeServerPortLayout = findViewById(R.id.remote_port_view_layout); mRemoteEncodeServerIp = findViewById(R.id.edit_text_remote_ip); mRemoteEncodeServerPort = findViewById(R.id.edit_text_remote_port); + mFlowLayout = findViewById(R.id.flow); + setAdapter(mFlowLayout); mEncodeTypeGroup.check(R.id.radioButtonCpu); mEncodeTypeGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() { @@ -119,7 +138,7 @@ public class CasCloudMainActivity extends Activity { } public void cloudPhoneConnect(View view) { - String phoneIp = mCloudPhoneId.getText().toString().trim(); + String phoneIp = mCloudPhoneIp.getText().toString().trim(); if (TextUtils.isEmpty(phoneIp)) { CASLog.e(TAG, "输入Ip为空"); return; @@ -173,4 +192,68 @@ public class CasCloudMainActivity extends Activity { return connectorInfo; } + private void initAutoCompleteTextView(String key, AutoCompleteTextView autoCompleteTextView) { + String[] keyHistoryList = mCasHistory.getHistory(key); + ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_dropdown_item_1line, keyHistoryList); + autoCompleteTextView.setAdapter(adapter); + autoCompleteTextView.setDropDownHeight(450); + autoCompleteTextView.setCompletionHint("仅显示最近的10条记录"); + autoCompleteTextView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + dropDownItem(view); + } + }); + autoCompleteTextView.setOnFocusChangeListener(new View.OnFocusChangeListener() { + @Override + public void onFocusChange(View view, boolean hasFocus) { + if (hasFocus) { + dropDownItem(view); + } + } + }); + InputFilter filter = new InputFilter() { + public CharSequence filter(CharSequence source, int start, int end, + Spanned dest, int dstart, int dend) { + for (int i = start; i < end; i++) { + char c = source.charAt(i); + if (!Character.isDigit(c) && c != '.') { + return ""; + } + } + return null; + } + }; + autoCompleteTextView.setFilters(new InputFilter[]{filter}); + } + + private void dropDownItem(View view) { + AutoCompleteTextView autoCompleteTextView = ((AutoCompleteTextView) view); + if (autoCompleteTextView.getAdapter().getCount() != 0) { + autoCompleteTextView.showDropDown(); + } else { + autoCompleteTextView.dismissDropDown(); + } + } + + private void setAdapter(TagFlowLayout flowLayout) { + String[] data = mCasHistory.getHistory("ip:port"); + if (data.length == 0) return; + flowLayout.setAdapter(new TagAdapter(data) { + @Override + public View getView(FlowLayout parent, int position, String s) { + TextView textView = (TextView) View.inflate(CasCloudMainActivity.this, R.layout.flow_item, null); + textView.setText(s); + return textView; + } + + @Override + public void onSelected(int position, View view) { + String[] ipAndPortStr = data[position].split(":"); + mCloudPhoneIp.setText(ipAndPortStr[0]); + mCloudPhonePort.setText(ipAndPortStr[1]); + Log.e(TAG, "ipAndPortStr : "+ Arrays.toString(ipAndPortStr)); + } + }); + } } \ No newline at end of file diff --git a/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java b/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java index 424cbe99751afb009be8edda34f915f87a8d4c62..92b13625623d3af8d319223f2071951542d8660a 100644 --- a/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java +++ b/app/src/main/java/com/huawei/cloudapp/ui/CasCloudPhoneActivity.java @@ -53,6 +53,7 @@ import com.huawei.cloudapp.R; import com.huawei.cloudapp.common.CASLog; import com.huawei.cloudapp.common.CasCommonDialog; import com.huawei.cloudapp.common.CasConnectInfo; +import com.huawei.cloudapp.common.CasHistory; import com.huawei.cloudapp.common.CasImageQualityManager; import com.huawei.cloudapp.common.CasListener; import com.huawei.cloudapp.common.CasState; @@ -129,6 +130,7 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl private int currentRotation = -1; private CasCommonDialog quitDialog; private CasCommonDialog mDialog; + private CasHistory mCasHistory; //virtual devices VirtualDeviceSession mVirtualDeviceSession = null; @@ -253,7 +255,7 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl keepScreenLongLight(this, true); getIntentData(); initVirtualDeviceSession(); - + mCasHistory = new CasHistory(getSharedPreferences("input_history", MODE_PRIVATE)); // get views loadingView = (ImageView) findViewById(R.id.loadingView); mFrameLayout = (FrameLayout) findViewById(R.id.frame_layout); @@ -309,8 +311,11 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl } mCloudPhone.startCloudPhone(this, mFrameLayout, parasMap); + } catch (IllegalArgumentException e) { + showDialog(getResources().getString(R.string.cas_phone_input_param_invalid)); } catch (Exception e) { CASLog.e(TAG, "startCloudApp start failed." + e.getMessage()); + showDialog(getResources().getString(R.string.cas_phone_start_fail_tip_message)); } } @@ -433,6 +438,9 @@ public class CasCloudPhoneActivity extends FragmentActivity implements View.OnCl lag.setVisibility(View.VISIBLE); loadingView.setVisibility(View.GONE); startSuccessThreadTask(); + mCasHistory.setHistory("ip", connectInfo.getConnectIp()); + mCasHistory.setHistory("port", connectInfo.getConnectPort()); + mCasHistory.setHistory("ip:port", connectInfo.getConnectIp() + ":" + connectInfo.getConnectPort()); if (mVirtualDeviceSession != null) { mVirtualDeviceSession.start(); } diff --git a/app/src/main/res/layout/activity_cas_cloud_main.xml b/app/src/main/res/layout/activity_cas_cloud_main.xml index edc4fdd8eb977f5178124d52c58b9075d07a827e..6dcf8df46f5033852f42e0c8dd8b4a12d97a288d 100644 --- a/app/src/main/res/layout/activity_cas_cloud_main.xml +++ b/app/src/main/res/layout/activity_cas_cloud_main.xml @@ -3,6 +3,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" android:background="@android:color/white" android:orientation="vertical" android:paddingTop="50dp" @@ -14,7 +15,8 @@ android:layout_marginLeft="20dp" android:layout_marginTop="30dp" android:layout_marginRight="20dp" - android:orientation="horizontal"> + android:orientation="horizontal" + android:focusableInTouchMode="true"> - - + android:textSize="18sp" + android:completionThreshold="0"/> - + android:textSize="18sp" + android:completionThreshold="1" /> @@ -217,4 +220,18 @@ android:onClick="cloudPhoneConnect" android:textSize="20dp" /> + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/flow_item.xml b/app/src/main/res/layout/flow_item.xml new file mode 100644 index 0000000000000000000000000000000000000000..8538425ea4f81aa631b42f0460f666d65f605731 --- /dev/null +++ b/app/src/main/res/layout/flow_item.xml @@ -0,0 +1,15 @@ + + + \ 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 431cd0836e8875ffb13e0be7e81fe9b1faa03c90..d4fc14e2ab41e58add2987bdb6b21749b62bcd5a 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -24,6 +24,7 @@ 验证失败 试玩时间已到 由于您长时间未操作游戏,服务断开 + 输入的参数不合法 云手机ip: 连接 云手机port: diff --git a/cloudphone/src/main/java/com/huawei/cloudphone/apiimpl/CloudPhoneImpl.java b/cloudphone/src/main/java/com/huawei/cloudphone/apiimpl/CloudPhoneImpl.java index 3bec08737e92e67189c08ca396dceee313e72f9d..c83f83f363320943068ff4c74ca69c49ec56a2b6 100644 --- a/cloudphone/src/main/java/com/huawei/cloudphone/apiimpl/CloudPhoneImpl.java +++ b/cloudphone/src/main/java/com/huawei/cloudphone/apiimpl/CloudPhoneImpl.java @@ -194,7 +194,7 @@ public class CloudPhoneImpl implements ICloudPhone { public void startCloudPhone(Activity activity, ViewGroup view, Map params) { if (mCurrentState == STATE_DEINIT) { CASLog.e(TAG, "Call init first."); - return; + throw new IllegalStateException("Call init first."); } CASLog.i(TAG, "startCloudPhone called"); mActivity = activity; @@ -203,7 +203,7 @@ public class CloudPhoneImpl implements ICloudPhone { mConnectorInfo = new CasConnectorInfo(); if (!mConnectorInfo.initConnectorParams(mStartParas)) { CASLog.e(TAG, "Init connector params failed."); - return; + throw new IllegalArgumentException("Init connector params failed."); } mBgTimeout = Integer.parseInt(mConnectorInfo.getBackgroundTimeout()) * 1000; mIsStartSuccess = false;