You are here

Modify your NodeDetailActivity class to add support for tags

The NodeDetailActivity class is where you will need to make most of your changes. You will add and modfy the existing code to retrieve the tags for the selected node. A slight complication is that as the list view where the tags are displayed will be rendered via the main UI thread, you cannot retrieve tags in this thread. This is because retrieving the tags requires a network operation, and in Android this is not permitted in the UI thread. To get around this you will create an AsyncTask, a background thread effectively, that can be used to retrieve the tags for the selected node. Once the tags have been retrieved, and the AsyncTask completes, the UI will be updated. This is done by updating the UI in the onPostExecute method of the AsyncTask - this method only runs after the AsyncTask completes. You could think of the onPostExecute method as a callback. In this task, rather than edit the code piecemeal, the completed code is shown and then explained.
  1. Modify the NodeDetailActivity code so that it matches the following:

                  
    package com.alfresco.tutorials.testapp1;
    
    import java.util.List;
    
    import com.alfresco.tutorials.testapp1.MessageObject;
    import com.alfresco.tutorials.testapp1.R;
    import com.alfresco.tutorials.testapp1.TestApp1Application;
    import com.alfresco.tutorials.testapp1.MainActivity;
    
    import org.alfresco.mobile.android.api.model.Node;
    import org.alfresco.mobile.android.api.model.Tag;
    import org.alfresco.mobile.android.api.services.TaggingService;
    import org.alfresco.mobile.android.api.session.RepositorySession;
    
    import android.os.AsyncTask;
    import android.os.Bundle;
    import android.app.Activity;
    import android.content.Intent;
    import android.util.Log;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.TextView;
    import android.support.v4.app.NavUtils;
    
    public class NodeDetailActivity extends Activity {
    
    	private static final String TAG = "NodeDetailActivity";
    	private Node node;
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_node_detail);
    		// Show the Up button in the action bar.
    		getActionBar().setDisplayHomeAsUpEnabled(true);
    
    		// Get message from intent
    		Intent intent = getIntent();
    
    		Bundle bundle = intent.getExtras();
    
    		MessageObject message = bundle.getParcelable(MainActivity.EXTRA_MESSAGE);
    
    		node = message.getNode();		
    
    		if (node == null){
    			Log.d(TAG, "FATAL ERROR: Node is null!");
    			System.exit(0);
    		}
    		else{
    
    			// We now need to display node details in a UI 
    
    			TextView tv = (TextView) findViewById(R.id.node_name_value);
    			tv.setText((CharSequence)node.getName());
    
    			tv = (TextView) findViewById(R.id.node_title_value);
    			tv.setText((CharSequence)node.getTitle());
    
    			tv = (TextView) findViewById(R.id.node_description_value);
    			tv.setText((CharSequence)node.getDescription());
    
    			tv = (TextView) findViewById(R.id.node_created_by_value);
    			tv.setText((CharSequence)node.getCreatedBy());
    
    			tv = (TextView) findViewById(R.id.node_created_at_value);
    			tv.setText((CharSequence)node.getCreatedAt().getTime().toString());
    
    			tv = (TextView) findViewById(R.id.node_identifier_value);
    			tv.setText((CharSequence)node.getIdentifier());
    
    			tv = (TextView) findViewById(R.id.node_type_value);
    			tv.setText((CharSequence)node.getType());
    
    			if(node.isFolder()){
    				tv = (TextView) findViewById(R.id.node_is_folder_value);
    				tv.setText("True");
    			}
    			else{
    				tv = (TextView) findViewById(R.id.node_is_folder_value);
    				tv.setText("False");
    			}
    
    			if(node.isDocument()){
    				tv = (TextView) findViewById(R.id.node_is_document_value);
    				tv.setText("True");
    			}
    			else{
    				tv = (TextView) findViewById(R.id.node_is_document_value);
    				tv.setText("False");
    			}
    
    			// Support for tags
    			new GetTagsTask().execute();
    		}
    	}
    
    	@Override
    	public boolean onCreateOptionsMenu(Menu menu) {
    		// Inflate the menu; this adds items to the action bar if it is present.
    		getMenuInflater().inflate(R.menu.node_detail, menu);
    		return true;
    	}
    
    	@Override
    	public boolean onOptionsItemSelected(MenuItem item) {
    		switch (item.getItemId()) {
    		case android.R.id.home:
    			// This ID represents the Home or Up button. In the case of this
    			// activity, the Up button is shown. Use NavUtils to allow users
    			// to navigate up one level in the application structure. For
    			// more details, see the Navigation pattern on Android Design:
    			//
    			// http://developer.android.com/design/patterns/navigation.html#up-vs-back
    			//
    			NavUtils.navigateUpFromSameTask(this);
    			return true;
    		}
    		return super.onOptionsItemSelected(item);
    	}
    
    	// get tags in background task and returns a string of tags
    	class GetTagsTask extends AsyncTask<Void, Integer, String> {
    
    		private static final String TAG = "GetTagsTask";
    
    		@Override
    		protected String doInBackground(Void... params) {
    
    			String tagString = "";
    
    			Log.d(TAG, "doInBackground");
    
    			TestApp1Application app = (TestApp1Application) getApplication();
    			RepositorySession session = app.getSession();
    			TaggingService taggingService = session.getServiceRegistry()
    					.getTaggingService();
    			List<Tag> tags = taggingService.getTags(node);
    
    			for (Tag tag : tags){
    				tagString = tagString + tag.getValue() + ", ";
    			}
    
    			Log.d(TAG, "doInBackground Complete");
    			return tagString;
    		}
    
    		@Override
    		protected void onPostExecute(String result) {
    			super.onPostExecute(result);
    			TextView tv = (TextView) findViewById(R.id.node_tags_value);
    			tv.setText(result);			
    		}
    	}
    }
                  
                

    The main revision to the code is the GetTagsTask, which is an AsyncTask. This uses the session object stored in the application context. The application context is retrieved and the session object obtained using the getter method you added to the Application class. Once the session object has been obtained it is possible to retrieve the tagging service. The getsTags(node) method is then called on the tagging service, to retrieve the tags for the specified node. A simple loop then combines the tags into a single string, the tagString variable. This tagString variable is returned from the doInBackground method, and is then passed into the onPostExecute method by the system, when it is called on completion of the GetTagsTask. The text view corresponding to where the tag list will be displayed is then retrieved and updated.

  2. Save all changes and test your application by running it in the usual way.
  3. When the list of nodes is displayed, click on one that has tags applied. You will then see the NodeDetailView, and the list of tags will be displayed as illustrated by the following screenshot: