Remote Configuration for Android using Alibaba Cloud Table Store-阿里云开发者社区

开发者社区> 芷沁> 正文

Remote Configuration for Android using Alibaba Cloud Table Store

简介: In this tutorial, you will learn how to use Table Store to create a simple user information database with a form accessible on mobile devices.
+关注继续查看

86e43d940883c108c3166060805b39ee921d58eb_jpeg

By Sai Sarath Chandra Alibaba Cloud Tech Share Author and Alibaba Cloud MVP

In this tutorial, you will learn how to use Table Store to create a simple user information database with a form accessible on mobile devices.

Prerequisites:

• You need an Alibaba Cloud Account. If you need you can get one with $300 by signing up here.
• Need Android Studio 3.0.0
• Basic knowledge of Android/Java.

Tutorial:

1.Activate Table Store Service:

a) Please login to Alibaba Cloud Console and Activate the Table Store service, if you are using this for the first time.

1

b) If you haven't used before you will see a "Activate Now" button. Upon which the service will be activated.
c) Go ahead to the Table Store console and "Create Instance" in the region you are interested in.
d) Fill in the relevant details here.
e) And your Instance should be created. Please click on the Instance and copy the endpoint.
f) This is the Internet endpoint is what we are interested in. Please copy it and keep it for future reference.
g) You can follow the below Illustrative guide for the obtaining access keys.
https://www.alibabacloud.com/help/doc-detail/51665.htm?spm=a3c0i.o51500en.b99.9.733cc1c22ZHdyM

2.Create an Android Project with the name you want

2

a) Select next and I have selected the minimum target Android version as Android Kitkat. Please find the screenshot below.

3

b) Click next and select empty activity

4

c) Click next and leave the defaults as is and select "Finish" button

5

d) Let the Gradle build finish and then follow ahead

3.Downloading dependencies :

a) We need to download 2 jar files which are the core for using the Alibaba Cloud. Please use the following link and download "tablestore-4.2.0-jar-with-dependencies.jar" & "slf4j-api-1.7.7.jar".
http://central.maven.org/maven2/com/aliyun/openservices/tablestore/4.2.0/
http://central.maven.org/maven2/org/slf4j/slf4j-api/1.7.7/
b) Add the jars into the libs folder in the projectview and add the jars to the dependencies

6

c) Make sure you right click the jar and the select "Add as library".

4.Adding dependencies to app level gradle.

The following should be your dependencies in gradle.

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.android.support:appcompat-v7:26.1.0'
    compile 'com.android.support:design:26.1.0'
    implementation 'com.android.support.constraint:constraint-layout:1.0.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'
    compile 'joda-time:joda-time:2.9.9'
    compile 'com.android.support:design:26.1.0'
    implementation files('libs/tablestore-4.2.0-jar-with-dependencies.jar')
    implementation files('libs/slf4j-api-1.7.7.jar')
}

Code level Guide:

Project Files:

1.We have three layouts

a) activity_main.xml
b) activity_config.xml
c) activity_welcome.xml

2.we have three activities

a) WelcomeActivity.java
b) RemoteConfig.java
c) MainActivity.java

3.One Strings.xml file, which handles the externalization of strings in the project.

4.One Styles.xml, which externalizes the styles in the project

Deep Dive:

1.First of all, we will talk about creating the layouts of the application. For reference, the following screenshot shows how the final layout will look like:

7

To achieve this create activity_welcome.xml in res > layout & copy the following code.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/alibaba_logo"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:layout_marginBottom="16dp"
        android:layout_marginTop="32dp"
        android:adjustViewBounds="true"
        android:scaleType="centerCrop"
        android:src="@drawable/alibaba_cloud" />

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/alibaba_logo"
        android:layout_margin="8dp"
        android:orientation="horizontal">

        <Button
            android:id="@+id/userForm"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="UserForm" />

        <Button
            android:id="@+id/remoteConfig"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="App Congig" />

    </LinearLayout>
</RelativeLayout>

This is a relative layout which consists of a Image View and Two Button. It is pretty simple layout

2.Create activity_config.xml and copy the following code in the same way what we have did earlier.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/headingText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:text="Character Count"
        android:textAlignment="center"
        android:textSize="18sp" />

    <android.support.design.widget.TextInputLayout
        android:id="@+id/countLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/headingText"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:textColorHint="@color/colorPrimary"
        app:hintTextAppearance="@style/TextLabel">

        <EditText
            android:id="@+id/countValue"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:hint="Character Count"
            android:inputType="text"
            android:textSize="18sp" />

    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:id="@+id/ageMinLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/countLayout"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:textColorHint="@color/colorPrimary"
        app:hintTextAppearance="@style/TextLabel">

        <EditText
            android:id="@+id/ageMinValue"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:hint="Minimum Age"
            android:inputType="text"
            android:textSize="18sp" />

    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:id="@+id/ageMaxLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/ageMinLayout"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:textColorHint="@color/colorPrimary"
        app:hintTextAppearance="@style/TextLabel">

        <EditText
            android:id="@+id/ageMaxValue"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:hint="Maximum Age"
            android:inputType="text"
            android:textSize="18sp" />

    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:id="@+id/imageLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/ageMaxLayout"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:textColorHint="@color/colorPrimary"
        app:hintTextAppearance="@style/TextLabel">

        <EditText
            android:id="@+id/imageValue"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:hint="Image value"
            android:inputType="text"
            android:textSize="18sp" />

    </android.support.design.widget.TextInputLayout>


    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/imageLayout"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="16dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="16dp"
        android:text="Update Configuration" />

    <TextView
        android:id="@+id/output"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/button"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:text="Updated Config:"
        android:textAlignment="center"
        android:textColor="#000000"
        android:textSize="18sp" />


</RelativeLayout>

3.The final layout of the file will look something like this:

8

4.Create activity_main.xml and copy the following code. The final layout will look something like this:

9

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="sample.alibabacloud.remoteconfig.MainActivity">

    <ImageView
        android:id="@+id/backgroundImage"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:alpha="0.7"
        android:scaleType="centerCrop"
        android:src="@drawable/background_2" />
    
    <TextView
        android:id="@+id/headingText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_margin="8dp"
        android:text="User Form"
        android:textAlignment="center"
        android:textSize="18sp" />

    <android.support.design.widget.TextInputLayout
        android:id="@+id/nameInputLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/headingText"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:textColorHint="@color/colorPrimary"
        app:hintTextAppearance="@style/TextLabel">

        <EditText
            android:id="@+id/nameValue"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="4dp"
            android:hint="@string/NameHint"
            android:inputType="text"
            android:textSize="18sp" />

    </android.support.design.widget.TextInputLayout>

    <TextView
        android:id="@+id/ageHeader"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/nameInputLayout"
        android:layout_marginBottom="4dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:text="Age"
        android:textSize="14sp" />

    <Spinner
        android:id="@+id/ageValue"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/ageHeader"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:spinnerMode="dialog" />

    <TextView
        android:id="@+id/genderHeader"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/ageValue"
        android:layout_marginBottom="4dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:text="Gender"
        android:textSize="14sp" />


    <RadioGroup
        android:id="@+id/radioGender"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@id/genderHeader"
        android:layout_marginBottom="8dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp">

        <RadioButton
            android:id="@+id/radioMale"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:checked="true"
            android:text="Male"
            android:textSize="18sp" />

        <RadioButton
            android:id="@+id/radioFemale"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Female"
            android:textSize="18sp" />

    </RadioGroup>

    <Button
        android:id="@+id/button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/radioGender"
        android:layout_centerHorizontal="true"
        android:layout_marginBottom="16dp"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:layout_marginTop="16dp"
        android:text="Submit Form" />

    <TextView
        android:id="@+id/output"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/button"
        android:layout_marginLeft="8dp"
        android:layout_marginRight="8dp"
        android:text="Click 'SUBMIT FORM' to see output"
        android:textAlignment="center"
        android:textColor="#000000"
        android:textSize="18sp" />

</RelativeLayout>

5.Since we have created all the layouts, we will now work on creating the Activities. Create MainActivity.java file by right clicking on the package > New > Java Class and copy the following code

package sample.alibabacloud.remoteconfig;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.design.widget.TextInputLayout;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.Spinner;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    //Creating local objects
    TextInputLayout nameInputLayout;
    EditText nameValue;
    Spinner ageValue;
    String[] ageArr;
    RadioGroup radioGender;
    RadioButton radioMale, radioFemale, selectedRdoBtn;
    Button button;
    TextView output;
    ImageView backgroundImage;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        nameInputLayout = findViewById(R.id.nameInputLayout);
        nameValue = findViewById(R.id.nameValue);
        ageValue = findViewById(R.id.ageValue);
        radioGender = findViewById(R.id.radioGender);
        radioMale = findViewById(R.id.radioMale);
        radioFemale = findViewById(R.id.radioFemale);
        button = findViewById(R.id.button);
        output = findViewById(R.id.output);
        backgroundImage = findViewById(R.id.backgroundImage);

        nameInputLayout.setCounterEnabled(true);

        int minAge;
        int maxAge;

        //Logic for checking the App is installed first or existing
        SharedPreferences sharedPreferences = getSharedPreferences(WelcomeActivity.SHARED_PREF_FILE_NAME,MODE_PRIVATE);
        boolean isPresent = sharedPreferences.contains(WelcomeActivity.COUNT_KEY);
        if(isPresent){
            minAge = Integer.parseInt(sharedPreferences.getString(WelcomeActivity.MIN_AGE,null));
            maxAge = Integer.parseInt(sharedPreferences.getString(WelcomeActivity.MAX_AGE,null));
            nameInputLayout.setCounterMaxLength(Integer.parseInt(sharedPreferences.getString(WelcomeActivity.COUNT_KEY,null)));

            if(sharedPreferences.getString(WelcomeActivity.IMG_NUM,null).equals("1")){
                backgroundImage.setImageResource(R.drawable.background_1);
            }else{
                backgroundImage.setImageResource(R.drawable.background_2);
            }

        }else{
            //if the app opening is new
            minAge = 18;
            maxAge = 35;
            nameInputLayout.setCounterMaxLength(20);
        }

        ageArr = new String[maxAge-minAge+1];
        for(int i =minAge;i<=maxAge;i++){
            ageArr[i-minAge] = String.valueOf(i);
        }

        // set the values into the spinner
        ArrayAdapter<String> adapter = new ArrayAdapter<>(this,
        android.R.layout.simple_spinner_item,ageArr);

        ageValue.setAdapter(adapter);
        button.setOnClickListener(this);

    }

    @Override
    public void onClick(View view) {

        StringBuffer opStringBuf = new StringBuffer();

        int id = view.getId();
        if(id == R.id.button){

            opStringBuf.append("Form Submitted : ");
            // Get Name Input
            opStringBuf.append("\n Name given : "+nameValue.getEditableText());
            // Get Selected Age
            opStringBuf.append("\n"+"The age selected is : "+ageValue.getSelectedItem());
            // Get selected Gender
            int selectedRadio = radioGender.getCheckedRadioButtonId();
            selectedRdoBtn = findViewById(selectedRadio);
            opStringBuf.append("\n"+"selected Gender : "+selectedRdoBtn.getText());

            output.setText(opStringBuf);

        }

    }

}

6.Create RemoteConfig.java file and copy the following code

package sample.alibabacloud.remoteconfig;

import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.alicloud.openservices.tablestore.ClientException;
import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.TableStoreException;
import com.alicloud.openservices.tablestore.model.Column;
import com.alicloud.openservices.tablestore.model.ColumnValue;
import com.alicloud.openservices.tablestore.model.PrimaryKey;
import com.alicloud.openservices.tablestore.model.PrimaryKeyBuilder;
import com.alicloud.openservices.tablestore.model.PrimaryKeyValue;
import com.alicloud.openservices.tablestore.model.PutRowRequest;
import com.alicloud.openservices.tablestore.model.RowPutChange;
import com.alicloud.openservices.tablestore.model.RowUpdateChange;
import com.alicloud.openservices.tablestore.model.UpdateRowRequest;

import java.util.ArrayList;
import java.util.List;

import sample.alibabacloud.remoteconfig.model.ColumnData;

import static sample.alibabacloud.remoteconfig.WelcomeActivity.TABLE_NAME;

public class RemoteConfig extends Activity implements View.OnClickListener {

    //Fetch class level variables
    Button button;
    EditText countValue,ageMinValue,ageMaxValue,imageValue;
    TextView headingText,output;


    private final static String TAG = "RemoteConfig";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_config);

        button = findViewById(R.id.button);
        countValue = findViewById(R.id.countValue);
        ageMinValue = findViewById(R.id.ageMinValue);
        ageMaxValue = findViewById(R.id.ageMaxValue);
        imageValue = findViewById(R.id.imageValue);

        headingText = findViewById(R.id.headingText);
        output = findViewById(R.id.output);

        button.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();

        if(id == R.id.button){
            SyncClient client = new SyncClient(getString(R.string.Endpoint), getString(R.string.AccessKey), getString(R.string.AccessKeySecret),
                    getString(R.string.InstanceName));
            updateConfigValues updateConfigValues = new updateConfigValues();
            updateConfigValues.execute(client);

        }
    }

    private static void updateRow(SyncClient client, ColumnData cData) {
        // Creating Primary Key
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn(WelcomeActivity.PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(WelcomeActivity.PRIMARY_KEY_VALUE));
        PrimaryKey primaryKey = primaryKeyBuilder.build();
        // Creating list of Columns
        List<Column> columnsList = new ArrayList<>();

        columnsList.add(new Column(WelcomeActivity.COUNT_KEY,ColumnValue.fromString(cData.getCharCount())));
        columnsList.add(new Column(WelcomeActivity.MIN_AGE,ColumnValue.fromString(cData.getMinAge())));
        columnsList.add(new Column(WelcomeActivity.MAX_AGE,ColumnValue.fromString(cData.getMaxAge())));
        columnsList.add(new Column(WelcomeActivity.IMG_NUM,ColumnValue.fromString(cData.getImageNum())));

        RowUpdateChange rowUpdateChange = new RowUpdateChange(TABLE_NAME, primaryKey);

        rowUpdateChange.put(columnsList);

        try {
            client.updateRow(new UpdateRowRequest(rowUpdateChange));
        } catch (TableStoreException ex) {
            Log.e(TAG, "updateRow: Error "+ex);
            ex.printStackTrace();
        }

        RowPutChange rowPutChange = new RowPutChange(TABLE_NAME, primaryKey);

        rowPutChange.addColumn(WelcomeActivity.COUNT_KEY,ColumnValue.fromString(cData.getCharCount()));
        rowPutChange.addColumn(WelcomeActivity.MIN_AGE,ColumnValue.fromString(cData.getMinAge()));
        rowPutChange.addColumn(WelcomeActivity.MAX_AGE,ColumnValue.fromString(cData.getMaxAge()));
        rowPutChange.addColumn(WelcomeActivity.IMG_NUM,ColumnValue.fromString(cData.getImageNum()));

        client.putRow(new PutRowRequest(rowPutChange));
    }


    class updateConfigValues extends AsyncTask<SyncClient, Void, Void> {

        ProgressDialog loading = new ProgressDialog(RemoteConfig.this);
        SyncClient client;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            loading.setMessage("Updating App Config Values");
            loading.show();
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            loading.dismiss();
        }

        @Override
        protected Void doInBackground(SyncClient... syncClients) {
            try {

                client = syncClients[0];
                
                try {
                    Thread.sleep(10 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                
                updateRow( client ,new ColumnData(countValue.getText().toString(),ageMinValue.getText().toString(),ageMaxValue.getText().toString(),imageValue.getText().toString()));
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        updateOutput();
                    }
                });

            } catch (TableStoreException e) {
                Log.e(TAG, "TableStoreException: Request error Message : " + e.getMessage());
                Log.e(TAG, "TableStoreException: Request error ID : " + e.getRequestId());

            } catch (ClientException e) {
                Log.e(TAG, "ClientException: Request error Message : " + e.getMessage());

            } finally {
            
            }

            return null;
        }
    }

    private void updateOutput() {
        StringBuffer opBuf = new StringBuffer();

        opBuf.append("Updated Config:\n")
                .append("Character Count : ")
                .append(countValue.getText())
                .append("\nMinimum Age : ")
                .append(ageMinValue.getText())
                .append("\nMaximum Age : ")
                .append(ageMaxValue.getText())
                .append("\nUpdated Image Value : ")
                .append(imageValue.getText());
        
        output.setText(opBuf);
    }
}

7.Create WelcomeActivity.java and copy the following code

package sample.alibabacloud.remoteconfig;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.View;
import android.widget.Button;

import com.alicloud.openservices.tablestore.ClientException;
import com.alicloud.openservices.tablestore.SyncClient;
import com.alicloud.openservices.tablestore.TableStoreException;
import com.alicloud.openservices.tablestore.model.ColumnValue;
import com.alicloud.openservices.tablestore.model.CreateTableRequest;
import com.alicloud.openservices.tablestore.model.GetRowRequest;
import com.alicloud.openservices.tablestore.model.GetRowResponse;
import com.alicloud.openservices.tablestore.model.PrimaryKey;
import com.alicloud.openservices.tablestore.model.PrimaryKeyBuilder;
import com.alicloud.openservices.tablestore.model.PrimaryKeySchema;
import com.alicloud.openservices.tablestore.model.PrimaryKeyType;
import com.alicloud.openservices.tablestore.model.PrimaryKeyValue;
import com.alicloud.openservices.tablestore.model.PutRowRequest;
import com.alicloud.openservices.tablestore.model.Row;
import com.alicloud.openservices.tablestore.model.RowPutChange;
import com.alicloud.openservices.tablestore.model.SingleRowQueryCriteria;
import com.alicloud.openservices.tablestore.model.TableMeta;
import com.alicloud.openservices.tablestore.model.TableOptions;

import sample.alibabacloud.remoteconfig.model.ColumnData;

/**
 * Created by saisarathchandra on 06/12/17.
 */

public class WelcomeActivity extends Activity implements View.OnClickListener {


    public final static String COUNT_KEY = "CHARACTER_COUNT";
    public final static String MIN_AGE = "MINIMUM_AGE";
    public final static String MAX_AGE = "MAXIMUM_AGE";
    public final static String IMG_NUM = "IMAGE_NUMBER";

    public final static String DEF_COUNT_VALUE = "20";
    public final static String DEF_MIN_AGE = "18";
    public final static String DEF_MAX_AGE = "35";
    public final static String DEF_IMG_NUM = "1";

    private final static String TAG = "WelcomeActivity";
    public final static String SHARED_PREF_FILE_NAME = "RemoteConfigPref";

    public static final String PRIMARY_KEY_NAME = "Version";
    public static final String PRIMARY_KEY_VALUE = "User1";
    public static final String TABLE_NAME = "RemoteConfiguration";

    //Fetch class level variables
    Button userForm,remoteConfig;
    static SharedPreferences sharedPreferences;
    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_welcome);

        userForm = findViewById(R.id.userForm);
        remoteConfig = findViewById(R.id.remoteConfig);

        userForm.setOnClickListener(this);
        remoteConfig.setOnClickListener(this);

        sharedPreferences = getSharedPreferences(SHARED_PREF_FILE_NAME,MODE_PRIVATE);
        boolean isPresent = sharedPreferences.contains(COUNT_KEY);
        if(!isPresent){
            // create Table & Shared preferences and put initial values

            SyncClient client = new SyncClient(getString(R.string.Endpoint), getString(R.string.AccessKey), getString(R.string.AccessKeySecret),
                getString(R.string.InstanceName));

            CreateTableNDefValues createTableNDefValues = new CreateTableNDefValues();
            createTableNDefValues.execute(client);

            SharedPreferences.Editor prefFileEdit = sharedPreferences.edit();

            prefFileEdit.putString(COUNT_KEY,DEF_COUNT_VALUE);
            prefFileEdit.putString(MIN_AGE,DEF_MIN_AGE);
            prefFileEdit.putString(MAX_AGE,DEF_MAX_AGE);
            prefFileEdit.putString(IMG_NUM,DEF_IMG_NUM);

            prefFileEdit.apply();
        }else{
            SyncClient client = new SyncClient(getString(R.string.Endpoint), getString(R.string.AccessKey), getString(R.string.AccessKeySecret),
                    getString(R.string.InstanceName));

            GetRowValues getRowValues = new GetRowValues();
            getRowValues.execute(client);
        }


    }

    @Override
    protected void onResume() {
        super.onResume();
        SyncClient client = new SyncClient(getString(R.string.Endpoint), getString(R.string.AccessKey), getString(R.string.AccessKeySecret),
                getString(R.string.InstanceName));

        GetRowValues getRowValues = new GetRowValues();
        getRowValues.execute(client);
    }

    //Create a Table with a Primary Key Defined with some Additional Parameters
    private static void createTable(SyncClient client) {
        TableMeta tableMeta = new TableMeta(TABLE_NAME);
        tableMeta.addPrimaryKeyColumn(new PrimaryKeySchema(PRIMARY_KEY_NAME, PrimaryKeyType.STRING));
        int timeToLive = -1;
        int maxVersions = 1;

        TableOptions tableOptions = new TableOptions(timeToLive, maxVersions);
        CreateTableRequest request = new CreateTableRequest(tableMeta, tableOptions);

        client.createTable(request);
    }

    private static void updatePreferences(Row row){
        
        SharedPreferences.Editor prefFileEdit = sharedPreferences.edit();

        prefFileEdit.putString(COUNT_KEY,row.getColumn(COUNT_KEY).get(0).getValue().toString());
        prefFileEdit.putString(MIN_AGE,row.getColumn(MIN_AGE).get(0).getValue().toString());
        prefFileEdit.putString(MAX_AGE,row.getColumn(MAX_AGE).get(0).getValue().toString());
        prefFileEdit.putString(IMG_NUM,row.getColumn(IMG_NUM).get(0).getValue().toString());

        prefFileEdit.apply();

    }

    private static void putRow(SyncClient client, ColumnData cData) {
        // Creating Primary Key
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(PRIMARY_KEY_VALUE));
        PrimaryKey primaryKey = primaryKeyBuilder.build();

        RowPutChange rowPutChange = new RowPutChange(TABLE_NAME, primaryKey);

//        if you wish to have timestamp, add it as the third parameter to the addColumn method
//        long ts = System.currentTimeMillis();

        rowPutChange.addColumn(COUNT_KEY,ColumnValue.fromString(cData.getCharCount()));
        rowPutChange.addColumn(MIN_AGE,ColumnValue.fromString(cData.getMinAge()));
        rowPutChange.addColumn(MAX_AGE,ColumnValue.fromString(cData.getMaxAge()));
        rowPutChange.addColumn(IMG_NUM,ColumnValue.fromString(cData.getImageNum()));

        client.putRow(new PutRowRequest(rowPutChange));
    }

    private static void getRow(SyncClient client) {
        
        PrimaryKeyBuilder primaryKeyBuilder = PrimaryKeyBuilder.createPrimaryKeyBuilder();
        primaryKeyBuilder.addPrimaryKeyColumn(PRIMARY_KEY_NAME, PrimaryKeyValue.fromString(PRIMARY_KEY_VALUE));
        PrimaryKey primaryKey = primaryKeyBuilder.build();

        
        SingleRowQueryCriteria criteria = new SingleRowQueryCriteria(TABLE_NAME, primaryKey);
        
        criteria.setMaxVersions(1);
        GetRowResponse getRowResponse = client.getRow(new GetRowRequest(criteria));
        Row row = getRowResponse.getRow();
        Log.d(TAG, "getRow: Row Received Compelte");
        Log.d(TAG, "getRow:" + row);


        String[] columnNames = new String[]{WelcomeActivity.COUNT_KEY,
                                            WelcomeActivity.MIN_AGE,
        WelcomeActivity.MAX_AGE,WelcomeActivity.IMG_NUM};

        criteria.addColumnsToGet(columnNames);
        getRowResponse = client.getRow(new GetRowRequest(criteria));
        row = getRowResponse.getRow();

        Log.d(TAG, "getRow: Row Received after get Operation");
        Log.d(TAG, "getRow:" + row);

        updatePreferences(row);
    }

    @Override
    public void onClick(View view) {
        int id = view.getId();

        if(id == R.id.userForm){
            Intent intent = new Intent(this,MainActivity.class);
            startActivity(intent);
        }else if (id == R.id.remoteConfig){
            Intent intent = new Intent(this,RemoteConfig.class);
            startActivity(intent);
        }
    }

    class CreateTableNDefValues extends AsyncTask<SyncClient, Void, Void> {

        ProgressDialog loading = new ProgressDialog(WelcomeActivity.this);
        SyncClient client;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            loading.setMessage("Creating Tables and Setting Values");
            loading.show();
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            loading.dismiss();
        }

        @Override
        protected Void doInBackground(SyncClient... syncClients) {
            try {

                client = syncClients[0];

                // Create Table
                createTable(client);

                // Give some time to load
                try {
                    Thread.sleep(10 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                // Creating Object with all the values
                ColumnData cData = new ColumnData();
                cData.setCharCount(DEF_COUNT_VALUE);
                cData.setMinAge(DEF_MIN_AGE);
                cData.setMaxAge(DEF_MAX_AGE);
                cData.setImageNum(DEF_IMG_NUM);

                // putRow
                putRow(client, cData);

            } catch (TableStoreException e) {
                Log.e(TAG, "TableStoreException: Request error Message : " + e.getMessage());
                Log.e(TAG, "TableStoreException: Request error ID : " + e.getRequestId());

            } catch (ClientException e) {
                Log.e(TAG, "ClientException: Request error Message : " + e.getMessage());

            } finally {
                // Do your maintainence activites here
            }
//            client.shutdown();
            return null;
        }
    }

    class GetRowValues extends AsyncTask<SyncClient, Void, Void> {

        ProgressDialog loading = new ProgressDialog(WelcomeActivity.this);
        SyncClient client;

        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            loading.setMessage("Fetching updated values");
            loading.show();
        }

        @Override
        protected void onPostExecute(Void aVoid) {
            super.onPostExecute(aVoid);
            loading.dismiss();
        }

        @Override
        protected Void doInBackground(SyncClient... syncClients) {
            try {

                client = syncClients[0];

                // Give some time to load
                try {
                    Thread.sleep(10 * 1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                getRow(client);

            } catch (TableStoreException e) {
                Log.e(TAG, "TableStoreException: Request error Message : " + e.getMessage());
                Log.e(TAG, "TableStoreException: Request error ID : " + e.getRequestId());

            } catch (ClientException e) {
                Log.e(TAG, "ClientException: Request error Message : " + e.getMessage());

            } finally {
                // Do your maintainence activites here
            }

            return null;
        }
    }

}

8.Final configuration files:

• Open your "AndroidManifest.xml"and copy the following code

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="sample.alibabacloud.remoteconfig">

    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".WelcomeActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".MainActivity"/>
        <activity android:name=".RemoteConfig"/>
    </application>

</manifest>

• Open your styles.xml under the values folder and copy the following one.

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>

    <style name="TextLabel" parent="TextAppearance.Design.Hint">
        <item name="android:textSize">14sp</item>
    </style>

</resources>

• Update the strings.xml with the values you store earlier

<resources>
    <string name="app_name">RemoteConfig</string>

    <!-- Alibaba TableStore Service details-->
    <!-- Please replace this details with your own-->
    <!--Public Endpoint-->
    <string name="Endpoint"></string>
    <!-- Access ID -->
    <string name="AccessKey"></string>
    <!-- Access key Secret -->
    <string name="AccessKeySecret"></string>
    <!-- Queue Names -->
    <string name="InstanceName">AndroidDemo</string>
    
    <!--App Related Strings-->
    <string name="NameHint">Name</string>

</resources>

Detailed Code Explanation:

  1. In this Remote Configuration project, we are storing some app attributes like the maximum number of characters that the person can enter for his name, minimum age and the maximum age allowed, background image. We can see the user app analytics, review comments in appstore and sometimes we think we need to change some parameters for the code. We tend to launch and update which may not be efficient as we can achieve the same through remote configuration.
  2. When the Code loads the activity_welcome.xml is loaded and the respective WelcomeActivity is initialized. This happens through the WeclomeActivity declaration in the Android manifest.
  3. The welcome activity is responsible for checking the app is installed in the device for the first time or is it installed already. We use this scenario to setup the local secured
    SharedPreferences file.
  4. If the app is opening for the first time we will create a table called "Remote Configuration"& Create a primary key named "Version". And we will update the values to be default. This will be onetime activity along side we will also create the sharedpreferences file and update the values to be default.
  5. We will also copy the same logic onto the onPause() method so whenever the user navigates to the home screen the app can fetch the latest values from the server.
  6. The UserForm screen is responsible for checking the latest values from the TableStore and updating the same in the form.
  7. The RemoteConfig is responsible for updating the values in the TableStore.
  8. You can see all the methods are self-explanatory.
  9. If everything is done correctly all your compilation issues will go away and the application starts installing in by clicking the small play(run) button in the status bar of the android studio.

10

I strongly recommend to clone the repo you will eliminate lot of manual errors and get this app running in minutes.

Please take a look at this repo for the final code repo and let me know if you face any issues or raise any pull requests for improvements.

https://github.com/saichandu415/Table-Store-Android-Sample

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
9441 0
阿里云服务器ECS远程登录用户名密码查询方法
阿里云服务器ECS远程连接登录输入用户名和密码,阿里云没有默认密码,如果购买时没设置需要先重置实例密码,Windows用户名是administrator,Linux账号是root,阿小云来详细说下阿里云服务器远程登录连接用户名和密码查询方法
11171 0
使用SSH远程登录阿里云ECS服务器
远程连接服务器以及配置环境
2460 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
10828 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,阿里云优惠总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系.
13111 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
4618 0
阿里云ECS云服务器初始化设置教程方法
阿里云ECS云服务器初始化是指将云服务器系统恢复到最初状态的过程,阿里云的服务器初始化是通过更换系统盘来实现的,是免费的,阿里云百科网分享服务器初始化教程: 服务器初始化教程方法 本文的服务器初始化是指将ECS云服务器系统恢复到最初状态,服务器中的数据也会被清空,所以初始化之前一定要先备份好。
6877 0
+关注
芷沁
https://www.alibabacloud.com/blog/
417
文章
1
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载