I want to create an AlertDialog inside an IntentService, but when passing the context inside the AlertDialog.Builder constructor it shows me the following error:
06-30 00:01:31.265 11994-11994/com.alwa7y W/System.err: android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
06-30 00:01:31.267 11994-11994/com.alwa7y W/System.err: at android.view.ViewRootImpl.setView(ViewRootImpl.java:572)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:310)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:86)
at android.app.Dialog.show(Dialog.java:319)
at com.go.mushaf.mushafapplication.services.DownloadService$override.showAlert(DownloadService.java:176)
at com.go.mushaf.mushafapplication.services.DownloadService$override.access$dispatch(DownloadService.java)
at com.go.mushaf.mushafapplication.services.DownloadService.showAlert(DownloadService.java:0)
at com.go.mushaf.mushafapplication.services.DownloadService$BackGroundTask.onPostExecute(DownloadService.java:88)
at com.go.mushaf.mushafapplication.services.DownloadService$BackGroundTask.onPostExecute(DownloadService.java:61)
at android.os.AsyncTask.finish(AsyncTask.java:651)
at android.os.AsyncTask.access$500(AsyncTask.java:180)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
06-30 00:01:31.268 11994-11994/com.alwa7y W/System.err: at android.app.ActivityThread.main(ActivityThread.java:5451)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
and this is the method that creates the AlertDialog:
public void showAlert(String message, String header) {
if (header.equals(""))
header = "Alert!";
try {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getApplicationContext());
// Log.d(TAG, "show: " + alertDialog.getOwnerActivity());
alertDialogBuilder.setTitle(header);
alertDialogBuilder.setMessage(message);
alertDialogBuilder.setPositiveButton("موافق",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
((Activity) context).finish();
dialog.dismiss();
showEndLoadingNotification(context);
}
});
// alertDialogBuilder.show();
alertDialogBuilder.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
((Activity) context).finish();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
} catch (Exception ignored) {
ignored.printStackTrace();
}//when app trying to display a dialog using a previously finished activity as a context
}
And this is the IntentService class:
package com.go.mushaf.mushafapplication.services;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.IntentService;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.drawable.Drawable;
import android.os.AsyncTask;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestBuilder;
import com.bumptech.glide.load.DataSource;
import com.bumptech.glide.load.engine.GlideException;
import com.bumptech.glide.request.RequestListener;
import com.bumptech.glide.request.target.Target;
import com.go.mushaf.mushafapplication.DownloadActivity;
import com.go.mushaf.mushafapplication.MainActivity;
import java.util.ArrayList;
import static com.go.mushaf.mushafapplication.DownloadActivity.BUNDLE;
import static com.go.mushaf.mushafapplication.DownloadActivity.CONTEXT;
import static com.go.mushaf.mushafapplication.DownloadActivity.TEXT_ID;
import static com.go.mushaf.mushafapplication.DownloadActivity.getLoadingText;
import static com.go.mushaf.mushafapplication.DownloadActivity.mTxtProgress;
import static com.go.mushaf.mushafapplication.DownloadActivity.showEndLoadingNotification;
import static com.go.mushaf.mushafapplication.Utility.getPages;
public class DownloadService extends IntentService {
public int viewId;
Context context;
public static final String TAG = "servicee";
public DownloadService() {
super("DownloadService");
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent.hasExtra(BUNDLE)) {
viewId = intent.getBundleExtra(BUNDLE).getInt(TEXT_ID);
Log.d(TAG, "onHandleIntent: ");
}
new BackGroundTask().execute();
}
#Override
public int onStartCommand(#Nullable Intent intent, int flags, int startId) {
context = getApplicationContext();
return super.onStartCommand(intent, flags, startId);
}
public class BackGroundTask extends AsyncTask<Void, Integer, Void> {
private final String ASYNC_ERROR = this.getClass().getName();
private RequestBuilder<Drawable> x;
private ArrayList<String> pagesList = getPages();
#Override
protected Void doInBackground(Void... arg0) {
// FIXME: 6/27/2018
doAllCache(mTxtProgress);
return null;
}
#Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
// if(x!=null) {
// x.preload();
//// if (!cancelFlag || count < MainActivity.mushafTotal)
//// new BackGroundTask().execute(++count);
// }
showAlert("تم اكتمال التحميل بنجاح", "تم التحميل");
// getApplicationContext(), unable to add window
// DownladService.this, unable to add window
// getBaseContext(), unable to add window
}
private void doAllCache(final TextView mTxtProgress) {
Log.d(TAG, "doAllCache: " + mTxtProgress.getText().toString());
Log.d(TAG, "doAllCache: " + pagesList.size());
for (int i=0; i<pagesList.size(); i++) {
String pageNumber = pagesList.get(i); //get string for page number
Log.d(TAG, "doAllCache: " + pageNumber);
String url = MainActivity.mainUril + pageNumber + ".gif"; // get page url
final int finalI = i;
x = Glide.with(DownloadService.this)
.load(url)
.listener(new RequestListener<Drawable>() {
#Override
public boolean onResourceReady(Drawable resource, Object model, Target<Drawable> target, DataSource dataSource, boolean isFirstResource) {
// Log.i("Image Loading End", String.valueOf(i));
mTxtProgress.setText(getLoadingText(getApplicationContext(), finalI));
Log.d(TAG, "onResourceReady: " + resource +"\n"+model.toString()+"\n"+target+"\n"+dataSource);
//// //check cancel
//// if (cancelFlag) {
//// finish();
//// } else {
//
// if (finalI < MainActivity.mushafTotal) {
// final int ii = finalI + 1;
// new BackGroundTask().execute();
//
//// new Handler().postDelayed(new Runnable() {
//// #Override
//// public void run() {//Use your "bitmap" here
//// doAllCache(ii);
//// }
//// }, 100);
// }
//// else{
//// cancelFlag = true;
//// }
//// }
return true;
}
#Override
public boolean onLoadFailed(#Nullable GlideException e, Object model, Target target, boolean isFirstResource) {
Log.d(ASYNC_ERROR, String.valueOf(finalI));
Log.d(ASYNC_ERROR, "onLoadFailed: " + e);
return false;
}
});
}
}
}
public void showAlert(String message, String header) {
if (header.equals(""))
header = "Alert!";
try {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(getApplicationContext());
// Log.d(TAG, "show: " + alertDialog.getOwnerActivity());
alertDialogBuilder.setTitle(header);
alertDialogBuilder.setMessage(message);
alertDialogBuilder.setPositiveButton("موافق",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
((Activity) context).finish();
dialog.dismiss();
showEndLoadingNotification(context);
}
});
// alertDialogBuilder.show();
alertDialogBuilder.setOnCancelListener(new DialogInterface.OnCancelListener() {
#Override
public void onCancel(DialogInterface dialog) {
((Activity) context).finish();
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
} catch (Exception ignored) {
ignored.printStackTrace();
}//when app trying to display a dialog using a previously finished activity as a context
}
}
and this is how I start the service:
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.download_btn:
startLoadingNotification();
Bundle bundle = new Bundle();
bundle.putInt(TEXT_ID, R.id.txt_load);
// bundle.putSerializable(CONTEXT, (Serializable) DownloadActivity.this);
startService(new Intent(DownloadActivity.this, DownloadService.class).putExtra(BUNDLE, bundle));
mViewDownload.setVisibility(View.GONE);
mViewCancel.setVisibility(View.VISIBLE);
break;
case R.id.cancel_btn:
createLogoutDialog().show();
break;
}
}
I want to show the dialog in the onPostExecute method.
I have tried:
getApplicationContext(), DownloadService.this, this, getBaseContext()
all of the above give the same error.
Thanks in advance.
You cannot show an AlertDialog from a Service. You can only show an AlertDialog from an Activity. In this case, show the dialog from the activity that is starting this service. Or, do not use a dialog, but instead use a Notification.
Beyond that:
Do not do asynchronous things inside of an IntentService, as the service goes away as soon as onHandleIntent() returns. Once the service goes away, your process might terminate, killing your background threads before the work is done. Remove BackGroundTask and move all of its logic to be executed from onHandleIntent(). Also, get rid of Glide or figure out how to have it download images synchronously (which, AFAIK, it cannot do).
IntentService will not work well on Android 8.0+ unless you make it be a foreground service and use startForegroundService(). Consider using JobIntentService or, in 2019 and beyond, WorkManager.
Related
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));
}
}
});
}
Here is my code:
package com.saba.admin.w2track;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.AsyncTask;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;
import Adapters.VehicleListAdapter;
import Model.UserData;
import Model.VehicleData;
public class DashboardActivity extends AppCompatActivity {
static ArrayList<VehicleData> vehicleArrayList=new ArrayList<>();
static ArrayList<VehicleData> vehicleArrayList1=new ArrayList<>();
boolean clearflag=false;
static ArrayList<VehicleData> vehicleArrayListMoving=new ArrayList<>();
static ArrayList<VehicleData> vehicleArrayListStopped=new ArrayList<>();
static ArrayList<VehicleData> vehicleArrayListActive=new ArrayList<>();
static ArrayList<VehicleData> vehicleArrayListInActive=new ArrayList<>();
String acctype;
//static VehicleListAdapter listAdapter;
UserData userData;
TextView txtStopped,txtMoving,txtTotal,txtInactive,txtAlerts;
RelativeLayout moving,alerts,inactive,stopped,total;
boolean doubleBackToExitPressedOnce = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard3);
setView();
getBundleData();
// String acc[]={acctype};
updateVehicles();
}
public void updateVehicles() {
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
DashboardActivity.this.runOnUiThread(new Runnable() {
public void run() {
try {
vehicle v = new vehicle();
v.execute(acctype);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 30000);
}
public void setView(){
txtStopped=(TextView)findViewById(R.id.txtstopped);
txtMoving=(TextView)findViewById(R.id.txtmoving);
txtAlerts=(TextView)findViewById(R.id.txtalerts);
txtInactive=(TextView)findViewById(R.id.txtinactive);
txtTotal=(TextView)findViewById(R.id.txttotal);
moving=(RelativeLayout)findViewById(R.id.LayoutMoving);
stopped=(RelativeLayout)findViewById(R.id.LayoutStopped);
alerts=(RelativeLayout)findViewById(R.id.LayoutAlerts);
inactive=(RelativeLayout)findViewById(R.id.LayoutInActive);
total=(RelativeLayout)findViewById(R.id.LayoutTotal);
}
public void getBundleData(){
Bundle b = getIntent().getExtras();
if (b != null && b.containsKey("userData"))
{
userData=b.getParcelable("userData");
acctype=b.getString("acctype");
// Log.d("accountid",userData.getAccountId()+" ");
Log.d("userid123..",userData.getUserId()+" ");
Log.d("timediff123..",userData.getTimediff()+" ");
//Log.d("km1..",userData.getMilesPerKms()+" ");
}
}
//vehicle asyncclass in dashboard..which is called in dashboard every 30 sec to get updated data & store in arraylist.
private class vehicle extends AsyncTask<String,String,String> {
private ProgressDialog dialog;
String response="";
private JSONObject res;
#Override
protected void onPreExecute() {
super.onPreExecute();
try {
if(!DashboardActivity.this.isFinishing()) {
dialog = new ProgressDialog(DashboardActivity.this);
dialog.setMessage("Please Wait..");
dialog.setCancelable(false);
// searchBox.setEnabled(false);
dialog.show();
}
if(true) {
vehicleArrayList.clear();
vehicleArrayList1.clear();
vehicleArrayListMoving.clear();
vehicleArrayListStopped.clear();
vehicleArrayListActive.clear();
vehicleArrayListInActive.clear();
Log.d("cleared1111", "cleared ");
clearflag=true;
}
}catch (Exception e){
Log.d("eroror1111", e.toString() + " ");
// Toast.makeText(getActivity(),e.toString(),Toast.LENGTH_SHORT).show();
}
}
#Override
protected String doInBackground(String... params) {
try {
JSONObject vehicle_json = new JSONObject();
vehicle_json.put("pAccountId", userData.getUserId());
res = CustomHttpClient.postJsonObject("http://"+params[0]+".w2track.com/api/index.php?cmd=vehicles", vehicle_json,DashboardActivity.this);
String resData=res.getString("ResponseData");
JSONArray array=new JSONArray(resData);
Log.d("1111",array.length()+" ");
for(int i=0;i<array.length();i++){
Log.d("11112","2222");
VehicleData vehicleData=new VehicleData();
JSONObject jsonVehicleObj=new JSONObject(array.get(i).toString());
Log.d("111123", "2222");
if(jsonVehicleObj.getString("vehiclenumber").equals("null") ||jsonVehicleObj.getString("vehiclenumber")==null ){
Log.d("111124","2222");
continue;
// Log.d("11112","2222");
}
vehicleData.setVehicleNumber(jsonVehicleObj.getString("vehiclenumber"));
vehicleData.setPlacename(jsonVehicleObj.getString("location"));
vehicleData.setSpeed(jsonVehicleObj.getString("speed"));
vehicleData.setLandmark(jsonVehicleObj.getString("landmark"));
vehicleData.setIsActive(jsonVehicleObj.getBoolean("isactive"));
vehicleData.setVehicleType(jsonVehicleObj.getString("vehicletype"));
vehicleData.setFuel(jsonVehicleObj.getString("fuel"));
Log.d("fuel11115", vehicleData.getFuel() + " ");
vehicleData.setDept(jsonVehicleObj.getString("department"));
vehicleData.setDivision(jsonVehicleObj.getString("division"));
vehicleData.setIginition(jsonVehicleObj.getString("ignition"));
vehicleData.setLati(jsonVehicleObj.getString("lat"));
vehicleData.setLongi(jsonVehicleObj.getString("lng"));
vehicleData.setOdometer(jsonVehicleObj.getString("odometer"));
vehicleData.setGpsmode(jsonVehicleObj.getString("gpsmode"));
vehicleData.setInnerbattery(jsonVehicleObj.getDouble("inbatt"));
vehicleData.setExtbattery(jsonVehicleObj.getDouble("extbatt"));
vehicleData.setUnitId(jsonVehicleObj.getString("unitid"));
vehicleData.setUnitNo(jsonVehicleObj.getString("unitno"));
vehicleData.setIgnitionTime(jsonVehicleObj.getString("ign_time"));
vehicleData.setDate1(jsonVehicleObj.getString("date"));
vehicleData.setIconImage(jsonVehicleObj.getString("icon"));
vehicleData.setSignal(jsonVehicleObj.getString("signal"));
Log.d("111126", "2222");
if(clearflag) {
vehicleArrayList.add(vehicleData);
vehicleArrayList1.add(vehicleData);
Log.d("111127", "2222");
if (vehicleData.getIginition().equals("Off") && vehicleData.isActive()) {
vehicleArrayListStopped.add(vehicleData);
vehicleArrayListActive.add(vehicleData);
} else if (vehicleData.getIginition().equals("On") && vehicleData.isActive()) {
vehicleArrayListMoving.add(vehicleData);
vehicleArrayListActive.add(vehicleData);
} else if (!vehicleData.isActive()) {
vehicleArrayListInActive.add(vehicleData);
}
}
Log.d("vehicleno1111",vehicleData.getVehicleNumber()+" ");
}
clearflag=false;
// JSONObject jsonObject1=new JSONObject(array.get(0).toString());
// response=jsonObject1.toString();
//Log.d("myresponse",response+" ");
}catch (Exception e){
Log.d("errorrrr1111", e.toString());
}
return response;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
txtTotal.setText("Total ("+ vehicleArrayList.size()+")");
txtMoving.setText("Moving ("+ vehicleArrayListMoving.size()+")");
txtStopped.setText("Stopped ("+vehicleArrayListStopped.size()+")");
// txtAlerts.setText(jsonObject.getString("TotalActive"));
txtInactive.setText("InActive (" + vehicleArrayListInActive.size() + ")");
if(!DashboardActivity.this.isFinishing()) {
if (dialog.isShowing()) {
dialog.dismiss();
}
}
}
}
//dashboard activty calls vehicle service every 30 seconds & storing in different arraylist like moving, stopped etc. i am using that arraraylist & settting adapter & calling notifydatasetchanged (every 10 sec) in vehicle activity
VehicleList class
public class VehicleList extends android.support.v4.app.Fragment {
Runnable r;
Timer timer;
TimerTask myTimerTask;
ListView lstVehicle;
EditText searchBox;
static String status;
// Context context;
VehicleListActivityFinal vehicleListActivityFinal;
ImageView img;
static UserData userData;
int accid,timdiff,mile;
String userid,acctype;
VehicleListAdapter listAdapter;
final Handler handler =new Handler() ;
VehicleListActivityFinal vehiclefinal;
}*/
public VehicleList() {
// Required empty public constructor
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("oncreate..", "oncreate..");
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view= inflater.inflate(R.layout.fragment_vehicle_list, container, false);
//vehicleArrayList =new ArrayList<VehicleData>();
lstVehicle =(ListView)view.findViewById(R.id.vehicle_listview);
// lstVehicle.requestFocus();
img=(ImageView)view.findViewById(R.id.Imgnodata);
Log.d("createview", "createview");
if (getArguments() != null) {
// Bundle bundle=getArguments();
userid=getArguments().getString("UserID");
acctype=getArguments().getString("acctype");
timdiff=getArguments().getInt("TimeDiff");
status=getArguments().getString("status");
Log.d("arg1111",userid+" ");
Log.d("arg11112",timdiff+" ");
}
else
{
Log.d("insidenull","nullnull");
}
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
vehicleListActivityFinal=(VehicleListActivityFinal)getActivity();
searchBox=(EditText)vehicleListActivityFinal.findViewById(R.id.searchBox);
Log.d("onactivitycrated..", "activitycreated...");
if(savedInstanceState==null) {
if (CheckInternet.isConnectionAvailable(vehicleListActivityFinal)) {
getVehicleData();
updateVehicleData();
} else {
CheckInternet.showNoInternet(vehicleListActivityFinal);
}
}
Log.d("testtest", vehicleListActivityFinal.test + " ");
lstVehicle.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
try {
VehicleData vehicleData = (VehicleData) parent.getAdapter().getItem(position);
Intent intent = new Intent(vehicleListActivityFinal, VehicleDetailActivity.class);
intent.putExtra("vehicleData1", vehicleData);
intent.putExtra("acctype", acctype);
// intent.putExtra()
startActivity(intent);
vehicleListActivityFinal.overridePendingTransition(R.anim.push_in, R.anim.push_out);
}catch (Exception e){
Toast.makeText(vehicleListActivityFinal,e.toString(),Toast.LENGTH_SHORT).show();
}
}
});
searchText();
// updateVehicleData();
// setRetainInstance(true);
}
//method which calls notifydatasetchanged every 10 seconds on vehicle activity
public void updateVehicleData(){
final Handler handler = new Handler();
Timer timer = new Timer();
TimerTask doAsynchronousTask = new TimerTask() {
#Override
public void run() {
vehicleListActivityFinal.runOnUiThread(new Runnable() {
public void run() {
try {
// getVehicleData();
img.setVisibility(View.GONE);
listAdapter.notifyDataSetChanged();
lstVehicle.invalidate();
if (lstVehicle.getAdapter().getCount() == 0) {
img.setVisibility(View.VISIBLE);
Toast.makeText(vehicleListActivityFinal, "empty list..", Toast.LENGTH_SHORT).show();
}
Toast.makeText(vehicleListActivityFinal, "Refreshing Data..", Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
};
timer.schedule(doAsynchronousTask, 0, 10000);
}
method which sets adapter of vehicle on vehicle activity
public void getVehicleData(){
// lstVehicle.requestFocus();
if(VehicleListActivityFinal.movingStatus.equals("moving")) {
listAdapter = new VehicleListAdapter(vehicleListActivityFinal, DashboardActivity.vehicleArrayListMoving,vehicleListActivityFinal);
// Log.d("adapterempty", listAdapter.isEmpty()+" ");
lstVehicle.setAdapter(listAdapter);
//listAdapter.notifyDataSetChanged();
}
else if(VehicleListActivityFinal.movingStatus.equals("total")){
listAdapter = new VehicleListAdapter(vehicleListActivityFinal, DashboardActivity.vehicleArrayList1,vehicleListActivityFinal);
lstVehicle.setAdapter(listAdapter);
//listAdapter.notifyDataSetChanged();
}
else if(VehicleListActivityFinal.movingStatus.equals("inactive")){
listAdapter = new VehicleListAdapter(vehicleListActivityFinal, DashboardActivity.vehicleArrayListInActive,vehicleListActivityFinal);
lstVehicle.setAdapter(listAdapter);
//listAdapter.notifyDataSetChanged();
}
else if(VehicleListActivityFinal.movingStatus.equals("stopped")){
listAdapter = new VehicleListAdapter(vehicleListActivityFinal, DashboardActivity.vehicleArrayListStopped,vehicleListActivityFinal);
lstVehicle.setAdapter(listAdapter);
// listAdapter.notifyDataSetChanged();
}
else
{
listAdapter = new VehicleListAdapter(vehicleListActivityFinal, DashboardActivity.vehicleArrayList1,vehicleListActivityFinal);
lstVehicle.setAdapter(listAdapter);
// listAdapter.notifyDataSetChanged();
}
// lstVehicle.invalidate();
//lstVehicle.requestLayout();
Log.d("postexecute1111", searchBox.isFocused() + " ");
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
VehicleListActivityFinal.currentFragment="VehicleList";
}
#Override
public void onDetach() {
super.onDetach();
Log.d("detach1", "detach");
}
#Override
public void onResume() {
super.onResume();
Log.d("onresume", "onresume");
}
public void searchText() {
// lstVehicle.setAdapter(listAdapter);
searchBox.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
Toast.makeText(vehicleListActivityFinal,"beforetextchanged",Toast.LENGTH_SHORT).show();
}
#Override
public void onTextChanged(CharSequence s1, int start, int before, int count) {
listAdapter.getFilter().filter(s1.toString());
// Toast.makeText(getActivity(),"ontextchanged",Toast.LENGTH_SHORT).show();
//lstVehicle.setAdapter(listAdapter);
//listAdapter.notifyDataSetChanged();
}
#Override
public void afterTextChanged(Editable s) {
//Toast.makeText(getActivity(),"afterrtextchanged",Toast.LENGTH_SHORT).show();
}
});
}
}
I am making a retrofit enqueue call from SplashActivity and passing data to next activity via bundles.Even after explicitly calling finish on splash activity it still has 48 references in retained heap as seen in MAT.
The app in general is also taking a lot of memory in the background. I debugged and found that my activity's onDestroy() method is getting called, but why are the objects still persistent in the memory? Is it somehow related to the data being passed by reference instead of value? I've been trying to search around the web but with hardly any luck. Please point me if I'm looking in the wrong direction here.
Here's a snapshot of my Splash Activity-
public class SplashActivity extends AppCompatActivity {
private String TAG = SplashActivity.class.getSimpleName();
List<Sport> mSportsList;
List<Event> mEventsList;
List<Carousel> mCarouselList;
WatchOnApiService mWatchOnApiService;
#BindString(R.string.package_name)
String mPackageName;
ProgressBar mProgressBar;
AlertDialog.Builder alertDialogBuilder;
AlertDialog alertDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash);
ButterKnife.bind(this);
MobileAds.initialize(getApplicationContext(), "ca-app-pub-8433136449848959~7585529227");
mProgressBar = (ProgressBar) findViewById(R.id.progressBar);
mProgressBar.getIndeterminateDrawable().setColorFilter(Color.WHITE, PorterDuff.Mode.MULTIPLY);
}
#Override
protected void onResume() {
super.onResume();
getSportsAndEventsAndCarousel();
}
private void getSportsAndEventsAndCarousel() {
mProgressBar.setVisibility(View.VISIBLE);
WatchOnApiService mWatchOnApiService = RetrofitFactory.getRetrofit().create(WatchOnApiService.class);
final Call<WatchOnSportsEventsCarousel> mCall = mWatchOnApiService.getAllSportsAndEventsAndCarousel(TimeZone.getDefault().getID());
mCall.enqueue(new Callback<WatchOnSportsEventsCarousel>() {
#Override
public void onResponse(final Response<WatchOnSportsEventsCarousel> response, Retrofit retrofit)
{
if (response.isSuccess()) {
mProgressBar.setVisibility(View.INVISIBLE);
if (Float.parseFloat(BuildConfig.VERSION_NAME) < Float.parseFloat(response.body().getAndroidLatestVersion())) {
if (response.body().getAndroidForceUpdate().equalsIgnoreCase("1")) {
showForceUpdateDialog();
} else {
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(SplashActivity.this);
alertDialogBuilder.setTitle("WatchOn");
alertDialogBuilder.setMessage("WatchOn just got better.Would you like to upgrade ?");
alertDialogBuilder.setPositiveButton("Upgrade",
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int arg1) {
dialog.dismiss();
try { SplashActivity.this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=" + mPackageName)));
} catch (android.content.ActivityNotFoundException anfe) {
SplashActivity.this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + mPackageName)));
}
}
});
alertDialogBuilder.setNegativeButton("Dismiss", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
beginFlow(response);
}
});
AlertDialog alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
} else {
beginFlow(response);
}
}
//Response not received something went wrong
else {
showAlertDialogNoResponse();
}
}
private void beginFlow(final Response<WatchOnSportsEventsCarousel> response) {
Bundle mBundle = new Bundle();
mSportsList = CodeUtils.convertSportsListToLocalTime(response.body().getData().getSports());
Parcelable wrappedSports = Parcels.wrap(new ArrayList<>(mSportsList));
mBundle.putParcelable(AppConstants.SPORTS_LIST, wrappedSports);
mEventsList = CodeUtils.convertEventsListToLocalTime(response.body().getData().getEvents());
Parcelable wrappedEvents = Parcels.wrap(new ArrayList<>(mEventsList));
mBundle.putParcelable(AppConstants.EVENTS_LIST, wrappedEvents);
mCarouselList = response.body().getData().getCarousels();
Parcelable wrappedCarousels = Parcels.wrap(new ArrayList<>(mCarouselList));
mBundle.putParcelable(AppConstants.CAROUSELS_LIST, wrappedCarousels);
if ((response.body().getLiveSponsors() == 1)) {
mBundle.putBoolean(AppConstants.LIVE_SPONSORS_AVAILABLE, true);
} else {
mBundle.putBoolean(AppConstants.LIVE_SPONSORS_AVAILABLE, false);
}
Intent i = new Intent(SplashActivity.this, SelectSportEventActivity.class);
i.putExtras(mBundle);
mSportsList = null;
mEventsList = null;
mCarouselList = null;
startActivity(i);
SplashActivity.this.finish();
}
#Override
public void onFailure(Throwable t) {
showAlertDialogInternetFail();
alertDialogBuilder.setNegativeButton("Retry", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
getSportsAndEventsAndCarousel();
dialog.dismiss();
}
});
alertDialog = alertDialogBuilder.create();
alertDialog.show();
}
});
}
#Override
protected void onDestroy() {
ButterKnife.unbind(this);
Log.d(TAG, "onDestroy: " + mSportsList + mEventsList + mCarouselList);
alertDialog = null;
super.onDestroy();
}
}
I'm trying to make ads that give "100 coins" and the button just disappear after 0,2 - 1 second.
I've got no clue why this error could appear. Has someone got an idea how to fix that?
My error
06-03 21:42:16.017: V/PTAdHeyzapBridge(27950): PTAdHeyzapBridge -- Start Session: "MyHeyzapID"
06-03 21:42:16.023: E/Heyzap(27950): Heyzap encountered a runtime exception and is now disabled. Error: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
06-03 21:42:16.023: V/PTAdHeyzapBridge(27950): PTAdHeyzapBridge -- Start Session FAILED : Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
06-03 21:42:16.023: V/PTAdHeyzapBridge(27950): Heyzap SDK Version : 8.4.1
My PTAdHeyzapBridge.java
package com.secrethq.ads;
import java.lang.ref.WeakReference;
import org.cocos2dx.lib.Cocos2dxActivity;
import com.google.android.gms.ads.AdView;
import com.heyzap.sdk.ads.HeyzapAds;
import com.heyzap.sdk.ads.InterstitialAd;
import com.heyzap.sdk.ads.VideoAd;
import com.heyzap.sdk.ads.IncentivizedAd;
import com.heyzap.sdk.ads.BannerAdView;
import com.heyzap.sdk.ads.HeyzapAds.BannerListener;
import com.heyzap.sdk.ads.HeyzapAds.BannerError;
import com.heyzap.sdk.ads.HeyzapAds.OnStatusListener;
import com.heyzap.sdk.ads.HeyzapAds.OnIncentiveResultListener;
import android.util.Log;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.RelativeLayout;
public class PTAdHeyzapBridge {
private static native String bannerId();
private static native String interstitialId();
private static native void interstitialDidFail();
private static native void bannerDidFail();
private static native void rewardVideoComplete();
private static final String TAG = "PTAdHeyzapBridge";
private static Cocos2dxActivity activity;
private static WeakReference<Cocos2dxActivity> s_activity;
private static BannerAdView bannerAdView;
public static void initBridge(Cocos2dxActivity activity){
Log.v(TAG, "PTAdHeyzapBridge -- INIT");
PTAdHeyzapBridge.s_activity = new WeakReference<Cocos2dxActivity>(activity);
PTAdHeyzapBridge.activity = activity;
PTAdHeyzapBridge.initBanner();
PTAdHeyzapBridge.initInterstitial();
PTAdHeyzapBridge.initVideo();
}
public static void initBanner(){
Log.v(TAG, "PTAdHeyzapBridge -- Init Banner");
PTAdHeyzapBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
PTAdHeyzapBridge.bannerAdView = new BannerAdView(PTAdHeyzapBridge.activity);
FrameLayout frameLayout = (FrameLayout)PTAdHeyzapBridge.activity.findViewById(android.R.id.content);
RelativeLayout layout = new RelativeLayout( PTAdHeyzapBridge.activity );
frameLayout.addView( layout );
RelativeLayout.LayoutParams adViewParams = new RelativeLayout.LayoutParams(
AdView.LayoutParams.WRAP_CONTENT,
AdView.LayoutParams.WRAP_CONTENT);
adViewParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
adViewParams.addRule(RelativeLayout.CENTER_IN_PARENT, RelativeLayout.TRUE);
layout.addView(PTAdHeyzapBridge.bannerAdView, adViewParams);
PTAdHeyzapBridge.bannerAdView.setVisibility( View.INVISIBLE );
// Add a listener.
PTAdHeyzapBridge.bannerAdView.setBannerListener(new BannerListener() {
#Override
public void onAdClicked(BannerAdView b) {
// The ad has been clicked by the user.
}
#Override
public void onAdLoaded(BannerAdView b) {
// The ad has been loaded.
}
#Override
public void onAdError(BannerAdView b, BannerError bannerError) {
// There was an error loading the ad.
Log.v(TAG, "PTAdHeyzapBridge -- Banner onAdError : " + bannerError.getErrorMessage());
bannerDidFail();
}
});
}
});
}
public static void initInterstitial(){
Log.v(TAG, "PTAdHeyzapBridge -- Init Interstitial");
InterstitialAd.setOnStatusListener(new OnStatusListener() {
#Override
public void onShow(String tag) {
// Ad is now showing
}
#Override
public void onClick(String tag) {
// Ad was clicked on. You can expect the user to leave your application temporarily.
}
#Override
public void onHide(String tag) {
// Ad was closed. The user has returned to your application.
}
#Override
public void onFailedToShow(String tag) {
// Display was called but there was no ad to show
}
#Override
public void onAvailable(String tag) {
// An ad has been successfully fetched
}
#Override
public void onFailedToFetch(String tag) {
// No ad was able to be fetched
Log.v(TAG, "PTAdHeyzapBridge -- Interstitial onFailedToFetch : " + tag);
interstitialDidFail();
}
#Override
public void onAudioFinished() {
// TODO Auto-generated method stub
}
#Override
public void onAudioStarted() {
// TODO Auto-generated method stub
}
});
}
public static void initVideo() {
IncentivizedAd.setOnIncentiveResultListener(new OnIncentiveResultListener() {
#Override
public void onComplete(String tag) {
Log.v(TAG, "PTAdHeyzapBridge -- IncentivizedAd Complete ");
// Give the player their reward
rewardVideoComplete();
}
#Override
public void onIncomplete(String tag) {
// Don't give the player their reward, and tell them why
Log.v(TAG, "PTAdHeyzapBridge -- IncentivizedAd InComplete ");
}
});
PTAdHeyzapBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
// As early as possible, and after showing a rewarded video, call fetch
IncentivizedAd.fetch();
}
});
}
public static void showRewardedVideo(){
Log.v(TAG, "PTAdHeyzapBridge -- showRewardedVideo");
PTAdHeyzapBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
if (IncentivizedAd.isAvailable()) {
IncentivizedAd.display(PTAdHeyzapBridge.activity);
}
}
});
}
public static void startSession( String sdkKey ){
if(sdkKey != null){
Log.v(TAG, "PTAdHeyzapBridge -- Start Session: " + sdkKey);
try {
HeyzapAds.start(sdkKey, PTAdHeyzapBridge.activity);
} catch (Exception e) {
// TODO: handle exception
Log.v(TAG, "PTAdHeyzapBridge -- Start Session FAILED : " + e.getMessage());
}
Log.v(TAG, "Heyzap SDK Version : " + HeyzapAds.getVersion());
}else{
Log.v(TAG, "Start Session : null ");
}
}
public static void showFullScreen(){
Log.v(TAG, "PTAdHeyzapBridge -- showFullScreen");
PTAdHeyzapBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
// InterstitialAds are automatically fetched from our server
InterstitialAd.display(PTAdHeyzapBridge.activity);
}
});
}
public static void showBannerAd(){
Log.v(TAG, "PTAdHeyzapBridge -- showBannerAd");
PTAdHeyzapBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
if(PTAdHeyzapBridge.bannerAdView != null){
PTAdHeyzapBridge.bannerAdView.setVisibility(View.VISIBLE);
// Load the banner ad.
PTAdHeyzapBridge.bannerAdView.load();
}
}
});
}
public static void hideBannerAd(){
Log.v(TAG, "PTAdHeyzapBridge -- hideBannerAd");
PTAdHeyzapBridge.s_activity.get().runOnUiThread( new Runnable() {
public void run() {
if(PTAdHeyzapBridge.bannerAdView != null){
PTAdHeyzapBridge.bannerAdView.setVisibility(View.INVISIBLE);
}
}
});
}
public static boolean isBannerVisible() {
return (PTAdHeyzapBridge.bannerAdView.getVisibility() == View.VISIBLE);
}
public static boolean isRewardedVideoAvialable(){
return IncentivizedAd.isAvailable();
}
}
My Main activity
package com.lopeostudios.runningpanda;
import org.cocos2dx.lib.Cocos2dxActivity;
import org.cocos2dx.lib.Cocos2dxGLSurfaceView;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;
import com.secrethq.store.PTStoreBridge;
import com.google.android.gms.games.GamesActivityResultCodes;
import com.lopeostudios.runningpanda.R;
import com.secrethq.ads.*;
import com.secrethq.utils.*;
import com.onesignal.OneSignal;
public class PTPlayer extends Cocos2dxActivity {
private static native void loadModelController();
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.v("----------","onActivityResult: request: " + requestCode + " result: "+ resultCode);
if(PTStoreBridge.iabHelper().handleActivityResult(requestCode, resultCode, data)){
Log.v("-----------", "handled by IABHelper");
}
else if(requestCode == PTServicesBridge.RC_SIGN_IN){
if(resultCode == RESULT_OK){
PTServicesBridge.instance().onActivityResult(requestCode, resultCode, data);
}
else if(resultCode == GamesActivityResultCodes.RESULT_SIGN_IN_FAILED){
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(this, "Google Play Services: Sign in error", duration);
toast.show();
}
else if(resultCode == GamesActivityResultCodes.RESULT_APP_MISCONFIGURED){
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(this, "Google Play Services: App misconfigured", duration);
toast.show();
}
}
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
OneSignal.startInit(this).init();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
#Override
public void onNativeInit(){
initBridges();
}
private void initBridges(){
PTStoreBridge.initBridge( this );
PTServicesBridge.initBridge(this, getString( R.string.app_id ));
if (PTJniHelper.isAdNetworkActive("kChartboost")) {
PTAdChartboostBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kRevMob")) {
PTAdRevMobBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kAdMob") || PTJniHelper.isAdNetworkActive("kFacebook")) {
PTAdAdMobBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kAppLovin")) {
PTAdAppLovinBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kLeadBolt")) {
PTAdLeadBoltBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kVungle")) {
PTAdVungleBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kPlayhaven")) {
PTAdUpsightBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kMoPub")) {
PTAdMoPubBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kFacebook")) {
PTAdFacebookBridge.initBridge(this);
}
if (PTJniHelper.isAdNetworkActive("kHeyzap")) {
PTAdHeyzapBridge.initBridge(this);
}
}
#Override
public Cocos2dxGLSurfaceView onCreateView() {
Cocos2dxGLSurfaceView glSurfaceView = new Cocos2dxGLSurfaceView(this);
glSurfaceView.setEGLConfigChooser(8, 8, 8, 0, 0, 0);
return glSurfaceView;
}
static {
System.loadLibrary("player");
}
#Override
protected void onResume() {
super.onResume();
if (PTJniHelper.isAdNetworkActive("kChartboost")) {
PTAdChartboostBridge.onResume( this );
}
}
#Override
protected void onStart() {
super.onStart();
if (PTJniHelper.isAdNetworkActive("kChartboost")) {
PTAdChartboostBridge.onStart( this );
}
}
#Override
protected void onStop() {
super.onStop();
if (PTJniHelper.isAdNetworkActive("kChartboost")) {
PTAdChartboostBridge.onStop( this );
}
}
#Override
protected void onDestroy() {
super.onDestroy();
}
}
I'm an engineer at Heyzap. Our SDK will catch exceptions from third party SDKs, and shut down our SDK if we catch one (this is our last line of defense in preventing exceptions from crashing your game). In this case, we're catching this exception:
06-03 21:42:16.023: E/Heyzap(27950): Heyzap encountered a runtime exception and is now disabled. Error: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
We've previously seen this exception caused by an outdated UnityAds SDK. Are you using that network, and if so, can you try UnityAds 1.5.6? If you're not, can you tell us which networks you're using, or the Android package of your game?
Also, I see in yours logs that you're using Heyzap 8.4.1, which was released in June of last year. Can you update to our latest version?
I have a seekbar in my cursor adaptor, code below, when I am playing a song I am supposed to increment it, I have a separate utility class, but the problem is the seekbar is not progressing at all, even if I hard code it, but the log cat is showing my calculations fine which I commented in my run handler.
When I am sliding the seekbar "onStartTrackingTouch" and "onStopTrackingTouch" is responding fine with proper integer value. Music is played via a service which is working fine too.
Where am I going wrong ?
package com.kavayah.spotifystreamer;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.media.Image;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.CursorAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.ToggleButton;
import com.kavayah.spotifystreamer.data.SpotifyContract;
import com.squareup.okhttp.Call;
import com.squareup.picasso.MemoryPolicy;
import com.squareup.picasso.NetworkPolicy;
import com.squareup.picasso.Picasso;
import java.util.ArrayList;
public class TrackPlayerAdapter extends CursorAdapter {
private final static String LOG_TAG = TrackPlayerAdapter.class.getSimpleName();
private static Context context;
private SpotifyMusicService mSpotifyMusicService;
private Intent playIntent;
private boolean iSMusicServiceBoundToActivity = false;
private static ServiceConnection spotifyMusicConnection;
private Handler mDurationHandler = new Handler();
private SeekBar mSpotifyMusicSeekBar;
private static int mDuration_ms;
private Utility utils;
//declare a interface which will communicate with the fragment
Callback callback;
public interface Callback {
/**
* DetailFragmentCallback for when an item has been selected.
*/
public void playItemSelected();
public void nextItemSelected(Uri trackUri);
}
/*
public TrackPlayerAdapter(Context context, Cursor c, int flags){
super(context, c, flags);
trackPlayerActivityFragment = new TrackPlayerActivityFragment();
}
*/
public TrackPlayerAdapter(Context context, Cursor c, int flags, Callback callback) {
super(context, c, flags);
this.context = context;
this.callback = callback;
utils = new Utility();
//connect to the service
spotifyMusicConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
SpotifyMusicService.SpotifyMusicBinder binder = (SpotifyMusicService.SpotifyMusicBinder) service;
//get the service
mSpotifyMusicService = binder.getService();
iSMusicServiceBoundToActivity = true;
}
#Override
public void onServiceDisconnected(ComponentName name) {
Log.i(LOG_TAG, ">>>>> Music service disconnected.");
iSMusicServiceBoundToActivity = false;
}
};
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
if (playIntent == null) {
playIntent = new Intent(context, SpotifyMusicService.class);
context.bindService(playIntent, spotifyMusicConnection, context.BIND_AUTO_CREATE);
context.startService(playIntent);
}
int viewType = getItemViewType(cursor.getPosition());
int layoutId = -1;
layoutId = R.layout.list_item_player;
View view = LayoutInflater.from(context).inflate(layoutId, parent, false);
TrackPlayerViewHolder trackPlayerViewHolder = new TrackPlayerViewHolder(view);
view.setTag(trackPlayerViewHolder);
return view;
}
#Override
public void bindView(View view, final Context context, final Cursor cursor) {
TrackPlayerViewHolder trackPlayerViewHolder = (TrackPlayerViewHolder) view.getTag();
int viewType = getItemViewType(cursor.getPosition());
String artistIcon = cursor.getString(TrackPlayerActivityFragment.COL_ALBUM_ICON2);
Log.i(LOG_TAG, ">>>>> TrackPlayerActivityFragment.COL_ALBUM_ICON2 " + artistIcon);
if (artistIcon != null && !artistIcon.equals("")) {
Picasso.with(context)
.load(artistIcon)
.memoryPolicy(MemoryPolicy.NO_CACHE)
.networkPolicy(NetworkPolicy.NO_CACHE)
.tag(context)
.into(trackPlayerViewHolder.iconView);
} else {
trackPlayerViewHolder.iconView.setImageResource(0);
}
String artistName = cursor.getString(TrackPlayerActivityFragment.COL_ARTIST_NAME);
trackPlayerViewHolder.artistNameView.setText(artistName);
String albumName = cursor.getString(TrackPlayerActivityFragment.COL_ALBUM_NAME);
trackPlayerViewHolder.albumNameView.setText(albumName);
String trackName = cursor.getString(TrackPlayerActivityFragment.COL_TRACK_NAME);
trackPlayerViewHolder.trackNameView.setText(trackName);
String duration = String.valueOf(cursor.getInt(TrackPlayerActivityFragment.COL_DURATION_MS));
trackPlayerViewHolder.durationView.setText(duration);
//implement the OnSeekBarChangeListener interface methods
mSpotifyMusicSeekBar = (SeekBar) view.findViewById(R.id.musicSeekBar);
mSpotifyMusicSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
if (fromUser) {
Log.i("onProgressChanged", "" + progress);
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
Log.i("onStartTrackingTouch",
"" + seekBar.getProgress());
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
Log.i("onStopTrackingTouch",
"" + seekBar.getProgress());
mSpotifyMusicService.seek(seekBar.getProgress());
}
});
final ToggleButton play_button = (ToggleButton) view.findViewById(R.id.media_play);
play_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (view != null) {
Log.i(LOG_TAG, ">>>>> play button click - " + cursor.getInt(TrackPlayerActivityFragment.COL_PRIMARY_TRACK_ID));
//((Callback)trackPlayerActivityFragment).onItemSelected();
callback.playItemSelected();
mSpotifyMusicService.setSongURL(cursor.getString(TrackPlayerActivityFragment.COL_PREVIEW_URL));
mSpotifyMusicService.playSong(cursor.getString(TrackPlayerActivityFragment.COL_TRACK_NAME));
mDuration_ms = cursor.getInt(TrackPlayerActivityFragment.COL_DURATION_MS);
mSpotifyMusicSeekBar.setProgress(0);
mSpotifyMusicSeekBar.setMax(100);
updateSeekbarProgress();
}
}
});
final ImageButton next_button = (ImageButton) view.findViewById(R.id.media_next);
next_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (view != null) {
Integer nextSongId = cursor.getInt(TrackPlayerActivityFragment.COL_PRIMARY_TRACK_ID);
Log.i(LOG_TAG, ">>>>> next button click - " + ++nextSongId);
//check to see if query return null, means it has reached the end of the
// tracks list, stay of the last song even if the user presses next key
Uri nextTrackUri = SpotifyContract.TrackEntry.buildTrackUri(nextSongId);
Cursor cur = context.getContentResolver().query(nextTrackUri, null, null, null, null);
if (cur.getCount() < 1) {
//--nextSongId;
//nextTrackUri = SpotifyContract.TrackEntry.buildTrackUri(nextSongId);
} else {
callback.nextItemSelected(nextTrackUri);
}
if(cur.getCount() > 0){
cur.moveToFirst();
mSpotifyMusicService.setSongURL(cur.getString(TrackPlayerActivityFragment.COL_PREVIEW_URL));
mSpotifyMusicService.playSong(cur.getString(TrackPlayerActivityFragment.COL_TRACK_NAME));
}
//Intent intent = new Intent(context, TrackPlayerActivity.class);
//intent.setData(SpotifyContract.TrackEntry.buildTrackUri(nextSongId));
//context.startActivity(intent);
}
}
});
final ImageButton prev_button = (ImageButton) view.findViewById(R.id.media_prev);
prev_button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (view != null) {
Integer prevSongId = cursor.getInt(TrackPlayerActivityFragment.COL_PRIMARY_TRACK_ID);
Log.i(LOG_TAG, ">>>>> prev button click - " + --prevSongId);
//check if the query returns null, means it has reached the beginning
//increment the track id, else it will show null.
Uri prevTrackUri = SpotifyContract.TrackEntry.buildTrackUri(prevSongId);
Cursor cur = context.getContentResolver().query(prevTrackUri, null, null, null, null);
if (cur.getCount() < 1) {
//++prevSongId;
//prevTrackUri = SpotifyContract.TrackEntry.buildTrackUri(prevSongId);
} else {
callback.nextItemSelected(prevTrackUri);
}
if (cur.getCount() > 0) {
cur.moveToFirst();
mSpotifyMusicService.setSongURL(cur.getString(TrackPlayerActivityFragment.COL_PREVIEW_URL));
mSpotifyMusicService.playSong(cur.getString(TrackPlayerActivityFragment.COL_TRACK_NAME));
}
}
}
});
}
public void updateSeekbarProgress(){
mDurationHandler.postDelayed(mUpdateSeekbarTime, 100);
}
private Runnable mUpdateSeekbarTime = new Runnable() {
public void run() {
//long totalDuration = mSpotifyMusicService.getDur();
long currentDuration = mSpotifyMusicService.getPosn();
// Updating progress bar
int progress = (int)(utils.getProgressPercentage(currentDuration, mDuration_ms));
//Log.i(LOG_TAG, " Seekbar position : " + progress);
mSpotifyMusicSeekBar.setProgress(progress);
mDurationHandler.postDelayed(this, 100);
}
};
}
The problem is that you have only one Adapter Object and only one mSpotifyMusicSeekBar variable and bind() is called multiple times, each time for every visible list item.
By the time the Handler is called, the seekBar reference is changed so you never see the progress because some other seekbar is getting updated.
I tried a sample of your code. And here it is - and - seek bar is getting updated as expected:
public class TrackPlayerAdapter extends RecyclerView.Adapter<TrackPlayerAdapter.MyHolder>
{
private final static String TAG = TrackPlayerAdapter.class.getSimpleName();
private Context context;
public TrackPlayerAdapter(Context context)
{
this.context = context;
}
#Override
public MyHolder onCreateViewHolder(ViewGroup viewGroup, int i)
{
LinearLayout container = new LinearLayout(context);
container.setOrientation(LinearLayout.VERTICAL);
container.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams
.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
SeekBar seekbar = new SeekBar(context);
seekbar.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams
.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
Button button = new Button(viewGroup.getContext());
button.setLayoutParams(new LinearLayout.LayoutParams(ViewGroup.LayoutParams
.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT));
button.setText("play");
seekbar.setTag("SEEKBAR");
button.setTag("BUTTON");
container.addView(seekbar);
container.addView(button);
return new MyHolder(container);
}
#Override
public void onBindViewHolder(MyHolder myHolder, int i)
{
myHolder.bind();
}
/**
* Get the row id associated with the specified position in the list.
*
* #param position The position of the item within the adapter's data set whose row id we want.
* #return The id of the item at the specified position.
*/
#Override
public long getItemId(int position)
{
return position;
}
#Override
public int getItemCount()
{
return 3;
}
public static class MyHolder extends RecyclerView.ViewHolder
{
private Handler mDurationHandler = new Handler();
private SeekBar mSpotifyMusicSeekBar;
private Button mToggleButton;
int totalProgress = 0;
public void updateSeekbarProgress()
{
mDurationHandler.postDelayed(mUpdateSeekbarTime, 100);
}
private Runnable mUpdateSeekbarTime = new Runnable()
{
public void run()
{
if(totalProgress <= 10000)
{
totalProgress += 100;
int progress = (int) ((float) totalProgress / 100);
mSpotifyMusicSeekBar.setProgress(progress);
mDurationHandler.postDelayed(this, 1000);
}
}
};
public MyHolder(View itemView)
{
super(itemView);
mSpotifyMusicSeekBar = (SeekBar)itemView.findViewWithTag("SEEKBAR");
mToggleButton = (Button) itemView.findViewWithTag("BUTTON");
}
public void bind()
{
mSpotifyMusicSeekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener()
{
#Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
{
Log.i(TAG, "onProgressChanged::" + progress);
}
#Override
public void onStartTrackingTouch(SeekBar seekBar)
{
// TODO Auto-generated method stub
Log.i(TAG, "onStartTrackingTouch::" + seekBar.getProgress());
}
#Override
public void onStopTrackingTouch(SeekBar seekBar)
{
// TODO Auto-generated method stub
Log.i(TAG, "onStopTrackingTouch" + seekBar.getProgress());
}
});
mToggleButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
mSpotifyMusicSeekBar.setProgress(0);
mSpotifyMusicSeekBar.setMax(100);
updateSeekbarProgress();
}
});
}
}
}