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

あらいの履歴書

プログラマー志望、文系大学生が、プログラミング・ランニング・就活について発信

Android ~Activity を Fragment にする~

こんにちは。新しい方のあらいではなく、荒れてる方のあらいです。



今日は、歩数計アプリの、Main となるActivity を Fragment に直してみました。



いくつかエラーが出たので、1つ1つどのように直したのか、書こうと思います。



まずは、直す前のActivity

public class WalkMeterActivity extends Activity implements OnClickListener {
    private TextView mSensorTextView;
    private TextView mSensorTextView2;

    private Button mStartButton;
    private Button mStopButton;
    
    WalkMeterSQLiteOpenHelper db;

    
 private class WalkMeterReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction() == WalkMeterService.ACTION) {
                screenDisplay();
            }
        }
    }

    private WalkMeterService mWalkMeterService;

    private final WalkMeterReceiver mWalkMeterReceiver = new WalkMeterReceiver();

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            mWalkMeterService = ((WalkMeterService.WalkMeterBinder)service).getService();
            startDisplay();
        }

        @Override
        public void onServiceDisconnected(ComponentName className) {
            mWalkMeterService = null;
        }
    };
    
    
    //Preferenceの値
    
    private SharedPreferences preference;
    
    private Editor editor;
    

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mSensorTextView = (TextView)findViewById(R.id.text_sensor);
        mSensorTextView2 = (TextView)findViewById(R.id.text_sensor_distance);
        mStartButton = (Button)findViewById(R.id.button_start);
        mStopButton = (Button)findViewById(R.id.button_stop);
        mStartButton.setOnClickListener(this);
        mStopButton.setOnClickListener(this);
        
        db = new WalkMeterSQLiteOpenHelper(this);
        
        //プリファレンスの準備
        preference = getSharedPreferences("name_and_height", MODE_PRIVATE);
        editor = preference.edit();
        
      //初回起動だけの処理
        if(preference.getBoolean("Launched", false)==false){
        Intent intent = new Intent();
        intent.setClassName("com.notnewarai.walkmeter","com.notnewarai.walkmeter.FirstSetting");
        startActivity(intent);
       
        //Launchedの書き換え(2回目以降は、設定しなくてもいいように)
        editor.putBoolean("Launched", true);
        editor.commit();
       
        }
    }

    @Override
    public void onResume() {
        startService(new Intent(this, WalkMeterService.class));
        registerReceiver(mWalkMeterReceiver, new IntentFilter(WalkMeterService.ACTION));
        bindService(new Intent(this, WalkMeterService.class), mServiceConnection,
                Context.BIND_AUTO_CREATE);
        super.onResume();
    }

    public void startDisplay() {
        if (mWalkMeterService.getState()) {
            screenDisplay();
        }
    }

    public void screenDisplay() {
        mSensorTextView.setText(mWalkMeterService.getCounter() + getString(R.string.label_counter));
        
        mSensorTextView2.setText(calcDistance(mWalkMeterService.getCounter()) + getString(R.string.label_counter2));
        
        /* getHistoryStepsがうまくいかないので、コメントアウト
        if(calcDistance(mWalkMeterService.getCounter()+db.getAllHistorySteps()) >= 2400 ){
       
       
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("ゴール!!")
        .setMessage("おめでとうー。")
        .show();
        }
        
        */
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        db.close();
        unbindService(mServiceConnection); 
        unregisterReceiver(mWalkMeterReceiver);
        if (!mWalkMeterService.getState())
            mWalkMeterService.stopSelf();

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.button_start:
                if (mWalkMeterService.getState())
                    return;
                mWalkMeterService.startCount();
                break;
        case R.id.button_stop:
                if (!mWalkMeterService.getState())
                    return;
                mWalkMeterService.stopCount();
                break;
        }
    }
    
    
    public double calcDistance(int counter){
   
    double km_distance = counter * getHeight(this) * 0.45 / 100000;
   
    BigDecimal bd_km_distance = new BigDecimal(km_distance);
   
    BigDecimal down_bd_km_distance = bd_km_distance.setScale(1, BigDecimal.ROUND_DOWN);
   
    double distance = down_bd_km_distance.doubleValue();
   
    return distance;
    }
    
    public int getHeight(Context context){
    SharedPreferences pref = context.getSharedPreferences( "name_and_height", Context.MODE_PRIVATE );
   
    String strHeight = pref.getString("user_height", "-1");
   
    return Integer.parseInt(strHeight);
    }
    
}




エラー


  • setContentView(R.layout.main);
  • findViewByIdの箇所
  • db = new WalkMeterSQLiteOpenHelper(this); のような、this など Contextを使っている箇所
  • Preference
  • startService(new Intent(this, WalkMeterService.class)); のような、サービスに関係する箇所




先に、直し終えたFragmentのコードです。



public class WalkMeterFragment extends Fragment implements OnClickListener {
    private TextView mSensorTextView;
    private TextView mSensorTextView2;

    private Button mStartButton;
    private Button mStopButton;
    
    WalkMeterSQLiteOpenHelper db;

    
 private class WalkMeterReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction() == WalkMeterService.ACTION) {
                screenDisplay();
            }
        }
    }

    private WalkMeterService mWalkMeterService;

    private final WalkMeterReceiver mWalkMeterReceiver = new WalkMeterReceiver();

    private ServiceConnection mServiceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName className, IBinder service) {
            mWalkMeterService = ((WalkMeterService.WalkMeterBinder)service).getService();
            startDisplay();
        }

        @Override
        public void onServiceDisconnected(ComponentName className) {
            mWalkMeterService = null;
        }
    };
    
    
    //Preferenceの値
    
    private SharedPreferences preference;
    
    private Editor editor;
    

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        
        View view =inflater.inflate(R.layout.walkmeterfragment, container, false);
        
        mSensorTextView = (TextView)view.findViewById(R.id.text_sensor);
        mSensorTextView2 = (TextView)view.findViewById(R.id.text_sensor_distance);
        mStartButton = (Button)view.findViewById(R.id.button_start);
        mStopButton = (Button)view.findViewById(R.id.button_stop);
        mStartButton.setOnClickListener(this);
        mStopButton.setOnClickListener(this);
        
        
        return view;
    }
    
    @Override
    public void onAttach(Activity act){
        super.onAttach(act);
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        
        
        
        db = new WalkMeterSQLiteOpenHelper((MainActivity)getActivity()); 
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
      super.onActivityCreated(savedInstanceState);
     
      
    }

    @Override
    public void onResume() {
        getActivity().startService(new Intent(getActivity(), WalkMeterService.class));
        getActivity().registerReceiver(mWalkMeterReceiver, new IntentFilter(WalkMeterService.ACTION));
        getActivity().bindService(new Intent(getActivity(), WalkMeterService.class), mServiceConnection,
                Context.BIND_AUTO_CREATE);
        super.onResume();
    }

    public void startDisplay() {
            if (mWalkMeterService.getState()) {
            screenDisplay();
        }
    }

    public void screenDisplay() {
        mSensorTextView.setText(mWalkMeterService.getCounter() + getString(R.string.label_counter));
        
        mSensorTextView2.setText(calcDistance(mWalkMeterService.getCounter()) + getString(R.string.label_counter2));
        
        
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        db.close();
        getActivity().unbindService(mServiceConnection); 
        getActivity().unregisterReceiver(mWalkMeterReceiver);
        if (!mWalkMeterService.getState())
            mWalkMeterService.stopSelf();

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.button_start:
                if (mWalkMeterService.getState())
                    return;
                mWalkMeterService.startCount();
                break;
        case R.id.button_stop:
                if (!mWalkMeterService.getState())
                    return;
                mWalkMeterService.stopCount();
                break;
        }
    }
    
    
    public double calcDistance(int counter){
        
        
        

        
        
        double km_distance = counter * getHeight((MainActivity)getActivity()) * 0.45 / 100000;
        
        BigDecimal bd_km_distance = new BigDecimal(km_distance);
        
        BigDecimal down_bd_km_distance = bd_km_distance.setScale(1, BigDecimal.ROUND_DOWN);
        
        double distance = down_bd_km_distance.doubleValue();
        
        return distance;
    }
    
    public int getHeight(Context context){
        SharedPreferences pref = context.getSharedPreferences( "name_and_height", Context.MODE_PRIVATE );
        
        String strHeight = pref.getString("user_height", "-1");
        
        return Integer.parseInt(strHeight);
    }
    
}




どのように変更したか


  • setContentView → onCreateViewメソッドを作成
  • findViewById → view.findViewById にする
  • db = new WalkMeterSQLiteOpenHelper(this); のthis → getActivity() にする 
  • Preference → Fragmentから消し去り、Tabを管理する MainActivity の onCreate に移す
  • startService(new Intent(this, WalkMeterService.class)); → getActivity().startService ・・・ のように先頭にgetActivity()をつける




以上、AcitivityをFragment に直す際に出たエラーと、解決策でした!



ありがとうございました。また今度!





(最近、運動にハマってきました・・・。目指せ逆三角形!ww)

Android -歩数計使ったアプリを作ってる-

こんにちは。新しい方のあらいではなく、荒れてる方のあらいです。



今、歩数計を使ったアプリを作っています。




f:id:notNewArai:20141009230328p:plain




色以外、前作ってたアプリと違いないじゃないか!



確かにそうなんですけどね~・・・




今回はデータべ―スと連携しています。あと、歩数カウント機能をサービスにしてます。



だから、アプリを1度停止しても、歩数はリセットされない!


バックグラウンドで起動していれば、歩けば、歩いた分だけ歩数を増やすことができる!




(デザインどうしようか・・・。)




最近、更新を止めていたので、経過報告を、無理やり記事にしてみました。



ではまた!

Android -Serviceについて(2) onResumeメソッド-

こんにちは。新しい方のあらいではなく、荒れてる方のあらいです。



今日は、超ピンポイントな説明です。



昨日は、日本語でServiceの動きを説明しました。
今日は、少しコードを紹介しながら、Activityでサービスを動かすところの説明です。



目次





全体の流れ



public void onResume() {
        startService(new Intent(this,WalkMeterService.class));
        registerReceiver(mWalkMeterReceiver, new IntentFilter(WalkMeterService.ACTION));
        bindService(new Intent(this, WalkMeterService.class), mServiceConnection,
                Context.BIND_AUTO_CREATE);
        super.onResume();
    }


(こちらのコードは リックテレコム Androidプログラミング上達支援サイト
炎のAndroid開発道場、WalkMeter2のコードの一部です)



1.startService でサービスを開始
2.registerReceiverでfilterによる、Intentの識別 + Intentを受け取るBroadCastReceiverの指定。
3.bindServiceで、サービスに接続





bindServiceについて


他のメソッドに比べて解釈に時間がかかったメソッド

public abstract boolean bindService (Intent service, ServiceConnection conn, int flags)



Intent service
接続するService



ServiceConnection conn

Receives information as the service is started and stopped. This must be a valid ServiceConnection object; it must not be null.

http://developer.android.com/reference/android/content/Context.html#bindService(android.content.Intent, android.content.ServiceConnection, int)
Serviceに繋がったか切れたかを知らせる。(くらいの解釈でいきましょう!・・・w)



onServiceConnected メソッドと、 onServiceDisconnected しかないみたいです。
ServiceConnection | Android Developers



int flags
bindServiceメソッドのオプション


BIND_AUTO_CREATE, BIND_DEBUG_UNBIND, BIND_NOT_FOREGROUND, BIND_ABOVE_CLIENT, BIND_ALLOW_OOM_MANAGEMENT, or BIND_WAIVE_PRIORITY


色々あるみたいですよ




もう23時か。1日早い!
おやすみなさい。ありがとうございました!