Saturday, December 20, 2014

Samsung Look Package - Some Fundamentals

Again, based on the fact that the Samsung SmartApp Challenge  that has already begun on the 5th of September and is going on currently with the last date of submission being 30th Nov 2013, which expects the use of the pen package and the look package, this is the promised article on the look package. Let us start from some fundamentals.

First, What is Look?

From the last 3 articles, we have seen that Samsung Mobile SDK is a SDK that brings 10 different small packages together into one SDK to ease the developers world. Look is a java package available as part of that same Samsung Mobile SDK. It is a package that provides specialized widgets for additional functions beyond what the Android Views already provide. And of course it builds on what the pen package already provides. In fact, Look requires that S Pen be used to access its features.

Next, then, what are the functions Look provides?

It supports
  • ·      WritingBuddy – This basically helps by giving an editor when a S Pen comes closer to an area that can take an input from the pen. The user can write in this editor, which would then by recognized by the WritingBuddy and converted into a digital format for further usage! 

Quite a useful feature considering that the S Pen would lead to a lot of apps that would take a written input but the UI should still be compact with out having large canvases occupying the UI for pen inputs. 

     
      This can be used with on any view layouts and in TextEdit. WritingBuddy recognizes numbers and alpahabets and even handwriting images which would lead to usages like signature recognition etc.

  • ·      AirButton – I see this feature as an advanced context sensitive menu! A set of items or images or what ever may be relevant to a particular context can be shown using an air button. 

The wow factor in this is you can creatively define the gravity, the direction and the display type making it look like a feature that was always needed but not invented till now!

Based on the user selection of a menu item / a recent item display there, the next set of actions can be invoked.


  • ·      SmartClip – As the name says, SmartClip is indeed a smart clipboard, which does not just capture the selected content, but also the metadata related to the content! This metadata is converted to text that can be searched on or sent to other applications for further use.  
This is certainly an interesting feature that can be used very imaginatively to provide seamless copy and paste options between various apps and also help in capturing related content. 

This feature would look more magical especially when there is metadata available with the content captured. For example, if there are URLs that are part of the content that is captured, the SmartClip can capture data from the URL too and send it to the destination app.

  • ·      PointerIcon – This is a good to have feature – something that is taken for granted in many desktop apps but has found its way into a mobile through this package! 
This allows you to modify the look of the pointer when you place an S Pen on a view. 


The Look Package Architecture

This diagram is taken from the Samsung documentation.

Lot of custom apps can be developed using the look package and as you see the look package is mainly an extension to the Android View package.

The Development environment

In order to develop an app that uses the look package and support all of the above-mentioned features, you need to download the complete Samsung Mobile SDK which can be downloaded independently or through an eclipse. Both ways of downloading the SDK and setting up the Development environment are described here


Once the SDK is downloaded, the contents of the SDK are as shown:

The libs folder has all the 10 different packages that I have detailed out in my earlier post. Each of the folders has the respective library jars along with the basic Samsung mobile SDK.

These jars are to be copied into the libs folder of your project trying to develop using a look feature.

Now, let us see a very simple example that changes the pointer icon when the pen hovers over a TextView. On the click of a button, the icon changes.

The 3 member variables created are:
private boolean mIsDefault false;
private TextView mHoverTextView;
private SlookPointerIcon mPointerIcon new SlookPointerIcon();
With in the onCreate() method,

//get a handle to the button
Button changeIcon = (Button)findViewById(R.id.btn_changeicon);
//get a handle to the text view
mHoverTextView = (TextView)findViewById(R.id.text_hoverarea);
// set the hover icon
mPointerIcon.setHoverIcon(mHoverTextView, getResources()
.getDrawable(R.drawable.ic_launcher));
//On click of the button, change the icon
changeIcon.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
if (mIsDefault) {
mPointerIcon.setHoverIcon(mHoverTextView,getResources().getDrawable(R.drawable.ic_launcher)); mIsDefault =false;
((Button) v).setText("Turn off");
else {
mPointerIcon.setHoverIcon(mHoverTextView, null); mIsDefault =true;((Button) v).setText("Turn on");
}
  }
});
As simple as this, you can change the pointer icon!!
Similarly you can work with the WritingBuddy or the AirButton and the SmartClip. The samples in the downloaded SDK are a good guide to go by.

Google Play Services 6.5

oogle Play services 6.5 includes new features in Google Maps, Google Drive and Google Wallet as well as the recently launched Google Fit API. Also providing developers with more granular control over which Google Play services APIs your app depends on to help you maintain a lean app.

Thursday, December 18, 2014

ListView with EditText


InSide ListView :   android:descendantFocusability="beforeDescendants"


row xml :


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:background="@color/white"
    android:orientation="horizontal" >

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:orientation="vertical" >

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/row_renew_tran_txtSSCode"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:singleLine="true"
                android:text="SS Code"
                android:textColor="@color/black"
                android:textSize="22sp" />

            <ImageView
                android:layout_width="0.5px"
                android:layout_height="fill_parent"
                android:background="@color/blue" />

            <TextView
                android:id="@+id/row_renew_tran_txtUID"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:singleLine="true"
                android:text="uID"
                android:textColor="@color/blue"
                android:textSize="17sp" />
        </LinearLayout>

        <ImageView
            android:layout_width="fill_parent"
            android:layout_height="0.5px"
            android:background="@color/blue" />

        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal" >

            <TextView
                android:id="@+id/row_renew_tran_txtInstAmt"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="Inst Amt."
                android:textColor="@color/blue"
                android:textSize="17sp" />

            <ImageView
                android:layout_width="0.5px"
                android:layout_height="fill_parent"
                android:background="@color/blue" />

            <TextView
                android:id="@+id/row_renew_tran_txtDueAmt"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:gravity="center"
                android:text="Due Amt."
                android:textColor="@color/blue"
                android:textSize="17sp" />
        </LinearLayout>
    </LinearLayout>

    <ImageView
        android:layout_width="1px"
        android:layout_height="fill_parent"
        android:background="@color/blue" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:layout_weight="2.5"
        android:orientation="vertical" >

        <EditText
            android:id="@+id/row_renew_tran_edtTranAmt"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="@android:drawable/editbox_background_normal"
            android:gravity="right|center_vertical"
            android:imeOptions="actionNext"
            android:inputType="number"
            android:singleLine="true"
            android:textColor="@color/black"
            android:textSize="22sp" />
    </LinearLayout>

</LinearLayout>


In Adapter :



final ViewHolder holder;
View rowView = convertView;

if (rowView == null) {
holder = new ViewHolder();
rowView = inflater.inflate(R.layout.row_renew_tran, null);
holder.txtSSCode = (TextView) rowView.findViewById(R.id.row_renew_tran_txtSSCode);
holder.txtUID = (TextView) rowView.findViewById(R.id.row_renew_tran_txtUID);
holder.txtInstAmt = (TextView) rowView.findViewById(R.id.row_renew_tran_txtInstAmt);
holder.txtDueAmt= (TextView) rowView.findViewById(R.id.row_renew_tran_txtDueAmt);
holder.edtTranAmt = (EditText) rowView.findViewById(R.id.row_renew_tran_edtTranAmt);

holder.txtSSCode.setTag(position);
holder.edtTranAmt.setTag(holder.edtTranAmt);
rowView.setTag(holder);

} else {
holder = (ViewHolder) rowView.getTag();
}
final ReNewTranModel model = arrayList.get(position);
try {
holder.txtSSCode.setText(model.getSSCode());
holder.txtUID.setText(String.valueOf(model.getUID()));
holder.txtInstAmt.setText(String.valueOf(model.getInstAmt()));
holder.txtDueAmt.setText(String.valueOf(model.getDueAmt()));

if(model.getTranAmt() > 0)
holder.edtTranAmt.setText(String.valueOf(model.getTranAmt()));
else
holder.edtTranAmt.setText("");
} catch (Exception e) {
e.printStackTrace();
}

int tag_position=(Integer) holder.txtSSCode.getTag();
holder.txtSSCode.setId(tag_position);

holder.edtTranAmt.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {

 final int position2 = holder.txtSSCode.getId();
                  final EditText Caption = (EditText) holder.edtTranAmt;
                  if(Caption.getText().toString().length()>0){
                   arrayList.get(position2).setTranAmt(Integer.valueOf(Caption.getText().toString()));
                  }
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});

holder.edtTranAmt.setOnEditorActionListener(
       new EditText.OnEditorActionListener() {
           @Override
           public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            if (actionId == EditorInfo.IME_ACTION_NEXT
                &&  position != arrayList.size() - 1) {
                     final EditText Caption = (EditText) holder.edtTranAmt.getTag();
                     Caption.postDelayed(new Runnable() {
                         public void run() {
                         EditText nextField = (EditText)Caption.focusSearch(View.FOCUS_DOWN);
                             if(nextField != null) {
                                 nextField.requestFocus();
                             }
                         }
                     }, 200);
                   return false;
               }else if (actionId == EditorInfo.IME_ACTION_NEXT &&
                (position == arrayList.size() - 1) ) {
                mUpdateTotalValue.onUpdateResult();
                InputMethodManager imm =
                   (InputMethodManager)mContext.getSystemService(Context.INPUT_METHOD_SERVICE);
                imm.hideSoftInputFromWindow(holder.edtTranAmt.getWindowToken(), 0);
                return false;
               }else if (actionId == EditorInfo.IME_ACTION_DONE ) {
                return false;
               }
               return false;
             
               /*if (actionId == EditorInfo.IME_ACTION_NEXT ) {
                try {
model.setTranAmt(Integer.valueOf(holder.edtTranAmt.getText().toString()));
notifyDataSetChanged();
mUpdateTotalValue.onUpdateTotal(position, Integer.valueOf(holder.edtTranAmt.getText().toString()));
} catch (NumberFormatException e) {
e.printStackTrace();
}
holder.edtTranAmt.clearFocus();
holder.edtTranAmt.requestFocus();
                   return true;
               }
               return false;*/
           }
       });
/*holder.edtTranAmt.setOnFocusChangeListener(new OnFocusChangeListener() {
            public void onFocusChange(View v, boolean hasFocus) {
            Log.e("", "onFocusChange "+hasFocus+ " name " +model.getSSCode());
                if (!hasFocus){
//                    final int position = v.getId();
                    final EditText caption = (EditText) v;
                    holder.edtTranAmt.setText(caption.getText().toString());
                    try {
if(caption.getText().toString().trim().length() >0){
   model.setTranAmt(Integer.valueOf(caption.getText().toString()));
notifyDataSetChanged();
mUpdateTotalValue.onUpdateTotal(position, Integer.valueOf(holder.edtTranAmt.getText().toString()));
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
                }
            }
        });*/
return rowView;

Thursday, November 27, 2014

Intro To Material Design


These days, UI designers need to be thinking about phones, tablets, laptops, TVs, smartwatches, and beyond. In this DesignByte talk about how Google designers have been working on making cross-platform and multi-screen design easier. We wanted to build a design system that felt at home on every screen, from the smallest watch to the largest TV.

DesignBytes: Intro To Material Design

App Indexing for Google Search



The App Indexing API provides a way for developers to notify Google about deep links in their native apps and allows the Google app, version 3.6 and above, to drive re-engagement through Google Search query autocompletions, providing fast and easy access to inner pages in apps. The deep links reported using the App Indexing API are also used by Google to index app content and are surfaced in Google Search results.

In this video, product manager Lawrence Chang presents an overview of the new App Indexing API for Android that lets you specify links -- through your app itself -- for App Indexing. It also gives you a way to re-engage users through Google Search App autocompletions. We'll provide step-by-step guidelines for how to get started. Take a few minutes and find out how to increase user engagement using the App Indexing API.
 

Visit: https://developers.google.com/app-indexing/

Html.ImageGetter load image from internet, in AsyncTask

This example code use Html.ImageGetter load image from internet, in AsyncTask, to solve error of android.os.NetworkOnMainThreadException in the old example Html.ImageGetter load image from internet.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
package com.example.androidhtmltextview;
 
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
 
import android.support.v7.app.ActionBarActivity;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.os.Bundle;
import android.widget.TextView;
import android.widget.Toast;
 
public class MainActivity extends ActionBarActivity {
 
 public class HttpGetDrawableTask extends AsyncTask<String, Void, Drawable> {
 
  TextView taskTextView;
  String taskHtmlString;
 
  HttpGetDrawableTask(TextView v, String s) {
   taskTextView = v;
   taskHtmlString = s;
  }
 
  @Override
  protected Drawable doInBackground(String... params) {
   Drawable drawable = null;
   URL sourceURL;
   try {
    sourceURL = new URL(params[0]);
    URLConnection urlConnection = sourceURL.openConnection();
    urlConnection.connect();
    InputStream inputStream = urlConnection.getInputStream();
    BufferedInputStream bufferedInputStream = new BufferedInputStream(
      inputStream);
    Bitmap bm = BitmapFactory.decodeStream(bufferedInputStream);
 
    // convert Bitmap to Drawable
    drawable = new BitmapDrawable(getResources(), bm);
 
    drawable.setBounds(0, 0, bm.getWidth(), bm.getHeight());
 
   } catch (MalformedURLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   } catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
 
   return drawable;
  }
 
  @Override
  protected void onPostExecute(Drawable result) {
 
   final Drawable taskDrawable = result;
 
   if (taskDrawable != null) {
    taskTextView.setText(Html.fromHtml(taskHtmlString,
     new Html.ImageGetter() {
 
      @Override
      public Drawable getDrawable(String source) {
       return taskDrawable;
      }
     }, null));
   }
 
  }
 
 }
 
 TextView htmlTextViewRemote;
 
 String htmlStringRemote = "Image load from internet"
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
 
  htmlTextViewRemote = new TextView(this);
  setContentView(htmlTextViewRemote);
 
  htmlTextViewRemote.setText(Html.fromHtml(htmlStringRemote,
   new Html.ImageGetter() {
 
    @Override
    public Drawable getDrawable(String source) {
 
     Toast.makeText(getApplicationContext(), source,
       Toast.LENGTH_LONG).show();
 
     HttpGetDrawableTask httpGetDrawableTask = new HttpGetDrawableTask(
       htmlTextViewRemote, htmlStringRemote);
     httpGetDrawableTask.execute(source);
 
     return null;
    }
 
   }, null));
 
  htmlTextViewRemote.setMovementMethod(LinkMovementMethod.getInstance());
 
 }
 
}

In order to load image from internet, permission of "android.permission.INTERNET" have to be added in AndroidManifest.xml.