スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

Android: 平凡クラスでアクティビティ

 自分のはまったこと、それは、
  • Googleアカウントの利用認証画面を表示させたい
    → メインアクティビティの直下で実施し、無事成功
  • その機能(認証画面の表示)を外に出したい(クラス化したい)
    → 認証画面を表示させるところで、エラーになる
  • 別画面を表示させなくても、「this」とかを使うもの(AccountManagerとか)でもエラーになる
この問題は、簡単なところで言うと、平凡クラスでトースト(toast:ぼーっと出てくる、中途半端なダイアログボックスみたいなやつ)するときなんかですかね。

エラーのポイントは、「別の画面を出すときは、コンテキストを渡してあげなきゃいけない」ということでした。
メインアクティティの直下で実施するときは、単に“this”としてあげればよかったんですが、別のクラスに持っていった場合、自分はアクティビティじゃないので、thisじゃ動きません。
ちなみに、“別の画面をだす”というのは、インテントという機能を使います。


以下のサンプルは、「メインアクティビティ以外のところ(別のクラス)で、Googleアカウントのログイン認証画面を表示させる」ものです。
-----------------------------------------------
1.プロジェクトの新規作成
-----------------------------------------------
Eclipseで、プロジェクトを新規作成します。
ちなみに、私は以下の設定で作りました。
  • Target Name:Google APIs(Platform=8)
  • アプリケーション名:TestContext
  • パッケージ名:com.fxscore.testcontext
  • Activity名:TestContextActivity
  • Minimum SDK:8
-----------------------------------------------
2.パーミッションの追加
-----------------------------------------------
サンプルなのでそこまでする必要もなかったのですが、せっかくなので「Googleアカウントの利用許可」画面を出す風なサンプルにしました。
そのために、以下のパーミッションをマニュフェストに記述する必要があります。
AndroidManifest.xmlに、以下のパーミッションを追加してください。
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
-----------------------------------------------
3.クラスの追加
-----------------------------------------------
左のパッケージエクスプローラで、「TestContext->src->com.fxscore.testcontextを右クリック->New->Class」として、クラスを作りましょう。
私は、クラス名を「TestClass」としました。
そして、以下のようなプログラムを記述してください。
このプログラムのミソは、「コンストラクタ」。変数名では「context」。
コンストラクタ=クラスの初期化時に、context=このアプリの親玉の居場所みたいな変数に値を入れてあげることです。
実際には、以下の4番で親玉がこのクラスを呼んでいます。
あとは、「AccountManager.get(context)」や「Toast」、「startActivity(intent)」で、親玉の居場所をAndroidに渡しながら処理を進めていってます。
package com.fxscore.testcontext;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
public class TestClass {
Context context ;
TestClass(Context context){
this.context = context ;
}
public void test(){
   // Googleアカウントの検索
AccountManager mAccountManager = null;
if (mAccountManager == null) mAccountManager = AccountManager.get(context);
Account[] accounts = null;
accounts = mAccountManager.getAccountsByType("com.google");
mAccountManager.getAuthToken(accounts[0], "cl", false, new GetAuthTokenCallback(), null);
}
private class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
@Override
public void run(AccountManagerFuture<Bundle> arg0) {
Bundle bundle;
try {
bundle = arg0.getResult();
Intent intent = (Intent) bundle.get(AccountManager.KEY_INTENT);
context.startActivity(intent); //許可画面を出す
} catch (Exception e) {
Toast.makeText(context, "Error !", Toast.LENGTH_LONG).show();
}
}
}
-----------------------------------------------
4.テインアクティビティ(親玉)への追記
-----------------------------------------------
クラスを初期化し、test関数を呼び出します。
OnCreateの中に、以下の2文を追記してください。
親玉=このアプリのメインアクティビティが、自分の居場所(this)をクラスに教えてあげてるといった感じです。
        TestClass test = new TestClass(this);
        test.test();
以上で、外出しされた平凡クラスでも、ウィンドウを出したりトーストしたりといったことができるようになります。
■■■■■■■■■■■■■■■■■■■■■■■
 Sample Program(OnCreate)
■■■■■■■■■■■■■■■■■■■■■■■
package com.fxscore.testcontext;
import android.app.Activity;
import android.os.Bundle;
public class TestContextActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        TestClass test = new TestClass(this);
        test.test();
    }
}
■■■■■■■■■■■■■■■■■■■■■■■
 Sample Program(TestClass)
■■■■■■■■■■■■■■■■■■■■■■■
package com.fxscore.testcontext;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Toast;
public class TestClass {
Context context ;
TestClass(Context context){
this.context = context ;
}
public void test(){
   // Googleアカウントの検索
AccountManager mAccountManager = null;
if (mAccountManager == null) mAccountManager = AccountManager.get(context);
Account[] accounts = null;
accounts = mAccountManager.getAccountsByType("com.google");
mAccountManager.getAuthToken(accounts[0], "cl", false, new GetAuthTokenCallback(), null);
}
private class GetAuthTokenCallback implements AccountManagerCallback<Bundle> {
@Override
public void run(AccountManagerFuture<Bundle> arg0) {
Bundle bundle;
try {
bundle = arg0.getResult();
Intent intent = (Intent) bundle.get(AccountManager.KEY_INTENT);
context.startActivity(intent); //許可画面を出す
} catch (Exception e) {
                Toast.makeText(context, "Error !", Toast.LENGTH_LONG).show();
}
}
}
■■■■■■■■■■■■■■■■■■■■■■■
 Sample Program(AndroidManifest.xml)
■■■■■■■■■■■■■■■■■■■■■■■
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.fxscore.testcontext"
    android:versionCode="1"
    android:versionName="1.0" >
    <uses-sdk android:minSdkVersion="8" />
    
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.USE_CREDENTIALS"/>
    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:name=".TestContextActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>
スポンサーサイト

トラックバック

コメント

コメントを残す

Secret



上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。