org.droid2droid.test.TestDroid2DroidListFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.droid2droid.test.TestDroid2DroidListFragment.java

Source

/******************************************************************************
 *
 * droid2droid - Distributed Android Framework
 * ==========================================
 *
 * Copyright (C) 2012 by Atos (http://www.http://atos.net)
 * http://www.droid2droid.org
 *
 ******************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations
 * under the License.
 *
******************************************************************************/
package org.droid2droid.test;

import static org.droid2droid.Droid2DroidManager.ACTION_CONNECT_ANDROID;
import static org.droid2droid.Droid2DroidManager.DISCOVER_INFINITELY;
import static org.droid2droid.Droid2DroidManager.EXTRA_DISCOVER;
import static org.droid2droid.Droid2DroidManager.EXTRA_FLAGS;
import static org.droid2droid.Droid2DroidManager.EXTRA_SUBTITLE;
import static org.droid2droid.Droid2DroidManager.EXTRA_THEME_ID;
import static org.droid2droid.Droid2DroidManager.EXTRA_TITLE;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.droid2droid.Droid2DroidManager;
import org.droid2droid.Droid2DroidManager.ManagerListener;
import org.droid2droid.ListRemoteAndroidInfo;
import org.droid2droid.RemoteAndroidInfo;
import org.droid2droid.test.Droid2DroidContext.OnRemoteAndroidContextUpdated;

import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.nfc.NfcAdapter.CreateNdefMessageCallback;
import android.nfc.NfcEvent;
import android.os.AsyncTask;
import android.os.Build.VERSION;
import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.ToggleButton;

import com.actionbarsherlock.app.SherlockFragmentActivity;
import com.actionbarsherlock.app.SherlockListFragment;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;

// Checkbox pour la decouverte des ProximityNetwork
public class TestDroid2DroidListFragment extends SherlockListFragment
        implements View.OnClickListener, OnItemSelectedListener, OnRemoteAndroidContextUpdated,
        OnCheckedChangeListener, ListRemoteAndroidInfo.DiscoverListener {
    public static final String TAG = "RA-Test";

    private static final String URL_NOT_KNOWN = "[hack] ips://localhost"; // FIXME "Not known";
    private static final String EXTRA_BURST = "burst";

    private static final int REQUEST_CONNECT_CODE = 1;

    private NfcAdapter mNfcAdapter;
    private final ExecutorService mExecutors = Executors.newCachedThreadPool();
    private final Handler mHandler = new Handler();
    private SharedPreferences mPreferences;
    private MenuItem mDiscoverMenu;
    private MenuItem mBurstMenu;

    private final List<String> mItems = new ArrayList<String>();

    private volatile ListRemoteAndroidInfo mDiscoveredAndroid;
    private final ArrayList<Droid2DroidContext> mRemoteAndroids = new ArrayList<Droid2DroidContext>(5);
    private BaseAdapter mAdapter;
    private ArrayAdapter<String> mItemAdapter;
    private boolean mBurst;
    private Droid2DroidManager mManager;

    @Override
    @TargetApi(14)
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        if (VERSION.SDK_INT > VERSION_CODES.ICE_CREAM_SANDWICH) {
            mNfcAdapter = NfcAdapter.getDefaultAdapter(activity);
            if (mNfcAdapter != null) {
                mNfcAdapter.setNdefPushMessageCallback(
                        // Hook for compatibility
                        new CreateNdefMessageCallback() {
                            @Override
                            public NdefMessage createNdefMessage(NfcEvent event) {
                                return TestDroid2DroidListFragment.this.createNdefMessage(event);
                            }

                        }, activity);

            }
        }
    }

    public final Droid2DroidManager getManager() {
        return mManager;
    }

    @Override
    public void onDiscoverStart() {
        FragmentActivity activity = getActivity();
        if (activity != null) {
            setDiscover(true);
        }
    }

    @Override
    public void onDiscoverStop() {
        FragmentActivity activity = getActivity();
        if (activity != null) {
            setDiscover(false);
        }
    }

    @Override
    public void onDiscover(RemoteAndroidInfo info, boolean replace) {
        //      if (!mIsDiscover && !replace) return;
        addRemoteAndroid(info, replace);
    }

    private void addRemoteAndroid(RemoteAndroidInfo info, boolean replace) {
        String[] uris = info.getUris();
        mItemAdapter.remove(URL_NOT_KNOWN);
        for (String s : uris) {
            final String key = '[' + info.getName() + "] " + s;
            mItemAdapter.remove(key);
            mItemAdapter.add(key);
        }
        if (mDiscoveredAndroid == null)
            return;
        if (!mDiscoveredAndroid.contains(info)) {
            mDiscoveredAndroid.add(info);
            replace = false;
        }
        if (!replace) {
            if (uris.length != 0) {
                mRemoteAndroids.add(new Droid2DroidContext(getActivity(), mManager, this));
                int position = mRemoteAndroids.size() - 1;
                Droid2DroidContext racontext = mRemoteAndroids.get(position);
                racontext.mUri = '[' + info.getName() + "] " + uris[0];
            } else {
                Log.e(TAG, "Discover error"); //FIXME: Discover error
            }
        }
        mItemAdapter.sort(new Comparator<String>() {
            @Override
            public int compare(String object1, String object2) {
                return object1.compareTo(object2);
            }
        });
        mItemAdapter.notifyDataSetChanged();
        mAdapter.notifyDataSetChanged();
    }

    private void setDiscover(boolean status) {
        mDiscoverMenu.setChecked(status);
        mDiscoverMenu.setIcon(
                status ? android.R.drawable.ic_menu_close_clear_cancel : android.R.drawable.ic_menu_search);
        ((SherlockFragmentActivity) getActivity()).setSupportProgressBarIndeterminateVisibility(status);
    }

    private void setBurst(boolean status) {
        mBurstMenu.setChecked(status);
        mBurstMenu.setIcon(status ? R.drawable.ic_menu_burst_toggle : R.drawable.ic_menu_burst);
        mBurst = status;
    }

    /** Called when the activity is first created. */
    class Caches {
        Spinner mUri;
        ToggleButton mActive;
        Button mInstall;
        ToggleButton mBind;
        Button mInvoke;
        Spinner mCmds;
        TextView mStatus;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        return inflater.inflate(R.layout.main, container);
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        outState.putBoolean(EXTRA_BURST, mBurst);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        Log.v(TAG, "Fragment.onCreate");
        super.onCreate(savedInstanceState);
        mDiscoveredAndroid = Droid2DroidManager.newDiscoveredAndroid(getActivity(), this);
        Intent market = Droid2DroidManager.getIntentForMarket(getActivity());
        if (market == null) {
            //           mRetain=(Retain)getActivity().getLastNonConfigurationInstance(); // FIXME: single fragment in activity
            Droid2DroidManager.bindManager(getActivity(), new ManagerListener() {

                @Override
                public void bind(Droid2DroidManager manager) {
                    mManager = manager;
                }

                @Override
                public void unbind(Droid2DroidManager manager) {
                    mDiscoveredAndroid = null;
                    setDiscover(false);
                    setBurst(mBurst);
                    mManager = null;
                }

            });
            if (savedInstanceState != null) {
                mBurst = savedInstanceState.getBoolean(EXTRA_BURST);
            }

            mItemAdapter = new ArrayAdapter<String>(getActivity(), android.R.layout.simple_spinner_item, mItems);
            mAdapter = new BaseAdapter() {

                @Override
                public View getView(int position, View convertView, ViewGroup parent) {
                    View view;
                    Caches caches;
                    if (convertView == null) {
                        Activity activity = getActivity();
                        if (activity == null) {
                            Log.d(TAG, "null activity");
                            return null;
                        }
                        view = getActivity().getLayoutInflater().inflate(R.layout.test_item, null);
                        caches = new Caches();
                        caches.mUri = (Spinner) view.findViewById(R.id.uri);
                        caches.mUri.setOnItemSelectedListener(TestDroid2DroidListFragment.this);
                        caches.mActive = (ToggleButton) view.findViewById(R.id.active);
                        caches.mActive.setOnClickListener(TestDroid2DroidListFragment.this);
                        caches.mInstall = (Button) view.findViewById(R.id.install);
                        caches.mInstall.setOnClickListener(TestDroid2DroidListFragment.this);
                        caches.mBind = (ToggleButton) view.findViewById(R.id.bind);
                        caches.mBind.setOnClickListener(TestDroid2DroidListFragment.this);
                        caches.mInvoke = (Button) view.findViewById(R.id.invoke);
                        caches.mInvoke.setOnClickListener(TestDroid2DroidListFragment.this);
                        caches.mStatus = (TextView) view.findViewById(R.id.status);
                        view.setTag(caches);

                        mItemAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
                        caches.mUri.setAdapter(mItemAdapter);

                    } else {
                        view = convertView;
                        caches = (Caches) view.getTag();
                    }
                    caches.mUri.setTag(position);
                    caches.mActive.setTag(position);
                    caches.mInstall.setTag(position);
                    caches.mBind.setTag(position);
                    caches.mInvoke.setTag(position);
                    Droid2DroidContext racontext = mRemoteAndroids.get(position);
                    if (racontext.mUri != null) {

                        for (int i = 0; i < mItems.size(); ++i) {
                            if (racontext.mUri.equals(mItems.get(i))) {
                                caches.mUri.setSelection(i);
                                break;
                            }
                        }
                    }
                    caches.mActive.setEnabled((racontext.mState != Droid2DroidContext.State.BindingRemoteAndroid));
                    caches.mActive.setChecked(racontext.mRemoteAndroid != null);
                    boolean enabled = (racontext.mRemoteAndroid != null);
                    caches.mInstall.setEnabled(enabled);
                    caches.mBind.setEnabled(enabled);
                    caches.mBind.setChecked(racontext.binded);
                    caches.mInvoke.setEnabled(racontext.mRemoteObject != null);
                    caches.mStatus.setText(racontext.mStatus);
                    return view;
                }

                @Override
                public long getItemId(int position) {
                    return position;
                }

                @Override
                public Object getItem(int position) {
                    // TODO Auto-generated method stub
                    return null;
                }

                @Override
                public int getCount() {
                    return mRemoteAndroids.size();
                }
            };
            setListAdapter(mAdapter);
            setHasOptionsMenu(true);
        }
    }

    @Override
    public void onResume() {
        Log.v(TAG, "Fragment.onResume");
        super.onResume();
        initAndroids();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mDiscoveredAndroid != null)
            mDiscoveredAndroid.close();
        if (mManager != null)
            mManager.close();
    }

    private void initAndroids() {
        new AsyncTask<Void, Void, SharedPreferences>() {
            @Override
            protected SharedPreferences doInBackground(Void... params) {
                return PreferenceManager.getDefaultSharedPreferences(getActivity().getBaseContext());
            }

            @Override
            protected void onPostExecute(SharedPreferences preferences) {
                if (mItemAdapter == null)
                    return;
                mPreferences = preferences;
                int size = Integer.parseInt(preferences.getString("init.androids", "0"));
                if (mRemoteAndroids != null && mRemoteAndroids.size() <= size) {
                    {
                        for (int i = mRemoteAndroids.size(); i < size; ++i) {
                            Droid2DroidContext context = new Droid2DroidContext(getActivity(), mManager,
                                    TestDroid2DroidListFragment.this);
                            context.mUri = (mItems.size() > 0) ? mItems.get(0) : URL_NOT_KNOWN;
                            mRemoteAndroids.add(context);
                        }
                        mItemAdapter.notifyDataSetChanged();
                        mAdapter.notifyDataSetChanged();
                    }
                }
            }
        }.execute();
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.menu, menu);
        mDiscoverMenu = menu.findItem(R.id.discover);
        mBurstMenu = menu.findItem(R.id.burst);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        final int id = item.getItemId();
        if (id == R.id.discover) {
            item.setChecked(!item.isChecked());
            if (item.isChecked()) {
                if (mDiscoveredAndroid == null)
                    return false;

                SharedPreferences preferences = mPreferences;
                int flags = Integer.parseInt(preferences.getString("discover.mode", "1"));
                mManager.startDiscover(flags, DISCOVER_INFINITELY);
            } else {
                mManager.cancelDiscover();
            }
        } else if (id == R.id.add) {
            Intent intent = new Intent(ACTION_CONNECT_ANDROID);
            //         intent.setFlags(
            //            Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET
            //            |Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS
            //            |Intent.FLAG_
            //            );
            intent.putExtra(EXTRA_THEME_ID, android.R.style.Theme_Holo_Light_DarkActionBar);
            intent.putExtra(EXTRA_TITLE, "Test");
            intent.putExtra(EXTRA_SUBTITLE, "Select device.");
            SharedPreferences preferences = PreferenceManager
                    .getDefaultSharedPreferences(getActivity().getBaseContext());
            int flags = Droid2DroidContext.parseFlags(preferences.getString("discover.mode", "1"));
            intent.putExtra(EXTRA_FLAGS, flags);

            startActivityForResult(intent, REQUEST_CONNECT_CODE);
        } else if (id == R.id.clear) {
            if (mDiscoveredAndroid != null) {
                mDiscoveredAndroid.clear();
                for (final Droid2DroidContext rac : mRemoteAndroids) {
                    if (rac.mRemoteAndroid != null) {
                        // With strict mode
                        mExecutors.execute(new Runnable() {
                            @Override
                            public void run() {
                                rac.mRemoteAndroid.close();
                            }
                        });
                    }
                }
                mRemoteAndroids.clear();
                initAndroids();
                mAdapter.notifyDataSetChanged();
            }
        } else if (id == R.id.burst) {
            setBurst(!item.isChecked());
        } else if (id == R.id.config) {
            getActivity().startActivity(new Intent(getActivity(), TestDroid2DroidPreferenceActivity.class));
        }
        return super.onOptionsItemSelected(item);
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_CONNECT_CODE && resultCode == Activity.RESULT_OK) {

            RemoteAndroidInfo info = (RemoteAndroidInfo) data.getParcelableExtra(EXTRA_DISCOVER);
            addRemoteAndroid(info, false);
        }
    }

    @Override
    public void onClick(final View view) {
        final int position = (Integer) view.getTag();
        final Droid2DroidContext context = mRemoteAndroids.get(position);
        switch (view.getId()) {
        case R.id.active:
            Log.d(TAG, "Active " + position);
            view.setEnabled(false);
            if (mBurst) {
                for (final Droid2DroidContext ra : mRemoteAndroids) {
                    mExecutors.execute(new Runnable() {
                        @Override
                        public void run() {
                            if (!((ToggleButton) view).isChecked())
                                ra.disconnect(getActivity());
                            else
                                ra.connect(getActivity());
                        }
                    });
                }
            } else {
                new AsyncTask<Void, Void, Void>() {
                    @Override
                    protected Void doInBackground(Void... params) {
                        if (!((ToggleButton) view).isChecked())
                            context.disconnect(getActivity());
                        else
                            context.connect(getActivity());
                        return null;
                    }
                }.execute();
            }
            break;

        case R.id.install:
            Log.d(TAG, "Install " + position);
            if (mBurst) {
                for (Droid2DroidContext ra : mRemoteAndroids) // FIXME Install en mode burst
                {
                    ra.install(getActivity());
                }
            } else
                context.install(getActivity());
            break;

        case R.id.bind:
            Log.d(TAG, "Invoke " + position);
            if (mBurst) {
                final boolean toogle = ((ToggleButton) view).isChecked();
                for (final Droid2DroidContext ra : mRemoteAndroids) // FIXME
                {
                    mExecutors.execute(new Runnable() {
                        @Override
                        public void run() {
                            if (!toogle)
                                ra.unbindService(getActivity());
                            else
                                ra.bindService(getActivity());
                        }
                    });
                }
            } else {
                final Droid2DroidContext ra = mRemoteAndroids.get(position);
                if (!((ToggleButton) view).isChecked())
                    ra.unbindService(getActivity());
                else
                    ra.bindService(getActivity());
            }
            break;

        case R.id.invoke:
            Log.d(TAG, "Invoke " + position);
            if (mBurst) {
                for (final Droid2DroidContext ra : mRemoteAndroids) {
                    mExecutors.execute(new Runnable() {
                        @Override
                        public void run() {
                            ra.invoke(getActivity());
                        }
                    });
                }
            } else
                context.invoke(getActivity());
            break;
        }
    }

    @Override
    public void onItemSelected(AdapterView<?> parent, View view, int itemPosition, long id) {
        final int position = (Integer) parent.getTag();
        Droid2DroidContext context = mRemoteAndroids.get(position);
        context.mUri = mItems.get(itemPosition);
    }

    @Override
    public void onNothingSelected(AdapterView<?> parent) {
    }

    @Override
    public void onUpdated() {
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                mAdapter.notifyDataSetChanged();
            }
        });
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
    }

    public final Droid2DroidManager getRemoteAndroidManager() {
        return mManager;
    }

    //    @Override
    @TargetApi(14)
    public NdefMessage createNdefMessage(NfcEvent event) {
        return (mManager != null) ? mManager.createNdefMessage() : null;
    }
}