読者です 読者をやめる 読者になる 読者になる

Androidプログラミングブログ

Androidプログラミングを勉強していく中でわかったことをメモする

【Androidプログラミング入門 #007】ネット上の画像を取得しImageViewに表示する

はじめに

前回記事ではアプリ内の画像をImageViewに表示しました。 android.swift-studying.com

今回はネット上の画像を取得しImageViewに表示します。
ネット上の画像を取得し表示するすには2つのことを学ぶ必要があります。

  1. AsyncTask
  2. HttpURLConnection

AsyncTaskは非同期処理を実行するときに使うクラスです。
Android3.0以上ではインターネットなどネットワーク上に通信する処理をする場合、
メインスレッドで実行すると例外となり、アプリが強制終了されてしまいます。
そのため、AsyncTaskを使った非同期処理を学ぶ必要があります。

HttpURLConnectionはインターネット通信を行うためのクラスです。
画像をインターネット上から取得するので学ぶ必要があります。

1. プロジェクト作成

f:id:fjswkun:20151024130724p:plain

f:id:fjswkun:20151024130817p:plain

f:id:fjswkun:20151024131102p:plain

f:id:fjswkun:20151024130950p:plain

2. 画面レイアウトの作成

content_main.xmlファイルを開き、
プロジェクト作成時に自動的に追加されるTextViewを削除します。
ImageViewを追加する。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:showIn="@layout/activity_main" tools:context=".MainActivity">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/imageView"
        />
</RelativeLayout>

3. インターネット通信を許可する

AndroidManifest.xmlを開き、applicationタグの上に
インターネットアクセス許可を設定する。

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

↓こうなります。

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

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

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

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

4. AsyncTaskを使うクラスの作成

ファイルの作成

AsyncTaskHttpRequestというクラス名にしました。

f:id:fjswkun:20151024141050p:plain

f:id:fjswkun:20151024141115p:plain

実装

作成したファイルの中身を下記のように書き換えます。

package com.swift_studying.sampleinternetimage;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.net.Uri;
import android.widget.ImageView;

public class AsyncTaskHttpRequest extends AsyncTask<Uri.Builder, Void, Bitmap>{
    private ImageView imageView;

    public AsyncTaskHttpRequest(ImageView imageView){
        this.imageView = imageView;
    }

    @Override
    protected Bitmap doInBackground(Uri.Builder... builder){

        // 受け取ったbuilderでインターネット通信する
        // 後で入力する
        
        return bitmap;
    }

    @Override
    protected void onPostExecute(Bitmap result){
        // インターネット通信して取得した画像をImageViewにセットする
        this.imageView.setImageBitmap(result);
    }
}

5. HttpURLConnectionを実装

「2. AsyncTaskを使うクラスの作成」で作成したファイルの

// 受け取ったbuilderでインターネット通信する // 後で入力する

に入力します。

@Override
protected Bitmap doInBackground(Uri.Builder... builder){
    // 受け取ったbuilderでインターネット通信する
    HttpURLConnection connection = null;
    InputStream inputStream = null;
    Bitmap bitmap = null;

    try{

        URL url = new URL(builder[0].toString());
        connection = (HttpURLConnection)url.openConnection();
        connection.setRequestMethod("GET");
        connection.connect();
        inputStream = connection.getInputStream();

        bitmap = BitmapFactory.decodeStream(inputStream);
    }catch (MalformedURLException exception){

    }catch (IOException exception){

    }finally {
        if (connection != null){
            connection.disconnect();
        }
        try{
            if (inputStream != null){
                inputStream.close();
            }
        }catch (IOException exception){
        }
    }

    return bitmap;
}
import文追加

import文に下記追加する。

import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

6. 呼び出し側MainActivityの実装

MainActivityのonCreateメソッドを下記のように入力します。

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

    FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
    fab.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
        }
    });

    ImageView imageView = (ImageView)findViewById(R.id.imageView);

    Uri uri = Uri.parse("http://cdn-ak.f.st-hatena.com/images/fotolife/f/fjswkun/20150927/20150927140905.jpg");
    Uri.Builder builder = uri.buildUpon();
    AsyncTaskHttpRequest task = new AsyncTaskHttpRequest(imageView);
    task.execute(builder);
}

7. 実行

実行します。

f:id:fjswkun:20151024143350p:plain

うまく実行できなかった方はこちらからサンプルをダウンロードして確認してください。 SampleInternetImage.zip - Google ドライブ

参考情報

shirusu-ni-tarazu.hatenablog.jp

Androidアプリ開発逆引きレシピ (PROGRAMMER’S RECiPE)

Androidアプリ開発逆引きレシピ (PROGRAMMER’S RECiPE)

開発用デバイス

Androidの勉強をはじめた人は知っているようにエミュレーターはちょー遅い。
開発用に安いAndroidを買えば、勉強がはかどります!
iPhoneと比較すると安いので買ったほうがいいと思います。

おすすめデバイス

勉強用に使うだけなので価格が高い最新デバイスは必要ないと思います。
最新のデバイスは一人前のAndroidプログラマーになったら購入を検討しましょう。

nexus5 16GBASUS Nexus7 ( 2013 ) TABLET

その他に探すなら↓から。
Android nexus5を勉強用に購入