Android Studio 2.2

%d1%81%d0%bd%d0%b8%d0%bc%d0%be%d0%ba-%d1%8d%d0%ba%d1%80%d0%b0%d0%bd%d0%b0-2016-09-21-%d0%b2-1-16-51

New version of Android Studio published. Following improvements are made:

– New layout editor
– Constraint layout support
– Sample code search
– Instant Run improvement
– APK analyzer
– build cache
– Virtual sensors in emulator
– Espresso Test recorder
– GPU debugger

Happy Android coding =)

Android – How to get tweets JSON from Twitter API?

This code uses this library: Android Asynchronous Http Client

    String url = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=manutd";
    AsyncHttpClient client = new AsyncHttpClient();

    private void getTweets() {

        RequestParams requestParams = new RequestParams();
        requestParams.put("grant_type", "client_credentials");
        AsyncHttpClient httpClient = new AsyncHttpClient();
        httpClient.addHeader("Authorization", "Basic " + Base64.encodeToString((CONSUMER_KEY + ":" + CONSUMER_SECRET).getBytes(), Base64.NO_WRAP));
        httpClient.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
        httpClient.post("https://api.twitter.com/oauth2/token", requestParams, new AsyncHttpResponseHandler() {
            @Override
            public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
                try {
                    JSONObject jsonObject = new JSONObject(new String(responseBody));
                    client.addHeader("Authorization", jsonObject.getString("token_type") + " " + jsonObject.getString("access_token"));
                    client.get(url, handler);
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {

            }

        });
    }

    AsyncHttpResponseHandler handler = new AsyncHttpResponseHandler() {
        @Override
        public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) {
            String json = new String(responseBody);
            int length = json.length();
        }

        @Override
        public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {

        }
    };

Android – How to avoid runtime exception when implementing home button to navigate back?

I faced problem when I tried to implement home button as back button.

        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        getSupportActionBar().setHomeButtonEnabled(true);

That’s why I have removed these two lines, override onOptionsItemSelected method:

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            // Respond to the action bar's Up/Home button
            case android.R.id.home:
                onBackPressed();
                return true;
        }
        return super.onOptionsItemSelected(item);
    }

Now it works without runtime exceptions!

Android – Add content descriptions for accessibility

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   android:orientation="vertical"
   tools:context="com.gayratrakhimov.accessibilitysandbox.MainActivity">

    <Button
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="Hello World!"
       android:contentDescription="Click this button to send email!"/>

    <TextView
       android:text="Banana"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:id="@+id/label"/>

</LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

        TextView label = (TextView) findViewById(R.id.label);
        String contentDescription = "This text was set using code";
        label.setContentDescription(contentDescription);

    }
}

Android – Navigation Drawer Example

menu/activity_main_drawer.xml

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

    <group android:checkableBehavior="single">
        <item
           android:id="@+id/nav_camera"
           android:icon="@drawable/ic_menu_camera"
           android:title="Import" />
        <item
           android:id="@+id/nav_gallery"
           android:icon="@drawable/ic_menu_gallery"
           android:title="Gallery" />
        <item
           android:id="@+id/nav_slideshow"
           android:icon="@drawable/ic_menu_slideshow"
           android:title="Slideshow" />
        <item
           android:id="@+id/nav_manage"
           android:icon="@drawable/ic_menu_manage"
           android:title="Tools" />
    </group>

    <item android:title="Communicate">
        <menu>
            <item
               android:id="@+id/nav_share"
               android:icon="@drawable/ic_menu_share"
               android:title="Share" />
            <item
               android:id="@+id/nav_send"
               android:icon="@drawable/ic_menu_send"
               android:title="Send" />
        </menu>
    </item>

</menu>

nav_main_header.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:layout_width="match_parent"
   android:layout_height="@dimen/nav_header_height"
   android:background="@drawable/side_nav_bar"
   android:gravity="bottom"
   android:orientation="vertical"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   android:theme="@style/ThemeOverlay.AppCompat.Dark">

    <ImageView
       android:id="@+id/imageView"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:paddingTop="@dimen/nav_header_vertical_spacing"
       android:src="@android:drawable/sym_def_app_icon" />

    <TextView
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:paddingTop="@dimen/nav_header_vertical_spacing"
       android:text="Android Studio"
       android:textAppearance="@style/TextAppearance.AppCompat.Body1" />

    <TextView
       android:id="@+id/textView"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:text="android.studio@android.com" />

</LinearLayout>

app_bar_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout 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"
   android:fitsSystemWindows="true"
   tools:context="com.gayratrakhimov.navigationdrawersandbox2.MainActivity">

    <android.support.design.widget.AppBarLayout
       android:layout_width="match_parent"
       android:layout_height="wrap_content"
       android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar
           android:id="@+id/toolbar"
           android:layout_width="match_parent"
           android:layout_height="?attr/actionBarSize"
           android:background="?attr/colorPrimary"
           app:popupTheme="@style/AppTheme.PopupOverlay" />

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

    <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"
       android:paddingBottom="@dimen/activity_vertical_margin"
       android:paddingLeft="@dimen/activity_horizontal_margin"
       android:paddingRight="@dimen/activity_horizontal_margin"
       android:paddingTop="@dimen/activity_vertical_margin"
       app:layout_behavior="@string/appbar_scrolling_view_behavior"
       tools:context="com.gayratrakhimov.navigationdrawersandbox2.MainActivity"
       tools:showIn="@layout/app_bar_main">

        <TextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:text="Hello World!" />
    </RelativeLayout>

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

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout 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:id="@+id/drawer_layout"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:fitsSystemWindows="true"
   tools:openDrawer="start">

    <include
       layout="@layout/app_bar_main"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />

    <android.support.design.widget.NavigationView
       android:id="@+id/nav_view"
       android:layout_width="wrap_content"
       android:layout_height="match_parent"
       android:layout_gravity="start"
       android:fitsSystemWindows="true"
       app:headerLayout="@layout/nav_header_main"
       app:menu="@menu/activity_main_drawer" />

</android.support.v4.widget.DrawerLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity
        implements NavigationView.OnNavigationItemSelectedListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
                this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
        drawer.setDrawerListener(toggle);
        toggle.syncState();

        NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
        navigationView.setNavigationItemSelectedListener(this);
    }

    @Override
    public void onBackPressed() {
        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        if (drawer.isDrawerOpen(GravityCompat.START)) {
            drawer.closeDrawer(GravityCompat.START);
        } else {
            super.onBackPressed();
        }
    }

    @SuppressWarnings("StatementWithEmptyBody")
    @Override
    public boolean onNavigationItemSelected(MenuItem item) {
        // Handle navigation view item clicks here.
        int id = item.getItemId();

        if (id == R.id.nav_camera) {
            // Handle the camera action
        } else if (id == R.id.nav_gallery) {

        } else if (id == R.id.nav_slideshow) {

        } else if (id == R.id.nav_manage) {

        } else if (id == R.id.nav_share) {

        } else if (id == R.id.nav_send) {

        }

        DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
        drawer.closeDrawer(GravityCompat.START);
        return true;
    }
}

Android – Recycler View Example

build.gradle

compile 'com.android.support:recyclerview-v7:24.0.0'

item.xml

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

    <TextView
       android:id="@+id/title"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content"
       android:textSize="30sp" />

    <TextView
       android:id="@+id/author"
       android:layout_width="wrap_content"
       android:layout_height="wrap_content" />

</LinearLayout>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context="com.gayratrakhimov.recyclerviewsandbox.MainActivity">

    <android.support.v7.widget.RecyclerView
       android:id="@+id/rv"
       android:layout_width="match_parent"
       android:layout_height="match_parent" />

</RelativeLayout>

Book.java

public class Book {

    String title;
    String author;

    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }

}

MyAdapter.java

public class MyAdapter extends RecyclerView.Adapter<MyAdapter.PersonViewHolder> {

    public static class PersonViewHolder extends RecyclerView.ViewHolder {

        TextView title;
        TextView author;

        PersonViewHolder(View itemView) {
            super(itemView);
            title = (TextView)itemView.findViewById(R.id.title);
            author = (TextView)itemView.findViewById(R.id.author);
        }
    }

    List<Book> books;

    MyAdapter(List<Book> books){
        this.books = books;
    }

    @Override
    public void onAttachedToRecyclerView(RecyclerView recyclerView) {
        super.onAttachedToRecyclerView(recyclerView);
    }

    @Override
    public PersonViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.item, viewGroup, false);
        PersonViewHolder pvh = new PersonViewHolder(v);
        return pvh;
    }

    @Override
    public void onBindViewHolder(PersonViewHolder personViewHolder, int i) {
        personViewHolder.title.setText(books.get(i).title);
        personViewHolder.author.setText(books.get(i).author);
    }

    @Override
    public int getItemCount() {
        return books.size();
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

    private List<Book> books;
    private RecyclerView rv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        rv=(RecyclerView)findViewById(R.id.rv);

        LinearLayoutManager llm = new LinearLayoutManager(this);
        rv.setLayoutManager(llm);
        rv.setHasFixedSize(true);

        List<Book> books = new ArrayList<>();
        books.add(new Book("Alchemist", "Paulo Coelho"));
        books.add(new Book("War and Peace", "Leo Tolstoy"));
        books.add(new Book("Farhod and Shirin", "Alisher Navai"));

        MyAdapter adapter = new MyAdapter(books);
        rv.setAdapter(adapter);
    }

}

Screenshot_20160824-101529

Android – Menu example

menu/main.xml

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

    <item
        android:id="@+id/start"
        android:icon="@drawable/ic_play_circle_filled_white_24dp"
        android:orderInCategory="1"
        android:title="Start"
        app:showAsAction="always"></item>
    <item
        android:id="@+id/pause"
        android:icon="@drawable/ic_pause_circle_filled_white_24dp"
        android:orderInCategory="2"
        android:title="Pause"
        app:showAsAction="always"></item>

</menu>
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.start:

                break;
            case R.id.pause:

                break;
        }
        return true;
    }

Android – SimpleAdapter using Map

        for (Sensor sensor: sensorList) {
            Map<String, String> data = new HashMap<String, String>();
            data.put("name", sensor.getName());
            data.put("vendor", sensor.getVendor());
            sensorData.add(data);
        }


        SimpleAdapter sa = new SimpleAdapter(this, sensorData, android.R.layout.simple_list_item_2, new String[]{"name", "vendor"}, new int[]{android.R.id.text1, android.R.id.text2});

        ListView lv = (ListView) findViewById(R.id.sensorList);
        lv.setAdapter(sa);

Service (Associate Android Developer Certification)

Service works in background, used for long time operations. It has 3 lifecycle methods: onCreate(), onStartCommand(), onDestroy();
In order to start and stop service: you can use startService() and stopService() methods. Or you can use startSelf() and stopSelf() methods inside service.
If you want to interact with service you can use bindService() and unbindService() methods. When you bindService(), if service is not running, it will start.
If you want to connect to service from another application, you can use following methods:

  • IBinder onBind(Intent intent)
  • onUnbind(Intent intent)
  • onRebind(Intent intent)
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return Service.START_STICKY;
}

START_NOT_STICKY – service won’t be restarted after stopped by system
START_STICKY – service will be restarted after stopped by system
START_REDLIVER_INTENT – service wil be restarted after stopped by system. receives all startService calls.

Example:

PlayService.java

public class PlayService extends Service
{
    MediaPlayer mPlayer;
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate()
    {
        Toast.makeText(this, "Служба создана",
            Toast.LENGTH_SHORT).show();
        mPlayer = MediaPlayer.create(this, R.raw.zara);
        mPlayer.setLooping(false);
    }

    @Override
    public void onStart(Intent intent, int startid)
    {
        Toast.makeText(this, "Служба запущена",
            Toast.LENGTH_SHORT).show();
        mPlayer.start();
    }
   
    @Override
    public void onDestroy()
    {
        Toast.makeText(this, "Служба остановлена",
            Toast.LENGTH_SHORT).show();
        mPlayer.stop();
    }
}

MainActivity.java

public class MainActivity extends AppCompatActivity {

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

        final Button btnStart = (Button) findViewById(R.id.btn_start);
        final Button btnStop = (Button) findViewById(R.id.btn_stop);

        btnStart.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                startService(new Intent(MainActivity.this, PlayService.class));
            }
        });

        btnStop.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                stopService(new Intent(MainActivity.this, PlayService.class));
            }
        });
    }
}

AndroidManifest.xml

        <service
           android:enabled="true"
           android:name=".PlayService">
        </service>

How to start service on boot completed:

public class BootBroadcast extends BroadcastReceiver {
 
    @Override
    public void onReceive(Context context, Intent intent) {      
        context.startService(new Intent(context, TestService.class));
    }
}
<receiver android:name=".BootBroadcast">  
    <intent-filter >
        <action android:name="android.intent.action.BOOT_COMPLETED"/>              
    </intent-filter>
</receiver>

How to get list of running services?

ActivityManager am = (ActivityManager) this
        .getSystemService(ACTIVITY_SERVICE);
List<ActivityManager.RunningServiceInfo> rs = am.getRunningServices(50);

for (int i = 0; i < rs.size(); i++) {
    ActivityManager.RunningServiceInfo rsi = rs.get(i);
    Log.i("Service", "Process " + rsi.process + " with component "
            + rsi.service.getClassName());
}

Source