switching between open applications android through adb - android

I writed a robotium test that runs a test on a apk file. The test runs on a apk file in a debug mode. the test clicks and inserts data in the app.
The problem is, that sometimes a user hit on a link in a app, and opend a new app/website on the device, and now the root app is not visible.
there is a way to make it visible through the adb?
this is the main class of the test:
package genericTest.test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import android.annotation.SuppressLint;
import android.app.KeyguardManager;
import android.content.Context;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.view.View;
import com.robotium.solo.Solo;
#SuppressWarnings("rawtypes")
public class Main extends ActivityInstrumentationTestCase2 {
private FunctonsForViews mFunctonsForViews;
private Random mRand;
private Solo mSolo;
private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.hobbyistsoftware.android.vlcremote_us.main";
private final int DELAY = 50;
private final int SCREEN_SIZE = 1280;
private final int ERROR_COUNT_LIMIT = 10;
private final int CLICK_ON_LOOP_LIMIT = 8;
private final int WHAITING_FOR_VIEWS_LIMIT = 10;
private final int LOOP_LIMIT = 10000;
private static Class launcherActivityClass;
private static int error_count = 0;
static {
try {
launcherActivityClass = Class
.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
#SuppressLint("NewApi")
#SuppressWarnings("unchecked")
public Main() throws ClassNotFoundException {
super(null, launcherActivityClass);
}
protected void setUp() throws Exception {
setActivityInitialTouchMode(true);
mSolo = new Solo(getInstrumentation(), getActivity());
Context context = getActivity();
KeyguardManager km =
(KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
if (km.inKeyguardRestrictedInputMode())
{
KeyguardManager.KeyguardLock lock = km.newKeyguardLock("some_tag");
lock.disableKeyguard();
SystemClock.sleep(2000);
}
setActivityInitialTouchMode(true);
}
/*
* runs the test for the app.
*/
public void testMethod()
{
mFunctonsForViews = new FunctonsForViews(mSolo);
mSolo.sleep(DELAY * DELAY);
mRand = new Random();
/*
* the test will take place in the loop, and will be limit in time.
* in every iteration it will get the vies in activity's, and run a test on a random view.
*/
//for(int i=0 ; i<LOOP_LIMIT ; i++)
while(true)
{
mSolo.unlockScreen();
ArrayList Views = mSolo.getViews();
int arraySize = Views.size();
if (arraySize == 0)// now View in activity.
{
whenNoViewsInScreen(Views, arraySize);
}
if (arraySize != 0)
{
int ViewIndexInArray = mRand.nextInt(arraySize + 2);
if (ViewIndexInArray == arraySize)
{
mSolo.scrollDown();
}
else if (ViewIndexInArray == arraySize + 1)
{
if (!mSolo.getCurrentActivity().getClass().toString().split(" ")[1].equals
(LAUNCHER_ACTIVITY_FULL_CLASSNAME))
{
goingBack();
}
}
else
{
View randomView = (View)(Views.get(ViewIndexInArray));
runTestOnOneView(randomView);
}
}
}
}
/*
* performing clicks onScreen()
*/
public void myClickOnScreen()
{
try {
mSolo.unlockScreen();
mSolo.clickOnScreen(mRand.nextInt(SCREEN_SIZE), mRand.nextInt(SCREEN_SIZE));
} catch (Exception e) {
e.printStackTrace();
error_count++;
} catch (Error e2) {
error_count++;
e2.printStackTrace();
}
}
/*
* there is no Views available.
* we will try pressing on screen or the goBack function.
*/
public void whenNoViewsInScreen(ArrayList Views, int arraySize)
{
for (int j = 0; j < WHAITING_FOR_VIEWS_LIMIT; j++)
{
for (int k= 0; k < CLICK_ON_LOOP_LIMIT; k++)
{
myClickOnScreen();
}
Views = mSolo.getViews();
arraySize = Views.size();
if (arraySize != 0)
{
return;
}
mSolo.sleep(DELAY);
Views = mSolo.getViews();
arraySize = Views.size();
if (arraySize != 0)
{
return;
}
}
if (!mSolo.getCurrentActivity().getClass().toString().split(" ")[1].equals
(LAUNCHER_ACTIVITY_FULL_CLASSNAME))
{
goingBack();
}
mSolo.sleep(DELAY);
return;
}
public void runTestOnOneView(View randomView)
{
String rawViewName = randomView.getClass().getName();
String viewName = parseRawViewName(rawViewName);
if (viewName.contains("ActionBarContainer"))
{
return;
}
MyRunnable myRunnable = mFunctonsForViews.getMethodMap().get(viewName);
try{
if (myRunnable != null)
{
myRunnable.run((View)randomView);
}
else // view not in map.
{
boolean inMap = false;
Iterator it = mFunctonsForViews.getMethodMap().entrySet().iterator();
/*
* iterating in case the View is a version of one of View in map
* example:
* View is "CustomEditText", and map contains o view "EditText".
*/
while (it.hasNext())
{
Map.Entry pairs = (Map.Entry)it.next();
if ( viewName.contains((String)pairs.getKey()) )
{
inMap = true;
// next two lines changed
myRunnable = (MyRunnable)(pairs.getValue());
myRunnable.run((View)randomView);
break;
}
}
if (inMap == false)
{
if (viewName.contains("Layout"))
{
return;
}
mSolo.clickOnView((View)randomView);
}
error_count = 0;
}
}catch(Exception exception)
{
exception.printStackTrace();
if(error_count > ERROR_COUNT_LIMIT &&
!(mSolo.getCurrentActivity().getClass().toString().split(" ")[1].equals(LAUNCHER_ACTIVITY_FULL_CLASSNAME)))
{
goingBack();
error_count = 0;
}
return;
}catch(Error error)
{
error.printStackTrace();
error_count ++;
if(error_count > ERROR_COUNT_LIMIT &&
!(mSolo.getCurrentActivity().getClass().toString().split(" ")[1].equals(LAUNCHER_ACTIVITY_FULL_CLASSNAME)))
{
goingBack();
error_count = 0;
}
return;
}
mSolo.sleep(DELAY);
}
/*
* performs a goBack command surrounded with catch/try
*/
public void goingBack()
{
try {
String currentActivity = mSolo.getCurrentActivity().getClass().toString();
mSolo.goBack();
if (mSolo.getCurrentActivity().getClass().toString().equals(currentActivity))
{
for (int i = 0; i< 20; i++)
{
myClickOnScreen();
}
}
} catch (Exception e) {
e.printStackTrace();
} catch (Error e) {
e.printStackTrace();
}
}
/*
* extract the name of View from raw View name.
* example:
* raw View name: android.widget.TextView
* raw View name:TextView
*/
public String parseRawViewName(String rawViewName)
{
if (rawViewName.contains(" "))
{
String [] array = rawViewName.split(" ");
rawViewName = array [0];
}
if (rawViewName.contains(".") || rawViewName.contains("$"))
{
String [] array = rawViewName.split("\\.|$");
rawViewName = array [array.length-1];
}
return rawViewName;
}
public void tearDown() throws Exception {
mSolo.finishOpenedActivities();
}
}

Related

how to track percentage of progressing download of each downloading file in exoplayer library?

I am working on a media player app. I'm using ExoPlayer library. I have a playlist of videos, and I want to download videos simultaneously. I done it by using available demo app of exoplayer library on GitHub. I want to show progress of each downloading in the UI. For this job I get help from DownloadNotificationUtil.buildProgressNotification method.
#Override
protected Notification getForegroundNotification(TaskState[] taskStates) {
float totalPercentage = 0;
int downloadTaskCount = 0;
boolean allDownloadPercentagesUnknown = true;
boolean haveDownloadedBytes = false;
boolean haveDownloadTasks = false;
boolean haveRemoveTasks = false;
Log.e(TAG,"size task state: "+taskStates.length);
for (TaskState taskState : taskStates) {
Log.e(TAG,"taskId= "+taskState.taskId);
if (taskState.state != TaskState.STATE_STARTED
&& taskState.state != TaskState.STATE_COMPLETED) {
continue;
}
if (taskState.action.isRemoveAction) {
haveRemoveTasks = true;
continue;
}
haveDownloadTasks = true;
if (taskState.downloadPercentage != C.PERCENTAGE_UNSET) {
allDownloadPercentagesUnknown = false;
totalPercentage += taskState.downloadPercentage;
}
haveDownloadedBytes |= taskState.downloadedBytes > 0;
downloadTaskCount++;
}
int progress = 0;
boolean indeterminate = true;
if (haveDownloadTasks) {
progress = (int) (totalPercentage / downloadTaskCount);
indeterminate = allDownloadPercentagesUnknown && haveDownloadedBytes;
Log.e(TAG,"notifi "+progress);
}
return DownloadNotificationUtil.buildProgressNotification(
this,
R.drawable.exo_icon_play,
DOWNLOAD_CHANNEL_ID,
null,
null,
taskStates);
}
Now,I can track the progress downloading. But I still have a problem. I can't understand which item is downloading to update it's progress bar in the UI. Is there a Identical id of each download to recognize it? For example Android Download Manager has a download ID for each downloading file. But I don't know , how to handle this problem.
This is MediaDownloadService:
public class MediaDownloadService extends DownloadService {
public static String TAG="MediaDownloadService";
private static final int FOREGROUND_NOTIFICATION_ID = 1;
public MediaDownloadService() {
super(
DOWNLOAD_NOTIFICATION_ID,
DEFAULT_FOREGROUND_NOTIFICATION_UPDATE_INTERVAL,
DOWNLOAD_CHANNEL_ID,
R.string.download_channel_name);
}
#Override
protected DownloadManager getDownloadManager() {
return ((MyApplication) getApplication()).getDownloadManager();
}
#Nullable
#Override
protected Scheduler getScheduler() {
return null;
}
#Override
protected Notification getForegroundNotification(TaskState[] taskStates) {
float totalPercentage = 0;
int downloadTaskCount = 0;
boolean allDownloadPercentagesUnknown = true;
boolean haveDownloadedBytes = false;
boolean haveDownloadTasks = false;
boolean haveRemoveTasks = false;
for (TaskState taskState : taskStates) {
if (taskState.state != TaskState.STATE_STARTED
&& taskState.state != TaskState.STATE_COMPLETED) {
continue;
}
if (taskState.action.isRemoveAction) {
haveRemoveTasks = true;
continue;
}
haveDownloadTasks = true;
if (taskState.downloadPercentage != C.PERCENTAGE_UNSET) {
allDownloadPercentagesUnknown = false;
totalPercentage += taskState.downloadPercentage;
}
haveDownloadedBytes |= taskState.downloadedBytes > 0;
downloadTaskCount++;
}
int progress = 0;
boolean indeterminate = true;
if (haveDownloadTasks) {
progress = (int) (totalPercentage / downloadTaskCount);
indeterminate = allDownloadPercentagesUnknown && haveDownloadedBytes;
Log.e(TAG,"notifi "+progress);
sendIntent(progress);
}
return DownloadNotificationUtil.buildProgressNotification(
this,
R.drawable.exo_icon_play,
DOWNLOAD_CHANNEL_ID,
null,
null,
taskStates);
}
private void sendIntent(int progress){
Intent intent = new Intent(ConstantUtil.MESSAGE_PROGRESS);
intent.putExtra("progress",progress);
LocalBroadcastManager.getInstance(MediaDownloadService.this).sendBroadcast(intent);
}
#Override
protected void onTaskStateChanged(TaskState taskState) {
if (taskState.action.isRemoveAction) {
return;
}
Notification notification = null;
if (taskState.state == TaskState.STATE_COMPLETED) {
Log.e(TAG,"STATE_COMPLETED");
notification =
DownloadNotificationUtil.buildDownloadCompletedNotification(
/* context= */ this,
R.drawable.exo_controls_play,
DOWNLOAD_CHANNEL_ID,
/* contentIntent= */ null,
Util.fromUtf8Bytes(taskState.action.data));
} else if (taskState.state == TaskState.STATE_FAILED) {
Log.e(TAG,"STATE_FAILED");
notification =
DownloadNotificationUtil.buildDownloadFailedNotification(
/* context= */ this,
R.drawable.exo_controls_play,
DOWNLOAD_CHANNEL_ID,
/* contentIntent= */ null,
Util.fromUtf8Bytes(taskState.action.data));
}
int notificationId = FOREGROUND_NOTIFICATION_ID + 1 + taskState.taskId;
NotificationUtil.setNotification(this, notificationId, notification);
}
}
This is DownloadTracker class:
public class DownloadTracker implements DownloadManager.Listener {
/** Listens for changes in the tracked downloads. */
public interface Listener {
/** Called when the tracked downloads changed. */
void onDownloadsChanged();
}
private static final String TAG = "DownloadTracker";
private final Context context;
private final DataSource.Factory dataSourceFactory;
private final TrackNameProvider trackNameProvider;
private final CopyOnWriteArraySet<Listener> listeners;
private Listener onDownloadsChanged;
private final HashMap<Uri, DownloadAction> trackedDownloadStates;
private final ActionFile actionFile;
private final Handler actionFileWriteHandler;
public DownloadTracker(
Context context,
DataSource.Factory dataSourceFactory,
File actionFile,
DownloadAction.Deserializer... deserializers) {
this.context = context.getApplicationContext();
this.dataSourceFactory = dataSourceFactory;
this.actionFile = new ActionFile(actionFile);
trackNameProvider = new DefaultTrackNameProvider(context.getResources());
listeners = new CopyOnWriteArraySet<>();
trackedDownloadStates = new HashMap<>();
HandlerThread actionFileWriteThread = new HandlerThread("DownloadTracker");
actionFileWriteThread.start();
actionFileWriteHandler = new Handler(actionFileWriteThread.getLooper());
loadTrackedActions(
deserializers.length > 0 ? deserializers : DownloadAction.getDefaultDeserializers());
}
public void addListener(Listener listener) {
listeners.add(listener);
}
public void removeListener(Listener listener) {
listeners.remove(listener);
}
public boolean isDownloaded(Uri uri) {
return trackedDownloadStates.containsKey(uri);
}
#SuppressWarnings("unchecked")
public List<StreamKey> getOfflineStreamKeys(Uri uri) {
if (!trackedDownloadStates.containsKey(uri)) {
return Collections.emptyList();
}
return trackedDownloadStates.get(uri).getKeys();
}
public int toggleDownload(Activity activity, String name, Uri uri, String extension) {
if (isDownloaded(uri)) {
Log.e(TAG,"isDownloaded");
DownloadAction removeAction =
getDownloadHelper(uri, extension).getRemoveAction(Util.getUtf8Bytes(name));
startServiceWithAction(removeAction);
return -1;
} else {
StartDownloadDialogHelper helper =
new StartDownloadDialogHelper(activity, getDownloadHelper(uri, extension), name);
helper.prepare();
return helper.getTaskId();
}
}
#Override
public void onInitialized(DownloadManager downloadManager) {
// Do nothing.
}
#Override
public void onTaskStateChanged(DownloadManager downloadManager, TaskState taskState) {
DownloadAction action = taskState.action;
Uri uri = action.uri;
if ((action.isRemoveAction && taskState.state == TaskState.STATE_COMPLETED)
|| (!action.isRemoveAction && taskState.state == TaskState.STATE_FAILED)) {
// A download has been removed, or has failed. Stop tracking it.
if (trackedDownloadStates.remove(uri) != null) {
handleTrackedDownloadStatesChanged();
}
}
}
#Override
public void onIdle(DownloadManager downloadManager) {
// Do nothing.
}
// Internal methods
private void loadTrackedActions(DownloadAction.Deserializer[] deserializers) {
try {
DownloadAction[] allActions = actionFile.load(deserializers);
for (DownloadAction action : allActions) {
trackedDownloadStates.put(action.uri, action);
}
} catch (IOException e) {
Log.e(TAG, "Failed to load tracked actions", e);
}
}
private void handleTrackedDownloadStatesChanged() {
for (Listener listener : listeners) {
listener.onDownloadsChanged();
}
final DownloadAction[] actions = trackedDownloadStates.values().toArray(new DownloadAction[0]);
Log.e(TAG,"actions: "+actions.toString());
actionFileWriteHandler.post(
() -> {
try {
actionFile.store(actions);
} catch (IOException e) {
Log.e(TAG, "Failed to store tracked actions", e);
}
});
}
private void startDownload(DownloadAction action) {
if (trackedDownloadStates.containsKey(action.uri)) {
// This content is already being downloaded. Do nothing.
Log.e(TAG,"download already exsit");
return;
}
trackedDownloadStates.put(action.uri, action);
handleTrackedDownloadStatesChanged();
startServiceWithAction(action);
}
private void startServiceWithAction(DownloadAction action) {
DownloadService.startWithAction(context, MediaDownloadService.class, action, false);
}
private DownloadHelper getDownloadHelper(Uri uri, String extension) {
int type = Util.inferContentType(uri, extension);
switch (type) {
case C.TYPE_DASH:
return new DashDownloadHelper(uri, dataSourceFactory);
case C.TYPE_SS:
return new SsDownloadHelper(uri, dataSourceFactory);
case C.TYPE_HLS:
return new HlsDownloadHelper(uri, dataSourceFactory);
case C.TYPE_OTHER:
return new ProgressiveDownloadHelper(uri);
default:
throw new IllegalStateException("Unsupported type: " + type);
}
}
private final class StartDownloadDialogHelper
implements DownloadHelper.Callback, DialogInterface.OnClickListener {
private final DownloadHelper downloadHelper;
private final String name;
private final AlertDialog.Builder builder;
private final View dialogView;
private final List<TrackKey> trackKeys;
private final ArrayAdapter<String> trackTitles;
private final ListView representationList;
private int taskId;
public StartDownloadDialogHelper(
Activity activity, DownloadHelper downloadHelper, String name) {
this.downloadHelper = downloadHelper;
this.name = name;
builder =
new AlertDialog.Builder(activity)
.setTitle(R.string.exo_download_description)
.setPositiveButton(android.R.string.ok, this)
.setNegativeButton(android.R.string.cancel, null);
// Inflate with the builder's context to ensure the correct style is used.
LayoutInflater dialogInflater = LayoutInflater.from(builder.getContext());
dialogView = dialogInflater.inflate(R.layout.start_download_dialog, null);
trackKeys = new ArrayList<>();
trackTitles =
new ArrayAdapter<>(
builder.getContext(), android.R.layout.simple_list_item_multiple_choice);
representationList = dialogView.findViewById(R.id.representation_list);
representationList.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
representationList.setAdapter(trackTitles);
}
public void prepare() {
downloadHelper.prepare(this);
}
#Override
public void onPrepared(DownloadHelper helper) {
for (int i = 0; i < downloadHelper.getPeriodCount(); i++) {
TrackGroupArray trackGroups = downloadHelper.getTrackGroups(i);
for (int j = 0; j < trackGroups.length; j++) {
TrackGroup trackGroup = trackGroups.get(j);
for (int k = 0; k < trackGroup.length; k++) {
trackKeys.add(new TrackKey(i, j, k));
trackTitles.add(trackNameProvider.getTrackName(trackGroup.getFormat(k)));
}
}
}
if (!trackKeys.isEmpty()) {
builder.setView(dialogView);
}
builder.create().show();
}
#Override
public void onPrepareError(DownloadHelper helper, IOException e) {
Toast.makeText(
context.getApplicationContext(), R.string.download_start_error, Toast.LENGTH_LONG)
.show();
Log.e(TAG, "Failed to start download", e);
}
#Override
public void onClick(DialogInterface dialog, int which) {
ArrayList<TrackKey> selectedTrackKeys = new ArrayList<>();
for (int i = 0; i < representationList.getChildCount(); i++) {
if (representationList.isItemChecked(i)) {
selectedTrackKeys.add(trackKeys.get(i));
}
}
if (!selectedTrackKeys.isEmpty() || trackKeys.isEmpty()) {
// We have selected keys, or we're dealing with single stream content.
DownloadAction downloadAction =
downloadHelper.getDownloadAction(Util.getUtf8Bytes(name), selectedTrackKeys);
taskId=MyApplication.getInstance().getDownloadManager().handleAction(downloadAction);
startDownload(downloadAction);
}
}
}
}
In my Fragment/Activity:
/* this method will be called when user click on download button of each item */
#Override
public void onDownloadClick(LectureList lecture) {
Log.e(TAG,"onClickDownload");
downloadTracker.toggleDownload(this,lecture.getTitle_lecture(),
Uri.parse(lecture.getUrlPath()),lecture.getExtension());
}
And here is my broadcast receiver:
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG,"onRecive download");
if(intent.getAction().equals(MESSAGE_PROGRESS)){
int progress=intent.getLongExtra("progress",0);
}
}
};
In the getForegroundNotification() method, you will get list of TaskState objects, which has a members downloadPercentage and your download Uri taskState.action.uri which is unique for each download task. Store these variables into a map and broadcast the map.
override fun getForegroundNotification(taskStates: Array<TaskState>): Notification {
var totalPercentage = 0f
var downloadTaskCount = 0
var progressMap : HashMap<Uri, Int> = HashMap()
for (taskState in taskStates) {
if (taskState.state != TaskState.STATE_STARTED && taskState.state != TaskState.STATE_COMPLETED) {
continue
}
if (taskState.action.isRemoveAction) {
continue
}
if (taskState.downloadPercentage != C.PERCENTAGE_UNSET.toFloat()) {
totalPercentage += taskState.downloadPercentage
progressMap.put(taskState.action.uri, taskState.downloadPercentage.toInt())
}
downloadTaskCount++
}
var progress = 0
progress = (totalPercentage / downloadTaskCount).toInt()
broadcastIndividualProgress(progressMap)
return buildProgressNotification(progress)
}

ListView is not displaying anything

Im taking presets fields from the database and display them in ListView using PresetsListAdapter.
Coded as below:
public class BasicAcActivity extends Activity implements OnCheckedChangeListener {
private static final String TAG = BasicAcActivity.class.getName();
public static volatile PresetsListAdapter presetsListAdapter;
public static volatile SwitchCompat basicEQToggle;
private ListView mListView;
private FlipBeatsDataManager mDataManager;
private PresetsManager mPrstManager;
private SharedPreferences mShrdPrefs;
private SharedPreferences mShrdPrefPresets;
private TextView tvPresets;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.basic_eq_settings);
initialize();
String text = Utilities.getResourceValue(this, R.string.equalizer_presets);
tvPresets.setText(text);
// Get presets
List<Preset> presets = generatePresets();
if (presets != null && presets.size() > 0)
{
for (Preset preset : presets)
{
mDataManager.createPreset(preset);
}
}
List<Preset> dbPresets = mDataManager.getMandotoryPresets();
presetsListAdapter = new PresetsListAdapter(this, dbPresets);
basicEQToggle.setChecked(true);
mListView.setAdapter(presetsListAdapter);
String onOrOff = mShrdPrefPresets.getString("Presets", "on");
if (onOrOff.equalsIgnoreCase("on"))
{
basicEQToggle.setChecked(true);
}
else
{
basicEQToggle.setChecked(false);
}
basicEQToggle.setOnCheckedChangeListener(this);
}
private void initialize()
{
tvPresets = (TextView) findViewById(R.id.lbl_presets);
mListView = (ListView) findViewById(R.id.presets_list);
basicEQToggle = (SwitchCompat) findViewById(R.id.basic_eq_toggle);
tvPresets.setTypeface(CommonUtils.getTfRobotoRegFont());
mPrstManager = PresetsManager.getInstance(getApplicationContext());
mDataManager = FlipBeatsDataManager.getInstance(getApplicationContext());
mShrdPrefs = getApplicationContext().getSharedPreferences("Prefs", Context.MODE_PRIVATE);
mShrdPrefPresets = getApplicationContext().getSharedPreferences("Preset", Context.MODE_PRIVATE);
}
private List<Preset> generatePresets()
{
// Default value is set if 'equalizer' is null
short bands = 5;
if (PlayerService.sEqualizer != null)
{
try
{
bands = PlayerService.sEqualizer.getNumberOfBands();
}
catch (Exception | Error e)
{
Log.w(TAG, "-- createPresets " + e.getMessage());
}
}
// Create Preset Based on the Bands Level
return mPrstManager.createPresets(bands);
}
#Override
protected void onResume()
{
super.onResume();
setLastUsedType();
boolean isSelected = mDataManager.findMandatoryPresetSelected();
if (!isSelected)
{
int preselect = mDataManager.getLastSelectedPresetId();
mDataManager.updateSelectedToPro1(preselect);
}
presetsListAdapter.notifyDataSetChanged();
Activity actv = getParent();
if (actv != null && actv instanceof AudioConfigurationActivity)
{
AudioConfigurationActivity parent = (AudioConfigurationActivity) actv;
// Sets default advance settings.
parent.setDefaultAdvanceSettings();
parent.setThroughBasicActivity();
}
setDefaultAdvancedSettings();
}
#Override
public boolean onKeyUp(int keyCode, #NonNull KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_VOLUME_UP)
{
if (SoundHealth.getSoundHealth(this))
{
Message.alertMsg(this, Utilities.getResourceValue(this, R.string.sound_health),
Utilities.getResourceValue(this, R.string.sound_health_msg));
}
return true;
}
return super.onKeyUp(keyCode, event);
}
#Override
public void onCheckedChanged(final CompoundButton buttonView, final boolean isChecked)
{
if (isChecked)
{
basicEQToggle.setSelected(true);
if (PlayerService.sEqualizer != null)
{
try
{
PlayerService.sEqualizer.setEnabled(true);
}
catch (Exception | Error e)
{
Log.w(TAG, "-- onCheckedChanged " + e.getMessage());
}
}
getApplicationContext();
mShrdPrefPresets.edit().putString("Presets", "on").apply();
if (BasicAcActivity.presetsListAdapter != null)
{
BasicAcActivity.presetsListAdapter.mPresets = mDataManager.getMandotoryPresets();
}
presetsListAdapter.notifyDataSetChanged();
}
else
{
basicEQToggle.setSelected(false);
if (PlayerService.sEqualizer != null)
{
try
{
PlayerService.sEqualizer.setEnabled(false);
}
catch (Exception | Error e)
{
Log.w(TAG, "-- onCheckedChanged " + e.getMessage());
}
}
if (BasicAcActivity.presetsListAdapter != null)
{
BasicAcActivity.presetsListAdapter.setPreset(14);
}
mShrdPrefPresets.edit().putString("Presets", "off").commit();
if (BasicAcActivity.presetsListAdapter != null)
{
BasicAcActivity.presetsListAdapter.mPresets = mDataManager.getMandotoryPresets();
}
presetsListAdapter.notifyDataSetChanged();
}
}
private void setLastUsedType()
{
mShrdPrefs.edit().putString(AudioConfigurationActivity.AU_SET_TYPE_KEY,
AudioConfigurationActivity.AU_SET_TYPE_BASIC);
}
/*
* Sets default advanced sound settings
*/
private void setDefaultAdvancedSettings()
{
try
{
if (PlayerService.sAudioDefaultValues != null)
{
AudioDefaultValues def = PlayerService.sAudioDefaultValues;
PlayerService.sBaseBooster.setStrength(def.getBassBoost());
PlayerService.sSurroundSound.setStrength(def.getSurroundSound());
PlayerService.sPresetReverb.setPreset(def.getRoomSize());
/** EnvironmentalReverb attributes */
PlayerService.sEnvironmentalReverb.setDecayHFRatio(def.getDecayHfRatio());
PlayerService.sEnvironmentalReverb.setDecayTime(def.getDecayTime());
PlayerService.sEnvironmentalReverb.setDensity(def.getDensity());
PlayerService.sEnvironmentalReverb.setDiffusion(def.getDiffusion());
PlayerService.sEnvironmentalReverb.setReflectionsDelay(def.getReflectionsDelay());
PlayerService.sEnvironmentalReverb.setReflectionsLevel(def.getReflectionsLevel());
PlayerService.sEnvironmentalReverb.setReverbDelay(def.getReverbDelay());
PlayerService.sEnvironmentalReverb.setReverbLevel(def.getReverbLevel());
PlayerService.sEnvironmentalReverb.setRoomHFLevel(def.getRoomHfLevel());
PlayerService.sEnvironmentalReverb.setRoomLevel(def.getRoomLevel());
}
}
catch (Exception e)
{
Log.w(TAG, "--- setDefaultAdvancedSettings, " + e.getMessage());
}
}
}
Adapter class :
abstract class BeatsBaseAdapter extends BaseAdapter {
final ThemeManager mThemeManager;
Context mContext;
Activity mActivity;
ImageLoader mImageLoader;
int mCategory;
FlipBeatsDataManager mDataManager;
int txtColorNumber;
int colorPrimaryText;
int colorSecondaryText;
int colorListBg;
int seperatorBg;
int listDrawbleBg;
int flipCardBg;
int dashboardCardBg;
/**
* Base Constructor
*
* #param context Application Context
*/
FlipBeatsBaseAdapter(Context context) {
mContext = context;
mDataManager = FlipBeatsDataManager.getInstance(mContext);
int sysThemeId = ThemeUtils.getTheme(mContext);
mThemeManager = ThemeManager.getInstance(mContext, sysThemeId);
}
/**
* Base Constructor
*
* #param activity Current Activity
*/
FlipBeatsBaseAdapter(Activity activity) {
if (activity != null) {
mContext = activity.getApplicationContext();
mActivity = activity;
mDataManager = FlipBeatsDataManager.getInstance(mContext);
int sysThemeId = ThemeUtils.getTheme(mContext);
mThemeManager = ThemeManager.getInstance(mContext, sysThemeId);
if (FlipBeatsGlobals.isBlackEditionActive) {
txtColorNumber = mContext.getResources().getColor(R.color.color_app_txt_numbers_dark);
colorPrimaryText = mContext.getResources().getColor(R.color.color_app_text_color_dark);
colorSecondaryText = mContext.getResources().getColor(R.color.color_app_secondary_text_color_dark);
colorListBg = mContext.getResources().getColor(R.color.color_black);
seperatorBg = mContext.getResources().getColor(R.color.color_app_disable_color_dark);
listDrawbleBg = R.drawable.list_front_bg_dark;
flipCardBg = mContext.getResources().getColor(R.color.color_frame_menu_dark);
dashboardCardBg = mContext.getResources().getColor(R.color.color_app_txt_disable_dark);
} else {
txtColorNumber = mContext.getResources().getColor(R.color.color_app_txt_numbers);
colorPrimaryText = mContext.getResources().getColor(R.color.color_app_text_color);
colorSecondaryText = mContext.getResources().getColor(R.color.color_app_secondary_text_color);
colorListBg = mContext.getResources().getColor(R.color.color_white);
seperatorBg = mContext.getResources().getColor(R.color.color_app_disable_color);
listDrawbleBg = R.drawable.list_front_bg;
flipCardBg = mContext.getResources().getColor(R.color.color_frame_menu);
dashboardCardBg = mContext.getResources().getColor(R.color.color_app_txt_disable);
}
} else {
mThemeManager = null;
}
}
}
This works fine until API level 25 but for Android Oreo version the ListView is not displayed, each item is only displayed when it is selected. What is possibly gone wrong here?
Thanks in advance.
Edit: actually the colorListBg is not setting for those devices. that's why the list is not displayed as the text color is set to white color

Loading many asset effectively into android project

I have 231 sound files ( duration ~ 0.2 Sec each) of size 5.7 MB total to load into my android project. I am trying load them when the application starts using for loop like
for (int i = 0; i < 231; i++){
...
loadSoundAsset(i); //method to load the sound files
i++;
...
}
Yet the above method is taking too long to load the sound files. What should be done to load effectively many asset files into android project?
I create sample code for you. How to get faster? (I test it for assets files about 180 sounds files.)
MainActivity
public class MainActivity extends Activity implements TaskListener {
MultiLoader loader = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TextView view = new TextView(this);
view.setText("Loader");
setContentView(view);
}
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
loader = new MultiLoader(this, this);
loader.load("sound");
}
#Override
public void onTaskEnd() {
Vector<byte[]> soundDatas = loader.getData();
Log.e("MainActivity", "TaskEnd");
}
#Override
protected void onDestroy() {
loader.clear();
super.onDestroy();
}
}
MultiLoader
package com.fastload;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Vector;
import java.util.regex.Pattern;
import android.content.Context;
import android.util.Log;
public class MultiLoader {
private int threadCount = 0;
private String[] mFiles;
private Vector<byte[]> fileContents = new Vector<byte[]>();
private Thread[] mQueue = null;
private Context mContext;
private TaskListener listener;
public MultiLoader(Context mContext, TaskListener listener) {
super();
this.mContext = mContext;
this.listener = listener;
}
public Vector<byte[]> getData(){
return fileContents;
}
public void reQueue(int index){
boolean status = true;
mQueue[index] = null;
for(Thread item : mQueue){
status &= (item == null);
}
if(status){
listener.onTaskEnd();
}
}
public void load(final String path){
initialize(path);
if(mFiles == null || (mFiles != null && mFiles.length < 1))
return;
mQueue = new Thread[threadCount];
for(int i = 0; i < threadCount; ++i){
int len = mFiles.length;
int piece = len / threadCount;
final int startIndex = i * piece;
final int endIndex = (i == threadCount - 1) ? len - startIndex - 1 : startIndex + piece;
MyTask task = new MyTask("MyTask##"+i, i, new EndListener(){
#Override
public void onEnd(int index, String name) {
Log.e("ThreadEND", "name = "+name);
reQueue(index);
}
}) {
#Override
public void execute() {
for(int index = startIndex; index < endIndex; ++index){
File file = new File(mFiles[index]);
InputStream is = null;
ByteArrayOutputStream os = null;
byte[] data = null;
try {
is = mContext.getAssets().open(path + File.separator + file.getName());
os = new ByteArrayOutputStream();
int count = 0;
byte[] buffer = new byte[1024];
while((count = is.read(buffer)) > 0){
os.write(buffer, 0, count);
}
os.flush();
data = os.toByteArray();
debug(getName(), index, path + File.separator + file.getName());
} catch (Exception e) {
e.printStackTrace();
} finally{
if(is != null){
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(os != null){
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
if(data != null){
add(data);
}
}
}
};
mQueue[i] = task;
task.start();
}
}
private void debug(String who, int index, String name){
Log.e("MULTI LOADER DEBUG", "who = "+who+" , name = "+name+", index = "+index);
}
private void initialize(String path){
threadCount = getNumCores() * 2;
try {
mFiles = mContext.getAssets().list(path);
} catch (IOException e) {
e.printStackTrace();
}
}
private void add(byte[] data){
synchronized (fileContents) {
fileContents.add(data);
}
}
private void remove(byte[] data){
synchronized (fileContents) {
fileContents.remove(data);
}
}
public void clear(){
synchronized (fileContents) {
fileContents.clear();
}
}
private int getNumCores() {
class CpuFilter implements FileFilter {
#Override
public boolean accept(File pathname) {
if(Pattern.matches("cpu[0-9]+", pathname.getName())) {
return true;
}
return false;
}
}
try {
File dir = new File("/sys/devices/system/cpu/");
File[] files = dir.listFiles(new CpuFilter());
return files.length;
} catch(Exception e) {
return 1;
}
}
private abstract class MyTask extends Thread{
private EndListener listener;
private int index;
private MyTask() { }
public MyTask(String threadName, int index, EndListener listener) {
super(threadName);
this.index = index;
this.listener = listener;
}
public abstract void execute();
#Override
public void run() {
execute();
end();
}
public void end(){
listener.onEnd(index, getName());
}
public int getIndex(){
return index;
}
}
public interface TaskListener{
public void onTaskEnd();
}
public interface EndListener{
public void onEnd(int index, String name);
}
}

"Injecting to another application requires INJECT_EVENTS permission" error, in robotium test on android apk

I writed a robotium test that runs a test on a apk file.
In this case i created the apk file in a previous android poroject, as the apk is still in a debug mode.
the test clicks and inserts data in the app.
as running it in emulator i get the error "Injecting to another application requires INJECT_EVENTS permission".
i tried every selution thst i finded in the internet, But to no avail.
Here is a list of the selutions i tried:
setting emulator on root.
making the test sleep for e few seconds in beginng of test.
adding to manifest:
<uses-permission android:name="android.permission.INJECT_EVENTS"/>
aslo adding this to manifest:
android:anyDensity="true"
adding in setUp function:
setActivityInitialTouchMode(true);
aslo adding this in setUp function:
KeyguardManager km =
(KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
if (km.inKeyguardRestrictedInputMode())
{
KeyguardManager.KeyguardLock lock = km.newKeyguardLock("some_tag");
lock.disableKeyguard();
SystemClock.sleep(2000);
}
moved the app from data/appfolder to system aoo folder.
unlocked screen in code with:
mSolo.unlockScreen();
aslo unlocked with:
adb shell input keyevent 82
i am adding the code.
the code contains three classes, and the manifest:
class Main:
package genericTest.test;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Map;
import java.util.Random;
import android.annotation.SuppressLint;
import android.app.KeyguardManager;
import android.content.Context;
import android.os.SystemClock;
import android.test.ActivityInstrumentationTestCase2;
import android.test.SingleLaunchActivityTestCase;
import android.util.Log;
import android.view.Display;
import android.view.View;
import com.robotium.solo.Solo;
#SuppressWarnings("rawtypes")
public class Main extends ActivityInstrumentationTestCase2 {
//public class Main extends SingleLaunchActivityTestCase {
//SingleLaunchActivityTestCase
private FunctonsForViews mFunctonsForViews;
private Random mRand;
private Solo mSolo;
//private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.goldtouch.ynet.ui.activities.SplashActivity";
private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.bignerdranch.android.criminalintent.CrimeListActivity";
//in Manifest: <!--android:targetPackage="com.bignerdranch.android.criminalintent"-->
//private static final String LAUNCHER_ACTIVITY_FULL_CLASSNAME = "com.mojang.minecraftpe.MainActivity";
//in Manifest: <!--android:targetPackage="com.mojang.minecraftpe"-->
private final int LIMIT_TIME = 300000;
private final int DELAY = 200;
private final int SCREEN_SIZE = 200;
private final int ERROR_COUNT_LIMIT = 10;
private final int CLICK_ON_LOOP_LIMIT = 20;
private final int WHAITING_FOR_VIEWS_LIMIT = 20;
private static Class launcherActivityClass;
private static int error_count = 0;
static {
try {
launcherActivityClass = Class
.forName(LAUNCHER_ACTIVITY_FULL_CLASSNAME);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
#SuppressLint("NewApi")
#SuppressWarnings("unchecked")
public Main() throws ClassNotFoundException {
super(launcherActivityClass);
}
protected void setUp() throws Exception {
setActivityInitialTouchMode(true);
mSolo = new Solo(getInstrumentation(), getActivity());
Context context = getActivity();
int temp = 0;
KeyguardManager km =
(KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
if (km.inKeyguardRestrictedInputMode())
{
KeyguardManager.KeyguardLock lock = km.newKeyguardLock("some_tag");
lock.disableKeyguard();
SystemClock.sleep(2000);
}
setActivityInitialTouchMode(true);
}
/*
* runs the test for the app.
*/
public void testMethod()
{
mFunctonsForViews = new FunctonsForViews(mSolo);
mSolo.sleep(10000);
mRand = new Random();
/*
* the test will take place in the loop, and will be limit in time.
* in every iteration it will get the vies in activity's, and run a test on a random view.
*/
for(int i=0 ;i < LIMIT_TIME ; i += DELAY)
{
mSolo.unlockScreen();
ArrayList Views = mSolo.getViews();
int arraySize = Views.size();
if (arraySize == 0)// now View in activity.
{
whenNoViewsInScreen(Views, arraySize);
}
if (arraySize != 0)
{
int ViewIndexInArray = mRand.nextInt(arraySize + 1);
if (ViewIndexInArray == arraySize)
{
mSolo.scrollDown();
}
else
{
View randomView = (View)(Views.get(ViewIndexInArray));
runTestOnOneView(randomView);
}
}
}
}
/*
* performing clicks onScreen()
*/
public void myClickOnScreen()
{
try {
mSolo.unlockScreen();
mSolo.clickOnScreen(mRand.nextInt(SCREEN_SIZE), mRand.nextInt(SCREEN_SIZE));
//mSolo.clickLongOnScreen(mRand.nextInt(SCREEN_SIZE), mRand.nextInt(SCREEN_SIZE));
} catch (Exception e) {
e.printStackTrace();
Log.e("in exception of clickOnScreen function.", "error_count=" + error_count);
if(error_count > ERROR_COUNT_LIMIT)
{
//goingBack();
error_count = 0;
}
//e.printStackTrace();
} catch (Error e2) {
e2.printStackTrace();
Log.e("in error of clickOnScreen function.", "error_count=" + error_count);
if(error_count > ERROR_COUNT_LIMIT)
{
//goingBack();
error_count = 0;
}
//e2.printStackTrace();
}
}
/*
* there is no Views available.
* we will try pressing on screen or the goBack function.
*/
public void whenNoViewsInScreen(ArrayList Views, int arraySize)
{
for (int j = 0; j < WHAITING_FOR_VIEWS_LIMIT; j++)
{
for (int k= 0; k < CLICK_ON_LOOP_LIMIT; k++)
{
myClickOnScreen();
}
Views = mSolo.getViews();
arraySize = Views.size();
if (arraySize != 0)
{
return;
}
mSolo.sleep(DELAY);
Views = mSolo.getViews();
arraySize = Views.size();
if (arraySize != 0)
{
return;
}
}
goingBack();
mSolo.sleep(DELAY);
return;
}
public void runTestOnOneView(View randomView)
{
String rawViewName = randomView.getClass().getName();
String viewName = parseRawViewName(rawViewName);
Log.i("ViewName", viewName);
//temp
/*if (viewName.contains("ActionBarContainer"))
{
return;
}*/
MyRunnable myRunnable = mFunctonsForViews.getMethodMap().get(viewName);
try{
if (myRunnable != null)
{
Log.e("myRunnable != null", viewName);
myRunnable.run((View)randomView);
}
else // view not in map.
{
boolean inMap = false;
Iterator it = mFunctonsForViews.getMethodMap().entrySet().iterator();
/*
* iterating in case the View is a version of one of View in map
* example:
* View is "CustomEditText", and map contains o view "EditText".
*/
while (it.hasNext())
{
Map.Entry pairs = (Map.Entry)it.next();
if ( viewName.contains((String)pairs.getKey()) )
{
inMap = true;
// next two lines changed
myRunnable = (MyRunnable)(pairs.getValue());
myRunnable.run((View)randomView);
break;
}
}
if (inMap == false)
{
mSolo.clickOnView((View)randomView);
}
error_count = 0;
}
}catch(Exception exception)
{
exception.printStackTrace();
Log.e("Exception click on view", viewName);
for (int i=0 ; i < CLICK_ON_LOOP_LIMIT; i++)
{
myClickOnScreen();
error_count ++;
if(error_count > ERROR_COUNT_LIMIT)
{
goingBack();
error_count = 0;
}
}
}catch(Error error)
{
error.printStackTrace();
Log.e("Error click on view ", viewName+ " " + error.toString());
for (int i=0 ; i < CLICK_ON_LOOP_LIMIT; i++)
{
myClickOnScreen();
error_count ++;
if(error_count > ERROR_COUNT_LIMIT)
{
goingBack();
error_count = 0;
}
}
}
mSolo.sleep(DELAY);
}
/*
* performs a goBack command surrounded with catch/try
*/
public void goingBack()
{
try {
mSolo.goBack();
} catch (Exception e) {
//Log.e("Exeption! ", "Can;t go back" );
e.printStackTrace();
} catch (Error e) {
//Log.e("Error! ", "Can;t go back" );
e.printStackTrace();
}
}
/*
* extract the name of View from raw View name.
* example:
* raw View name: android.widget.TextView
* raw View name:TextView
*/
public String parseRawViewName(String rawViewName)
{
if (rawViewName.contains(" "))
{
String [] array = rawViewName.split(" ");
rawViewName = array [0];
}
if (rawViewName.contains(".") || rawViewName.contains("$"))
{
String [] array = rawViewName.split("\\.|$");
Log.i("array length:", ""+ array.length);
rawViewName = array [array.length-1];
}
return rawViewName;
}
public void tearDown() throws Exception {
mSolo.finishOpenedActivities();
//super.tearDown();
}
}
class FunctonsForViews:
package genericTest.test;
import java.lang.reflect.*;
import java.util.*;
import android.test.ActivityInstrumentationTestCase2;
import android.util.Log;
import android.view.View;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.TimePicker;
import com.robotium.solo.Solo;
/*
* contains the functions and parameters running for every View.
*/
public class FunctonsForViews {
private Map<String, MyRunnable> mMethodMap;
private Solo mSolo;
private Random mRand = new Random();
private final int LIST_TEST_FUNCTIONS = 4;
private final String TAG = "FunctonsForViews";
private final String [] editTextMailInput =
{"example#gmail.com", "secondExample#gmail.com", "erongFormat","123"};
private final String [] editTextPasswordInput =
{"0987654321", "0987654321a", "12","iioo", "ui9"};
private final String [] editTextNameInput =
{"yoav", "567", "ran","iioott", "iioottrr", "iioottrraaqqhh", "iioottrraaqqhh23"};
private final String [] editTextTelephoneInput =
{"078123456", "078123456a", "dan","4675", "123"};
//getter
public Map<String, MyRunnable> getMethodMap()
{
return mMethodMap;
}
/*
* initials the HashMap mMethodMap, and insert the fitting function for handling every View in activity
*/
public FunctonsForViews(Solo solo)
{
mSolo = solo ;
mMethodMap = new HashMap<String, MyRunnable>();
try {
mMethodMap.put("EditText", new MyRunnable() {
public void run(View view) { MyEnterText(view); }
});
/*
mMethodMap.put("CustomEditText", new MyRunnable() {
public void run(View view) { MyEnterText(view); }
});*/
mMethodMap.put("ProgressBar", new MyRunnable() {
public void run(View view) { MySetProgressBar(view); }
});
mMethodMap.put("TimePicker", new MyRunnable() {
public void run(View view) { MySetTimePicker(view); }
});
mMethodMap.put("DatePicker", new MyRunnable() {
public void run(View view) { MySetDatePicker(view); }
});
mMethodMap.put("ListView", new MyRunnable() {
public void run(View view) { MyListTest(view); }
});
/*
mMethodMap.put("e", new MyRunnable() {
public void run(View view) { doNuthing(view); }
});
*/
} catch (Exception e) {
Log.i(TAG, "Cant put in map");
e.printStackTrace();
}
}
/*
* sets random values in the TimePicker View
*/
public void MySetTimePicker(View view)
{
int hour = mRand.nextInt(24);
int minute = mRand.nextInt(60);
mSolo.setTimePicker((android.widget.TimePicker)view, hour, minute);
}
/*
* sets random values in the DatePicker View
*/
public void MySetDatePicker(View view)
{
int year = mRand.nextInt((2020 - 1900) ) + 1900;
int month = mRand.nextInt(12);
int dayOfMonth = mRand.nextInt((31 - 1) ) + 1;
mSolo.setDatePicker((android.widget.DatePicker)view, year, month, dayOfMonth);
}
/*
* sets random values in the ProgressBar View
*/
public void MySetProgressBar(View view)
{
ProgressBar progressBar = (ProgressBar)view;
mSolo.setProgressBar(progressBar, mRand.nextInt(progressBar.getMax()));
}
/*
* calls a random ViewList Solo function
*/
public void MyListTest(View view)
{
int function = mRand.nextInt(LIST_TEST_FUNCTIONS );
switch (function)
{
case 0:
if (((((ListView)view).getLastVisiblePosition()
- ((ListView)view).getFirstVisiblePosition()) + 1) >0)
{
mSolo.clickInList(mRand.nextInt(((ListView)view).getLastVisiblePosition()
- ((ListView)view).getFirstVisiblePosition()) + 1);
}
break;
case 1:
if (((((ListView)view).getLastVisiblePosition()
- ((ListView)view).getFirstVisiblePosition()) + 1) >0)
{
//mSolo.clickLongInList(mRand.nextInt(((ListView)view).getLastVisiblePosition()
//- ((ListView)view).getFirstVisiblePosition()) + 1);
mSolo.clickInList(mRand.nextInt(((ListView)view).getLastVisiblePosition()
- ((ListView)view).getFirstVisiblePosition()) + 1);
}
break;
case 2:
mSolo.scrollListToBottom((ListView)view) ;
break;
default:
mSolo.scrollListToTop((ListView)view) ;
break;
}
}
/*
* sets the text of a EditText View
*/
public void MyEnterText(View view)
{
mSolo.clearEditText((android.widget.EditText)view);
mSolo.enterText((android.widget.EditText)view, getStringForEditTextInput(view));
}
/*
* return a string to be use to set in EditText View.
* the specific string will be choose randomly.
*/
public String getStringForEditTextInput(View view)
{
ArrayList Views = mSolo.getViews();
String EditTextInput = null;
int index = Views.indexOf(view);
for (int i = index - 1; i> index - 4; i--)
{
if (Views.get(i).getClass().getName() == "TextView" )
{
String textViewText = ((TextView)Views.get(i)).getText().toString().toLowerCase();
if(textViewText.contains("mail"))
{
EditTextInput = editTextMailInput[mRand.nextInt(editTextMailInput.length) ];
}
else if(textViewText.contains("password"))
{
EditTextInput = editTextPasswordInput[mRand.nextInt(editTextPasswordInput.length) ];
}
else if(textViewText.contains("telephone"))
{
EditTextInput = editTextTelephoneInput[mRand.nextInt(editTextTelephoneInput.length) ];
}
return EditTextInput;
}
}
EditTextInput = editTextNameInput[mRand.nextInt(editTextNameInput.length) ];
return EditTextInput;
}
}
interface MyRunnable:
package genericTest.test;
import android.view.View;
/*
* used for storing function HashMap
*/
public interface MyRunnable {
public void run(View view);
}
manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="genericTest.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk android:minSdkVersion="7" />
<uses-permission android:name="android.permission.INJECT_EVENTS"/>
android:anyDensity=”true"
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.bignerdranch.android.criminalintent"/>
/>
<supports-screens
android:resizeable="true"
android:smallScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"
android:normalScreens="true"
android:anyDensity="true"/>
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<uses-library android:name="android.test.runner" />
</application>
</manifest>

Android XMLRPC Exception handling

I wanted to ask what is the best way to handle an exception when you are calling a XMLRPC function and the server is down or not responding. I have the following code:
try
{
mXmlRpcClient.call(mRequestVariantsFunc, SessionID, newID, "1970-01-01T00:00:00+00" ,"1970-01-01T00:00:00+00");
}
catch (Exception e)
{
e.printStackTrace();
}
The code above works alright when the server is running but when its down I get a black screen and the phone freezes. The rest of the code is running while in black screen but no exception is thrown. Is there a way to handle this problem in case the server is down not to go into a black screen?
For me, in another tool there is a message going via a handler to indicate progress. Also, a seperate class to handle exceptions is nice to have.
If you have the same library as me, here my example for what it's worth:
package hha.zhongcan.communication;
import java.net.URI;
import android.os.Handler;
import android.util.Log;
import hha.zhongcan.framework.Citem;
import hha.zhongcan.framework.Configuration;
import hha.zhongcan.framework.CtimeFrame;
import hha.zhongcan.framework.Ctransaction;
import hha.zhongcan.microfood.AskTableDialog;
import hha.zhongcan.resources.Global;
import org.apache.http.conn.HttpHostConnectException;
interface XMLRPCMethodCallback
{
void callFinished(Object result);
}
/** Messages to send to the PC at high level. Receive the menu items, pages, transactions.
* Create fake data for the demo.
*
* #author mensfort
*
*/
public class Cmessage
{
static private Cmessage m_message =null;
private static URI m_uri;
public static XMLRPCClient m_client;
private final static String TAG="message";
private boolean m_connected =false;
private int m_pingId =0;
private int m_lost =0;
private int m_wait =0;
private boolean m_sendTransactions =true;
private Handler m_updateHandler = new Handler();
boolean m_getItems = false;
boolean m_getPages = false;
private static Global m_global =null;
private int m_countTransactions =10;
private int transactionMessageCount =0;
private long getValue( String s)
{
try
{
if ( s.startsWith("0x") || s.startsWith("0X"))
{
s =s.substring(2);
while (s.startsWith("0"))
{
s=s.substring(1);
}
if ( s.length() ==0)
{
return 0;
}
return Long.parseLong(s, 16);
}
if ( s=="")
{
return 0;
}
return Long.parseLong(s);
}
catch(Exception e)
{
e.printStackTrace();
return 0;
}
}
/// #brief New thread for running ask-table.
private Runnable messageTask = new Runnable()
{
//#override
public void run()
{
if ( m_getItems)
{
m_getItems =false;
getMenuItems();
}
else if ( m_getPages)
{
m_getPages =false;
getMenuPages();
}
else if ( m_sendTransactions)
{
// If I have sth to send and I'm not in page mode, then start sending items.
sendTransactions();
m_wait =2;
}
else if ( Configuration.getInstance().isDemo())
{
m_connected =true;
next();
}
else if ( m_wait>0)
{
m_wait--;
next();
}
else if ( --m_countTransactions<=0)
{
sendMessage_getTransactions();
m_countTransactions =5;
}
else
{
// Update this screen every 10 seconds.
sendConnected();
}
}
};
/** #brief At startup start the first message after a second.
*/
private Cmessage()
{
m_updateHandler.postDelayed( messageTask, 1000);
}
/** #brief Set the address and port.
*
* #param address [in] Address to use.
* #param port [in] Port to use.
*/
public void setPath( String address, Integer port)
{
m_uri = URI.create("http://192.168.0.105:9876");
m_client =new XMLRPCClient( m_uri);
}
/** #brief Singleton implementation, only this instance can send messages.
*
* #return Pointer to the singleton.
*/
public static Cmessage getInstance()
{
if ( m_message ==null)
{
m_message =new Cmessage();
m_global =Global.getInstance();
}
return m_message;
}
/** #brief In a second, the next command can be send to the PC.
*/
public void next()
{
m_updateHandler.postDelayed( messageTask, 1000);
}
/** #brief Check if we are connected to the PC.
*
* #return true when connected.
*/
public boolean isConnected()
{
return m_connected;
}
/** #brief Send Ping message, just to check the connection status.
*/
public void sendConnected()
{
{
XMLRPCMethod method =new XMLRPCMethod( "ping", new XMLRPCMethodCallback() {
public void callFinished(Object result)
{
try
{
String s = (String) (result);
if ( s.equals("bart"))
{
m_lost =0;
m_connected =true;
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
m_lost++;
}
}
});
Object[] params ={ m_pingId++ }; // {};
method.call(params);
}
if ( ++m_lost>2)
{
m_connected =false;
}
}
public void sendMessage_getConfiguration()
{
// TODO Auto-generated method stub
}
private void createMenuFrom( Object [] arrY)
{
if ( arrY.length >0)
{
m_global.itemDB.clean();
}
int v=(int)(arrY.length/9);
int lvl=1;
for (int y=0; y<arrY.length; y++)
{
if ( y==lvl*v)
{
setSlider(lvl++);
}
Log.i(TAG, "item " + y);
Object[] arrX = (Object[]) arrY[y];
int id =(Integer) arrX[0];
String alias =(String) arrX[1];
String local =(String) arrX[2];
String chinese =(String) arrX[3];
int restaurant_price =(Integer) arrX[4];
int takeaway_price =(Integer) arrX[5];
int level =(Integer) arrX[6];
int page =(Integer) arrX[7];
int sequence =(Integer) arrX[8];
int colour_text = (int)(getValue( (String) arrX[9])&0xffffffff);
int colour_background = (int)(getValue( (String) arrX[10])&0xffffffff);
int colour_selected_text = (int)(getValue( (String) arrX[11])&0xffffffff);
int colour_selected_background = (int)(getValue( (String) arrX[12])&0xffffffff);
int colour_background2 = (int)(getValue( (String) arrX[13])&0xffffffff);
int colour_selected_background2 = (int)(getValue( (String) arrX[14])&0xffffffff);
if ( m_global.mainMenuHandler !=null)
{
// m_global.mainMenuHandler.obtainMessage( y, "UPDATE_MENU_SLIDEBAR "+y).sendToTarget();
}
m_global.itemDB.insert( id, alias, local, chinese, restaurant_price,
takeaway_price, (byte)level, (byte)page, (short)sequence,
colour_text, colour_background, colour_selected_text,
colour_selected_background, colour_background2,
colour_selected_background2);
}
m_global.itemDB.complete();
Log.i(TAG, "Items received correct.");
}
/** Indicate that we want to get the menu card.
*/
public void sendMessage_getMenuItems()
{
m_getItems = true;
m_getPages = true;
}
/** #brief Get the menu items. */
public void getMenuItems()
{
boolean demo =Configuration.getInstance().isDemo();
if (demo ==true)
{
createMenuFrom( demoMenu.items);
next();
}
else
{
XMLRPCMethod method =new XMLRPCMethod( "items", new XMLRPCMethodCallback() {
public void callFinished(Object result)
{
try
{
m_global.itemDB.deleteAll();
m_global.itemDB.clean();
Object[] arrY = (Object[]) result;
createMenuFrom( arrY);
m_connected =true;
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
}
}
});
Object[] params = {};
if ( m_global.mainMenuHandler !=null)
{
m_global.mainMenuHandler.obtainMessage( 1, "UPDATE_MENU_SLIDEBAR 1").sendToTarget();
}
method.call(params);
if ( m_global.mainMenuHandler !=null)
{
m_global.mainMenuHandler.obtainMessage( 1, "UPDATE_MENU_SLIDEBAR 5").sendToTarget();
}
}
}
/** Call to get all transactions from the server, including payments, items and time-frames. */
public void sendMessage_sendTransactions()
{
m_sendTransactions =true;
}
/** Set slider to a value 1..10
*
* #param n [in] 0..10
*/
private void setSlider( int n)
{
if ( m_global.mainMenuHandler !=null)
{
m_global.mainMenuHandler.obtainMessage( 0, "UPDATE_MENU_SLIDEBAR "+n).sendToTarget();
}
}
/** After sending the orders, the database can be cleaned...
*/
private void cleanDatabase()
{
try
{
m_global.transactionDB.clean();
m_global.timeFrameDB.clean();
m_global.transactionItemDB.clean();
m_connected =true;
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
}
}
/** Send all transaction */
private void sendTransactions()
{
if ( m_global.transactionDB.size() ==0)
{
m_sendTransactions =false;
cleanDatabase();
next();
return;
}
if ( Configuration.getInstance().isDemo())
{
cleanDatabase();
try
{
m_global.askTableHandler.obtainMessage( AskTableDialog.MESSAGE_DATA_SENT,-1,-1, -1).sendToTarget();
}
catch (Exception e)
{
e.printStackTrace();
}
m_sendTransactions =false;
}
XMLRPCMethod method =new XMLRPCMethod( "orders", new XMLRPCMethodCallback()
{
public void callFinished(Object result)
{
cleanDatabase();
m_global.askTableHandler.obtainMessage( AskTableDialog.MESSAGE_DATA_SENT,-1,-1, -1).sendToTarget();
m_sendTransactions =false;
}
});
Object[][] transaction =m_global.transactionDB.get();
Object[][] timeFrame =m_global.timeFrameDB.get();
Object[][] item =m_global.transactionItemDB.get();
Object[] params ={ transaction,timeFrame,item };
//{
// transaction, timeFrame, item
//}/;
if ( transaction ==null || timeFrame ==null || item ==null)
{
cleanDatabase();
Log.e( TAG,"Database problem!!");
}
method.call( params);
}
/// Call to get all transactions from the server, including payments, items and time-frames.
public void sendMessage_getTransactions()
{
if ( m_global.transactionDB.size() >0)
{
return;
}
if ( m_global.timeFrameDB.size() >0)
{
return;
}
if ( m_global.transactionItemDB.size() >0)
{
return;
}
XMLRPCMethod method =new XMLRPCMethod( "get_transactions", new XMLRPCMethodCallback()
{
public void callFinished(Object result)
{
m_countTransactions =10;
m_connected =true;
if ( m_global.transactionDB.size() >0)
{
Log.i(TAG, "Transaction DB not empty.");
return;
}
if ( m_global.timeFrameDB.size() >0)
{
Log.i(TAG, "Time Frame DB not empty.");
return;
}
if ( m_global.transactionItemDB.size() >0)
{
Log.i(TAG, "Transaction Item DB not empty.");
return;
}
try
{
m_global.transactionList.clean();
Object[] arrY = (Object[]) result;
Object[] transactions =(Object[]) arrY[0];
Object[] timeFrames =(Object[]) arrY[1];
Object[] items =(Object[]) arrY[2];
//Object[] payments =(Object[]) arrY[3];
for (int y=0; y<transactions.length; y++)
{
Object[] trx = (Object[]) transactions[y];
int id = Integer.valueOf(trx[0].toString());
String tme =trx[1].toString();
String name =trx[2].toString();
int customer_id =Integer.valueOf( trx[3].toString());
int status =Integer.valueOf( trx[4].toString());
int total =Integer.valueOf( trx[5].toString());
Ctransaction t=new Ctransaction( id, name, tme, status, customer_id, total);
m_global.transactionList.insert( t);
}
for (int y=0; y<timeFrames.length; y++)
{
Object[] trx = (Object[]) timeFrames[y];
int id = Integer.valueOf( trx[0].toString());
int tfi =Integer.valueOf( trx[1].toString());
int waiter =Integer.valueOf( trx[2].toString());
String start_time =trx[3].toString();
String end_time =trx[4].toString();
int transaction_id =Integer.valueOf( trx[5].toString());
int device_id =Integer.valueOf( trx[6].toString());
CtimeFrame c =new CtimeFrame( id, (short)tfi, waiter,
start_time, end_time,
transaction_id, device_id);
m_global.transactionList.insert( c);
}
for (int y=0; y<items.length; y++)
{
Object[] trx = (Object[]) items[y];
//int id = (Integer) trx[0];
long menu_item_id =Long.valueOf( trx[1].toString());
int sequence =Integer.valueOf( trx[2].toString());
int time_frame_index =Integer.valueOf( trx[3].toString());
int deleted_time_frame_index =Integer.valueOf( trx[4].toString());
long transaction_id =Long.valueOf( trx[5].toString());
int quantity =Integer.valueOf( trx[6].toString());
int level =Integer.valueOf( trx[7].toString());
int deleted =Integer.valueOf( trx[8].toString());
int portion =Integer.valueOf( trx[9].toString());
int orig_price =Integer.valueOf( trx[10].toString());
int unit_price =Integer.valueOf( trx[11].toString());
String time =trx[12].toString();
Citem i=new Citem( menu_item_id, y, (short)sequence,
(short)time_frame_index,
(short)deleted_time_frame_index,
transaction_id, quantity,
(byte)level, deleted, (byte)portion, unit_price, orig_price, time);
m_global.transactionList.insert( i);
}
//for (int y=0; y<payments.length; y++)
//{
//Object[] pay = (Object[]) payments[y];
//int id = (Integer) pay[0];
//String time =(String) pay[1];
//int money_received =(Integer) pay[2];
//int customer_id =(Integer) pay[3];
//int pay_method =(Integer) pay[4];
//int partial_index =(Integer) pay[5];
//global.paymentsDB.insert( id, time, money_received, customer_id, pay_method, partial_index);
//}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
}
}
});
Object[] params = { transactionMessageCount++ };
method.call(params);
}
/// Call, but not in main thread, answer comes in a thread.
private void getMenuPages()
{
if ( Configuration.getInstance().isDemo())
{
decodePages( demoMenu.pages);
next();
return;
}
XMLRPCMethod method =new XMLRPCMethod( "pages", new XMLRPCMethodCallback()
{
public void callFinished(Object result)
{
decodePages( result);
}
});
setSlider(7);
Object[] params = {};
method.call(params);
setSlider(8);
}
/**
* #brief Convert an array to page data.
* #param result [in] array with local, chinese names.
*/
private void decodePages( Object result)
{
try
{
m_global.pageDB.clean();
Object[] arrY = (Object[]) result;
setSlider(9);
for (int y=0; y<arrY.length; y++)
{
Object[] arrX = (Object[]) arrY[y];
int id = (Integer) arrX[0];
String local =(String) arrX[1];
String chinese =(String) arrX[2];
String lc =local.replace( "'", "''");
String ch =chinese.replace( "'", "''");
m_global.pageDB.insert( id, lc, ch);
}
m_connected =true;
if ( m_global.mainMenuHandler !=null)
{
m_global.mainMenuHandler.obtainMessage( 0, "UPDATE_MENU_READY").sendToTarget();
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
m_connected =false;
}
}
class XMLRPCMethod extends Thread
{
private String method;
private Object[] params;
private Handler handler;
private XMLRPCMethodCallback callBack;
public XMLRPCMethod(String method, XMLRPCMethodCallback callBack)
{
this.method = method;
this.callBack = callBack;
handler = new Handler();
}
public void call()
{
call(null);
}
public void call(Object[] params)
{
this.params = params;
start();
}
//#Override
public void run()
{
synchronized(this)
{
try
{
final long t0 = System.currentTimeMillis();
final Object result = m_client.callEx(method, params);
final long t1 = System.currentTimeMillis();
handler.post(new Runnable()
{
public void run()
{
Log.i(TAG, "XML-RPC call took " + (t1-t0) + "ms");
callBack.callFinished(result);
next();
}
});
}
catch (final XMLRPCFault e)
{
handler.post(new Runnable()
{
public void run()
{
Log.e(TAG, "Fault message: " + e.getFaultString() + "\nFault code: " + e.getFaultCode());
Log.d("Test", "error", e);
next();
}
});
}
catch (final XMLRPCException e)
{
next();
handler.post(new Runnable()
{
public void run()
{
Throwable couse = e.getCause();
if (couse instanceof HttpHostConnectException)
{
Log.e(TAG, "Cannot connect to " + m_uri.getHost() + "\nMake sure server.py on your development host is running !!!");
}
else
{
Log.e(TAG, "Error " + e.getMessage());
}
Log.d(TAG, "error", e);
}
});
}
catch (Exception e)
{
next();
e.printStackTrace();
}
}
}
}
}

Categories

Resources