I'm using Android Studio and trying to show some chosen Street View paths in VR. I already have Street View running well and now I'm trying to show it in VR.
I have put the com.google.vr.sdk.widgets.pano.VrPanoramaView in the layout and, inside onCreate in my class, referenced it to a VrPanoramaView variable through findViewById. Now I'm trying to show an image calling a method which I've defined in this class, loadPanoImage. This method loads an image from the storage and shows it through loadImageFromBitmap.
The problem is that it isn't able to show anything, even though I've followed a guide and I've done everything as showed. I've even tryed calling it in different parts of the code (before doing any other action, on clicking a button, before and after showing streetview) but I can't understand why it isn't working and how will I be able to use it to show images taken from StreetView (I don't know if I will be able to do it dinamically or I should download them and put them in the storage).
I'm putting part of the code for reference:
public class VrExperience extends FragmentActivity {
Button buttonCitta;
Button buttonMare;
Button buttonMontagna;
TextView titleTextView;
// George St, Sydney
private static final LatLng SYDNEY = new LatLng(-33.87365, 151.20689);
// LatLng with no panorama
private static final LatLng INVALID = new LatLng(-45.125783, 151.276417);
//VrPanoramaView is inserted in the layout
private VrPanoramaView panoWidgetView;
//StreetViewPanorama is another class in my project which shows Street View
private StreetViewPanorama mStreetViewPanorama;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_vrexperiences);
panoWidgetView = (VrPanoramaView) findViewById(R.id.pano_view);
panoWidgetView.setEventListener(new VrPanoramaEventListener());
//download image and show it, but it doesn't show anything
loadPanoImage();
titleTextView = (TextView) findViewById(R.id.titleTextView);
buttonCitta = (Button) findViewById(R.id.buttonCitta);
buttonCitta.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (!checkReady()) {
return;
}
titleTextView.setVisibility(View.GONE);
buttonCitta.setVisibility(View.GONE);
buttonMare.setVisibility(View.GONE);
buttonMontagna.setVisibility(View.GONE);
loadPanoImage(); //it doesn't show anything
mStreetViewPanorama.setPosition(SYDNEY);
loadPanoImage(); //it doesn't show anything
}
}};
//code for buttonMontagna and buttonMare as well, it's identical
SupportStreetViewPanoramaFragment streetViewPanoramaFragment =
(SupportStreetViewPanoramaFragment)
getSupportFragmentManager().findFragmentById(R.id.streetviewpanorama);
streetViewPanoramaFragment.getStreetViewPanoramaAsync(
new OnStreetViewPanoramaReadyCallback() {
#Override
public void onStreetViewPanoramaReady(StreetViewPanorama panorama) {
mStreetViewPanorama = panorama;
// Only set the panorama to INVALID on startup (when no panoramas have been
// loaded which is when the savedInstanceState is null).
if (savedInstanceState == null) {
mStreetViewPanorama.setPosition(INVALID);
}
}
});
}
/**
* When the panorama is not ready the PanoramaView cannot be used. This should be called on
* all entry points that call methods on the Panorama API.
*/
private boolean checkReady() {
if (mStreetViewPanorama == null)
return false;
return true;
}
/**
* Called when the Animate To Invalid button is clicked.
*/
public void onGoToInvalid(View view) {
if (!checkReady()) {
return;
}
mStreetViewPanorama.setPosition(INVALID);
}
//retrieves image from the assets folder and loads it into the VrPanoramaView
private void loadPanoImage() {
VrPanoramaView.Options options = new VrPanoramaView.Options();
InputStream inputStream = null;
AssetManager assetManager = getAssets();
try {
inputStream = assetManager.open("demo2.jpg");
options.inputType = VrPanoramaView.Options.TYPE_MONO;
panoWidgetView.loadImageFromBitmap(
BitmapFactory.decodeStream(inputStream), options
);
inputStream.close();
} catch (IOException e) {
Log.e("Fail", "Exception in loadPanoImage" + e.getMessage());
}
}
#Override
protected void onPause() {
panoWidgetView.pauseRendering();
super.onPause();
}
#Override
protected void onResume() {
super.onResume();
panoWidgetView.resumeRendering();
}
#Override
protected void onDestroy() {
panoWidgetView.shutdown();
super.onDestroy();
}
}
This is my layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/vrExperienceActivity"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<com.google.vr.sdk.widgets.pano.VrPanoramaView
android:id="#+id/pano_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dip"
android:layout_weight="5"
android:scrollbars="none" />
<TextView
android:id="#+id/titleTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:text="VR Experience"
android:textAlignment="center"
android:textAppearance="#android:style/TextAppearance.Large"
android:textColor="#0000F0"
android:visibility="visible" />
<Button
android:id="#+id/buttonCitta"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Città " />
<fragment
class="com.google.android.gms.maps.SupportStreetViewPanoramaFragment"
android:id="#+id/streetviewpanorama"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
EDIT: #LucioB
a) those are the places I've tried to call loadPanoImage, but neither of them showed anything. It acts as nothing happens calling that method, the program keeps going to the other tasks. I'd like for images to be shown directly in VR when a button is clicked, or if that isn't possible to add the classic cardboard button in Street View mode to pass to VR view.
b) I mean the code isn't doing what I expected it to do. I thought that once I created VrPanoramaView in the layout and used it to show an image through .loadImageFromBitmap it would have shown the image I loaded from asset (I have an image saved on the virtual SD), and that once I was able to do that for a single image I would have found a way to do it for a whole path.
The code doesn't give any exception, I think I'm making a logic mistake or I didn't understand how VR api work.
EDIT: I've found that the java code is working, the problem was in the layout which didn't permit to see VrPanoramaView because it was obscured by StreetViewPanorama
Related
What i am doing : I am trying to play an mp3 file from an url in android. and control its position through progressbar.
what is happening:
FOR the strings.xml below code is working correctly song is playing and i am able to position the progress using the progressbar
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Android mp3 player</string>
<string name="testsong_20_sec">http://users.skynet.be/fa046054/home/P22/track06.mp3</string>
FOR the strings.xml below code the code is not working properly, i mean song is playing but i cannot control the position using the progress bar. only difference with this url is that this mp3 file is in google drive.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Android mp3 player</string>
<string name="testsong_20_sec">https://286898c83aa5e6a4f7b29cdbef3b2f54430b4e71.googledrive.com/host/0B6a-NfRKFX8HQVZRSzFON1ExZEE/Chadh%20Gayi%20Maa%20Tere%20Naam%20Ki%20Sherewali%20Ka%20Sancha.mp3</string>
</resources>
What i am looking for: how to make sure my code plays proper music and i could toggle using progress bar in the second url properly
StreamingMp3Player.java
public class StreamingMp3Player extends Activity implements OnClickListener, OnTouchListener, OnCompletionListener, OnBufferingUpdateListener{
private ImageButton buttonPlayPause;
private SeekBar seekBarProgress;
public EditText editTextSongURL;
private MediaPlayer mediaPlayer;
private int mediaFileLengthInMilliseconds; // this value contains the song duration in milliseconds. Look at getDuration() method in MediaPlayer class
private final Handler handler = new Handler();
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
initView();
}
/** This method initialise all the views in project*/
private void initView() {
buttonPlayPause = (ImageButton)findViewById(R.id.ButtonTestPlayPause);
buttonPlayPause.setOnClickListener(this);
seekBarProgress = (SeekBar)findViewById(R.id.SeekBarTestPlay);
seekBarProgress.setMax(99); // It means 100% .0-99
seekBarProgress.setOnTouchListener(this);
editTextSongURL = (EditText)findViewById(R.id.EditTextSongURL);
editTextSongURL.setText(R.string.testsong_20_sec);
mediaPlayer = new MediaPlayer();
mediaPlayer.setOnBufferingUpdateListener(this);
mediaPlayer.setOnCompletionListener(this);
}
/** Method which updates the SeekBar primary progress by current song playing position*/
private void primarySeekBarProgressUpdater() {
seekBarProgress.setProgress((int)(((float)mediaPlayer.getCurrentPosition()/mediaFileLengthInMilliseconds)*100)); // This math construction give a percentage of "was playing"/"song length"
if (mediaPlayer.isPlaying()) {
Runnable notification = new Runnable() {
public void run() {
primarySeekBarProgressUpdater();
}
};
handler.postDelayed(notification,1000);
}
}
#Override
public void onClick(View v) {
if(v.getId() == R.id.ButtonTestPlayPause){
/** ImageButton onClick event handler. Method which start/pause mediaplayer playing */
try {
mediaPlayer.setDataSource(editTextSongURL.getText().toString()); // setup song from http://www.hrupin.com/wp-content/uploads/mp3/testsong_20_sec.mp3 URL to mediaplayer data source
mediaPlayer.prepare(); // you must call this method after setup the datasource in setDataSource method. After calling prepare() the instance of MediaPlayer starts load data from URL to internal buffer.
} catch (Exception e) {
e.printStackTrace();
}
mediaFileLengthInMilliseconds = mediaPlayer.getDuration(); // gets the song length in milliseconds from URL
if(!mediaPlayer.isPlaying()){
mediaPlayer.start();
buttonPlayPause.setImageResource(R.drawable.button_pause);
}else {
mediaPlayer.pause();
buttonPlayPause.setImageResource(R.drawable.button_play);
}
primarySeekBarProgressUpdater();
}
}
#Override
public boolean onTouch(View v, MotionEvent event) {
if(v.getId() == R.id.SeekBarTestPlay){
/** Seekbar onTouch event handler. Method which seeks MediaPlayer to seekBar primary progress position*/
if(mediaPlayer.isPlaying()){
SeekBar sb = (SeekBar)v;
int playPositionInMillisecconds = (mediaFileLengthInMilliseconds / 100) * sb.getProgress();
mediaPlayer.seekTo(playPositionInMillisecconds);
}
}
return false;
}
#Override
public void onCompletion(MediaPlayer mp) {
/** MediaPlayer onCompletion event handler. Method which calls then song playing is complete*/
buttonPlayPause.setImageResource(R.drawable.button_play);
}
#Override
public void onBufferingUpdate(MediaPlayer mp, int percent) {
/** Method which updates the SeekBar secondary progress by current song loading from URL position*/
seekBarProgress.setSecondaryProgress(percent);
}
}
main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/widget31"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<EditText
android:id="#+id/EditTextSongURL"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:ems="10"
android:height="100dp"
android:lines="3"
android:maxLines="3"
android:minLines="1" >
<requestFocus />
<requestFocus />
</EditText>
<ImageButton
android:id="#+id/ButtonTestPlayPause"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/EditTextSongURL"
android:layout_centerHorizontal="true"
android:contentDescription="TestPlayPause"
android:onClick="onClick"
android:src="#drawable/button_play" />
<SeekBar
android:id="#+id/SeekBarTestPlay"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_below="#+id/ButtonTestPlayPause" />
</RelativeLayout>
This happens because google drive HTTP server does not return proper length of the file.
$ wget -S https://286898c83aa5e6a4f7b29cdbef3b2f54430b4e71.googledrive.com/host/0B6a-NfRKFX8HQVZRSzFON1ExZEE/Chadh%20Gayi%20Maa%20Tere%20Naam%20Ki%20Sherewali%20Ka%20Sancha.mp3
...
Length: unspecified [audio/mpeg]
You have no total stream length, and therefore you don't have position relative to total length. Bad luck.
I have this TextView in my application
<TextView
android:id="#+id/txtStatusMsg"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:paddingLeft="#dimen/feed_item_status_pad_left_right"
android:paddingRight="#dimen/feed_item_status_pad_left_right"
android:paddingTop="#dimen/feed_item_status_pad_top"
android:textIsSelectable="true"
/>
and its selectable ..when i select text and copy it i want to add extra text
example :
Test text
what i want is when i select the text and copy it :
Test text - Copied from xx app
how i can do it ?
You'll want to add a clipboardListener:
private boolean mSkipClip;
#Override
protected void onCreate(Bundle savedInstanceState) {
...
final ClipboardManager mClipboard = (ClipboardManager)mAct.getSystemService
(Context.CLIPBOARD_SERVICE);
mClipboard.addPrimaryClipChangedListener(new ClipboardManager
.OnPrimaryClipChangedListener() {
#Override
public void onPrimaryClipChanged() {
if (mSkipClip) {
mSkipClip = false;
} else {
// Append custom string
ClipData clipData = new ClipData(mClipboard.getPrimaryClip());
clipData.addItem(new ClipData.Item("Copied from xx app"));
mSkipClip = true;
mClipboard.setPrimaryClip(clipData);
}
}
});
}
Notes:
ClipData class which is available only since API 16.
Other classes and methods are available since API 11.
When you update the clipboard data, the listener is called again. mSkipClip helps the listener skip such callbacks.
When pausing your activity, make sure you remove the listener, as it will listen to clipboard activity on other activities and apps too.
I create simple Android app (https://www.linux.com/learn/docs/683628-android-programming-for-beginners-part-1) with latest Android Studio. Code:
public class test_act extends Activity {
private static final int MILLIS_PER_SECOND = 1000;
private static final int SECONDS_TO_COUNTDOWN = 30;
private android.widget.TextView countdownDisplay;
private android.os.CountDownTimer timer;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.full_act);
countdownDisplay = (android.widget.TextView) findViewById(R.id.time_display_box);
android.widget.Button startButton = (android.widget.Button) findViewById(R.id.startbutton);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
try {
showTimer(SECONDS_TO_COUNTDOWN * MILLIS_PER_SECOND);
} catch (NumberFormatException e) {
// method ignores invalid (non-integer) input and waits
// for something it can use
}
}
});
}
private void showTimer(int countdownMillis) {
if(timer != null) { timer.cancel(); }
timer = new android.os.CountDownTimer(countdownMillis, MILLIS_PER_SECOND) {
#Override
public void onTick(long millisUntilFinished) {
countdownDisplay.setText("counting down: " +
millisUntilFinished / MILLIS_PER_SECOND);
}
#Override
public void onFinish() {
countdownDisplay.setText("KABOOM!");
}
}.start();
}
}
My XML:
<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" >
<TextView
android:id="#+id/time_display_box"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="60dp"
android:text="#string/_00_30"
android:textAppearance="?android:attr/textAppearanceLarge"/>
<Button
android:id="#+id/startbutton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/time_display_box"
android:layout_centerHorizontal="true"
android:layout_marginTop="41dp"
android:text="#string/start" />
</RelativeLayout>
In emulator it's good working. But on my Galaxy S2 with CyanogenMod10.1(Android 4.2.2) app wrong updating TextView. Screenshot:
How I can resolve this problem?
upd: after screen rotate TextView is updating once.
You might want to try invalidating your layout every time it is updated. I am guessing with how often the text is being updated the phone is not having enough time to redraw the layout. This would also explain why it works when you rotate your phone, because then the layout is forced to update.
countdownDisplay.invalidate();
Let me know if that does not work.
It commonly happens when you put UI updates inside try blocks, try to avoid it or wrap with runOnUiThread.
EDIT:
Another reason - you update it to fast - you code does 1000 updates per second i dont think it can handle it.
I uploaded my app yesterday to Google Play and this morning I've wanted to make just a layout tweak as some of the text was overlapping buttons on smaller screens, basically I just want to move the buttons further down the screen. I thought this would be as easy as using eclipse's graphical editor... Nope.
I have no idea why but the small edit I've done to the position of the buttons on my "view_fact" layout has registered the buttons with the wrong OnClick listeners, there's only two buttons on the view and they're using eachothers event listeners and I have no idea why. I didn't touch the event listener code that was working perfectly on the old layout.
Here is my view_fact layout:
<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" >
<TextView
android:id="#+id/viewFactTitleText"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="18dp"
android:text="#string/factTitleText"
android:textSize="22dp"
tools:context=".MainActivity" />
<ImageView
android:id="#+id/randomFactImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/viewFactTitleText"
android:layout_centerHorizontal="true"
android:layout_marginTop="18dp"
android:contentDescription="Fact Image"
android:src="#drawable/canadaflag" />
<TextView
android:id="#+id/factData"
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_below="#+id/randomFactImage"
android:layout_centerHorizontal="true"
android:layout_marginTop="14dp"
android:text="TextView" />
<Button
android:id="#+id/anotherFactButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#+id/backToHomeButton"
android:layout_alignLeft="#+id/backToHomeButton"
android:layout_alignRight="#+id/backToHomeButton"
android:text="#string/anotherFactButtonText" />
<Button
android:id="#+id/backToHomeButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="#+id/factData"
android:layout_alignParentBottom="true"
android:layout_alignRight="#+id/factData"
android:text="#string/backToHomeButtonText" />
</RelativeLayout>
Listener and startup code:
public class MainActivity extends Activity {
/* Declaration of global variables */
private boolean debugMode = true; // Whether debugging is enabled or not
private static String logtag = "CanadianFacts"; // For use as the tag when logging
private TextView factData;
private int totalFacts = 72;
private String[][] facts = new String[totalFacts][5];
private int lastFact = 0;
/* Buttons */
/* Home page */
private Button randomFactButton;
/* View Fact page */
private Button anotherRandomFactButton;
private Button backToHomeButton;
/* About page */
private Button backToHomeFromAboutButton;
/* Image Views */
private ImageView randomFactImage;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/* Home Page Objects */
randomFactButton = (Button)findViewById(R.id.randomFactButton);
randomFactButton.setOnClickListener(randomFactListener); // Register the onClick listener with the implementation above
/* View Fact Page Objects */
/* Build Up Fact Array */
buildFactArray();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_about:
loadAboutPage(); // Call the loadAboutPage method
return true;
}
return false;
}
public void loadAboutPage() {
setContentView(R.layout.about);
/* Set up home page button listener */
backToHomeFromAboutButton = (Button)findViewById(R.id.backToHomeFromAboutButton);
backToHomeFromAboutButton.setOnClickListener(backToHomeListener); // We can reuse the backToHomeListener
}
/* Home Page Listeners */
//Create an anonymous implementation of OnClickListener, this needs to be done for each button, a new listener is created with an onClick method
private OnClickListener randomFactListener = new OnClickListener() {
public void onClick(View v) {
if (debugMode) {
Log.d(logtag,"onClick() called - randomFact button");
Toast.makeText(MainActivity.this, "The random fact button was clicked.", Toast.LENGTH_LONG).show();
}
setContentView(R.layout.view_fact); // Load the view fact page
/* We're now on the View Fact page, so elements on the page are now in our scope, instantiate them */
/* Another Random Fact Button */
anotherRandomFactButton = (Button)findViewById(R.id.anotherFactButton);
anotherRandomFactButton.setOnClickListener(anotherRandomFactListener); // Register the onClick listener with the implementation above
/* Back to Home Button */
backToHomeButton = (Button)findViewById(R.id.backToHomeButton);
backToHomeButton.setOnClickListener(backToHomeListener); // Register the onClick listener with the implementation above
// Get a random fact
String[] fact = getRandomFact();
if (fact[2] == null) { // If this fact doesn't have an image associated with it
fact[2] = getRandomImage();
}
int imageID = getDrawable(MainActivity.this, fact[2]);
/* See if this fact has an image available, if it doesn't select a random generic image */
randomFactImage = (ImageView) findViewById(R.id.randomFactImage);
randomFactImage.setImageResource(imageID);
factData = (TextView) findViewById(R.id.factData);
factData.setText(fact[1]);
if (debugMode) {
Log.d(logtag,"onClick() ended - randomFact button");
}
}
};
/* View Fact Page Listeners */
private OnClickListener anotherRandomFactListener = new OnClickListener() {
public void onClick(View v) {
if (debugMode) {
Log.d(logtag,"onClick() called - anotherRandomFact button");
Toast.makeText(MainActivity.this, "The another random fact button was clicked.", Toast.LENGTH_LONG).show();
}
// Get a random fact
String[] fact = getRandomFact();
if (fact[2] == null) { // If this fact doesn't have an image associated with it
fact[2] = getRandomImage();
}
int imageID = getDrawable(MainActivity.this, fact[2]); // Get the ID of the image
/* See if this fact has an image available, if it doesn't select a random generic image */
randomFactImage = (ImageView) findViewById(R.id.randomFactImage);
randomFactImage.setImageResource(imageID);
factData = (TextView) findViewById(R.id.factData);
factData.setText(fact[1]);
if (debugMode) {
Log.d(logtag,"onClick() ended - anotherRandomFact button");
}
}
};
private OnClickListener backToHomeListener = new OnClickListener() {
public void onClick(View v) {
if (debugMode) {
Log.d(logtag,"onClick() called - backToHome button");
Toast.makeText(MainActivity.this, "The back to home button was clicked.", Toast.LENGTH_LONG).show();
}
// Set content view back to the home page
setContentView(R.layout.main); // Load the home page
/* Reinstantiate home page buttons and listeners */
randomFactButton = (Button)findViewById(R.id.randomFactButton);
randomFactButton.setOnClickListener(randomFactListener); // Register the onClick listener with the implementation above
if (debugMode) {
Log.d(logtag,"onClick() ended - backToHome button");
}
}
};
Thank you.
I've managed to fix this, by moving the buttons around, changing the IDs a few times and then changing them back. And removing all of the align settings and resetting it's position.
A very strange problem, probably due to eclipse's graphical editor.
I want to show automatic checklist in android. For example I can have 4 list of item with unchecked check box adjutant to that.
After 5 sec. delay I want to check the first item then move on to second. At the end of 20 sec. I should have all 4 check box checked one by one.
Any idea how should I go on doing this ? I can use list view with checkbox opeion on ..right ??
I am a .net programmer and this is new experience for me so any comment / advise is appreciated.
Here is a basic example I've just written:
public class AutoChecker extends Activity {
private CheckBox checkbox1;
private CheckBox checkbox2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
checkbox1 = (CheckBox) findViewById(R.id.checkbox_1);
checkbox2 = (CheckBox) findViewById(R.id.checkbox_2);
new CheckerAsync(AutoChecker.this).execute(checkbox1, checkbox2);
}
private class CheckerAsync extends AsyncTask<CheckBox, CheckBox, Void>{
private Activity mActivity;
private CheckerAsync(Activity activity) {
mActivity = activity;
}
#Override
protected Void doInBackground(final CheckBox... checkboxes) {
try {
for(int i = 0, j = checkboxes.length; i < j; i++ ){
Thread.sleep(5000);
publishProgress(checkboxes[i]);
}
} catch (InterruptedException e) {}
return null;
}
#Override
public void onProgressUpdate(final CheckBox... checkboxes){
mActivity.runOnUiThread(new Runnable() {
#Override
public void run() {
checkboxes[0].setChecked(true);
}
});
}
}
}
This is the XML layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<CheckBox
android:id="#+id/checkbox_1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Checkbox 1"
/>
<CheckBox
android:id="#+id/checkbox_2"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Checkbox 2"
/>
</LinearLayout>
Explanation
It uses a class that extends AsyncTask which allows you to use threading in a easy to use/understand way. The way this class is executed is kind of simple:
new CheckerAsync(AutoChecker.this).execute(checkbox1, checkbox2);
You can add as many checkboxes as you want. For instance:
new CheckerAsync(AutoChecker.this).execute(checkbox1, checkbox2, checkbox4, checkbox3);
By the way, I don't know why you are trying to do this. But, if it's for testing purposes, you better take a look at the instrumentation framework.
For the automatic checking with delay, you should use an AsyncTask, like a thread where you can modify things within the Android main UI thread, i.e. like checking the checkboxes.
http://developer.android.com/resources/articles/painless-threading.html
http://www.xoriant.com/blog/mobile-application-development/android-async-task.html
http://developer.android.com/reference/android/os/AsyncTask.html
The checkboxes can be part of a listview, but don't have to be. You can also add them into a LinearLayout with vertical orientation one by one.