How to remove useless fragments in ViewPager2 - java

How to destroy retain Fragments or unused Fragments(Fragment with number 1-4) in ViewPager2 when right swap. I want only retain one Fragment in left of visible Fragment (Fragment 5)?
private static class SettingAdapter extends FragmentStateAdapter {
public SettingAdapter(#NonNull Fragment fragment) {
super(fragment);
}
public void destroyUnusedFragment(){
// ?
}
#NonNull
#Override
public Fragment createFragment(int position) {
Log.i("xxx", "createFragment: " + position);
switch (position) {
default:
case 0:
return new Fragment1();
case 1:
return new Fragment2();
case 2:
return new Fragment3();
case 3:
return new Fragment4();
case 4:
return new Fragment5();
case 5:
return new DispenserFragment();
case 6:
return new Fragment7();
case 7:
return new Fragment8();
case 8:
return new Fragment9();
case 9:
return new Fragment10();
case 10:
return new Fragment11();
case 11:
return new Fragment12();
case 12:
return new Fragment13();
case 13:
return new Fragment14();
case 14:
return new Fragment15();
}
}
#Override
public int getItemCount() {
return 15;
}
}
// call above from onCreateView in Fragment
String[] titles = getSettingTabTitlesRes(context);
settingAdapter = new SettingAdapter(this);
binding.settingViewpager.setOffscreenPageLimit(1);
binding.settingViewpager.setAdapter(settingAdapter);
new TabLayoutMediator(binding.settingTablayout, binding.settingViewpager, (tab, position) -> {
tab.setText(titles[position]);
}).attach();
package id.ctech.dispenser_pos.ui.fragment.setting.dispenser.view;
import android.app.Activity;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import java.util.List;
import id.ctech.dispenser_pos.R;
import id.ctech.dispenser_pos.databinding.FragmentDispenserBinding;
import id.ctech.dispenser_pos.db.local.datasource.setting.dispenser.dispenser.DispenserDataSource;
import id.ctech.dispenser_pos.db.local.datasource.setting.dispenser.dispenser_brand.DispenserBrandDataSource;
import id.ctech.dispenser_pos.db.local.datasource.setting.nozzle.NozzleDataSourceHelper;
import id.ctech.dispenser_pos.db.local.datasource.setting.work_schedule.shift_work.ShiftWorkDataSourceHelper;
import id.ctech.dispenser_pos.db.local.datasource.setting.work_schedule.work_schedule.WorkScheduleDataSourceHelper;
import id.ctech.dispenser_pos.etc.ChooseColor;
import id.ctech.dispenser_pos.etc.ThreadExecutors;
import id.ctech.dispenser_pos.ui.activity.main.MainActivity;
import id.ctech.dispenser_pos.ui.compound.table.listeners.ITableDataClickListener;
import id.ctech.dispenser_pos.ui.compound.table.listeners.ITableDataLongClickListener;
import id.ctech.dispenser_pos.ui.fragment.etc.DebouncedOnClickListener;
import id.ctech.dispenser_pos.ui.fragment.setting.SettingFragment;
import id.ctech.dispenser_pos.ui.fragment.setting.dispenser.model.Dispenser;
import id.ctech.dispenser_pos.ui.fragment.setting.dispenser.model.DispenserBrand;
import id.ctech.dispenser_pos.ui.fragment.setting.dispenser.presenter.DispenserPresenter;
import id.ctech.dispenser_pos.ui.fragment.setting.dispenser.presenter.IDispenserPresenter;
import id.ctech.dispenser_pos.ui.fragment.setting.dispenser.view.table.dispenser.DispenserDataAdapter;
import id.ctech.dispenser_pos.ui.fragment.setting.dispenser.view.table.dispenser_brand.DispenserBrandDataAdapter;
import id.ctech.dispenser_pos.ui.fragment.setting.nozzle.model.Nozzle;
import id.ctech.dispenser_pos.ui.fragment.setting.user_account.model.UserAccount;
import id.ctech.dispenser_pos.ui.fragment.setting.work_schedule.model.ShiftWork;
import id.ctech.dispenser_pos.ui.fragment.setting.work_schedule.model.WorkSchedule;
import static android.widget.Toast.LENGTH_SHORT;
import static id.ctech.dispenser_pos.dev.dispenser.ENozzleStatus.IN_HOLSTER;
import static id.ctech.dispenser_pos.etc.Common.ADMIN;
import static id.ctech.dispenser_pos.etc.Common.getDispenser;
import static id.ctech.dispenser_pos.etc.Common.getNozzles;
import static id.ctech.dispenser_pos.etc.Common.getShiftWorks;
import static id.ctech.dispenser_pos.etc.Common.getWorkSchedules;
import static id.ctech.dispenser_pos.etc.CommonColor.readThemeFromPref;
import static id.ctech.dispenser_pos.etc.CommonDate.toShortTime24;
import static id.ctech.dispenser_pos.ui.compound.alert_dialog.SweetAlertDialog.showConfirmDialog;
import static id.ctech.dispenser_pos.ui.compound.snackbar.SweetSnackbar.showSnackbarError;
import static id.ctech.dispenser_pos.ui.compound.snackbar.SweetSnackbar.showSnackbarInfo;
import static id.ctech.dispenser_pos.ui.compound.snackbar.SweetSnackbar.showSnackbarSuccess;
public class DispenserFragment extends Fragment implements IDispenserView {
private final static int PREV_PAGE = 3;
private final static int NEXT_PAGE = 5;
private Context context;
private IDispenserPresenter iDispenserPresenter;
// Dispenser
private DispenserDataAdapter dispenserDataAdapter;
private Dispenser dispenserClicked = null, dispenserLongClicked = null;
private int dispenserClickedRowIndex = -1, dispenserLongClickedRowIndex = -1;
private int hiddenNewID;
// DispenserBrand
private DispenserBrandDataAdapter dispenserBrandDataAdapter;
private DispenserBrand dispenserBrandClicked = null, dispenserBrandLongClicked = null;
private int dispenserBrandClickedRowIndex = -1, dispenserBrandLongClickedRowIndex = -1;
private int dispenserBrandNewID;
private FragmentDispenserBinding binding;
private ThreadExecutors threadExecutors;
private UserAccount signInAccount;
//
private Dispenser dispenser;
private Nozzle[] nozzles;
private ShiftWork[] shiftWorks;
private WorkSchedule[] workSchedules;
private int nozzleQty;
private int shiftWorkQty;
public DispenserFragment() {
}
private void readDispenser() {
try {
dispenser = getDispenser(context);
if (dispenser == null) {
showSnackbarError(getString(R.string.message_failed_to_load_dispenser_module), LENGTH_SHORT);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void readNozzles() {
try {
nozzles = getNozzles(context);
if (nozzles.length == 0) {
showSnackbarError(getString(R.string.message_failed_to_load_nozzle_module), LENGTH_SHORT);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void readShiftWorks() {
try {
shiftWorks = getShiftWorks(context);
if (shiftWorks.length == 0) {
showSnackbarError(getString(R.string.message_failed_to_load_shift_work_module), LENGTH_SHORT);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void readWorkSchedules() {
try {
workSchedules = getWorkSchedules(context);
if (workSchedules.length == 0) {
showSnackbarError(getString(R.string.message_failed_to_load_work_schedule_module), LENGTH_SHORT);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void nozzleSync() {
try {
readDispenser();
readNozzles();
// nozzle sync
if (dispenser != null && nozzles != null) {
nozzleQty = dispenser.getNozzleQty(); // references
if (nozzleQty < nozzles.length) {
for (int i = nozzleQty + 1; i <= nozzles.length; i++) {
NozzleDataSourceHelper.deleteNozzle(context, i);
}
} else if (nozzleQty > nozzles.length) {
for (int i = nozzles.length + 1; i <= nozzleQty; i++) {
Nozzle nozzle = new Nozzle(i, i, 0, 0, 0, 0, IN_HOLSTER);
NozzleDataSourceHelper.createNozzle(context, nozzle);
}
}
nozzles = getNozzles(context);
// nozzle validation
nozzleQty = dispenser.getNozzleQty();
if (nozzleQty != nozzles.length) {
showSnackbarError(getString(R.string.message_nozzle_sync_failed), LENGTH_SHORT);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void shiftWorkSync() {
try {
readDispenser();
readShiftWorks();
// shift work sync
if (dispenser != null && shiftWorks != null) {
shiftWorkQty = dispenser.getShiftWorkQty(); // references
if (shiftWorkQty < shiftWorks.length) {
for (int i = shiftWorkQty + 1; i <= shiftWorks.length; i++) {
ShiftWorkDataSourceHelper.deleteShiftWork(context, i);
}
} else if (shiftWorkQty > shiftWorks.length) {
for (int i = shiftWorks.length + 1; i <= shiftWorkQty; i++) {
String strTime24 = "";
switch (i) {
case 1:
strTime24 = "06:00";
break;
case 2:
strTime24 = "14:00";
break;
case 3:
strTime24 = "22:00";
break;
}
// create shift work
ShiftWork shiftWork = new ShiftWork(i, toShortTime24(strTime24));
ShiftWorkDataSourceHelper.createShiftWork(context, shiftWork);
}
}
shiftWorks = getShiftWorks(context);
// shiftWorks validation
shiftWorkQty = dispenser.getShiftWorkQty();
if (shiftWorkQty != shiftWorks.length) {
showSnackbarError(getString(R.string.message_shiftworks_sync_failed), LENGTH_SHORT);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void workScheduleSync() {
try {
readDispenser();
readWorkSchedules();
// work schedule sync
if (dispenser != null && workSchedules != null) {
nozzleQty = dispenser.getNozzleQty(); // references
if (nozzleQty < workSchedules.length) {
for (int i = nozzleQty + 1; i <= workSchedules.length; i++) {
WorkScheduleDataSourceHelper.deleteWorkSchedule(context, i);
}
} else if (nozzleQty > workSchedules.length) {
for (int i = workSchedules.length + 1; i <= nozzleQty; i++) {
WorkSchedule workSchedule = new WorkSchedule(i, i, 1, 1, 1);
WorkScheduleDataSourceHelper.createWorkSchedule(context, workSchedule);
}
}
workSchedules = getWorkSchedules(context);
// work schedule validation
nozzleQty = dispenser.getNozzleQty();
if (nozzleQty != workSchedules.length) {
showSnackbarError(getString(R.string.message_workschedule_sync_failed), LENGTH_SHORT);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void doSyncs() {
try {
nozzleSync();
shiftWorkSync();
workScheduleSync();
} catch (Exception ex) {
ex.printStackTrace();
}
}
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
try {
Log.i("xxx", "DispenserFragment onCreateView");
context = getActivity();
if (context != null) {
binding = FragmentDispenserBinding.inflate(inflater, container, false);
View rootView = binding.getRoot();
threadExecutors = ThreadExecutors.getInstance();
doSyncs();
DispenserDataSource dispenserDataSource = DispenserDataSource.getInstance(context);
DispenserBrandDataSource dispenserBrandDataSource = DispenserBrandDataSource.getInstance(context);
new DispenserPresenter(context, dispenserDataSource, dispenserBrandDataSource, this);
// DispenserBrand
binding.dispenserBrandAddButton.setOnClickListener(new DispenserBrandAddButtonClickListener());
binding.dispenserBrandEditButton.setOnClickListener(new DispenserBrandEditButtonClickListener());
binding.dispenserBrandDeleteButton.setOnClickListener(new DispenserBrandDeleteButtonClickListener());
iDispenserPresenter.readDispenserBrands();
// dispenser
binding.dispenserPrevButton.setOnClickListener(new DispenserPrevButtonClickListener());
binding.dispenserNextButton.setOnClickListener(new DispenserNextButtonClickListener());
binding.dispenserAddButton.setOnClickListener(new DispenserAddButtonClickListener());
binding.dispenserEditButton.setOnClickListener(new DispenserEditButtonClickListener());
binding.dispenserDeleteButton.setOnClickListener(new DispenserDeleteButtonClickListener());
signInAccount = ((MainActivity) getActivity()).getSignInAccount();
iDispenserPresenter.readDispensers();
setTheme(context);
return rootView;
}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
private void setTheme(#NonNull Context context) {
try {
// set theme from pref
ChooseColor chooseColor = readThemeFromPref(context);
if (chooseColor != null) {
context.setTheme(chooseColor.getTheme()); // app theme (default: R.style.app_theme_red)
}
Activity activity = getActivity();
if (activity != null) {
int colorPrimary = ((MainActivity) activity).getColorPrimary();
binding.dispenserAddButton.setBackgroundColor(colorPrimary);
binding.dispenserDeleteButton.setBackgroundColor(colorPrimary);
binding.dispenserEditButton.setBackgroundColor(colorPrimary);
binding.dispenserPrevButton.setBackgroundColor(colorPrimary);
binding.dispenserNextButton.setBackgroundColor(colorPrimary);
binding.dispenserBrandAddButton.setBackgroundColor(colorPrimary);
binding.dispenserBrandDeleteButton.setBackgroundColor(colorPrimary);
binding.dispenserBrandEditButton.setBackgroundColor(colorPrimary);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
#Override
public void onDestroyView() {
super.onDestroyView();
Log.i("xxx", "DispenserFragment onDestroyView");
binding = null;
threadExecutors = null;
dispenserBrandDataAdapter = null;
dispenserBrandClicked = null;
dispenserBrandLongClicked = null;
dispenserDataAdapter = null;
dispenserClicked = null;
dispenserLongClicked = null;
}
#Override
public void setPresenter(#NonNull IDispenserPresenter iPresenter) {
iDispenserPresenter = iPresenter;
}
// DispenserBrand
#Override
public void onCreateDispenserBrand(boolean result) {
Runnable r = () -> {
try {
if (binding == null) {
return;
}
if (result) {
showSnackbarSuccess(getString(R.string.message_successfully_to_save_data), LENGTH_SHORT);
iDispenserPresenter.readDispenserBrands();
binding.dispenserBrandAddButton.setText(getString(R.string.button_add));
binding.dispenserBrandEditButton.setEnabled(true);
binding.dispenserBrandDeleteButton.setEnabled(true);
binding.dispenserBrandAddButton.setTextColor(Color.WHITE);
} else {
showSnackbarError(getString(R.string.message_failed_to_save_data), LENGTH_SHORT);
}
} catch (Exception ex) {
ex.printStackTrace();
}
};
threadExecutors.getMainThreadExecutor().execute(r);
}
#Override
public void onReadDispenserBrands(#NonNull List<DispenserBrand> dispenserBrandList) {
Runnable r = () -> {
try {
if (binding == null) {
return;
}
dispenserBrandDataAdapter = new DispenserBrandDataAdapter(context, dispenserBrandList, binding.dispenserBrandTable);
dispenserBrandDataAdapter.setSelectedColor(-1);
binding.dispenserBrandTable.setDataAdapter(dispenserBrandDataAdapter);
binding.dispenserBrandTable.sort(0, true);
binding.dispenserBrandTable.invalidate();
binding.dispenserBrandTable.removeDataClickListener(new DispenserBrandClickListener());
binding.dispenserBrandTable.removeDataLongClickListener(new DispenserBrandLongClickListener());
binding.dispenserBrandTable.addDataClickListener(new DispenserBrandClickListener());
binding.dispenserBrandTable.addDataLongClickListener(new DispenserBrandLongClickListener());
dispenserBrandClickedRowIndex = -1;
dispenserBrandClicked = null;
dispenserBrandLongClickedRowIndex = -1;
dispenserBrandLongClicked = null;
} catch (Exception ex) {
ex.printStackTrace();
}
};
threadExecutors.getMainThreadExecutor().execute(r);
}
#Override
public void onUpdateDispenserBrand(boolean result) {
Runnable r = () -> {
try {
if (binding == null) {
return;
}
if (result) {
showSnackbarSuccess(getString(R.string.message_successfully_to_save_data), LENGTH_SHORT);
iDispenserPresenter.readDispenserBrands();
binding.dispenserBrandEditButton.setText(getString(R.string.button_edit));
binding.dispenserBrandAddButton.setEnabled(true);
binding.dispenserBrandDeleteButton.setEnabled(true);
binding.dispenserBrandEditButton.setTextColor(Color.WHITE);
} else {
showSnackbarError(getString(R.string.message_failed_to_save_data), LENGTH_SHORT);
}
} catch (Exception ex) {
ex.printStackTrace();
}
};
threadExecutors.getMainThreadExecutor().execute(r);
}
#Override
public void onDeleteDispenserBrand(boolean result) {
Runnable r = () -> {
try {
if (binding == null) {
return;
}
if (result) {
showSnackbarSuccess(getString(R.string.message_data_deleted), LENGTH_SHORT);
} else {
showSnackbarError(getString(R.string.message_failed_to_delete_data), LENGTH_SHORT);
}
iDispenserPresenter.readDispenserBrands();
binding.dispenserBrandAddButton.setEnabled(true);
binding.dispenserBrandEditButton.setEnabled(true);
} catch (Exception ex) {
ex.printStackTrace();
}
};
threadExecutors.getMainThreadExecutor().execute(r);
}
#Override
public void onNewIDDispenserBrand(int ID) {
Runnable r = () -> {
try {
if (binding == null) {
return;
}
dispenserBrandNewID = ID;
dispenserBrandDataAdapter.add(new DispenserBrand(dispenserBrandNewID, ""));
dispenserBrandDataAdapter.notifyDataSetChanged();
binding.dispenserBrandTable.enterEditMode();
} catch (Exception ex) {
ex.printStackTrace();
}
};
threadExecutors.getMainThreadExecutor().execute(r);
}
#Override
public void onErrorDispenserBrand(#NonNull Throwable result) {
Runnable r = () -> {
try {
String strMessage = result.getMessage();
if (strMessage != null) {
showSnackbarError(strMessage, LENGTH_SHORT);
}
} catch (Exception ex) {
ex.printStackTrace();
}
};
threadExecutors.getMainThreadExecutor().execute(r);
}
// Dispenser
#Override
public void onCreateDispenser(boolean result) {
Runnable r = () -> {
try {
if (binding == null) {
return;
}
if (result) {
showSnackbarSuccess(getString(R.string.message_successfully_to_save_data), LENGTH_SHORT);
iDispenserPresenter.readDispensers();
binding.dispenserAddButton.setText(getString(R.string.button_add));
binding.dispenserEditButton.setEnabled(true);
binding.dispenserDeleteButton.setEnabled(true);
binding.dispenserAddButton.setTextColor(Color.WHITE);
doSyncs();
} else {
showSnackbarError(getString(R.string.message_failed_to_save_data), LENGTH_SHORT);
}
} catch (Exception ex) {
ex.printStackTrace();
}
};
threadExecutors.getMainThreadExecutor().execute(r);
}
#Override
public void onReadDispensers(#NonNull List<Dispenser> result) {
Runnable r = () -> {
try {
if (binding == null) {
return;
}
dispenserDataAdapter = new DispenserDataAdapter(context, result, binding.dispenserTable);
dispenserDataAdapter.setSelectedColor(-1);
binding.dispenserTable.setDataAdapter(dispenserDataAdapter);
binding.dispenserTable.sort(0, true);
binding.dispenserTable.invalidate();
binding.dispenserTable.removeDataClickListener(new DispenserClickListener());
binding.dispenserTable.removeDataLongClickListener(new DispenserLongClickListener());
binding.dispenserTable.addDataClickListener(new DispenserClickListener());
binding.dispenserTable.addDataLongClickListener(new DispenserLongClickListener());
dispenserClickedRowIndex = -1;
dispenserClicked = null;
dispenserLongClickedRowIndex = -1;
dispenserLongClicked = null;
} catch (Exception ex) {
ex.printStackTrace();
}
};
threadExecutors.getMainThreadExecutor().execute(r);
}
#Override
public void onUpdateDispenser(boolean result) {
Runnable r = () -> {
try {
if (binding == null) {
return;
}
if (result) {
showSnackbarSuccess(getString(R.string.message_successfully_to_save_data), LENGTH_SHORT);
iDispenserPresenter.readDispensers();
binding.dispenserEditButton.setText(getString(R.string.button_edit));
binding.dispenserAddButton.setEnabled(true);
binding.dispenserDeleteButton.setEnabled(true);
binding.dispenserEditButton.setTextColor(Color.WHITE);
doSyncs();
} else {
showSnackbarError(getString(R.string.message_failed_to_save_data), LENGTH_SHORT);
}
} catch (Exception ex) {
ex.printStackTrace();
}
};
threadExecutors.getMainThreadExecutor().execute(r);
}
#Override
public void onDeleteDispenser(boolean result) {
Runnable r = () -> {
try {
if (binding == null) {
return;
}
if (result) {
showSnackbarSuccess(getString(R.string.message_data_deleted), LENGTH_SHORT);
doSyncs();
} else {
showSnackbarError(getString(R.string.message_failed_to_delete_data), LENGTH_SHORT);
}
iDispenserPresenter.readDispensers();
binding.dispenserAddButton.setEnabled(true);
binding.dispenserEditButton.setEnabled(true);
} catch (Exception ex) {
ex.printStackTrace();
}
};
threadExecutors.getMainThreadExecutor().execute(r);
}
#Override
public void onNewIDDispenser(int ID) {
Runnable r = () -> {
try {
if (binding == null) {
return;
}
hiddenNewID = ID;
// create default dispenser (dispenserId:1, dispenserType:new, nozzleQty:8, workScheduleQty:3)
dispenserDataAdapter.add(new Dispenser(hiddenNewID, 1, 2, 8, 3));
dispenserDataAdapter.notifyDataSetChanged();
binding.dispenserTable.enterEditMode();
} catch (Exception ex) {
ex.printStackTrace();
}
};
threadExecutors.getMainThreadExecutor().execute(r);
}
#Override
public void onErrorDispenser(#NonNull Throwable result) {
Runnable r = () -> {
try {
String strMessage = result.getMessage();
if (strMessage != null) {
showSnackbarError(strMessage, LENGTH_SHORT);
}
} catch (Exception ex) {
ex.printStackTrace();
}
};
threadExecutors.getMainThreadExecutor().execute(r);
}
// DispenserBrand
private class DispenserBrandAddButtonClickListener extends DebouncedOnClickListener {
#Override
public void onDebouncedClick(final View v) {
}
}
private class DispenserBrandEditButtonClickListener extends DebouncedOnClickListener {
#Override
public void onDebouncedClick(View v) {
}
}
private class DispenserBrandDeleteButtonClickListener extends DebouncedOnClickListener {
#Override
public void onDebouncedClick(View v) {
}
}
private class DispenserBrandClickListener implements ITableDataClickListener<DispenserBrand> {
#Override
public void onDataClicked(int rowIndex, DispenserBrand clickedData) {
}
}
private class DispenserBrandLongClickListener implements ITableDataLongClickListener<DispenserBrand> {
#Override
public boolean onDataLongClicked(int rowIndex, DispenserBrand clickedData) {
return false;
}
}
// Dispenser
private class DispenserPrevButtonClickListener extends DebouncedOnClickListener {
#Override
public void onDebouncedClick(View v) {
}
}
private class DispenserNextButtonClickListener extends DebouncedOnClickListener {
#Override
public void onDebouncedClick(View v) {
}
}
private class DispenserAddButtonClickListener extends DebouncedOnClickListener {
#Override
public void onDebouncedClick(final View v) {
}
}
private class DispenserEditButtonClickListener extends DebouncedOnClickListener {
#Override
public void onDebouncedClick(View v) {
}
}
private class DispenserDeleteButtonClickListener extends DebouncedOnClickListener {
#Override
public void onDebouncedClick(View v) {
}
}
private class DispenserClickListener implements ITableDataClickListener<Dispenser> {
#Override
public void onDataClicked(int rowIndex, Dispenser clickedData) {
}
}
private class DispenserLongClickListener implements ITableDataLongClickListener<Dispenser> {
#Override
public boolean onDataLongClicked(int rowIndex, Dispenser clickedData) {
return false;
}
}
}

Its bug of ViewPager2 and I get solution as follows:
/**
* Sets whether the LayoutManager should be queried for views outside of
* its viewport while the UI thread is idle between frames.
*
* <p>If enabled, the LayoutManager will be queried for items to inflate/bind in between
* view system traversals on devices running API 21 or greater. Default value is true.</p>
*
* <p>On platforms API level 21 and higher, the UI thread is idle between passing a frame
* to RenderThread and the starting up its next frame at the next VSync pulse. By
* prefetching out of window views in this time period, delays from inflation and view
* binding are much less likely to cause jank and stuttering during scrolls and flings.</p>
*
* <p>While prefetch is enabled, it will have the side effect of expanding the effective
* size of the View cache to hold prefetched views.</p>
*
* #param enabled <code>True</code> if items should be prefetched in between traversals.
*
* #see #isItemPrefetchEnabled()
*/
RecyclerView.LayoutManager layoutManager = ((RecyclerView)(binding.settingViewpager.getChildAt(0))).getLayoutManager();
if(layoutManager != null) {
layoutManager.setItemPrefetchEnabled(false);
}
/**
* Set the number of offscreen views to retain before adding them to the potentially shared
* {#link #getRecycledViewPool() recycled view pool}.
*
* <p>The offscreen view cache stays aware of changes in the attached adapter, allowing
* a LayoutManager to reuse those views unmodified without needing to return to the adapter
* to rebind them.</p>
*
* #param size Number of views to cache offscreen before returning them to the general
* recycled view pool
*/
RecyclerView recyclerView= ((RecyclerView)(binding.settingViewpager.getChildAt(0)));
if(recyclerView != null) {
recyclerView.setItemViewCacheSize(0);
}

Related

List View loading same data twice when scrolling for first time after that working fine

View Complaint Activity:
In this i have done debugging but i was unable to know the reason why the data is coming twice after scrolling. I have even check the data coming from server through postman but the data is not coming duplicate its coming perfectly fine the problem seems to be in front end while we are putting the data through adapter inside activity on scrolling.
public class ViewComplaintActivity extends AppCompatActivity implements AbsListView.OnScrollListener, View.OnClickListener {
TextView tv_notData;
List<Ticket> _data = new ArrayList<Ticket>();
ComplaintsAdapter settlementAdapter;
private String TAG = "ViewComplaintActivity";
private int visibleThreshold = 5;
private int currentPage = 0;
private int previousTotal = 0;
private boolean loading = true;
private boolean userScrolled = false;
a) Its is a Complaints Activity where we are showing the data comimg from server through adapter.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_view_compliants);
ButterKnife.bind(this);
try {
settlementAdapter = new ComplaintsAdapter(ViewComplaintActivity.this, _data);
AlphaInAnimationAdapter animationAdapter = new AlphaInAnimationAdapter(settlementAdapter);
animationAdapter.setAbsListView(ll_complaint_list);
ll_complaint_list.setAdapter(animationAdapter);
getComplaints(Utility.getTerminalId(ViewComplaintActivity.this), 0);
ll_complaint_list.setOnScrollListener(this);
fab_raise_complaint.setOnClickListener(this);
fab_call_customer.setOnClickListener(this);
ivBackButton.setOnClickListener(this);
} catch (NullPointerException e) {
Log.e(TAG, e.toString());
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
private void getComplaints(String terminalid, int pagenumber) {
if (!NetworkConnection.isConnected(this)) {
Toast.makeText(this, R.string.no_connection, Toast.LENGTH_SHORT).show();
return;
}
progressBar.setVisibility(View.VISIBLE);
JsonObject jsonObject = new JsonObject();
jsonObject.addProperty("subIdentifier", terminalid);
jsonObject.addProperty("pageLimit", "10");
jsonObject.addProperty("lastPageIndex", "" + pagenumber);
IRetrofit iRetrofit = MoApplication.getInstance().getRetrofitOsTickets(this).create(IRetrofit.class);
Log.e(TAG,"jsonObject "+jsonObject);
iRetrofit.getAllTicket(jsonObject, new Callback<Response>() {
#Override
public void success(Response response, Response response2) {
progressBar.setVisibility(View.GONE);
try {
if (response.getStatus() == 200) {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(response.getBody().in()));
String resultFromJson = bufferedReader.readLine();
/* Log.e(TAG, "resultFromJson " + resultFromJson);*/
GetTicketsResponse getSettlementsResDTO = new Gson().fromJson(resultFromJson, GetTicketsResponse.class);
switch (getSettlementsResDTO.getResCode()) {
case "0001":
if (null != getSettlementsResDTO.getTickets()) {
_data.addAll(getSettlementsResDTO.getTickets());
settlementAdapter.notifyDataSetChanged();
if (_data.isEmpty()) {
tv_notData.setVisibility(View.VISIBLE);
} else {
tv_notData.setVisibility(View.GONE);
}
} else {
Utility.showToast(ViewComplaintActivity.this, "No data found.");
}
break;
default:
Utility.showToast(ViewComplaintActivity.this, "Please try later.");
break;
}
}
} catch (NullPointerException e) {
Log.e(TAG, "" + e.toString());
} catch (Exception e) {
Log.e(TAG, "" + e.toString());
}
}
#Override
public void failure(RetrofitError error) {
if (Utility.parseException(error)){
Utility.mPosLogoutService((AppCompatActivity) ViewComplaintActivity.this);
}
progressBar.setVisibility(View.GONE);
}
});
}
#Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
/*Log.e(TAG,"one");*/
Log.e(TAG,"scrollState "+scrollState);
if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
userScrolled = true;
fab_call_customer.hide();
fab_raise_complaint.hide();
} else {
fab_call_customer.show();
fab_raise_complaint.show();
}
}
#Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
/*Log.e(TAG,"two");*/
view.getSelectedItemPosition();
if (userScrolled) {
Log.e(TAG,"loading "+loading);
if (loading) {
Log.e(TAG,"totalItemCount "+totalItemCount);
Log.e(TAG,"previousTotal "+previousTotal);
if (totalItemCount > previousTotal) {
loading = false;
previousTotal = totalItemCount;
currentPage++;
}
}
Log.e(TAG,"loadin after scroll "+loading);
if (!loading && ((totalItemCount - visibleItemCount) <= (firstVisibleItem + visibleThreshold))) {
getComplaints(Utility.getTerminalId(ViewComplaintActivity.this), currentPage);
loading = true;
}
}
else {
Log.e(TAG,"user is idle");
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
finish();
}
#Override
public void onClick(View v) {
if (NetworkConnection.isConnected(this)) {
if (v == fab_raise_complaint) {
Utility.navigate(this, RaiseComplaintActivity.class);
} else if (v == fab_call_customer) {
Intent callIntent = new Intent(Intent.ACTION_DIAL);
callIntent.setData(Uri.parse("tel:" + Uri.encode(Constant.helplineNumber.trim())));
callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(callIntent);
} else if (v == ivBackButton) {
startActivity(new Intent(ViewComplaintActivity.this, HomeQrActivity.class));
finish();
}
} else {
Toast.makeText(this, R.string.no_connection, Toast.LENGTH_SHORT).show();
}
}
public class ComplaintsAdapter extends BaseAdapter {
private static String TAG = "ComplaintsAdapter";
List<Ticket> _data;
Context _c;
ViewHolder holder;
public ComplaintsAdapter(Context context, List<Ticket> getData) {
_data = getData;
_c = context;
}
#Override
public int getCount() {
Log.e(TAG,"_data.size()"+_data.size());
return _data.size();
}
#Override
public Object getItem(int position) {
Log.e(TAG,"_data.get(position)"+_data.get(position));
return _data.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = convertView;
/*Log.e(TAG,"getData"+_data.toString());*/
try {
if (view == null) {
/*Log.e(TAG,"getData1"+_data.toString());*/
LayoutInflater li = (LayoutInflater)
_c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = li.inflate(R.layout.row_item_view_complaints,
null);
} else {
/*Log.e(TAG,"getData2"+_data.toString());*/
view = convertView;
}
holder = new ViewHolder();
holder.tv_ticketNo = (TextView)
view.findViewById(R.id.tv_ticketNo);
holder.tv_submitDate = (TextView)
view.findViewById(R.id.tv_submitDate); //ticket comments
holder.tv_updatedDate = (TextView)
view.findViewById(R.id.tv_updatedDate);//will act as ticket
last modified time
holder.tv_ticketStatus = (TextView)
view.findViewById(R.id.tv_ticketStatus); //ticket status open
or close
holder.tv_comment = (TextView)
view.findViewById(R.id.tv_comment);
holder.tv_subject = (TextView)
view.findViewById(R.id.tv_subject);
final Ticket ticket = _data.get(position);
holder.tv_ticketNo.setText("#" + ticket.getTicketNo());
holder.tv_submitDate.setText(Html.fromHtml("<b> Created On:
</b>" + Utility.dateReformatting("yyyy-MM-dd HH:mm:ss", "dd
MMM yyyy", ticket.getCreated())));
holder.tv_updatedDate.setText(Html.fromHtml("<b> Modified On:
</b>" + Utility.dateReformatting("yyyy-MM-dd HH:mm:ss", "dd
MMM yyyy", ticket.getModified())));
holder.tv_ticketStatus.setText(ticket.getStatus());
holder.tv_subject.setText(null != ticket.getSubject() && !ticket.getSubject().isEmpty() ? ticket.getSubject().trim().replace("|", "") : "NA"); //comments
if (null != ticket.getComment() && !ticket.getComment().isEmpty()) {
holder.tv_comment.setText(Html.fromHtml(ticket.getComment()));
holder.tv_comment.setVisibility(View.VISIBLE);
} else {
holder.tv_comment.setVisibility(View.GONE);
}
//holder.tv_comment.setText(null != ticket.getComment() && !ticket.getComment().isEmpty() ? ticket.getComment() : ""); //comments
if (ticket.getStatus().startsWith("Open"))
holder.tv_ticketStatus.setTextColor(_c.getResources().getColor(R.color.green_success));
else
Log.e(TAG,"getData4"+_data.toString());
holder.tv_ticketStatus.setTextColor(_c.getResources().getColor(R.color_color));
} catch (NullPointerException e) {
Log.e(TAG, e.toString());
} catch (Exception e) {
Log.e(TAG, e.toString());
}
return view;
}
public void set_data(List<Ticket> _data) {
this._data = _data;
}
static class ViewHolder {
public TextView tv_ticketStatus, tv_ticketNo, tv_submitDate,
tv_updatedDate, tv_comment, tv_subject;
}
}

libGDX using android device camera

I am trying to implement a barcode scanning function in my Libgdx project.
i have tried to follow : https://github.com/libgdx/libgdx/wiki/Integrating-libgdx-and-the-device-camera
but it seems to be outdated.
Does anyone have a clue on how to get the device camera working in libgdx?
I have a project that implemented the android camera. Heres the important code:
Manifest
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
AndroidDeviceCameraController (New Class)
import android.graphics.Bitmap;
import android.hardware.Camera;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewParent;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Pixmap;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
public class AndroidDeviceCameraController implements DeviceCameraControl,
Camera.PictureCallback, Camera.AutoFocusCallback {
private static final int ONE_SECOND_IN_MILI = 1000;
private final MainActivity activity;
private CameraSurface cameraSurface;
private byte[] pictureData;
FileHandle jpgfile;
Pixmap pixmap;
FileHandle jpgfile2;
Pixmap pixmap2;
public AndroidDeviceCameraController(MainActivity activity) {
this.activity = activity;
}
#Override
public synchronized void prepareCamera() {
activity.setFixedSize(960,640);
if (cameraSurface == null) {
cameraSurface = new CameraSurface(activity);
}
activity.addContentView( cameraSurface, new LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT ) );
}
#Override
public synchronized void startPreview() {
setCameraParametersForPicture(cameraSurface.getCamera());
if (cameraSurface != null && cameraSurface.getCamera() != null) {
cameraSurface.getCamera().startPreview();
}
}
#Override
public synchronized void stopPreview() {
if (cameraSurface != null) {
ViewParent parentView = cameraSurface.getParent();
if (parentView instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup) parentView;
viewGroup.removeView(cameraSurface);
}
if (cameraSurface.getCamera() != null) {
cameraSurface.getCamera().stopPreview();
}
}
activity.restoreFixedSize();
}
public void setCameraParametersForPicture(Camera camera) {
camera.setDisplayOrientation(90);
Camera.Parameters p = camera.getParameters();
List<Camera.Size> supportedSizes = p.getSupportedPictureSizes();
int maxSupportedWidth = -1;
int maxSupportedHeight = -1;
for (Camera.Size size : supportedSizes) {
if (size.width > maxSupportedWidth) {
maxSupportedWidth = size.width;
maxSupportedHeight = size.height;
}
}
p.setPictureSize(maxSupportedWidth, maxSupportedHeight);
p.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
camera.setParameters( p );
}
#Override
public synchronized void takePicture() {
setCameraParametersForPicture(cameraSurface.getCamera());
cameraSurface.getCamera().autoFocus(this);
}
#Override
public synchronized void onAutoFocus(boolean success, Camera camera) {
if (success) {
if (camera != null) {
camera.startPreview();
ShutterCallback shutterCallback = new ShutterCallback() {
#Override
public void onShutter() {
}
};
camera.takePicture(shutterCallback, null, null, this);
}
}
}
#Override
public synchronized void onPictureTaken(byte[] pictureData, Camera camera) {
main.makefoto = true;
this.pictureData = pictureData;
}
#Override
public synchronized byte[] getPictureData() {
return pictureData;
}
#Override
public void prepareCameraAsync() {
Runnable r = new Runnable() {
public void run() {
prepareCamera();
}
};
activity.post(r);
}
#Override
public synchronized void startPreviewAsync() {
Runnable r = new Runnable() {
public void run() {
startPreview();
}
};
activity.post(r);
}
#Override
public synchronized void stopPreviewAsync() {
Runnable r = new Runnable() {
public void run() {
stopPreview();
}
};
activity.post(r);
}
#Override
public synchronized byte[] takePictureAsync(long timeout) {
timeout *= ONE_SECOND_IN_MILI;
pictureData = null;
Runnable r = new Runnable() {
public void run() {
takePicture();
}
};
activity.post(r);
while (pictureData == null && timeout > 0) {
try {
Thread.sleep(ONE_SECOND_IN_MILI);
timeout -= ONE_SECOND_IN_MILI;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (pictureData == null) {
cameraSurface.getCamera().cancelAutoFocus();
}
return pictureData;
}
public void convert() {
new Thread(new Runnable() {
#Override
public void run() {
FileOutputStream fos;
int x=0,y=0;
int xl=0,yl=0;
try {
Bitmap bmp = Bitmap.createBitmap(pixmap.getWidth(),
pixmap.getHeight(), Bitmap.Config.ARGB_8888);
for (x=0,xl=pixmap.getWidth(); x<xl;x++) {
for (y=0,yl=pixmap.getHeight(); y<yl;y++) {
int color = pixmap.getPixel(x, y);
// RGBA => ARGB
int RGB = color >> 8;
int A = (color & 0x000000ff) << 24;
int ARGB = A | RGB;
bmp.setPixel(x, y, ARGB);
}
}
fos = new FileOutputStream(jpgfile.file());
bmp.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
jpgfile = jpgfile2;
pixmap = pixmap2;
}
}).start();
}
#Override
public void saveAsJpeg(FileHandle jpgfile, Pixmap pixmap) {
convert();
this.jpgfile = jpgfile;
this.pixmap = pixmap;
jpgfile2 = this.jpgfile;
pixmap2 = this.pixmap;
}
#Override
public boolean isReady() {
if (cameraSurface!=null && cameraSurface.getCamera() != null) {
return true;
}
return false;
}
}

In App Purchases - How to handle the second click?

i just want to implement in-app-purchasement into my app. It is a card game with different rulesets. So now want to implement 2 new rulesets which should work as my products and with in-app-purchasement.
I have this:
`go = (Button)findViewById(R.id.go);
go.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ArrayList skuList = new ArrayList();
skuList.add(inappid);
Bundle querySkus = new Bundle();
querySkus.putStringArrayList("ITEM_ID_LIST", skuList);
Bundle skuDetails;
try {
skuDetails = mservice.getSkuDetails(3, getPackageName(),
"inapp", querySkus);
int response = skuDetails.getInt("RESPONSE_CODE");
if (response == 0) {
ArrayList<String> responseList =
skuDetails.getStringArrayList("DETAILS_LIST");
for (String thisResponse : responseList) {
JSONObject object = new JSONObject(thisResponse);
String sku = object.getString("productId");
String price = object.getString("price");
if (sku.equals(inappid)) {
System.out.println("price " + price);
Bundle buyIntentBundle =
mservice.getBuyIntent(3, getPackageName(), sku,
"inapp",
"blablabla");
PendingIntent pendingIntent =
buyIntentBundle.getParcelable("BUY_INTENT");
startIntentSenderForResult(
pendingIntent.getIntentSender(), 1001,
new Intent(), Integer.valueOf(0),
Integer.valueOf(0), Integer.valueOf(0));
}
}
}
} catch (RemoteException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
} catch (IntentSender.SendIntentException e ) {
e.printStackTrace();
}
}
});`
First click on my ruleset works fine. The second click triggers the app to break down with the following error:
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.IntentSender android.app.PendingIntent.getIntentSender()' on a null object reference
Do you have some good in-app tutorials or a tipp for me?
Thanks in advance
JD
Here is my BaseClass that i use everywhere i need. Just extend your activity by this BaseInAppPurchaseActivity
Bonus in this class.
You can get what items are available for purchase so user can not get future exception if item is not available like
checkAvailablePurchases(skuList, new OnResultInApp() {
#Override
public void onResult(ArrayList<AvailablePurchase> availablePurchaseArrayList) {
.. logic for showing view with available purchaseItem
}
});
For purchasing an item
purchaseItem(googleInAppId, new OnResultPurchase() {
#Override
public void onSuccess(PurchaseResponseBean purchaseResponseBean, String inAppPurchaseData) {
// your stuff
}
#Override
public void onError() {
showToast(R.string.something_went_wrong);
}
});
Isn't this look pretty clean and nice.
BaseInAppPurchaseActivity.class
package in.kpis.nearyou.base;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender;
import android.content.ServiceConnection;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.IBinder;
import android.os.RemoteException;
import com.android.vending.billing.IInAppBillingService;
import com.google.gson.Gson;
import org.json.JSONException;
import org.json.JSONObject;
import java.math.BigInteger;
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import in.kpis.nearyou.entity.AvailablePurchase;
import in.kpis.nearyou.entity.Helper;
import in.kpis.nearyou.entity.PurchaseResponseBean;
import in.kpis.nearyou.entity.UserPurchaseItemsBean;
import in.kpis.nearyou.utilities.AppPreference;
import static in.kpis.nearyou.base.BaseInAppPurchaseActivity.ConsuptionResponseType.SUCCESS;
import static in.kpis.nearyou.base.BaseInAppPurchaseActivity.PurchaseStateTypes.PURCHASED;
public class BaseInAppPurchaseActivity extends BaseAppCompatActivity {
private static final String TAG = BaseInAppPurchaseActivity.class.getSimpleName();
private IInAppBillingService mService;
private static final char[] symbols = new char[36];
static {
for (int idx = 0; idx < 10; ++idx)
symbols[idx] = (char) ('0' + idx);
for (int idx = 10; idx < 36; ++idx)
symbols[idx] = (char) ('a' + idx - 10);
}
public void startInAppPurchaseServices() {
Intent serviceIntent = new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE);
}
private String appPackageName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
appPackageName = this.getPackageName();
startInAppPurchaseServices();
}
ServiceConnection mServiceConn = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = IInAppBillingService.Stub.asInterface(service);
startAsyncForCheckingAvailablePurchase();
}
};
private void startAsyncForCheckingAvailablePurchase() {
if (skuListByNearyouServer != null && skuListByNearyouServer.size() > 0 & onResultInApp != null) {
AvailablePurchaseAsyncTask mAsyncTask = new AvailablePurchaseAsyncTask(appPackageName, skuListByNearyouServer, onResultInApp);
mAsyncTask.execute();
}
}
private ArrayList<String> skuListByNearyouServer = new ArrayList<>();
OnResultInApp onResultInApp;
public void checkAvailablePurchases(ArrayList<String> skuList, OnResultInApp onResultInApp) {
skuListByNearyouServer = skuList;
this.onResultInApp = onResultInApp;
if (mService == null) startInAppPurchaseServices();
else startAsyncForCheckingAvailablePurchase();
}
public interface OnResultPurchase {
void onSuccess(PurchaseResponseBean purchaseResponseBean, String inAppPurchaseData);
void onError();
}
private OnResultPurchase onResultPurchase;
private String itemToPurchaseSku;
public void purchaseItem(String sku, OnResultPurchase onResultPurchase) {
this.onResultPurchase = onResultPurchase;
itemToPurchaseSku = sku;
if (isBillingSupported()) {
String generatedPayload = getPayLoad();
AppPreference.getInstance(BaseInAppPurchaseActivity.this).setDeveloperPayload(generatedPayload);
try {
Bundle buyIntentBundle = mService.getBuyIntent(3, getPackageName(), sku, "inapp", generatedPayload);
PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
try {
startIntentSenderForResult(pendingIntent.getIntentSender(), Helper.RESPONSE_CODE, new Intent(), Integer.valueOf(0), Integer.valueOf(0), Integer.valueOf(0));
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == Helper.RESPONSE_CODE) {
if (data != null && data.getExtras() != null && data.getStringExtra("INAPP_DATA_SIGNATURE") != null & data.getStringExtra("INAPP_PURCHASE_DATA") != null) {
int responseCode = data.getIntExtra("RESPONSE_CODE", 0);
String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
String dataSignature = data.getStringExtra("INAPP_DATA_SIGNATURE");
if (resultCode == RESULT_OK && responseCode == 0) {
try {
PurchaseResponseBean purchaseResponseBean = new Gson().fromJson(purchaseData, PurchaseResponseBean.class);
String sku = purchaseResponseBean.getProductId();
String developerPayload = purchaseResponseBean.getDeveloperPayload();
int responseCodeConsuption = consumePurchaseItem(purchaseResponseBean.getPurchaseToken());
if (responseCodeConsuption == SUCCESS) {
if (purchaseResponseBean.getPurchaseState() == PURCHASED && itemToPurchaseSku.equals(sku) && developerPayload.equals(AppPreference.getInstance(BaseInAppPurchaseActivity.this).getDeveloperPayload())) {
if (onResultPurchase != null)
onResultPurchase.onSuccess(purchaseResponseBean, purchaseData);
} else onErrorOfPurchase();
} else onResultPurchase.onSuccess(purchaseResponseBean, purchaseData);
} catch (Exception e) {
e.printStackTrace();
onErrorOfPurchase();
}
} else onErrorOfPurchase();
}
} else onErrorOfPurchase();
}
private void onErrorOfPurchase() {
if (onResultPurchase != null) onResultPurchase.onError();
}
interface PurchaseStateTypes {
int PURCHASED = 0;
int CANCELED = 1;
int REFUNDED = 2;
}
interface ConsuptionResponseType {
int SUCCESS = 0;
}
private String getPayLoad() {
RandomString randomString = new RandomString(36);
String payload = randomString.nextString();
return payload;
}
private class RandomString {
private final Random random = new Random();
private final char[] buf;
RandomString(int length) {
if (length < 1)
throw new IllegalArgumentException("length < 1: " + length);
buf = new char[length];
}
String nextString() {
for (int idx = 0; idx < buf.length; ++idx)
buf[idx] = symbols[random.nextInt(symbols.length)];
return new String(buf);
}
}
public final class SessionIdentifierGenerator {
private SecureRandom random = new SecureRandom();
public String nextSessionId() {
return new BigInteger(130, random).toString(32);
}
}
public interface OnResultInApp {
void onResult(ArrayList<AvailablePurchase> canPurchaseList);
}
private class AvailablePurchaseAsyncTask extends AsyncTask<Void, Void, Bundle> {
String packageName;
ArrayList<String> skuList;
OnResultInApp OnResultInApp;
AvailablePurchaseAsyncTask(String packageName, ArrayList<String> skuList, OnResultInApp OnResultInApp) {
this.packageName = packageName;
this.skuList = skuList;
this.OnResultInApp = OnResultInApp;
}
#Override
protected Bundle doInBackground(Void... voids) {
Bundle query = new Bundle();
query.putStringArrayList(Helper.ITEM_ID_LIST, skuList);
Bundle skuDetails = null;
try {
skuDetails = mService.getSkuDetails(3, packageName, "inapp", query);
} catch (RemoteException e) {
e.printStackTrace();
}
return skuDetails;
}
#Override
protected void onPostExecute(Bundle skuDetails) {
ArrayList<AvailablePurchase> availablePurchaseArrayList = new ArrayList<>();
if (skuDetails != null) {
int response = skuDetails.getInt("RESPONSE_CODE");
if (response == 0) {
ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");
if (responseList != null) {
for (String thisResponse : responseList) {
JSONObject object = null;
try {
object = new JSONObject(thisResponse);
String sku = object.getString("productId");
String price = object.getString("price");
availablePurchaseArrayList.add(new AvailablePurchase(sku, price, false));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
}
for (AvailablePurchase availablePurchase : availablePurchaseArrayList) {
for (String sku : skuList) {
if (sku.equals(availablePurchase.getSku())) {
availablePurchase.setActive(true);
}
}
}
if (OnResultInApp != null) {
OnResultInApp.onResult(availablePurchaseArrayList);
}
}
}
public boolean isBillingSupported() {
int response = 1;
try {
response = mService.isBillingSupported(3, getPackageName(), "inapp");
} catch (RemoteException e) {
e.printStackTrace();
}
if (response > 0) {
return false;
}
return true;
}
public int consumePurchaseItem(String purchaseToken) {
if (isBillingSupported()) {
try {
int response = mService.consumePurchase(3, getPackageName(), purchaseToken);
return response;
} catch (RemoteException e) {
e.printStackTrace();
return -1;
}
} else return -1;
}
public Bundle getAllUserPurchase() {
Bundle ownedItems = null;
try {
ownedItems = mService.getPurchases(3, getPackageName(), "inapp", null);
} catch (RemoteException e) {
e.printStackTrace();
}
return ownedItems;
}
public List<UserPurchaseItemsBean> extractAllUserPurchase(Bundle ownedItems) {
List<UserPurchaseItemsBean> mUserItems = new ArrayList<UserPurchaseItemsBean>();
int response = ownedItems.getInt("RESPONSE_CODE");
if (response == 0) {
ArrayList<String> ownedSkus = ownedItems.getStringArrayList("INAPP_PURCHASE_ITEM_LIST");
ArrayList<String> purchaseDataList = ownedItems.getStringArrayList("INAPP_PURCHASE_DATA_LIST");
ArrayList<String> signatureList = ownedItems.getStringArrayList("INAPP_DATA_SIGNATURE_LIST");
String continuationToken = ownedItems.getString("INAPP_CONTINUATION_TOKEN");
if (purchaseDataList != null) {
for (int i = 0; i < purchaseDataList.size(); ++i) {
String purchaseData = purchaseDataList.get(i);
assert signatureList != null;
String signature = signatureList.get(i);
assert ownedSkus != null;
String sku = ownedSkus.get(i);
UserPurchaseItemsBean allItems = new UserPurchaseItemsBean(sku, purchaseData, signature);
mUserItems.add(allItems);
}
}
}
return mUserItems;
}
#Override
public void onDestroy() {
super.onDestroy();
stopInAppPurchaseService();
}
private void stopInAppPurchaseService() {
if (mService != null) {
unbindService(mServiceConn);
}
}
}
AvailablePurchase.class
/**
* Created by KHEMRAJ on 7/13/2017.
*/
public class AvailablePurchase {
private String sku;
private String price;
private boolean isActive;
public AvailablePurchase(String sku, String price, boolean isActive) {
this.sku = sku;
this.price = price;
this.isActive = isActive;
}
public String getSku() {
return sku;
}
public String getPrice() {
return price;
}
public boolean isActive() {
return isActive;
}
public void setActive(boolean active) {
isActive = active;
}
}
Helper.class
/**
* Created by KHEMRAJ on 7/13/2017.
*/
import android.content.Context;
import android.widget.Toast;
public class Helper {
public static final String ITEM_ID_LIST = "ITEM_ID_LIST";
public static final String ITEM_ONE_ID = "android.test.purchased";
public static final String ITEM_TWO_ID = "2";
public static final String ITEM_THREE_ID = "3";
public static final String ITEM_FIVE_ID= "4";
public static final String ITEM_SIX_ID = "5";
public static final int RESPONSE_CODE = 1001;
public static void displayMessage(Context context, String message){
Toast.makeText(context.getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
}
PurchaseResponseBean.class
/**
* Created by KHEMRAJ on 7/15/2017.
*/
public class PurchaseResponseBean {
private String productId;
private String developerPayload;
private String purchaseToken;
private String orderId;
private String purchaseTime;
private int purchaseState;
public String getProductId() {
return productId;
}
public void setProductId(String productId) {
this.productId = productId;
}
public String getDeveloperPayload() {
return developerPayload;
}
public void setDeveloperPayload(String developerPayload) {
this.developerPayload = developerPayload;
}
public String getPurchaseToken() {
return purchaseToken;
}
public void setPurchaseToken(String purchaseToken) {
this.purchaseToken = purchaseToken;
}
public String getOrderId() {
return orderId;
}
public void setOrderId(String orderId) {
this.orderId = orderId;
}
public String getPurchaseTime() {
return purchaseTime;
}
public void setPurchaseTime(String purchaseTime) {
this.purchaseTime = purchaseTime;
}
public int getPurchaseState() {
return purchaseState;
}
public void setPurchaseState(int purchaseState) {
this.purchaseState = purchaseState;
}
}
UserPurchaseItemsBean.class
public class UserPurchaseItemsBean {
private String sku;
private String purchasedata;
private String signature;
public UserPurchaseItemsBean(String sku, String purchasedata, String signature) {
this.sku = sku;
this.purchasedata = purchasedata;
this.signature = signature;
}
public String getSku() {
return sku;
}
public String getPurchasedata() {
return purchasedata;
}
public String getSignature() {
return signature;
}
}
AppPreference.java
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
public class AppPreference {
String DEVELOPERPAYLOAD = "DEVELOPERPAYLOAD";
String PURCHASETOKEN = "PURCHASETOKEN";
//Configuration Variable
private static AppPreference singletonPreference = null;
private SharedPreferences sp;
private Context context;
private AppPreference(Context context) {
if (context == null)
return;
this.context = context;
sp = context.getSharedPreferences(Constants.sharedPreference.PREFERENCE, 0);
}
public static AppPreference getInstance(Context context) {
if (singletonPreference == null)
singletonPreference = new AppPreference(context);
return singletonPreference;
}
public void clearOnlogout() {
Editor prefsEditor = sp.edit();
prefsEditor.clear();
prefsEditor.apply();
}
void removeData(String key) {
SharedPreferences.Editor editor = sp.edit();
editor.remove(key);
editor.apply();
}
public void setStringData(String pKey, String pData) {
SharedPreferences.Editor editor = sp.edit();
editor.putString(pKey, pData);
editor.apply();
}
public void setBooleanData(String pKey, boolean pData) {
SharedPreferences.Editor editor = sp.edit();
editor.putBoolean(pKey, pData);
editor.apply();
}
void setIntegerData(String pKey, int pData) {
SharedPreferences.Editor editor = sp.edit();
editor.putInt(pKey, pData);
editor.apply();
}
public String getStringData(String pKey) {
return sp.getString(pKey, "");
}
public boolean getBooleanData(String pKey) {
return sp.getBoolean(pKey, false);
}
public int getIntegerData(String pKey) {
return sp.getInt(pKey, 0);
}
public String getDeveloperPayload() {
return sp.getString(DEVELOPERPAYLOAD, "");
}
public void setDeveloperPayload(String developerPayload) {
SharedPreferences.Editor editor = sp.edit();
editor.putString(DEVELOPERPAYLOAD, developerPayload);
editor.apply();
}
}
Happy coding :)

java android open street map, update position marker

I got a few markers and update a position of this markers (I send request for server). But when I put new markers I did this:
public void putMarkers() {
Singleton si = Singleton.getInstance();
Drawable newMarker = getApplication().getResources().getDrawable(R.drawable.znacznik_new);
Drawable newMarkerAktywny = getApplication().getResources().getDrawable(R.drawable.ikona_znacznik_pojazd_aktywna);
mResourceProxy = new DefaultResourceProxyImpl(getApplicationContext());
activeOverlayItemArray.clear();
anotherOverlayItemArray.clear();
for(ObjectDefExtends object : si.getListaVisible()){
if (object.lon == null) object.lon = 0.0;
if (object.lat == null) object.lat = 0.0;
/*if (si.getListaVisible().get(a).lon!=null&&si.getListaVisible().get(a).lon!=0)*/
if (object == Singleton.getInstance().currentObject) {
activeOverlayItemArray.add(new OverlayItem(object.name,
object.name, new GeoPoint(object.lat, object.lon)));
} {
anotherOverlayItemArray.add(new OverlayItem(object.name,
object.name, new GeoPoint(object.lat, object.lon)));
}
}
anotherItemizedIconOverlay = new ItemizedIconOverlay<>(anotherOverlayItemArray, newMarker, new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
#Override
public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
indexs = index + 1;
mPin.hideInfoWindow();
mapView.getOverlays().remove(mPin);
mPin.setPosition(anotherItemizedIconOverlay.getItem(index).getPoint());
mPin.setTitle(anotherItemizedIconOverlay.getItem(index).getTitle());
try {
tvStreetName.setText(getCityAndStreet(anotherItemizedIconOverlay.getItem(index).getPoint().getLatitude(), anotherItemizedIconOverlay.getItem(index).getPoint().getLongitude(), getBaseContext()));
} catch (IOException e) {
e.printStackTrace();
}
currentNumber = index;
Singleton.getInstance().setCurrentObjectIndex(currentNumber);
Log.e("azymut ", Singleton.getInstance().getListaODE().get(currentNumber).azimuth + "");
updateEverything();
mPin.showInfoWindow();
mapView.getOverlays().add(mPin);
return true;
}
#Override
public boolean onItemLongPress(final int index, final OverlayItem item) {
return false;
}
}, mResourceProxy);
activeItemizedIconOverlay = new ItemizedIconOverlay<>(activeOverlayItemArray, newMarkerAktywny, new ItemizedIconOverlay.OnItemGestureListener<OverlayItem>() {
#Override
public boolean onItemSingleTapUp(final int index, final OverlayItem item) {
mPin.hideInfoWindow();
mapView.getOverlays().remove(mPin);
mPin.setPosition(activeItemizedIconOverlay.getItem(index).getPoint());
mPin.setTitle(anotherItemizedIconOverlay.getItem(index).getTitle());
currentNumber = index;
Singleton.getInstance().setCurrentObjectIndex(currentNumber);
updateEverything();
mPin.showInfoWindow();
mapView.getOverlays().add(mPin);
return true;
}
#Override
public boolean onItemLongPress(final int index, final OverlayItem item) {
return false;
}
}, mResourceProxy);
for (int a = 0; a < anotherItemizedIconOverlay.size(); a++) {
if (si.listaVisible.indexOf(Singleton.getInstance().currentObject) == a) {
activeItemizedIconOverlay.removeAllItems();
activeItemizedIconOverlay.addItem(new OverlayItem(
si.getListaVisible().get(a).name,
si.getListaVisible().get(a).name,
new GeoPoint(si.getListaVisible().get(a).lat,
Singleton.getInstance().getListaVisible().get(a).lon)));
mPin.setPosition(anotherItemizedIconOverlay.getItem(a).getPoint());
mPin.setAnchor(0.5f, 0.5f);
mPin.setIcon(getResources().getDrawable(R.drawable.pusty));
mPin.setTitle(anotherItemizedIconOverlay.getItem(a).getTitle());
break;
}
}
runOnUiThread(new Runnable() {
#Override
public void run() {
mapView.getOverlays().add(mPin);
mapView.getOverlays().add(anotherItemizedIconOverlay);
mapView.getOverlays().add(activeItemizedIconOverlay);
mapView.invalidate();
}
});
}
And this is how I update a position:
public void aktualizujCoInterwal(int interwal) {
aktualizacja = true;
executor = Executors.newScheduledThreadPool(1);
executor.scheduleAtFixedRate(new Runnable() {
public void run() {
Log.e("aktualizacja", "akt");
if (timeout) {
executor.shutdown();
timedOut();
} else {
aktualizacjaDanych();
}
}
}, 0, interwalAktualizacji, TimeUnit.SECONDS);
}
public void aktualizacjaDanych() {
SmokConnectorImplPortBinding srv1 = new SmokConnectorImplPortBinding(null, URL);
try {
Singleton si = Singleton.getInstance();
ObjectLastStateResult lastState2;
lastState2 = srv1.GetObjectLastState(uid, now);
int rozmiarNowych = lastState2.objectState.size();
int value = (Integer) lastState2.getProperty(0);
if (value != 1) {
timeout = true;
executor.shutdownNow();
timedOut();
} else {
int rozmiarObecnych = si.getListaODE().size();
runOnUiThread(new Runnable() {
#Override
public void run() {
//czyszczenie poprzednio dodanych na mape obiektow
anotherOverlayItemArray.clear();
activeOverlayItemArray.clear();
mapView.getOverlays().clear();
}
});
for (int i = 0; i < rozmiarNowych; i++) {
for (int b = 0; b < rozmiarObecnych; b++) {
if (si.getListaODE().get(b).id.equals(lastState2.objectState.get(i).id)) {
if (lastState2.objectState.get(i).lon != null && lastState2.objectState.get(i).lon.doubleValue() != 0) {
if (lastState2.objectState.get(i).lat != null && lastState2.objectState.get(i).lat.doubleValue() != 0) {
si.getListaODE().get(b).lat = lastState2.objectState.get(i).lat.doubleValue();
si.getListaODE().get(b).lon = lastState2.objectState.get(i).lon.doubleValue();
}
si.getListaODE().get(b).azimuth = lastState2.objectState.get(i).azimuth.intValue();
si.getListaODE().get(b).lastDataTime = lastState2.objectState.get(i).dateTime;
si.getListaODE().get(b).statusGPS = lastState2.objectState.get(i).statusGPS;
try {
si.getListaODE().get(b).mySensors = lastState2.objectState.get(i).sensors.sensor;
} catch (NullPointerException e) {
Log.e("Null", "sensory są puste");
}
si.getListaODE().get(b).description1 = lastState2.objectState.get(i).description1;
si.getListaODE().get(b).description2 = lastState2.objectState.get(i).description2;
si.getListaODE().get(b).velocity = lastState2.objectState.get(i).velocity.intValue();
try {
si.getListaODE().get(b).icons = lastState2.objectState.get(i).sensors.icon;
} catch (NullPointerException e) {
Log.e("Null", "sensory są puste");
}
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
now = DateTime.now();
Singleton si = Singleton.getInstance();
if (si.getListaVisible().size() > 0) {
obiektyNaMape();
updateEverything();
}
showCurrentMarker();
}
All my objects from servers have a azimuth and I rotate a markers icon from all markers, and when a update is done first of all I see a default markers and later I see a rotate markers.

Mopub: integrating inmobi native ads with the adapter InMobiNative

It appears that the whole inmobi sdk has changed significantly from 4.4.1 to 5.2.3 which means that I cannot integrate the inmobi sdk successfully into mopub. This is adapter bundled within the mopub sdk:
https://github.com/motain/android-ads-MoPub/blob/master/extras/src/com/mopub/nativeads/InMobiNative.java
I have copied and pasted the code here for your convenience - you can see that the author has said that the adapter was tested on 4.4.1:
package com.mopub.nativeads;
import android.app.Activity;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import com.inmobi.commons.InMobi;
import com.inmobi.monetization.IMErrorCode;
import com.inmobi.monetization.IMNative;
import com.inmobi.monetization.IMNativeListener;
import com.mopub.common.util.MoPubLog;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import static com.mopub.common.util.Json.getJsonValue;
import static com.mopub.common.util.Numbers.parseDouble;
/*
* Tested with InMobi SDK 4.4.1
*/
class InMobiNative extends CustomEventNative implements IMNativeListener {
private static final String APP_ID_KEY = "app_id";
private Context mContext;
private CustomEventNativeListener mCustomEventNativeListener;
// CustomEventNative implementation
#Override
protected void loadNativeAd(final Context context,
final CustomEventNativeListener customEventNativeListener,
final Map<String, Object> localExtras,
final Map<String, String> serverExtras) {
mContext = context;
if (!(context instanceof Activity)) {
customEventNativeListener.onNativeAdFailed(NativeErrorCode.NATIVE_ADAPTER_CONFIGURATION_ERROR);
return;
}
final Activity activity = (Activity) context;
final String appId;
if (extrasAreValid(serverExtras)) {
appId = serverExtras.get(APP_ID_KEY);
} else {
customEventNativeListener.onNativeAdFailed(NativeErrorCode.NATIVE_ADAPTER_CONFIGURATION_ERROR);
return;
}
mCustomEventNativeListener = customEventNativeListener;
InMobi.initialize(activity, appId);
final IMNative imNative = new IMNative(this);
imNative.loadAd();
}
// IMNativeListener implementation
#Override
public void onNativeRequestSucceeded(final IMNative imNative) {
if (imNative == null) {
mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_INVALID_STATE);
return;
}
final InMobiForwardingNativeAd inMobiForwardingNativeAd;
try {
inMobiForwardingNativeAd = new InMobiForwardingNativeAd(imNative);
} catch (IllegalArgumentException e) {
mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.UNSPECIFIED);
return;
} catch (JSONException e) {
mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.INVALID_JSON);
return;
}
final List<String> imageUrls = new ArrayList<String>();
final String mainImageUrl = inMobiForwardingNativeAd.getMainImageUrl();
if (mainImageUrl != null) {
imageUrls.add(mainImageUrl);
}
final String iconUrl = inMobiForwardingNativeAd.getIconImageUrl();
if (iconUrl != null) {
imageUrls.add(iconUrl);
}
preCacheImages(mContext, imageUrls, new ImageListener() {
#Override
public void onImagesCached() {
mCustomEventNativeListener.onNativeAdLoaded(inMobiForwardingNativeAd);
}
#Override
public void onImagesFailedToCache(NativeErrorCode errorCode) {
mCustomEventNativeListener.onNativeAdFailed(errorCode);
}
});
}
#Override
public void onNativeRequestFailed(final IMErrorCode errorCode) {
if (errorCode == IMErrorCode.INVALID_REQUEST) {
mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_INVALID_REQUEST);
} else if (errorCode == IMErrorCode.INTERNAL_ERROR || errorCode == IMErrorCode.NETWORK_ERROR) {
mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_INVALID_STATE);
} else if (errorCode == IMErrorCode.NO_FILL) {
mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_NO_FILL);
} else {
mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.UNSPECIFIED);
}
}
private boolean extrasAreValid(final Map<String, String> serverExtras) {
final String placementId = serverExtras.get(APP_ID_KEY);
return (placementId != null && placementId.length() > 0);
}
static class InMobiForwardingNativeAd extends BaseForwardingNativeAd {
static final int IMPRESSION_MIN_TIME_VIEWED = 0;
// Modifiable keys
static final String TITLE = "title";
static final String DESCRIPTION = "description";
static final String SCREENSHOTS = "screenshots";
static final String ICON = "icon";
static final String LANDING_URL = "landing_url";
static final String CTA = "cta";
static final String RATING = "rating";
// Constant keys
static final String URL = "url";
private final IMNative mImNative;
InMobiForwardingNativeAd(final IMNative imNative) throws IllegalArgumentException, JSONException {
if (imNative == null) {
throw new IllegalArgumentException("InMobi Native Ad cannot be null");
}
mImNative = imNative;
final JSONTokener jsonTokener = new JSONTokener(mImNative.getContent());
final JSONObject jsonObject = new JSONObject(jsonTokener);
setTitle(getJsonValue(jsonObject, TITLE, String.class));
setText(getJsonValue(jsonObject, DESCRIPTION, String.class));
final JSONObject screenShotJsonObject = getJsonValue(jsonObject, SCREENSHOTS, JSONObject.class);
if (screenShotJsonObject != null) {
setMainImageUrl(getJsonValue(screenShotJsonObject, URL, String.class));
}
final JSONObject iconJsonObject = getJsonValue(jsonObject, ICON, JSONObject.class);
if (iconJsonObject != null) {
setIconImageUrl(getJsonValue(iconJsonObject, URL, String.class));
}
setClickDestinationUrl(getJsonValue(jsonObject, LANDING_URL, String.class));
setCallToAction(getJsonValue(jsonObject, CTA, String.class));
try {
setStarRating(parseDouble(jsonObject.opt(RATING)));
} catch (ClassCastException e) {
MoPubLog.d("Unable to set invalid star rating for InMobi Native.");
}
setImpressionMinTimeViewed(IMPRESSION_MIN_TIME_VIEWED);
}
#Override
public void prepareImpression(final View view) {
if (view != null && view instanceof ViewGroup) {
mImNative.attachToView((ViewGroup) view);
} else if (view != null && view.getParent() instanceof ViewGroup) {
mImNative.attachToView((ViewGroup) view.getParent());
} else {
MoPubLog.e("InMobi did not receive ViewGroup to attachToView, unable to record impressions");
}
}
#Override
public void handleClick(final View view) {
mImNative.handleClick(null);
}
#Override
public void destroy() {
mImNative.detachFromView();
}
}
}
Has anyone been successful in converting this adapter to work with the latest 5.2.3 inmobi sdk?
The 4.4.1 sdk is not even available to download anymore and if there is no adapter for 5.2.3, then I'm afraid inmobi integration with in mopub is not possible?
I waited a few days and did not get any response back from Inmobi so I decided to do some investigation myself on how to solve this issue. Eventually I can across this website which had a sample app with SDK 5.0.0 but the class seems to work with SDK 5.2.3 without any problems.
https://support.inmobi.com/monetize/integration/mediation-adapters/mopub-adaptor-android-sdk-integration-guide/#getting-started
I had to read the class and make my own adjustments to the adapter so that it will work - their adapter had issues as they were using deprecated classes. So here is the updated adapter:
package com.mopub.nativeads;
import android.app.Activity;
import android.content.Context;
import android.support.annotation.NonNull;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import com.inmobi.ads.InMobiAdRequestStatus;
import com.inmobi.sdk.InMobiSdk;
import com.mopub.common.MoPub;
import com.mopub.common.logging.MoPubLog;
import org.json.JSONException;
import org.json.JSONObject;
import org.json.JSONTokener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.mopub.common.util.Json.getJsonValue;
import static com.mopub.common.util.Numbers.parseDouble;
import static com.mopub.nativeads.NativeImageHelper.preCacheImages;
/*
* Tested with InMobi SDK 5.2.3
*/
public class InMobiNative extends CustomEventNative {
private static boolean isAppIntialize = false;
private JSONObject serverParams;
private String accountId="XXX";
private long placementId=123L;
#Override
protected void loadNativeAd(#NonNull Activity arg0,
#NonNull CustomEventNativeListener arg1,
#NonNull Map<String, Object> arg2,
#NonNull Map<String, String> arg3) {
// TODO Auto-generated method stub
Log.d("InMobiNativeCustomEvent", "Reached native adapter");
try {
serverParams = new JSONObject(arg3);
} catch (Exception e) {
Log.e("InMobi", "Could not parse server parameters");
e.printStackTrace();
}
Activity activity = null;
if (arg0 instanceof Activity) {
activity = arg0;
} else {
// You may also pass in an Activity Context in the localExtras map
// and retrieve it here.
}
if (activity == null) {
arg1.onNativeAdFailed(NativeErrorCode.NATIVE_ADAPTER_CONFIGURATION_ERROR);
return;
}
try {
accountId = serverParams.getString("accountid");
placementId = serverParams.getLong("placementId");
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (!isAppIntialize) {
try {
InMobiSdk.init(activity,"accountid");
} catch (Exception e) {
e.printStackTrace();
}
isAppIntialize = true;
}
InMobiSdk.setAreaCode("areacode");
InMobiSdk.setEducation(InMobiSdk.Education.HIGH_SCHOOL_OR_LESS);
InMobiSdk.setGender(InMobiSdk.Gender.MALE);
InMobiSdk.setIncome(1000);
InMobiSdk.setAge(23);
InMobiSdk.setPostalCode("postalcode");
InMobiSdk.setLogLevel(InMobiSdk.LogLevel.DEBUG);
InMobiSdk.setLocationWithCityStateCountry("blore", "kar", "india");
InMobiSdk.setLanguage("ENG");
InMobiSdk.setInterests("dance");
InMobiSdk.setEthnicity(InMobiSdk.Ethnicity.ASIAN);
InMobiSdk.setYearOfBirth(1980);
Map<String, String> map = new HashMap<String, String>();
map.put("tp", "c_mopub");
map.put("tp-ver", MoPub.SDK_VERSION);
final InMobiStaticNativeAd inMobiStaticNativeAd =
new InMobiStaticNativeAd(arg0,
new ImpressionTracker(arg0),
new NativeClickHandler(arg0),
arg1);
inMobiStaticNativeAd.setIMNative(new com.inmobi.ads.InMobiNative(placementId, inMobiStaticNativeAd));
inMobiStaticNativeAd.setExtras(map);
inMobiStaticNativeAd.loadAd();
}
static class InMobiStaticNativeAd extends StaticNativeAd implements com.inmobi.ads.InMobiNative.NativeAdListener {
static final int IMPRESSION_MIN_TIME_VIEWED = 1000;
// Modifiable keys
static final String TITLE = "title";
static final String DESCRIPTION = "description";
static final String SCREENSHOTS = "screenshots";
static final String ICON = "icon";
static final String LANDING_URL = "landingURL";
static final String CTA = "cta";
static final String RATING = "rating";
// Constant keys
static final String URL = "url";
private final Context mContext;
private final CustomEventNativeListener mCustomEventNativeListener;
private final ImpressionTracker mImpressionTracker;
private final NativeClickHandler mNativeClickHandler;
private com.inmobi.ads.InMobiNative mImNative;
InMobiStaticNativeAd(final Context context,
final ImpressionTracker impressionTracker,
final NativeClickHandler nativeClickHandler,
final CustomEventNativeListener customEventNativeListener) {
InMobiSdk.init(context,"9107a61fcda34c969d3f74934a352dcb");
mContext = context.getApplicationContext();
mImpressionTracker = impressionTracker;
mNativeClickHandler = nativeClickHandler;
mCustomEventNativeListener = customEventNativeListener;
}
void setIMNative(final com.inmobi.ads.InMobiNative imNative) {
mImNative = imNative;
}
void setExtras(Map<String,String> map){
mImNative.setExtras(map);
}
void loadAd() {
mImNative.load();
}
// Lifecycle Handlers
#Override
public void prepare(final View view) {
if (view != null && view instanceof ViewGroup) {
com.inmobi.ads.InMobiNative.bind((ViewGroup)view, mImNative);
} else if (view != null && view.getParent() instanceof ViewGroup) {
com.inmobi.ads.InMobiNative.bind((ViewGroup)(view.getParent()), mImNative);
} else {
Log.e("MoPub", "InMobi did not receive ViewGroup to attachToView, unable to record impressions");
}
mImpressionTracker.addView(view, this);
mNativeClickHandler.setOnClickListener(view, this);
}
#Override
public void clear(final View view) {
mImpressionTracker.removeView(view);
mNativeClickHandler.clearOnClickListener(view);
}
#Override
public void destroy() {
//InMobiNative.unbind(arg0);
mImpressionTracker.destroy();
}
// Event Handlers
#Override
public void recordImpression(final View view) {
notifyAdImpressed();
}
#Override
public void handleClick(final View view) {
notifyAdClicked();
mNativeClickHandler.openClickDestinationUrl(getClickDestinationUrl(), view);
mImNative.reportAdClick(null);
}
void parseJson(final com.inmobi.ads.InMobiNative inMobiNative) throws JSONException {
final JSONTokener jsonTokener = new JSONTokener((String) inMobiNative.getAdContent());
final JSONObject jsonObject = new JSONObject(jsonTokener);
setTitle(getJsonValue(jsonObject, TITLE, String.class));
String text = getJsonValue(jsonObject, DESCRIPTION, String.class);
if(text!=null)
setText(text);
final JSONObject screenShotJsonObject = getJsonValue(jsonObject, SCREENSHOTS, JSONObject.class);
if (screenShotJsonObject != null) {
setMainImageUrl(getJsonValue(screenShotJsonObject, URL, String.class));
}
final JSONObject iconJsonObject = getJsonValue(jsonObject, ICON, JSONObject.class);
if (iconJsonObject != null) {
setIconImageUrl(getJsonValue(iconJsonObject, URL, String.class));
}
final String clickDestinationUrl = getJsonValue(jsonObject, LANDING_URL, String.class);
if (clickDestinationUrl == null) {
final String errorMessage = "InMobi JSON response missing required key: "
+ LANDING_URL + ". Failing over.";
MoPubLog.d(errorMessage);
throw new JSONException(errorMessage);
}
setClickDestinationUrl(clickDestinationUrl);
String cta = getJsonValue(jsonObject, CTA, String.class);
if(cta!=null)
setCallToAction(cta);
try {
if(jsonObject.opt(RATING)!=null){
setStarRating(parseDouble(jsonObject.opt(RATING)));
}
} catch (ClassCastException e) {
Log.d("MoPub", "Unable to set invalid star rating for InMobi Native.");
} setImpressionMinTimeViewed(IMPRESSION_MIN_TIME_VIEWED);
}
#Override
public void onAdDismissed(com.inmobi.ads.InMobiNative inMobiNative) {
// TODO Auto-generated method stub
Log.d("InMobiNativeCustomEvent","Native Ad is dismissed");
}
#Override
public void onAdDisplayed(com.inmobi.ads.InMobiNative inMobiNative) {
// TODO Auto-generated method stub
Log.d("InMobiNativeCustomEvent","Native Ad is displayed");
}
#Override
public void onAdLoadFailed(com.inmobi.ads.InMobiNative arg0, InMobiAdRequestStatus arg1) {
// TODO Auto-generated method stub
Log.d("InMobiNativeCustomEvent","Native ad failed to load");
String errorMsg="";
switch (arg1.getStatusCode()) {
case INTERNAL_ERROR:
errorMsg="INTERNAL_ERROR";
break;
case REQUEST_INVALID:
errorMsg="INVALID_REQUEST";
break;
case NETWORK_UNREACHABLE:
errorMsg="NETWORK_UNREACHABLE";
break;
case NO_FILL:
errorMsg="NO_FILL";
break;
case REQUEST_PENDING:
errorMsg="REQUEST_PENDING";
break;
case REQUEST_TIMED_OUT:
errorMsg="REQUEST_TIMED_OUT";
break;
case SERVER_ERROR:
errorMsg="SERVER_ERROR";
break;
case AD_ACTIVE:
errorMsg="AD_ACTIVE";
break;
case EARLY_REFRESH_REQUEST:
errorMsg="EARLY_REFRESH_REQUEST";
break;
default:
errorMsg="NETWORK_ERROR";
break;
}
if (errorMsg == "INVALID_REQUEST") {
mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_INVALID_REQUEST);
} else if (errorMsg == "INTERNAL_ERROR" || errorMsg == "NETWORK_ERROR") {
mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_INVALID_STATE);
} else if (errorMsg == "NO_FILL") {
mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_NO_FILL);
} else if (errorMsg == "REQUEST_TIMED_OUT"){
mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.NETWORK_TIMEOUT);
}else if(errorMsg == "NETWORK_UNREACHABLE"){
mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.CONNECTION_ERROR);
}
else {
mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.UNSPECIFIED);
}
}
#Override
public void onUserLeftApplication(com.inmobi.ads.InMobiNative arg0) {
// TODO Auto-generated method stub
Log.d("InMobiNativeCustomEvent","User left application");
}
#Override
public void onAdLoadSucceeded(com.inmobi.ads.InMobiNative inMobiNative) {
// TODO Auto-generated method stub
Log.v("InMobiNativeCustomEvent", "Ad loaded:"+inMobiNative.getAdContent().toString());
try {
parseJson(inMobiNative);
} catch (JSONException e) {
mCustomEventNativeListener.onNativeAdFailed(NativeErrorCode.INVALID_RESPONSE);
return;
}
final List<String> imageUrls = new ArrayList<String>();
/*final String mainImageUrl = getMainImageUrl();
if (mainImageUrl != null) {
imageUrls.add(mainImageUrl);
}*/
final String iconUrl = getIconImageUrl();
if (iconUrl != null) {
imageUrls.add(iconUrl);
}
preCacheImages(mContext, imageUrls, new NativeImageHelper.ImageListener() {
#Override
public void onImagesCached() {
Log.v("InMobiNativeCustomEvent", "image cached");
mCustomEventNativeListener.onNativeAdLoaded(InMobiStaticNativeAd.this);
}
#Override
public void onImagesFailedToCache(NativeErrorCode errorCode) {
Log.v("InMobiNativeCustomEvent", "image failed to cache");
mCustomEventNativeListener.onNativeAdFailed(errorCode);
}
});
}
}
}
Then you need to read this website telling you more about how to integrate their SDK into your app. You need to copy and paste this into your manifest:
https://support.inmobi.com/android-sdk-integration-guide/#getting-started
<activity android:name="com.inmobi.rendering.InMobiAdActivity"
android:configChanges="keyboardHidden|orientation|keyboard|smallestScreenSize|screenSize"
android:theme="#android:style/Theme.Translucent.NoTitleBar"
android:hardwareAccelerated="true" />
<receiver
android:name="com.inmobi.commons.core.utilities.uid.ImIdShareBroadCastReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="com.inmobi.share.id" />
</intent-filter>
</receiver>
Without these classes, the SDK will not initialize and you will get an error in the logs.
Please do read through both websites, I'm just dealing on a high level on how you can solve the integration but there are other stuff you should put into your app to make mopub work successfully with inmobi for Android.

Categories

Resources