Bluetooth enable intent in fragment - android

I've been searching everywhere and I can't find the answer. I'm simply trying to enable bluetooth in my fragment. I added the following to lines to my OnResume() callback:
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);
}
for some reason, the output just keeps saying, Activity.onPostResume() called over and over again and it actually locks out my UI. I was wondering if there's a solution?
Edit: AutoConnectFragment:
public class AutoConnectFragment extends Fragment {
private static final int PERMISSION_REQUEST_COARSE_LOCATION = 1;
private Toolbar mToolbar;
private CollapsingToolbarLayout collapsingToolbar;
private ImageView mBackArrow;
private Button mStartTiming;
private RecyclerView mLaserRecyclerView;
private LaserAdapter mAdapter;
private String mCurrentEvent;
private BluetoothAdapter mBluetoothAdapter;
private BluetoothLeScanner mBluetoothLeScanner;
private AutoConnectBLE mScanner;
private static boolean mIsLasersConnected;
private Drill mCurrentDrill;
private AutoConnectEventSelected mCallback;
private static final int REQUEST_ENABLE_BT = 3;
private static final int REQUEST_CODE_LOCATION = 42;
private boolean permissionChecked = false;
// Container Activity must implement this interface
public interface AutoConnectEventSelected {
public void onAutoConnectEventSelected(String event);
}
// private nested custom view holder class
public class LaserHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
private TextView mLaserName;
private Module mModule;
private ImageView mConnectIcon;
private ProgressBar mProgressBar;
public LaserHolder(LayoutInflater inflater, ViewGroup parent) {
super(inflater.inflate(R.layout.list_item_laser, parent, false));
itemView.setOnClickListener(this);
// grab the font
Typeface mont_reg = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Montserrat-Regular.ttf");
// grab the user name and change the font
mLaserName = (TextView) itemView.findViewById(R.id.laser_name);
mLaserName.setTypeface(mont_reg);
// grab the progress bar
mProgressBar = (ProgressBar) itemView.findViewById(R.id.progress_bar);
//grab the connect icon
mConnectIcon = (ImageView) itemView.findViewById(R.id.connect_icon);
}
public void bind(Module module) {
// set the text view to the module name
mModule = module;
mLaserName.setText(module.getName());
}
// if the user clicks on the connect laser
#Override
public void onClick(View v) {
if (mModule.getName().equals("RFID")) {
mProgressBar.setVisibility(View.VISIBLE);
mConnectIcon.setVisibility(View.GONE);
// mScanner.scanRFID(mCurrentDrill, mModule.getName(), v, getContext(), mAdapter,getAdapterPosition());
} else {
mProgressBar.setVisibility(View.VISIBLE);
mConnectIcon.setVisibility(View.GONE);
mScanner.scanLaser(v,mCurrentDrill, mModule.getName(),mAdapter,getAdapterPosition());
}
mAdapter.setCurrentPosition(getAdapterPosition());
}
}
public class LaserAdapter extends RecyclerView.Adapter<LaserHolder> {
private List<Module> mModules;
private String mCurrentMAC;
private int mCurrentPosition;
public LaserAdapter(List<Module> modules) {
mModules = modules;
}
#Override
public LaserHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(getActivity());
return new LaserHolder(layoutInflater, parent);
}
#Override
public void onBindViewHolder(LaserHolder holder, int position) {
Module module = mModules.get(position);
/* if a laser is already connected and
the user tries to connect the same laser to another position,
unconnect the previous connection
*/
if (!TextUtils.isEmpty(module.getMACaddress())){
if ( module.getMACaddress().equals(mCurrentMAC) && position != mCurrentPosition){
holder.mConnectIcon.setImageResource(R.drawable.ic_flash);
module.setMACaddress(null);
}
}
checkAllLasersConnected(mModules);
holder.bind(module);
}
#Override
public int getItemCount() {
return mModules.size();
}
public String getCurrentMAC() {
return mCurrentMAC;
}
public void setCurrentMAC(String currentMAC) {
mCurrentMAC = currentMAC;
}
public int getCurrentPosition() {
return mCurrentPosition;
}
public void setCurrentPosition(int currentPosition) {
mCurrentPosition = currentPosition;
}
public void checkAllLasersConnected(List<Module> modules){
int numLasersConnected = 0;
// checking to see if all of the lasers are connected
for (int i = 0; i < modules.size(); i++) {
System.out.println("Name: " + modules.get(i).getName() + " MAC :" + modules.get(i).getMACaddress());
if (modules.get(i).getMACaddress() == null) {
numLasersConnected++;
}
}
// if all of the lasers are connected, enabled the start timing button
if (numLasersConnected == 0) {
mStartTiming.setEnabled(true);
} else {
mStartTiming.setEnabled(false);
}
}
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
// inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_autoconnect, container, false);
// grab the recyclerview and set its layout manager
mLaserRecyclerView = (RecyclerView) view.findViewById(R.id.list_recycler_view);
mLaserRecyclerView.setLayoutManager((new LinearLayoutManager(getActivity())));
// update the UI ( recycler view )
updateUI(savedInstanceState);
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
// grab the views
collapsingToolbar = (CollapsingToolbarLayout) view.findViewById(R.id.collapsing_toolbar);
mToolbar = (Toolbar) view.findViewById(R.id.toolbar);
mBackArrow = (ImageView) view.findViewById(R.id.back_arrow);
mStartTiming = (Button) view.findViewById(R.id.start_timing_button);
// disable the startTiming button until all of the lasers are connected
mStartTiming.setEnabled(false);
//Set toolbar title
collapsingToolbar.setTitle(getArguments().getString("Event") + " Connect");
// setting the text alignment
collapsingToolbar.setExpandedTitleColor(Color.WHITE);
collapsingToolbar.setCollapsedTitleGravity(Gravity.CENTER_HORIZONTAL);
collapsingToolbar.setCollapsedTitleTextColor(Color.WHITE);
collapsingToolbar.setExpandedTitleGravity(Gravity.CENTER_HORIZONTAL);
// set the font
Typeface mont_bold = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Montserrat-Bold.ttf");
Typeface mont_regular = Typeface.createFromAsset(getActivity().getAssets(), "fonts/Montserrat-Regular.ttf");
collapsingToolbar.setExpandedTitleTypeface(mont_bold);
collapsingToolbar.setCollapsedTitleTypeface(mont_regular);
// set background color to dark grey
mToolbar.setBackgroundColor(getResources().getColor(R.color.darkGrey));
// set up bluetooth
mScanner = new AutoConnectBLE(getContext());
// collapsing tool bar effect ( explained in main activtiy)
AppBarLayout mAppBarLayout = (AppBarLayout) view.findViewById(R.id.app_bar_layout);
mAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int i) {
//measuring for alpha
int toolBarHeight = mToolbar.getMeasuredHeight();
int appBarHeight = appBarLayout.getMeasuredHeight();
Float f = ((((float) appBarHeight - toolBarHeight) + i) / ((float) appBarHeight - toolBarHeight)) * 255;
if (Math.round(f) == 0) {
mToolbar.setBackgroundColor(getResources().getColor(R.color.darkGrey));
} else {
mToolbar.getBackground().setAlpha(0);
}
}
});
// if user clicks on the back arrow, go back to testing page
mBackArrow.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Fragment frag = new TestingFragment();
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.replace(R.id.container, frag, frag.getTag());
ft.addToBackStack(null);
ft.commit();
}
});
// if the user clicks on the start timing, goto the timing page
mStartTiming.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mCallback.onAutoConnectEventSelected(getArguments().getString("Event"));
}
});
}
#Override
public void onResume() {
super.onResume();
System.out.println("ON RESUME CALLED");
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
System.out.println("INTENT CALLED");
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
getActivity().startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
//
// if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
// Toast.makeText(getActivity(), "No LE Support, Please install this app on another phone", Toast.LENGTH_SHORT).show();
// return;
// }
}
private void updateUI(Bundle savedInstanceState) {
List<Module> modules = null;
// check to see which event the user chose and grab the laser array list
switch (getArguments().getString("Event")) {
case "Dash":
Dash dash = Dash.getInstance();
modules = dash.getModules();
mCurrentDrill = dash;
break;
case "ProAgility":
ProAgility pa = ProAgility.getInstance();
modules = pa.getModules();
mCurrentDrill = pa;
break;
case "DashSplit":
DashSplit ds = DashSplit.getInstance();
modules = ds.getModules();
mCurrentDrill = ds;
break;
case "Flying40":
Flying40 f = Flying40.getInstance();
modules = f.getModules();
mCurrentDrill = f;
break;
case "Lap":
Lap l = Lap.getInstance();
modules = l.getModules();
mCurrentDrill = l;
break;
}
mAdapter = new LaserAdapter(modules);
mLaserRecyclerView.setAdapter(mAdapter);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
Activity a;
if (context instanceof Activity){
a = (Activity) context;
// This makes sure that the container activity has implemented
// the callback interface. If not, it throws an exception
try {
mCallback = (AutoConnectEventSelected) a;
} catch (ClassCastException e) {
throw new ClassCastException(a.toString()
+ " must implement OnHeadlineSelectedListener");
}
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_ENABLE_BT) {
System.out.println(requestCode);
if (resultCode == Activity.RESULT_CANCELED) {
//Bluetooth not enabled.
getActivity().finish();
return;
} else {
return;
}
}
super.onActivityResult(requestCode, resultCode, data);
}
}
BLE auto connect Scanner class:
public class AutoConnectBLE {
private BluetoothAdapter mBluetoothAdapter;
private BluetoothManager mBluetoothManager;
private BluetoothLeScanner mBluetoothLEScanner;
private ScanSettings mSettings;
private Context mContext;
private long mStartScanTimeStamp;
private long connectTimeStamp = 0L;
private class laserCallBack extends ScanCallback {
private Drill drill;
private AutoConnectFragment.LaserAdapter mAdapter;
private int position;
private boolean isConnected = false;
private long scanTimeStamp = 0L;
private long mElapsedTimeScanning;
private String mHex;
private long mLaserTime;
private String mBeefMessage;
private String name;
private ImageView mConnectIcon;
private ProgressBar mProgressBar;
public laserCallBack(View view, Drill drill,String name, AutoConnectFragment.LaserAdapter mAdapter, int position) {
super();
this.drill = drill;
this.mAdapter = mAdapter;
this.position = position;
this.name = name;
// grab views
mProgressBar = (ProgressBar) view.findViewById(R.id.progress_bar);
mConnectIcon = (ImageView) view.findViewById(R.id.connect_icon);
}
#Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
// grab a timestamp of when the scan starts
scanTimeStamp = SystemClock.uptimeMillis();
// if its been 3 seconds, without scanning then stop
mElapsedTimeScanning = (scanTimeStamp - mStartScanTimeStamp) / 1000;
// if the elapsed time is 3 seconds, then stop the scan
if (mElapsedTimeScanning >= 3) {
if (mConnectIcon.getVisibility() != View.VISIBLE) {
// if nothing was found, stop the circular progress bar and place the lightning bolt
mProgressBar.setVisibility(View.GONE);
mConnectIcon.setImageResource(R.drawable.ic_flash);
mConnectIcon.setVisibility(View.VISIBLE);
// clear out laser
ArrayList<Module> m = drill.getModules();
m.get(position).setMACaddress(null);
}
mAdapter.notifyDataSetChanged();
isConnected = false;
mBluetoothLEScanner.stopScan(this);
} else {
// grabbing important data from byte record
mHex = ConversionHelper
.bytesToHex(result.getScanRecord().getBytes());
mLaserTime = ConversionHelper.
hex2decimal(mHex.substring(24, 32));
mBeefMessage = mHex.substring(32, 36);
/* if there is no connection yet, and the beef message is preset,
and the laser time < 3 seconds,
and its atleast 3 seconds since another laser has advertised,
accept this new scan record as a potential new laser
*/
System.out.println("CONNECTION DELAY:" + (scanTimeStamp - connectTimeStamp));
if (!isConnected
&& ConversionHelper.hex2decimal(mBeefMessage) == 48879
&& mLaserTime < 3000
&& scanTimeStamp - connectTimeStamp > 3000) {
// set isConnected to true
isConnected = true;
// grab second timestamp - used so that people can't connect the same MAC for 2 lasers
connectTimeStamp = SystemClock.uptimeMillis();
System.out.println("CONNECT TIME STAMP" + connectTimeStamp);
// set the MAC address of the laser
drill.setMAC(name, result.getDevice().getAddress());
mAdapter.setCurrentMAC(result.getDevice().getAddress());
mAdapter.notifyDataSetChanged();
// check to see if this laser is connected to another position
// if the device finds a viable laser, replace the circular progress bar with a checkmark
mProgressBar.setVisibility(View.GONE);
mConnectIcon.setImageResource(R.drawable.ic_connected);
mConnectIcon.setVisibility(View.VISIBLE);
// notify the user that the start laser has been connected
Toast message = Toast.makeText(mContext, name + " Connected!", Toast.LENGTH_SHORT);
message.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
message.show();
isConnected = false;
mBluetoothLEScanner.stopScan(this);
}
}
}
}
public AutoConnectBLE(Context context) {
// grab context
mContext = context;
// grab BLE scanner
mBluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = mBluetoothManager.getAdapter();
mBluetoothLEScanner = mBluetoothAdapter.getBluetoothLeScanner();
// set settings to LOW LATENCY
mSettings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
.build();
}
public void scanLaser(View view,Drill drill ,String name, final AutoConnectFragment.LaserAdapter mAdapter, int position) {
mStartScanTimeStamp = SystemClock.uptimeMillis();
mBluetoothLEScanner.startScan(new ArrayList<ScanFilter>(), mSettings,new laserCallBack(view, drill, name, mAdapter, position));
}
// public void scanRFID(final Drill drill, final String name, final View v, final Context context, final AutoConnectFragment.LaserAdapter mAdapter, final int position) {
//
// final ScanCallback RFIDCallBack = new ScanCallback() {
// #Override
// public void onScanResult(int callbackType, ScanResult result) {
// super.onScanResult(callbackType, result);
//
// // grab a timestamp
// scanTimeStamp = SystemClock.uptimeMillis();
//
//
// String hex = ConversionHelper
// .bytesToHex(result.getScanRecord().getBytes());
// String RFIDBeefMessage = hex.substring(36, 40);
// System.out.println(hex);
//
// // if its been 3 seconds, without connecting then stop
// mElapsedTimeScanning = (scanTimeStamp - mStartScanTimeStamp) / 1000;
// if (mElapsedTimeScanning == 3) {
// ImageView mConnectIcon = (ImageView) v.findViewById(R.id.connect_icon);
// if (mConnectIcon.getVisibility() != View.VISIBLE) {
//
// // if nothing was found, stop the circular progress bar and place the lightning bolt
// ProgressBar mProgressBar = (ProgressBar) v.findViewById(R.id.progress_bar);
// mProgressBar.setVisibility(View.GONE);
// mConnectIcon.setImageResource(R.drawable.ic_flash);
// mConnectIcon.setVisibility(View.VISIBLE);
//
// }
// System.out.println("STOPPED SCANNING");
// mBluetoothLEScanner.stopScan(this);
// isConnected = false;
// }
//
// // RFID
// if (!isConnected && RFIDBeefMessage.equals("BEEF")) {
// isConnected = true;
// mBluetoothLEScanner.stopScan(this);
//
// // set the MAC address of the laser
// String MACAddress = result.getDevice().getAddress();
// drill.setMAC(name, MACAddress);
// // notify the user that the start laser has been connected
//
// // if the device finds a viable laser, replace the circular progress bar with a checkmark
// ImageView mConnectIcon = (ImageView) v.findViewById(R.id.connect_icon);
// ProgressBar mProgressBar = (ProgressBar) v.findViewById(R.id.progress_bar);
// mProgressBar.setVisibility(View.GONE);
// mConnectIcon.setImageResource(R.drawable.ic_connected);
// mConnectIcon.setVisibility(View.VISIBLE);
// Toast message = Toast.makeText(context, name + " Connected!", Toast.LENGTH_SHORT);
// message.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
// message.show();
//
// }
//
// }
//
// };
// mStartScanTimeStamp = SystemClock.uptimeMillis();
// mBluetoothLEScanner.startScan(new ArrayList<ScanFilter>(), mSettings, RFIDCallBack);
//
//
// }
}

Use below code to enable your bluetooth
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(!mBluetoothAdapter.isEnabled()){
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getActivity());
alertBuilder.setCancelable(true);
alertBuilder.setMessage("Do you want to enable bluetooth");
alertBuilder.setNeutralButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
mBluetoothAdapter.enable();
}
});
AlertDialog alert = alertBuilder.create();
alert.show();
}

Just add a manifest permission for Bluetooth access.
<uses-permission android:name="android.permission.BLUETOOTH"/>
and add this snippet in your fragment, for run time permission allowance.
if (ContextCompat.checkSelfPermission(getContext(), Manifest.permission.BLUETOOTH)
!= PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(((Activity)getContext()),
new String[]{Manifest.permission.BLUETOOTH}, REQUEST_CODE);
}
The snippet automatically launch an alert for Bluetooth access.

First get a BluetoothAdapter object
BluetoothAdapter adapter = BluetoothAdapter.getDefaultBluetoothAdapter();
if(adapter != null){
adapter.enable();
}
Using above code you can enable Bluetooth without user permission.I hope this code will help you

Related

Viewpager operations triggered on wrong reference

I am having a Viewpager where i am loading data of different categories. I want to show a custom dialog popup whenever user stays on a particular category for 5 seconds or more asking the user if he/she wants to share the content. For that i have used a custom dialog and am hiding/showing based on the condition.
But the problem is, that if i want to open the dialog if the user stays on Viewpager item at position let's say 3, the dialog is opening for the Viewpager item at position 4.
I am not sure why it's referencing the wrong Viewpager item.
I am including the code of Adapter class for the reference.
ArticleAdapter.java
public class ArticleAdapter extends PagerAdapter {
public List<Articles> articlesListChild;
private LayoutInflater inflater;
Context context;
View rootView;
View customArticleShareDialog, customImageShareDialog;
public int counter = 0;
int contentType = 0;
int userId;
public ArticleAdapter(Context context, List<Articles> articlesListChild, int userId) {
super();
this.context = context;
this.userId = userId;
this.articlesListChild = articlesListChild;
}
#Override
public int getCount() {
return articlesListChild.size();
}
#Override
public void destroyItem(View collection, int position, Object view) {
((ViewPager) collection).removeView((View) view);
}
private Timer timer;
private TimerTask timerTask;
public void startTimer() {
timer = new Timer();
initializeTimerTask();
timer.schedule(timerTask, 5*1000, 5*1000);
}
private void initializeTimerTask() {
timerTask = new TimerTask() {
public void run() {
switch (contentType) {
case 1:
showShareDialog("articles");
break;
case 2:
showShareDialog("images");
break;
default :
// Do Nothing
}
}
};
}
#Override
public boolean isViewFromObject(View view, Object object) {
return view == object;
}
#SuppressLint("ClickableViewAccessibility")
#Override
public Object instantiateItem(ViewGroup container, final int position) {
inflater = LayoutInflater.from(container.getContext());
View viewLayout = inflater.inflate(R.layout.article_single_item, null, false);
final ImageView contentIv, imageContentIv;
final TextView sharingTextTv;
final LinearLayout articleShareBtn, articlesLayout, imagesLayout, customArticleShareDialog, customImageShareDialog;
contentIv = viewLayout.findViewById(R.id.content_iv);
articleShareBtn = viewLayout.findViewById(R.id.article_share_btn);
articlesLayout = viewLayout.findViewById(R.id.articles_layout);
imagesLayout = viewLayout.findViewById(R.id.images_layout);
imageContentIv = viewLayout.findViewById(R.id.image_content_iv);
sharingTextTv = viewLayout.findViewById(R.id.sharing_text_tv);
customArticleShareDialog = viewLayout.findViewById(R.id.articles_share_popup);
customImageShareDialog = viewLayout.findViewById(R.id.images_share_popup);
rootView = viewLayout.findViewById(R.id.post_main_cv);
viewLayout.setTag(rootView);
articleShareBtn.setTag(rootView);
// Images
if (articlesListChild.get(position).getArticleCatId() == 1) {
articlesLayout.setVisibility(GONE);
imagesLayout.setVisibility(View.VISIBLE);
RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(R.drawable.placeholder);
Glide.with(context)
.setDefaultRequestOptions(requestOptions)
.load(articlesListChild.get(position).getArticleImage())
.into(imageContentIv);
imageContentIv.setScaleType(ImageView.ScaleType.FIT_XY);
sharingTextTv.setText("Found this image interesting? Share it with your friends.");
counter = 0;
startTimer();
// Articles
} else if (articlesListChild.get(position).getArticleCatId() == 2){
RequestOptions requestOptions = new RequestOptions();
requestOptions.placeholder(R.drawable.placeholder);
articlesLayout.setVisibility(View.VISIBLE);
Glide.with(context)
.setDefaultRequestOptions(requestOptions)
.load(articlesListChild.get(position).getArticleImage())
.into(contentIv);
contentIv.setScaleType(ImageView.ScaleType.FIT_XY);
sharingTextTv.setText("Found this article interesting? Share it with your friends.");
counter = 0;
startTimer();
}
container.addView(viewLayout, 0);
return viewLayout;
}
public void showShareDialog(String categoryType) {
if (categoryType.equalsIgnoreCase("articles")) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
public void run() {
customArticleShareDialog.setVisibility(View.VISIBLE);
}
});
} else if (categoryType.equalsIgnoreCase("images")) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
public void run() {
customImageShareDialog.setVisibility(View.VISIBLE);
}
});
}
}
}
ArticleActivity.java
public class ArticleActivity extends AppCompatActivity {
#BindView(R.id.toolbar)
Toolbar toolbar;
#BindView(R.id.drawer_layout)
DrawerLayout drawer;
#BindView(R.id.articles_view_pager)
ViewPager articlesViewPager;
#BindView(R.id.constraint_head_layout)
CoordinatorLayout constraintHeadLayout;
private ArticleAdapter articleAdapter;
private List<List<Articles>> articlesList = null;
private List<Articles> articlesListChild = new ArrayList<>();
private List<Articles> articlesListChildNew = new ArrayList<>();
SessionManager session;
Utils utils;
final static int MY_PERMISSIONS_WRITE_EXTERNAL_STORAGE = 1;
int userIdLoggedIn;
LsArticlesSharedPreference lsArticlesSharedPreference;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
ButterKnife.bind(this);
toolbar.setTitle("");
toolbar.bringToFront();
session = new SessionManager(getApplicationContext());
if (session.isLoggedIn()) {
HashMap<String, String> user = session.getUserDetails();
String userId = user.get(SessionManager.KEY_ID);
userIdLoggedIn = Integer.valueOf(userId);
} else {
userIdLoggedIn = 1000;
}
utils = new Utils(getApplicationContext());
String storedTime = PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getString("lastUsedDate", "");
System.out.println("lastUsedDate : " + storedTime);
if (utils.isNetworkAvailable()) {
insertData();
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
toggle.getDrawerArrowDrawable().setColor(getResources().getColor(R.color.colorWhite));
drawer.addDrawerListener(toggle);
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_WRITE_EXTERNAL_STORAGE);
}
articleAdapter = new ArticleAdapter(getApplicationContext(), articlesListChild, userIdLoggedIn);
toggle.syncState();
clickListeners();
toolbar.setVisibility(View.GONE);
} else {
Intent noInternetIntent = new Intent(getApplicationContext(), NoInternetActivity.class);
startActivity(noInternetIntent);
}
}
#Override
public void onBackPressed() {
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
finishAffinity();
super.onBackPressed();
}
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onStop() {
super.onStop();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.home, menu);
return true;
}
#Override
public boolean onSupportNavigateUp() {
finish();
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_refresh:
articleAdapter.notifyDataSetChanged();
insertData();
Toast.makeText(this, "Refreshed", Toast.LENGTH_SHORT).show();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#SuppressLint("ClickableViewAccessibility")
public void clickListeners() {
}
private void insertData() {
Intent intent = new Intent(getBaseContext(), OverlayService.class);
startService(intent);
final SweetAlertDialog pDialog = new SweetAlertDialog(ArticleActivity.this, SweetAlertDialog.PROGRESS_TYPE);
pDialog.getProgressHelper().setBarColor(getResources().getColor(R.color.colorPrimary));
pDialog.setTitleText("Loading");
pDialog.setCancelable(false);
pDialog.show();
Api.getClient().getHomeScreenContents(userIdLoggedIn, new Callback<ArticlesResponse>() {
#Override
public void success(ArticlesResponse articlesResponse, Response response) {
articlesList = articlesResponse.getHomeScreenData();
if (!articlesList.isEmpty()) {
for (int i = 0; i < articlesList.size(); i++) {
articlesListChildNew = articlesList.get(i);
articlesListChild.addAll(articlesListChildNew);
}
articleAdapter = new ArticleAdapter(getApplicationContext(), articlesList, articlesListChild, userIdLoggedIn, toolbar);
articlesViewPager.setAdapter(articleAdapter);
articleAdapter.notifyDataSetChanged();
pDialog.dismiss();
} else {
List<Articles> savedArticles = lsArticlesSharedPreference.getFavorites(getApplicationContext());
if (!savedArticles.isEmpty()) {
articleAdapter = new ArticleAdapter(getApplicationContext(), articlesList, savedArticles, userIdLoggedIn, toolbar);
articlesViewPager.setAdapter(articleAdapter);
articleAdapter.notifyDataSetChanged();
pDialog.dismiss();
} else {
Api.getClient().getAllArticles(new Callback<AllArticlesResponse>() {
#Override
public void success(AllArticlesResponse allArticlesResponse, Response response) {
articlesListChild = allArticlesResponse.getArticles();
articleAdapter = new ArticleAdapter(getApplicationContext(), articlesList, articlesListChild, userIdLoggedIn, toolbar);
articlesViewPager.setAdapter(articleAdapter);
articleAdapter.notifyDataSetChanged();
};
#Override
public void failure(RetrofitError error) {
Log.e("articlesData", error.toString());
}
});
pDialog.dismiss();
}
}
}
#Override
public void failure(RetrofitError error) {
pDialog.dismiss();
Toast.makeText(ArticleActivity.this, "There was some error fetching the data.", Toast.LENGTH_SHORT).show();
}
});
}
}
Issue reason:
You face this issue because the viewpager preload fragments in background. It means that when you see 3rd fragment, the viewpager is instantiating 4th. Due to this workflow your timer for 3rd screen is cancelled and timer for 4th screen is started. Check out this link to understand what is going on.
Solution:
I would do next:
Then set page change listener for your adapter. How to do it
In this listener you can get current page and start timer for this page (and cancel timer for previously visible page).
You don't need to call startTimer() method when you instantiate item in instantiateItem() method.

when using a void in other class, get error on a null object reference

When I'm trying to use other RFID SDK to get Tag Code. And send to the server to fetch the tag information. But I only can get the RFID SDK demon working. So I just try to add HTTP request method into the demon. but I always get an error about I'm calling a null object reference. when I use
IAcitivity.IMakeHttpCall();
Inventory Activity
import com.android.volley.AuthFailureError;
import com.android.volley.NetworkError;
import com.android.volley.NoConnectionError;
import com.android.volley.ParseError;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.ServerError;
import com.android.volley.TimeoutError;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.Volley;
import com.uk.tsl.rfid.ModelBase;
import com.uk.tsl.rfid.TSLBluetoothDeviceActivity;
import com.uk.tsl.rfid.WeakHandler;
import com.uk.tsl.rfid.asciiprotocol.AsciiCommander;
import com.uk.tsl.rfid.asciiprotocol.DeviceProperties;
import com.uk.tsl.rfid.asciiprotocol.commands.FactoryDefaultsCommand;
import com.uk.tsl.rfid.asciiprotocol.enumerations.QuerySession;
import com.uk.tsl.rfid.asciiprotocol.enumerations.TriState;
import com.uk.tsl.rfid.asciiprotocol.parameters.AntennaParameters;
import com.uk.tsl.rfid.asciiprotocol.responders.LoggerResponder;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
public class InventoryActivity extends TSLBluetoothDeviceActivity {
// Debug control
private static final boolean D = BuildConfig.DEBUG;
private RequestQueue mVolleyQueue;
// OkHttpClient httpClient = new OkHttpClient();
// The list of results from actions
private ArrayAdapter<String> mResultsArrayAdapter;
private ListView mResultsListView;
private ArrayAdapter<String> mBarcodeResultsArrayAdapter;
private ListView mBarcodeResultsListView;
// The text view to display the RF Output Power used in RFID commands
private TextView mPowerLevelTextView;
// The seek bar used to adjust the RF Output Power for RFID commands
private SeekBar mPowerSeekBar;
// The current setting of the power level
private int mPowerLevel = AntennaParameters.MaximumCarrierPower;
// Error report
private TextView mResultTextView;
// Custom adapter for the session values to display the description rather than the toString() value
public class SessionArrayAdapter extends ArrayAdapter<QuerySession> {
private final QuerySession[] mValues;
public SessionArrayAdapter(Context context, int textViewResourceId, QuerySession[] objects) {
super(context, textViewResourceId, objects);
mValues = objects;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
TextView view = (TextView)super.getView(position, convertView, parent);
view.setText(mValues[position].getDescription());
return view;
}
#Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
TextView view = (TextView)super.getDropDownView(position, convertView, parent);
view.setText(mValues[position].getDescription());
return view;
}
}
// The session
private QuerySession[] mSessions = new QuerySession[] {
QuerySession.SESSION_0,
QuerySession.SESSION_1,
QuerySession.SESSION_2,
QuerySession.SESSION_3
};
// The list of sessions that can be selected
private SessionArrayAdapter mSessionArrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inventory);
mVolleyQueue = Volley.newRequestQueue(this);
mResultsArrayAdapter = new ArrayAdapter<String>(this,R.layout.result_item);
mBarcodeResultsArrayAdapter = new ArrayAdapter<String>(this,R.layout.result_item);
mResultTextView = (TextView)findViewById(R.id.resultTextView);
// Find and set up the results ListView
mResultsListView = (ListView) findViewById(R.id.resultListView);
mResultsListView.setAdapter(mResultsArrayAdapter);
mResultsListView.setFastScrollEnabled(true);
mBarcodeResultsListView = (ListView) findViewById(R.id.barcodeListView);
mBarcodeResultsListView.setAdapter(mBarcodeResultsArrayAdapter);
mBarcodeResultsListView.setFastScrollEnabled(true);
// Hook up the button actions
Button sButton = (Button)findViewById(R.id.扫描开始);
sButton.setOnClickListener(mScanButtonListener);
Button cButton = (Button)findViewById(R.id.清除按钮);
cButton.setOnClickListener(mClearButtonListener);
// The SeekBar provides an integer value for the antenna power
mPowerLevelTextView = (TextView)findViewById(R.id.powerTextView);
mPowerSeekBar = (SeekBar)findViewById(R.id.powerSeekBar);
mPowerSeekBar.setOnSeekBarChangeListener(mPowerSeekBarListener);
// Set the seek bar current value to maximum and to cover the range of the power settings
setPowerBarLimits();
mSessionArrayAdapter = new SessionArrayAdapter(this, android.R.layout.simple_spinner_item, mSessions);
// Find and set up the sessions spinner
Spinner spinner = (Spinner) findViewById(R.id.sessionSpinner);
mSessionArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner.setAdapter(mSessionArrayAdapter);
spinner.setOnItemSelectedListener(mActionSelectedListener);
spinner.setSelection(0);
// Set up Fast Id check box listener
CheckBox cb = (CheckBox)findViewById(R.id.fastIdCheckBox);
cb.setOnClickListener(mFastIdCheckBoxListener);
//
// An AsciiCommander has been created by the base class
//
AsciiCommander commander = getCommander();
// Add the LoggerResponder - this simply echoes all lines received from the reader to the log
// and passes the line onto the next responder
// This is added first so that no other responder can consume received lines before they are logged.
commander.addResponder(new LoggerResponder());
// Add a synchronous responder to handle synchronous commands
commander.addSynchronousResponder();
//Create a (custom) model and configure its commander and handler
mModel = new InventoryModel();
mModel.setCommander(getCommander());
mModel.setHandler(mGenericModelHandler);
}
#Override
public synchronized void onPause() {
super.onPause();
mModel.setEnabled(false);
// Unregister to receive notifications from the AsciiCommander
LocalBroadcastManager.getInstance(this).unregisterReceiver(mCommanderMessageReceiver);
}
#Override
public synchronized void onResume() {
super.onResume();
mModel.setEnabled(true);
// Register to receive notifications from the AsciiCommander
LocalBroadcastManager.getInstance(this).registerReceiver(mCommanderMessageReceiver,
new IntentFilter(AsciiCommander.STATE_CHANGED_NOTIFICATION));
displayReaderState();
UpdateUI();
}
//----------------------------------------------------------------------------------------------
// Menu
//----------------------------------------------------------------------------------------------
private MenuItem mReconnectMenuItem;
private MenuItem mConnectMenuItem;
private MenuItem mDisconnectMenuItem;
private MenuItem mResetMenuItem;
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.reader_menu, menu);
mResetMenuItem = menu.findItem(R.id.reset_reader_menu_item);
mReconnectMenuItem = menu.findItem(R.id.reconnect_reader_menu_item);
mConnectMenuItem = menu.findItem(R.id.insecure_connect_reader_menu_item);
mDisconnectMenuItem= menu.findItem(R.id.disconnect_reader_menu_item);
return true;
}
/**
* Prepare the menu options
*/
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
boolean isConnecting = getCommander().getConnectionState() == AsciiCommander.ConnectionState.CONNECTING;
boolean isConnected = getCommander().isConnected();
mResetMenuItem.setEnabled(isConnected);
mDisconnectMenuItem.setEnabled(isConnected);
mReconnectMenuItem.setEnabled(!(isConnecting || isConnected));
mConnectMenuItem.setEnabled(!(isConnecting || isConnected));
return super.onPrepareOptionsMenu(menu);
}
/**
* Respond to menu item selections
*/
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.reconnect_reader_menu_item:
Toast.makeText(this.getApplicationContext(), "重新连接中...", Toast.LENGTH_LONG).show();
reconnectDevice();
UpdateUI();
return true;
case R.id.insecure_connect_reader_menu_item:
// Choose a device and connect to it
selectDevice();
return true;
case R.id.disconnect_reader_menu_item:
Toast.makeText(this.getApplicationContext(), "断开连接中...", Toast.LENGTH_SHORT).show();
disconnectDevice();
displayReaderState();
return true;
case R.id.reset_reader_menu_item:
resetReader();
UpdateUI();
return true;
}
return super.onOptionsItemSelected(item);
}
//
private void UpdateUI() {
//boolean isConnected = getCommander().isConnected();
//TODO: configure UI control state
}
private void scrollResultsListViewToBottom() {
mResultsListView.post(new Runnable() {
#Override
public void run() {
// Select the last row so it will scroll into view...
mResultsListView.setSelection(mResultsArrayAdapter.getCount() - 1);
}
});
}
private void scrollBarcodeListViewToBottom() {
mBarcodeResultsListView.post(new Runnable() {
#Override
public void run() {
// Select the last row so it will scroll into view...
mBarcodeResultsListView.setSelection(mBarcodeResultsArrayAdapter.getCount() - 1);
}
});
}
//----------------------------------------------------------------------------------------------
// AsciiCommander message handling
//----------------------------------------------------------------------------------------------
//
// Handle the messages broadcast from the AsciiCommander
//
private BroadcastReceiver mCommanderMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (D) { Log.d(getClass().getName(), "AsciiCommander state changed - isConnected: " + getCommander().isConnected()); }
String connectionStateMsg = intent.getStringExtra(AsciiCommander.REASON_KEY);
Toast.makeText(context, connectionStateMsg, Toast.LENGTH_SHORT).show();
displayReaderState();
if( getCommander().isConnected() )
{
// Update for any change in power limits
setPowerBarLimits();
// This may have changed the current power level setting if the new range is smaller than the old range
// so update the model's inventory command for the new power value
mModel.getCommand().setOutputPower(mPowerLevel);
mModel.resetDevice();
mModel.updateConfiguration();
}
UpdateUI();
}
};
//----------------------------------------------------------------------------------------------
// Reader reset
//----------------------------------------------------------------------------------------------
//
// Handle reset controls
//
private void resetReader() {
try {
// Reset the reader
FactoryDefaultsCommand fdCommand = FactoryDefaultsCommand.synchronousCommand();
getCommander().executeCommand(fdCommand);
String msg = "Reset " + (fdCommand.isSuccessful() ? "succeeded" : "failed");
Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
UpdateUI();
} catch (Exception e) {
e.printStackTrace();
}
}
//----------------------------------------------------------------------------------------------
// Power seek bar
//----------------------------------------------------------------------------------------------
//
// Set the seek bar to cover the range of the currently connected device
// The power level is set to the new maximum power
//
private void setPowerBarLimits()
{
DeviceProperties deviceProperties = getCommander().getDeviceProperties();
mPowerSeekBar.setMax(deviceProperties.getMaximumCarrierPower() - deviceProperties.getMinimumCarrierPower());
mPowerLevel = deviceProperties.getMaximumCarrierPower();
mPowerSeekBar.setProgress(mPowerLevel - deviceProperties.getMinimumCarrierPower());
}
//
// Handle events from the power level seek bar. Update the mPowerLevel member variable for use in other actions
//
private OnSeekBarChangeListener mPowerSeekBarListener = new OnSeekBarChangeListener() {
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// Nothing to do here
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// Update the reader's setting only after the user has finished changing the value
updatePowerSetting(getCommander().getDeviceProperties().getMinimumCarrierPower() + seekBar.getProgress());
mModel.getCommand().setOutputPower(mPowerLevel);
mModel.updateConfiguration();
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
updatePowerSetting(getCommander().getDeviceProperties().getMinimumCarrierPower() + progress);
}
};
private void updatePowerSetting(int level) {
mPowerLevel = level;
mPowerLevelTextView.setText( mPowerLevel + " dBm");
}
//----------------------------------------------------------------------------------------------
// Button event handlers
//----------------------------------------------------------------------------------------------
// Scan action
private OnClickListener mScanButtonListener = new OnClickListener() {
public void onClick(View v) {
try {
mResultTextView.setText("");
// Perform a transponder scan
IMakeHttpCall();
UpdateUI();
} catch (Exception e) {
e.printStackTrace();
}
}
};
// Clear action
private OnClickListener mClearButtonListener = new OnClickListener() {
public void onClick(View v) {
try {
// Clear the list
mResultsArrayAdapter.clear();
mBarcodeResultsArrayAdapter.clear();
UpdateUI();
} catch (Exception e) {
e.printStackTrace();
}
}
};
//----------------------------------------------------------------------------------------------
// Handler for changes in session
//----------------------------------------------------------------------------------------------
private AdapterView.OnItemSelectedListener mActionSelectedListener = new AdapterView.OnItemSelectedListener()
{
#Override
public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
if( mModel.getCommand() != null ) {
QuerySession targetSession = (QuerySession)parent.getItemAtPosition(pos);
mModel.getCommand().setQuerySession(targetSession);
mModel.updateConfiguration();
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
};
//----------------------------------------------------------------------------------------------
// Handler for changes in FastId
//----------------------------------------------------------------------------------------------
private OnClickListener mFastIdCheckBoxListener = new OnClickListener() {
public void onClick(View v) {
try {
CheckBox fastIdCheckBox = (CheckBox)v;
mModel.getCommand().setUsefastId(fastIdCheckBox.isChecked() ? TriState.YES : TriState.NO);
mModel.updateConfiguration();
UpdateUI();
} catch (Exception e) {
e.printStackTrace();
}
}
};
public void IMakeHttpCall(){
String url = "http://192.168.1.76:4300/lottem/query/toolsstockInventory/";
Uri.Builder builder = Uri.parse(url).buildUpon();
builder.appendQueryParameter("barCode", "1121212121");
JsonArrayRequest jsonObjRequest = new JsonArrayRequest(builder.toString(),
new Response.Listener<JSONArray>(){
#Override
public void onResponse(JSONArray response) {
try {
JSONObject person;
for (int i = 0; i < response.length(); i++) {
person = response.getJSONObject(i);
String name = person.getString(("toolsName"));
mResultTextView.setText(name);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Handle your error types accordingly.For Timeout & No connection error, you can show 'retry' button.
// For AuthFailure, you can re login with user credentials.
// For ClientError, 400 & 401, Errors happening on client side when sending api request.
// In this case you can check how client is forming the api and debug accordingly.
// For ServerError 5xx, you can do retry or handle accordingly.
if (error instanceof NetworkError) {
} else if (error instanceof ServerError) {
} else if (error instanceof AuthFailureError) {
} else if (error instanceof ParseError) {
} else if (error instanceof NoConnectionError) {
} else if (error instanceof TimeoutError) {
}
}
});
//Set a retry policy in case of SocketTimeout & ConnectionTimeout Exceptions. Volley does retry for you if you have specified the policy.
mVolleyQueue.add(jsonObjRequest);
}
}
InventoryModel
//----------------------------------------------------------------------------------------------
// Copyright (c) 2013 Technology Solutions UK Ltd. All rights reserved.
//----------------------------------------------------------------------------------------------
package com.uk.tsl.rfid.samples.inventory;
import android.util.Log;
import com.uk.tsl.rfid.ModelBase;
import com.uk.tsl.rfid.asciiprotocol.commands.BarcodeCommand;
import com.uk.tsl.rfid.asciiprotocol.commands.FactoryDefaultsCommand;
import com.uk.tsl.rfid.asciiprotocol.commands.InventoryCommand;
import com.uk.tsl.rfid.asciiprotocol.enumerations.TriState;
import com.uk.tsl.rfid.asciiprotocol.responders.IBarcodeReceivedDelegate;
import com.uk.tsl.rfid.asciiprotocol.responders.ICommandResponseLifecycleDelegate;
import com.uk.tsl.rfid.asciiprotocol.responders.ITransponderReceivedDelegate;
import com.uk.tsl.rfid.asciiprotocol.responders.TransponderData;
import com.uk.tsl.utils.HexEncoding;
import java.util.Locale;
public class InventoryModel extends ModelBase
{
// Control
private boolean mAnyTagSeen;
private boolean mEnabled;
public boolean enabled() { return mEnabled; }
private InventoryActivity IAcitivity;
public void setEnabled(boolean state)
{
boolean oldState = mEnabled;
mEnabled = state;
// Update the commander for state changes
if(oldState != state) {
if( mEnabled ) {
// Listen for transponders
getCommander().addResponder(mInventoryResponder);
// Listen for barcodes
getCommander().addResponder(mBarcodeResponder);
} else {
// Stop listening for transponders
getCommander().removeResponder(mInventoryResponder);
// Stop listening for barcodes
getCommander().removeResponder(mBarcodeResponder);
}
}
}
// The command to use as a responder to capture incoming inventory responses
private InventoryCommand mInventoryResponder;
// The command used to issue commands
private InventoryCommand mInventoryCommand;
// The command to use as a responder to capture incoming barcode responses
private BarcodeCommand mBarcodeResponder;
// The inventory command configuration
public InventoryCommand getCommand() { return mInventoryCommand; }
public InventoryModel()
{
// This is the command that will be used to perform configuration changes and inventories
mInventoryCommand = new InventoryCommand();
mInventoryCommand.setResetParameters(TriState.YES);
// Configure the type of inventory
mInventoryCommand.setIncludeTransponderRssi(TriState.YES);
mInventoryCommand.setIncludeChecksum(TriState.YES);
mInventoryCommand.setIncludePC(TriState.YES);
mInventoryCommand.setIncludeDateTime(TriState.YES);
// Use an InventoryCommand as a responder to capture all incoming inventory responses
mInventoryResponder = new InventoryCommand();
// Also capture the responses that were not from App commands
mInventoryResponder.setCaptureNonLibraryResponses(true);
// Notify when each transponder is seen
mInventoryResponder.setTransponderReceivedDelegate(new ITransponderReceivedDelegate() {
int mTagsSeen = 0;
#Override
public void transponderReceived(final TransponderData transponder, boolean moreAvailable) {
mAnyTagSeen = true;
final String tidMessage = transponder.getTidData() == null ? "" : HexEncoding.bytesToString(transponder.getTidData());
final String infoMsg = String.format(Locale.US, "\nRSSI: %d PC: %04X CRC: %04X", transponder.getRssi(), transponder.getPc(), transponder.getCrc());
IAcitivity.IMakeHttpCall();
sendMessageNotification("条形码:"+transponder.getEpc());
mTagsSeen++;
if( !moreAvailable) {
sendMessageNotification("");
Log.d("扫描次数",String.format("扫描到的次数: %s", mTagsSeen));
}
}
});
}

Android kankan-wheel modification

I am making a slot machine app and using kankan's wheel for the same. I want to modify the library such that when the rotation stops the item it will point shoud be the one that I set . I have done this but there is a glitch that shows that we have changed the actual image to the one that we want . How to achieve this?
Update:
I have researched a lot on this and if I am right , android scroll is based on duration and distance not items . From kankan's wheel library I can get current item .Now , I am trying to stop the animation as well as scroll , as soon as a certain duration has been reached and the item is the one that I want (through index) . But this is not working .Please help!!
GameActivity
public class GameActivity extends Activity {
float mDeviceDensity;
String mUuid, mTitle, mContent, mReward;
ImageButton play;
SlotMachineAdapter slotAdapter;
private List<HashMap<String, Object>> slotImages = new ArrayList<HashMap<String, Object>>();
ArrayList<String> imagesWinId = new ArrayList<String>();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_filler_up_game);
DisplayMetrics display = getResources().getDisplayMetrics();
mDeviceDensity = display.density;
slotAdapter = new SlotMachineAdapter(this);
getPassedData();
setSoundPlayer(R.raw.clicks,true);
initWheel(R.id.slot_1, false, 0);
initWheel(R.id.slot_2, false, 1);
initWheel(R.id.slot_3, true, 2);
play = (ImageButton) findViewById(R.id.btn_mix);
play.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
shuffle(R.id.slot_1, 5000);
shuffle(R.id.slot_2, 7000);
shuffle(R.id.slot_3, 9000);
}
});
}
protected ImageLoader imageLoader;
ArrayList<SlotItem> arrListSlotItems;
private void getPassedData() {
try {
mUuid = getIntent().getStringExtra(getString(R.string.FILLER_UP_UUID));
imageLoader = ImageLoader.getInstance();
Uuid slotImagesExtra = (Uuid) (getIntent()
.getSerializableExtra(getString(R.string.FILLER_UP_IMAGES)));
arrListSlotItems = slotImagesExtra.getArrSlotItemArray();
for (int i = 0; i < arrListSlotItems.size(); i++)
downloadSlotImages(arrListSlotItems.get(i).getSlotId(), arrListSlotItems.get(i).getImageUrl());
} catch (Exception e) {
e.printStackTrace();
}
}
// Wheel scrolled flag
private boolean wheelScrolled = false;
// Wheel scrolled listener
OnWheelScrollListener scrolledListener = new OnWheelScrollListener() {
public void onScrollingStarted(WheelView wheel) {
wheelScrolled = true;
}
public void onScrollingFinished(WheelView wheel) {
wheelScrolled = false;
setStatus(wheel.getId(), getWheel(wheel.getId()).getWinningIndex());
}
};
// Wheel changed listener
private OnWheelChangedListener changedListener = new OnWheelChangedListener() {
public void onChanged(WheelView wheel, int oldValue, int newValue) {
if (!wheelScrolled) {
}
}
};
/**
* Updates status
*/
private void updateStatus() {
myThread();
}
public void myThread(){
Thread th=new Thread(){
#Override
public void run(){
try
{
Thread.sleep(2000);
GameActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
showAlertDialogWithSingleButton(GameActivity.this, mTitle, mContent, success);
}
});
}catch (InterruptedException e) {
// TODO: handle exception
}
}
};
th.start();
}
android.content.DialogInterface.OnClickListener success = new android.content.DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
if (mContent != null && mContent.contains("again"))
startHomeActivity();
else
startNewsActivity();
}
};
private void startHomeActivity() {
}
private void startNewsActivity() {
}
android.content.DialogInterface.OnClickListener fail = new android.content.DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//
}
};
public void showAlertDialogWithSingleButton(final Activity ctx, final String title, final String message,
DialogInterface.OnClickListener onClickListener) {
// show dialog
}
private void initWheel(int id, boolean monitorScroll, int itemIndex) {
Random randomGenerator = new Random();
int index = randomGenerator.nextInt(arrListSlotItems.size());
WheelView wheel = getWheel(id);
wheel.setViewAdapter(slotAdapter);
wheel.setCurrentItem((index ));
wheel.setVisibleItems(1);
wheel.setWinningIndex(itemIndex);
wheel.addChangingListener(changedListener);
wheel.addScrollingListener(scrolledListener);
wheel.setCyclic(true);
wheel.setEnabled(false);
}
private WheelView getWheel(int id) {
return (WheelView) findViewById(id);
}
private void setStatus(int id, int item) {
int index = 0;
for (int i = 0; i < arrListSlotItems.size(); i++) {
SlotItem d = arrListSlotItems.get(i);
if (d.getSlotId() != 0 && d.getSlotId() == Integer.parseInt(imagesWinId.get(item)))
index = arrListSlotItems.indexOf(d);
}
getWheel(id).setCurrentItem(index, true);
if (id == R.id.slot_3) {
if(player.isPlaying())
{
stopBackgroundAudio();
}
updateStatus();
}
}
private void shuffle(int id, int duration) {
WheelView wheel = getWheel(id);
wheel.scroll(450 + (int) (Math.random() * 50), duration);
}
private class SlotMachineAdapter extends AbstractWheelAdapter {
final int IMAGE_WIDTH = getImageWidth(mDeviceDensity);
final int IMAGE_HEIGHT = getImageHeight(mDeviceDensity);
private Context context;
/**
* Constructor
*/
public SlotMachineAdapter(Context context) {
this.context = context;
}
/**
* Loads image from resources
*/
private Bitmap loadImage(Bitmap bitmap) {
Bitmap scaled = Bitmap.createScaledBitmap(bitmap, IMAGE_WIDTH, IMAGE_HEIGHT, true);
return scaled;
}
#Override
public int getItemsCount() {
return slotImages.size();
}
// Layout params for image view
final LayoutParams params = new LayoutParams(IMAGE_WIDTH, IMAGE_HEIGHT);
#Override
public View getItem(int index, View cachedView, ViewGroup parent) {
ImageView img;
if (cachedView != null) {
img = (ImageView) cachedView;
} else {
img = new ImageView(context);
}
img.setPadding(0, 5, 0, 5);
img.setLayoutParams(params);
#SuppressWarnings("unchecked")
SoftReference<Bitmap> bitmapRef = (SoftReference<Bitmap>) slotImages.get(index).get("image");
Bitmap bitmap = bitmapRef.get();
if (bitmap == null) {
bitmap = loadImage(bitmap);
}
img.setImageBitmap(bitmap);
return img;
}
}
private int getImageWidth(float density) {
}
private int getImageHeight(float density) {
}
private void downloadSlotImages(final int id, String slotObj) {
//downloading slot images from server
}
}
This is the code. Through this code, when slot stops I want it to scroll some more untill it reaches the image position that I receaved from server. I can do this .But this is providing a lil glitch . Is there any way to stop scrolling when the image is reached as soon as certain duration is reached.
P.S. If you need anymore detail I can provide you.
P.P.S. Screenshots wont give you any detailed insight about the issue.
After days of searching I finally did it.All I had to do was set interpolater as LinearInterpolater and While setting setCurrentItem set animation as true.

How to save a List from an Adapter to a xml File in Android?

I have developed an app capable of detecting BLE signals and others parameters. I use a BaseAdapter to develop the ListView for showing each item. The problem is that I want to save those data in a xml file when the scan has finished (after a period of time I have established) but I don´t know how to do it.
In this class I do the scan of BLE and is where I want to initiate the process of saving the List when it has passed the time of scanning:
public class ScanBleActivity extends ScanBaseActivity {
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler = new Handler();
//private List<BluetoothDevice> mydata;
// Stops scanning after 10 seconds.
private static final long SCAN_PERIOD = 20000;
/* (non-Javadoc)
* #see com.zishao.bletest.ScanBaseActivity#initScanBluetooth()
*/
protected void initScanBluetooth() {
BluetoothManager manager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = manager.getAdapter();
startScanLen(true);
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mScanning) {
startScanLen(false);
}
}
/**
*
* #param enable
*/
private void startScanLen(final boolean enable) {
if (enable) {
// Stops scanning after a pre-defined scan period.
mHandler.postDelayed(new Runnable() {
#Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
try {
savedata(true);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
And here is my Adapter:
public class LeDeviceListAdapter extends BaseAdapter {
public List<BluetoothDevice> data;
private Activity context;
private final HashMap<BluetoothDevice, Integer> rssiMap = new HashMap<BluetoothDevice, Integer>();
public LeDeviceListAdapter(Activity context, List<BluetoothDevice> data) {
this.data = data;
this.context = context;
}
//public static List<BluetoothDevice> getAllData() {
// return data;
//}
public synchronized void addDevice(BluetoothDevice device, int rssi) {
if(!data.contains(device) ){
data.add(device);
}
rssiMap.put(device, rssi);
}
#Override
public int getCount() {
return data.size();
}
#Override
public Object getItem(int position) {
return data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
if (null == convertView) {
LayoutInflater mInflater =
(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = mInflater.inflate(R.layout.leaf_devices_list_item, null);
convertView.setTag(new DeviceView(convertView));
}
DeviceView view = (DeviceView) convertView.getTag();
view.init((BluetoothDevice) getItem(position));
return convertView;
}
public class DeviceView {
private TextView title;
private TextView status;
private TextView type;
private TextView address;
private TextView rssivalue;
public DeviceView(View view) {
title = (TextView) view.findViewById(R.id.device_name);
status = (TextView) view.findViewById(R.id.device_status_txt);
type = (TextView) view.findViewById(R.id.device_type_txt);
address = (TextView) view.findViewById(R.id.device_address_txt);
rssivalue = (TextView) view.findViewById(id.signal_intensity_txt);
}
public void init(BluetoothDevice device) {
title.setText(device.getName());
address.setText(device.getAddress());
setType(device.getType());
setStatus(device.getBondState());
rssivalue.setText(""+rssiMap.get(device)+" dBm");
}
public void setType(int status) {
switch(status) {
case BluetoothDevice.DEVICE_TYPE_CLASSIC:
type.setText("Bluetooth Signal");
break;
case BluetoothDevice.DEVICE_TYPE_LE:
type.setText("BLE Signal");
break;
case BluetoothDevice.DEVICE_TYPE_DUAL:
type.setText("Dual Mode - BR/EDR/LE");
break;
case BluetoothDevice.DEVICE_TYPE_UNKNOWN:
type.setText("Device Unknown");
break;
}
}
public void setStatus(int s) {
switch(s) {
case BluetoothDevice.BOND_NONE:
status.setText("Not Bonded");
break;
case BluetoothDevice.BOND_BONDED:
status.setText("Bonded");
break;
case BluetoothDevice.BOND_BONDING:
status.setText("Bonding");
break;
}
}
}
I want to save the title, address, type, status and rssivalue (shown in the code above) of each BLE signal that has been found during the scan to be saved in a xml file. I have provided only a part of the project but if it is necessarly I will edit and put the code that is missing.
Does anyone know how to do it?? Please help!!!!!
New code: This corresponds to the class ScanBaseActivity:
abstract public class ScanBaseActivity extends ListActivity {
protected LeDeviceListAdapter mLeDeviceListAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_devices_scan);
mLeDeviceListAdapter = new LeDeviceListAdapter(this, new ArrayList<BluetoothDevice>());
this.setListAdapter(mLeDeviceListAdapter);
initScanBluetooth();
}
/**
* Start Scan Bluetooth
*
*/
abstract protected void initScanBluetooth();
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
BluetoothDevice device = (BluetoothDevice) mLeDeviceListAdapter.getItem(position);
ParcelUuid[] uuids = device.getUuids();
String uuidString = "Getting UUID's from " + device.getName() + ";UUID:";
if (null != uuids && uuids.length > 0) {
uuidString += uuids[0].getUuid().toString();
} else {
uuidString += "empty";
}
Toast.makeText(this, uuidString, Toast.LENGTH_LONG).show();
}
/**
* #param device
*/
protected synchronized void addDevice(final BluetoothDevice device, final int rssi) {
runOnUiThread(new Runnable() {
#Override
public void run() {
mLeDeviceListAdapter.addDevice(device, rssi);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
}
protected void savedata(boolean enable) throws FileNotFoundException{
String filename = "file.txt";
FileOutputStream fos;
Bundle extras = getIntent().getExtras();
long timestamp = extras.getLong("currentTime");
try {
fos= openFileOutput(filename, Context.MODE_PRIVATE);
ObjectOutputStream out = new ObjectOutputStream(fos);
out.write((int) timestamp);
out.writeObject(mLeDeviceListAdapter);
out.write(null);
out.close();
Toast.makeText(this, R.string.list_saved, Toast.LENGTH_SHORT).show();
savedata(false);
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
}
New!!: I have edited ScanBaseActivity and ScanBleActivity to introduce the xml saving but when I run the app, when the scan stops it causes an error (moment when the list has to be saved in the sml file). Does anyone know how to solve it or correct it??!!!
OK, first, you need to re-shape how you are dealing with your adapter, after that, everything should fall into place.
so for that, I'm going to outsource to vogella, the cardinal of good android design patterns
http://www.vogella.com/tutorials/AndroidListView/article.html
you could read up through section 3, eat some copypasta and come back here, but every extra line you grok is a good thing =]
Now you have an activity that has a list of data, and an adapter that takes that list and--somewhat dumbly in comparison to your code--applies it to a view of some sort. When you want to update that data, you do so by modifying the List object in the activity by your method somewhere that gets a list of Bluetoothdevices--and I'd take that process off thread with an AsyncTask.
Since you are passing a List to the adapter, you can wait until you've populated the data in your activity, then do an adapter.notifyDataSetChanged. You do not want to adapter.add
then you have a nice List of your data in the activity; you don't need to worry if it's the right list, because--given the update pattern--it's the only list!
then follow the link Merleverde posted to serialize that data into an xml, maybe in a utility class, but in your activity is fine.
edit:
here is a perfectly good adapter, this is part of the larger pattern that displays dynamically changing data:
public class AnchorListAdapter extends ArrayAdapter<String>
{
private final List<String> anchorNames;
public AnchorListAdapter(Context context, int textviewId, List<String> anchors){
super(context, textviewId, anchors);
anchorNames = anchors;
}
#Override
public String getItem( int i ) {
return anchorNames.get(i).toString();
}
}
Well, it's not that you are going to be saving it from the adapter, it's that the adater is going to be 'adapting' a data set that you will put into preferences.
as a feild:
private SharedPreferences saveHash;
in onCreate:
saveHash = getSharedPreferences( getString( R.string.save_hash ), MODE_PRIVATE );
then later:
public void onFinishedLoading(){
super.onPause();
SharedPreferences.Editor editor = saveHash.edit();
editor.clear();
for( String s: myData){
editor.putString(x, s);
}
editor.commit();
}
edit: realized you want to make a hash from a list; what do you want as the key?

Android: Content Adapter shouldn't be modified from UI Thread

Sometimes I receive this error on my Activity below, sometimes not:
The content of the adapter has changed
but ListView did not receive a notification. Make sure the content of
your adapter is not modified from a background thread, but only from the
UI thread.
but I'm not sure where my mistake on my class below. Does anybody have idea?
public class FavoriteActivity extends SpeakSuperActivity {
private final static String TAG = FavoriteActivity.class.getSimpleName();
private Button btn_filter_topic, btn_filter_rating, btn_filter_none;
private TextView fav_filter_text;
private static ListView listViewFavorites;
private static TextView txtNoFavoritesYet;
private List<Favorite> currentFavorites;
private ArrayAdapter<Favorite> currentFavoritesArrayAdapter;
// required for list loading piece by piece
final int itemsPerLoading = Configuration.LOADED_ITEMS_ON_LIST_AT_ONCE;
boolean loadingMore = false;
private List<Long> idList;
int currentDataLoaded;
private static int oldBtnViewId = 0;
// set the start value as same as the loading value
int maximumDataLoadedYet = Configuration.LOADED_ITEMS_ON_LIST_AT_ONCE;
// 0 = not sorted, 1 = sorted by topic and minimum number of stars
private int caseSelection = 0;
private static View progressView;
private View footerView;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.favorites);
Log.d(TAG, "FavoritesScreen onCreate()...");
// indicator for waiting processes
progressView = UIUtils.addBlockingProgressIndicatorBlack(this);
// init Listview
listViewFavorites = (ListView) findViewById(R.id.fav_listview_favorites);
// add the footer before adding the adapter, else the footer
// will not load!
footerView = ((LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.listviewfooter, null, false);
listViewFavorites.addFooterView(footerView);
listViewFavorites = (ListView) findViewById(R.id.fav_listview_favorites);
fav_filter_text = (TextView) findViewById(R.id.fav_filter_text);
btn_filter_none = (Button) findViewById(R.id.btn_fav_filter_none);
btn_filter_topic = (Button) findViewById(R.id.btn_fav_filter_topic);
btn_filter_rating = (Button) findViewById(R.id.btn_fav_filter_rating);
toggleButtonStates(R.id.btn_fav_filter_none);
LoadDataTask ldTask = new LoadDataTask();
ldTask.execute();
// no favorites yet?
txtNoFavoritesYet = (TextView) findViewById(R.id.fav_no_favorites_yet);
updateUI();
}
/**
* An asynchronous Task (doesn't block the UI Thread) for loading the Data in background.
*
* #author Jonas Soukup
*/
private class LoadDataTask extends AsyncTask<Void, Void, LoudmouthException> {
private final String TAG = LoadDataTask.class.getName();
protected void onPreExecute() {
super.onPreExecute();
if (FavoriteProvider.getInstance().getNumOfFavorites() != 0)
progressView.setVisibility(View.VISIBLE);
else
progressView.setVisibility(View.GONE);
listViewFavorites.setVisibility(View.GONE);
fav_filter_text.setVisibility(View.GONE);
btn_filter_none.setVisibility(View.GONE);
btn_filter_topic.setVisibility(View.GONE);
btn_filter_rating.setVisibility(View.GONE);
}
protected LoudmouthException doInBackground(Void... params) {
LoudmouthException exception = null;
Log.d(TAG, "loading data..");
switch (caseSelection) {
case 0:
// Get FavoriteList without sorting
idList = FavoriteProvider.getInstance().getFavoritesByDate();
break;
case 1:
// Get FavoriteList sorted by
// Topics + amount of stars
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
float minRating = prefs.getFloat(getResources().getString(R.string.rating_filter_star_amount), 0);
idList = FavoriteProvider.getInstance().getFavoritesByTopicAndMinRating(minRating);
break;
default:
Log.e(TAG, "No Case with number: " + caseSelection);
}
// reset data loaded, so it loads till maximumDataLoadedYet on a
// refresh of the list
currentDataLoaded = 0;
// reset List on Data change
currentFavorites = new ArrayList<Favorite>();
Log.d(TAG, "..loading data finished");
return exception;
}
protected void onPostExecute(LoudmouthException result) {
try {
Log.d(TAG, "LoadDataTask.onPostExecute()");
super.onPostExecute(result);
progressView.setVisibility(View.GONE);
if (result != null) {
// Error ocurred during loading
android.content.DialogInterface.OnClickListener retryClickListener = new android.content.DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
new LoadDataTask().execute();
}
};
UIUtils.showRetryCancelAlertDialog(getApplicationContext(), result, retryClickListener, null);
} else {
// Everythings fine, data loaded
// showing & hiding
if (FavoriteProvider.getInstance().getNumOfFavorites() == 0) {
fav_filter_text.setVisibility(View.GONE);
btn_filter_none.setVisibility(View.GONE);
btn_filter_topic.setVisibility(View.GONE);
btn_filter_rating.setVisibility(View.GONE);
} else {
fav_filter_text.setVisibility(View.VISIBLE);
btn_filter_none.setVisibility(View.VISIBLE);
btn_filter_topic.setVisibility(View.VISIBLE);
btn_filter_rating.setVisibility(View.VISIBLE);
}
if (idList.size() == 0) {
txtNoFavoritesYet.setVisibility(View.VISIBLE);
listViewFavorites.setVisibility(View.GONE);
} else {
txtNoFavoritesYet.setVisibility(View.GONE);
listViewFavorites.setVisibility(View.VISIBLE);
runOnUiThread(new Runnable() {
public void run() {
btn_filter_none.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
caseSelection = 0;
FavoriteProvider.getInstance().setCurrentFavoriteListStateDirty(true);
toggleButtonStates(v.getId());
updateUI();
}
});
btn_filter_topic.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
caseSelection = 1;
TopicFilterFavDialog tfFavDialog = new TopicFilterFavDialog(FavoriteActivity.this, FavoriteActivity.this, v
.getId());
tfFavDialog.show();
}
});
btn_filter_rating.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
caseSelection = 1;
RatingFilterFavDialog ratDialog = new RatingFilterFavDialog(FavoriteActivity.this, FavoriteActivity.this, v
.getId());
ratDialog.show();
}
});
}
});
}
}
// init listview displaying with data loaded step by step
currentFavoritesArrayAdapter = new FavoriteArrayAdapter(FavoriteActivity.this, FavoriteActivity.this, R.layout.favorite_list_entry,
currentFavorites);
listViewFavorites.setAdapter(currentFavoritesArrayAdapter);
currentFavoritesArrayAdapter.notifyDataSetChanged();
} catch (Exception exception) {
// silent catch because activity could be closed meanwhile
Log.i(TAG, "silent exception catch in onPostExecute: " + exception.getMessage());
}
}
}
/**
* Update UI
*/
public void updateUI() {
LoadDataTask ldTask = new LoadDataTask();
ldTask.execute();
if (currentFavoritesArrayAdapter != null)
currentFavoritesArrayAdapter.notifyDataSetChanged();
}
#Override
protected void onResume() {
super.onResume();
updateUI();
}
private class ListMoreItemsTask extends AsyncTask<Void, Void, LoudmouthException> {
#Override
protected LoudmouthException doInBackground(Void... arg0) {
LoudmouthException exception = null;
loadingMore = true;
// reset loading values if adapter was reseted
if (currentFavoritesArrayAdapter.getCount() == 0)
maximumDataLoadedYet = Configuration.LOADED_ITEMS_ON_LIST_AT_ONCE;
// Get value of Configuration.LOADEDITEMSONLISTATONCE new listitems
for (; currentDataLoaded < maximumDataLoadedYet && currentDataLoaded < idList.size(); currentDataLoaded++) {
// Fill the list with new information
currentFavorites.add(FavoriteProvider.getInstance().getFavorite(idList.get(currentDataLoaded)));
}
maximumDataLoadedYet += itemsPerLoading;
// Done loading more.
loadingMore = false;
return exception;
}
protected void onPostExecute(LoudmouthException result) {
if (result == null) {
// Tell to the adapter that changes have been made, this will
// cause
// the list to refresh
currentFavoritesArrayAdapter.notifyDataSetChanged();
// remove loading view when maximum data is reached
if (currentFavorites.size() == idList.size()) {
listViewFavorites.removeFooterView(footerView);
}
}
}
}
public void toggleButtonStates(int viewId) {
// set clicked button as selected
if (viewId != 0) {
switch (viewId) {
case R.id.btn_fav_filter_none:
btn_filter_none.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.filter_neuste_selected), null, null,
null);
btn_filter_none.setTextColor(getResources().getColor(color.black));
break;
case R.id.btn_fav_filter_topic:
btn_filter_topic.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.filter_themen_selected), null, null,
null);
btn_filter_topic.setTextColor(getResources().getColor(color.black));
break;
case R.id.btn_fav_filter_rating:
btn_filter_rating.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.filter_rating_selected), null, null,
null);
btn_filter_rating.setTextColor(getResources().getColor(color.black));
break;
default:
Log.d("TAG", "No View with id: " + viewId);
}
}
// if previews Button exists and wasn't the same button set the old
// one
// to selected false
if (oldBtnViewId != 0 && oldBtnViewId != viewId) {
// set clicked button as not selected
switch (oldBtnViewId) {
case R.id.btn_fav_filter_none:
btn_filter_none.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.filter_neuste), null, null, null);
btn_filter_none.setTextColor(getResources().getColor(R.color.font_grey));
break;
case R.id.btn_fav_filter_topic:
btn_filter_topic.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.filter_themen), null, null, null);
btn_filter_topic.setTextColor(getResources().getColor(R.color.font_grey));
break;
case R.id.btn_fav_filter_rating:
btn_filter_rating.setCompoundDrawablesWithIntrinsicBounds(getResources().getDrawable(R.drawable.filter_rating), null, null, null);
btn_filter_rating.setTextColor(getResources().getColor(R.color.font_grey));
break;
default:
Log.d("TAG", "No View with id: " + viewId);
}
}
oldBtnViewId = viewId;
}
}
It fails because you modify currentFavorite in ListMoreItemsTasks, which is the underlying list that backs your adapter.
The modification is made in doInBackground, which is not the UI Thread.
I would recommend using publishProgress to receive the data to add on the UI Thread and add it to the adapter there (via the adapter's method, not the array, which you should probably not keep after having created the adapter)
edit
Replace
private class ListMoreItemsTask extends AsyncTask<Void, Void, LoudmouthException> {
with
private class ListMoreItemsTask extends AsyncTask<Void, Favorite, LoudmouthException> {
so progresses are Favorite elements, then
currentFavorites.add(FavoriteProvider.getInstance().getFavorite(idList.get(currentDataLoaded)));
with
publishProgress(FavoriteProvider.getInstance().getFavorite(idList.get(currentDataLoaded));
plus insert in the AsyncTask the onProgressUpdate :
onProgressUpdate(Favorite... values) {
currentFavorites.add(values[0]);
currentFavoritesArrayAdapter.notifyDataSetChanged();
}

Categories

Resources