Hi I'm try to get Google Play Service Ads Id in AsyncTask.
I read Android AsyncTask API documentation and many stackoverflow Answer. I want to get Ads Id first and will start other process.
Accordingly, I made AdIdAsyncTask for getting Ads Id in BackgroundThread and invoke in my MainActivity. But My AsyncTask status is always RUNNING.
What's Wrong?
MainActivity and AdIdAsyncTask
public class MainActivity extends Activity {
private static final String TAG = "DummyActivity";
private final long MEDIA_ID = 292929L;
private final String ACCESS_KEY = "xxxx-xxxx-xxxx";
private String adId = null;
private AdContext adContext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
AdIdAsyncTask task = new AdIdAsyncTask();
task.execute();
Log.d(TAG, "task.getStatus=" + task.getStatus());
if (task.getStatus().equals(AsyncTask.Status.FINISHED)) {
// do work
}
}
#Override
protected void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy");
}
public class AdIdAsyncTask extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... params) {
Log.d(TAG, "doInBackground");
AdvertisingIdClient.Info idInfo = null;
try {
idInfo = AdvertisingIdClient.getAdvertisingIdInfo(getApplicationContext());
} catch (GooglePlayServicesNotAvailableException | GooglePlayServicesRepairableException | IOException e) {
Log.e(TAG, "fetch Google Ads is failed. message=" + e.getMessage());
}
String advertisingId = null;
try {
advertisingId = idInfo.getId();
} catch (NullPointerException e) {
Log.e(TAG, "adId is null. message=" + e.getMessage());
}
adId = advertisingId;
cancel(true);
Log.i(TAG, "adId=" + advertisingId + ", isCancelled=" + isCancelled());
return null;
}
#Override
protected void onCancelled() {
super.onCancelled();
Log.i(TAG, "onCancelled");
}
#Override
protected void onCancelled(Void aVoid) {
super.onCancelled(aVoid);
Log.i(TAG, "onCancelled");
}
}
}
Log
D/DummyActivity: task.getStatus=RUNNING
D/DummyActivity: doInBackground
I/DummyActivity: adId=xxxx-xxxx-xxxx, isCancelled=true
I/DummyActivity: onCancelled
I/DummyActivity: onCancelled
SdkVersion
compileSdkVersion 25
minSdkVersion 14
targetSdkVersion 25
Hello you can force close the AsyncTask
Please use the following code in yout AsyncTask with condition and call it in your activity where you want to stop, it will stop your asynk task running
/**
* Check if asynctask is running, if still running cancel it.
*/
public void forceCancel(){
if (getStatus().equals(AsyncTask.Status.RUNNING)) {
cancel(true);
}
}
Related
I want to return a Boolean after a AsyncTask.
This is the AsyncTask (not the whole code because isn't important and sstackoverflow give me error):
public class CallSoap extends AsyncTask<CallSoapParams, Void, Void> {
public interface AsyncResponse {
void processFinish(String output);
}
private Context activityContext;
public AsyncResponse delegate = null;//Call back interface
public CallSoap(Context context, AsyncResponse asyncResponse) {
activityContext = context;
delegate = asyncResponse;
}
#Override
protected Void doInBackground(CallSoapParams... params) {
request = new SoapObject(params[0].NAMESPACE, params[0].METHOD_NAME);
// no important things
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
//dismiss ProgressDialog
delegate.processFinish(response.toString());
}
#Override
protected void onPreExecute() {
super.onPreExecute();
//create and show ProgressDialog
}
}
And this is the implementation on Activity (not the whole code because isn't important and sstackoverflow give me error):
private boolean checkDataRegistrationByServer() {
if (NickNameExist()) {
// DO STUFF
}
return true;
}
Boolean r;
private boolean NickNameExist() {
CallSoapParams callParams = new CallSoapParams(NICKNAME_EXIST);
CallSoap NickNameExistCall = new CallSoap(RegistrationActivity.this, new CallSoap.AsyncResponse() {
#Override
public void processFinish(String output) {
Log.d("Response From AsyTask:", output);
if (output.equals(FALSE_RESPONSE)) {
r = false;
Toast.makeText(getApplicationContext(), output + " - NickNameExistCall - Nick don't exist", Toast.LENGTH_SHORT).show();
} else {
r = true;
}
}
});
NickNameExistCall.execute(callParams);
return r;
}
I tried to create a global Boolean but the App crash. Someone can help me?
1) You don't have a response variable anywhere, and doInBackground has returned null instead of any response, so not clear how you got that value.
delegate.processFinish(response.toString());
2) You can't return from that function. And your app crashes probably because Boolean's can be null. boolean's cannot. However, you should not attempt to make a global variable here because that's not how asynchronous code should run.
What you need is to pass the callback through the function
private void checkDataRegistrationByServer(String data, CallSoap.AsyncResponse callback) {
CallSoap nickNameExistCall = new CallSoap(RegistrationActivity.this, callback);
CallSoapParams callParams = new CallSoapParams(data);
nickNameExistCall.execute(callParams);
}
Elsewhere...
final String nick = NICKNAME_EXIST;
checkDataRegistrationByServer(nick, new CallSoap.AsyncResponse() {
#Override
public void processFinish(String response) {
Log.d("Response From AsyncTask:", output);
boolean exists = !response.equals(FALSE_RESPONSE);
if (!exists) {
Toast.makeText(getApplicationContext(), output + " - NickNameExistCall - Nick " + nick + " doesn't exist", Toast.LENGTH_SHORT).show();
}
}
});
Note: If you make your AsyncTask just return a Boolean in the AsyncResponse you can shorten this code some.
public class MainActivity extends ActionBarActivity {
Handler handler = new Handler();
ArrayList<String> toastMQ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
toastMQ = new ArrayList<String>();
setContentView(R.layout.activity_main);
toastMQ.add("Message1");
try {
Thread.sleep(2000);
} catch (Exception e) {
e.printStackTrace();
}
callToast1();
PreSleepToast pst = new PreSleepToast();
pst.execute();
}
private Runnable r = new Runnable() {
#Override
public void run() {
for( int i = 0; i < toastMQ.size(); i++ ){
Toast t = Toast.makeText(getApplicationContext(), toastMQ.get(i), Toast.LENGTH_SHORT);
t.show();
}
}
};
public class PreSleepToast extends AsyncTask<Void, byte[], Void> {
/**
* The sender socket on which we send connections.
*/
public PreSleepToast() {
}
/**
* Polling loop for outgoing connections.
*/
#Override
protected Void doInBackground(Void... params) {
handler.post(r);
return null;
};
};
public void callToast1(){
toastMQ.add("Message2");
}
}
Above is my source codes... I just want to try to collect a bunch of messages where I would be calling Thread.sleep(xxx) in between them before posting them out via Toast messages....somehow when I loop through them and post, in Nougat Androidv7.0 and above it only shows the last message...anyone has any idea why it behaves this way?
in Marshmallow it works fine, it displays first Message1 followed by Message2...in Nougat it only display "Message2" only...
my question is this, I have my main class, she command to run a AyncTask with a URL audio, at the end repreduce the next audio, my question is, I have the player in another class, as I do so the TextView which is updated every actualize the url of the song to play?
Here my code:
Activity main:
AsyncTask
public class Repoduce extends AsyncTask<String, Integer, String> {
#Override
protected void onPreExecute() {
//mostrarNotificacion("Reproduciendo...");
}
#Override
protected String doInBackground(String... strings) {
String url = strings[0];
try {
PlayAudioManager.playAudio(getApplicationContext(), url, Lista);
runOnUiThread(new Runnable() {
#Override
public void run() {
//titulo.setText(guardaDatos.getArtista());
titulo_cancion.setText(guardaDatos.getArtista());
Picasso.with(getApplicationContext()).load(guardaDatos.getCoverURL()).into(caratula);
}
}
);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
Here class with media player
public static void playAudio(final Context context, final String url, String currentTrack) throws Exception {
mmr = new FFmpegMediaMetadataRetriever();
listaReproduccion a = new listaReproduccion(context);
//am = MusicPlayer.getAm();
//am.setMode(AudioManager.STREAM_MUSIC);
codigos = a.getArray("Codigos");
nombres = a.getArray("Nombres");
artista = a.getArray("Artista");
//guardaDatos.setArtista(nombres.get(cancion));
setIsPlaying(true);
mediaPlayer = MediaPlayer.create(context, Uri.parse(codigos.get(cancion)));
//coverDeezer.caratulaArtista(artista.get(cancion));
mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
#Override
public void onCompletion(MediaPlayer mp) {
if (cancion <= codigos.size()) {
try {
cancion++;
playAudio(context, "", "lista");
Log.i("CONTADOR2", String.valueOf(cancion));
} catch (Exception e) {
e.printStackTrace();
}
}
I have textview in activityclass, how to update this from class player automatically?
I think you have some solutions below if you want update textview in another activity :
1 - Create interface listener catch event change audio to update TextView.
2 - Use Broadcast receiver.
3 - Use Handler Message.
Make the AsyncTask inside (inner class) of your Acitivity and call .setTex() inside the onPostExecute() method
I am trying to design a good architecture for implementing Google API Services.
The current documentation looks like this:
public class MainActivity extends ActionBarActivity {
public static final String TAG = "BasicHistoryApi";
private static final int REQUEST_OAUTH = 1;
private static final String DATE_FORMAT = "yyyy.MM.dd HH:mm:ss";
/**
* Track whether an authorization activity is stacking over the current activity, i.e. when
* a known auth error is being resolved, such as showing the account chooser or presenting a
* consent dialog. This avoids common duplications as might happen on screen rotations, etc.
*/
private static final String AUTH_PENDING = "auth_state_pending";
private boolean authInProgress = false;
private GoogleApiClient mClient = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// This method sets up our custom logger, which will print all log messages to the device
// screen, as well as to adb logcat.
initializeLogging();
if (savedInstanceState != null) {
authInProgress = savedInstanceState.getBoolean(AUTH_PENDING);
}
buildFitnessClient();
}
/**
* Build a {#link GoogleApiClient} that will authenticate the user and allow the application
* to connect to Fitness APIs. The scopes included should match the scopes your app needs
* (see documentation for details). Authentication will occasionally fail intentionally,
* and in those cases, there will be a known resolution, which the OnConnectionFailedListener()
* can address. Examples of this include the user never having signed in before, or
* having multiple accounts on the device and needing to specify which account to use, etc.
*/
private void buildFitnessClient() {
// Create the Google API Client
mClient = new GoogleApiClient.Builder(this)
.addApi(Fitness.HISTORY_API)
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
.addConnectionCallbacks(
new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Connected!!!");
// Now you can make calls to the Fitness APIs. What to do?
// Look at some data!!
new InsertAndVerifyDataTask().execute();
}
#Override
public void onConnectionSuspended(int i) {
// If your connection to the sensor gets lost at some point,
// you'll be able to determine the reason and react to it here.
if (i == ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Log.i(TAG, "Connection lost. Cause: Network Lost.");
} else if (i == ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
Log.i(TAG, "Connection lost. Reason: Service Disconnected");
}
}
}
)
.addOnConnectionFailedListener(
new GoogleApiClient.OnConnectionFailedListener() {
// Called whenever the API client fails to connect.
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed. Cause: " + result.toString());
if (!result.hasResolution()) {
// Show the localized error dialog
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(),
MainActivity.this, 0).show();
return;
}
// The failure has a resolution. Resolve it.
// Called typically when the app is not yet authorized, and an
// authorization dialog is displayed to the user.
if (!authInProgress) {
try {
Log.i(TAG, "Attempting to resolve failed connection");
authInProgress = true;
result.startResolutionForResult(MainActivity.this,
REQUEST_OAUTH);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG,
"Exception while starting resolution activity", e);
}
}
}
}
)
.build();
}
#Override
protected void onStart() {
super.onStart();
// Connect to the Fitness API
Log.i(TAG, "Connecting...");
mClient.connect();
}
#Override
protected void onStop() {
super.onStop();
if (mClient.isConnected()) {
mClient.disconnect();
}
}
.... // MORE CODE
}
This looks really ugly inside an Activity, what if I have multiple Activities using Google API Services.
Would it be possible to move everything to a Client.java class that just handles creation of a GoogleApiClient object.
How would I pass an activity context parameter to GoogleApiClient.Builder(this)? Should I use an event bus driven system that sends off context values from each activity to the client and builds it each time?
This is pretty ugly, any way I can trim this code so I don't have to copy it everywhere in like 30 activities?
How about a manager class GoogleApiManager.java that would handle all that for me? What sorts of interfaces would I need to implement on this?
Can I instead store inside an application class instead?
Would appreciate any help on this.
You are going to have to mess around with the code to get it all working correctly. I don't have google api client hooked up so I can't debug.
You could create a separate class like below
public class BuildFitnessClient {
private static boolean mAuthInProgress;
private static final String TAG = "BasicHistoryApi";
private static final int REQUEST_OAUTH = 1;
public static GoogleApiClient googleApiClient(final Activity activity, boolean authInProgress) {
mAuthInProgress = authInProgress;
return new GoogleApiClient.Builder(activity)
.addApi(Fitness.HISTORY_API)
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
.addConnectionCallbacks(
new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
mCallbacks.connected();
}
#Override
public void onConnectionSuspended(int i) {
if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Log.i(TAG, "Connection lost. Cause: Network Lost.");
}
}
}
)
.addOnConnectionFailedListener(
new GoogleApiClient.OnConnectionFailedListener() {
// Called whenever the API client fails to connect.
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed. Cause: " + result.toString());
if (!result.hasResolution()) {
// Show the localized error dialog
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(),
activity, 0).show();
return;
}
if (!mAuthInProgress) {
try {
Log.i(TAG, "Attempting to resolve failed connection");
mAuthInProgress = true;
result.startResolutionForResult(activity,
REQUEST_OAUTH);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG,
"Exception while starting resolution activity", e);
}
}
}
}
)
.build();
}
/**
* Interface to communicate to the parent activity (MainActivity.java)
*/
private static MyCallbacks mCallbacks;
public interface MyCallbacks {
void connected();
}
public void onAttach(Activity activity) {
try {
mCallbacks = (MyCallbacks) activity;
} catch (ClassCastException e) {
throw new ClassCastException("Activity must implement Fragment One.");
}
}
}
Then in your Activity you could call it like:
public class TestingActivity extends AppCompatActivity implements BuildFitnessClient.MyCallbacks {
GoogleApiClient mClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_testing);
new BuildFitnessClient().onAttach(this);
mClient = new BuildFitnessClient().googleApiClient(this, true);
}
#Override
protected void onStart() {
super.onStart();
mClient.connect();
}
#Override
protected void onStop() {
super.onStop();
if (mClient.isConnected()) {
mClient.disconnect();
}
}
#Override
public void connected() {
Log.e("Connected", "Connected");
new InsertAndVerifyDataTask().execute();
}
}
I am new to android programming. I am developing a web crawler for which i am using a Async Task and it is working well.In order to keep user informed,i am using progress dialog. My problem is,if i use a Progress Dialog my program takes more time to execute and when i won`t use the progress dialog,it executes faster.
Done Work
OnCreate Method
protected void onCreate(Bundle savedInstanceState) {
try {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_results);
Intent intent = getIntent();
s1 = intent.getStringExtra("Number1");
s2 = intent.getStringExtra("Number2");
s3=intent.getIntExtra("selectedItem",0);
HttpAsyncTask asyncTask = new HttpAsyncTask();
asyncTask.execute();
}catch (Exception e)
{
messageBox("Exception",e.getMessage());
}
}
Async Task Class
private class HttpAsyncTask extends AsyncTask<List<String>, Integer, List<String>> {
private ProgressDialog dialog;
#Override
protected void onPreExecute()
{
dialog = new ProgressDialog(Results.this);
dialog.setIndeterminate(true);
dialog.setMessage("Please Wait");
dialog.setCancelable(true);
dialog.show();
super.onPreExecute();
}
#Override
protected List<String> doInBackground(List<String>... urls) {
//android.os.Debug.waitForDebugger();
// spinner.setVisibility(View.VISIBLE);
List<String>resultList=new ArrayList<String>();
try
{
if(isCancelled())
return resultList;
resultList=WebCrawlerClass.GetPost(s1,s2,s3);
}catch (Exception e)
{
messageBoxs("Error", e.getMessage());
}
return resultList;
}
// onPostExecute displays the results of the AsyncTask.
#Override
protected void onPostExecute(List<String> result)
{
if(dialog.isShowing())
{
dialog.dismiss();
}
if(s3 == 2)
{
docListAdapter=new ListViewData(Results.this,result);
}
else {
docListAdapter = new NameNumListData(Results.this, result);
}
docList=(ListView)findViewById(R.id.listView2);
docList.setAdapter(docListAdapter);
super.onPostExecute(result);
}
#Override
protected void onCancelled() {
super.onCancelled();
this.cancel(true);
}
}
Am I missing something? Need help..
Thanks and Regards,
Abhinav
In you activity
// Start the progress dialog
..
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
// dismiss the progress dialog
}
};
HttpAsyncTask asyncTask = new HttpAsyncTask(handler);
asyncTask.execute();
In your asynctask class
private class HttpAsyncTask extends AsyncTask<List<String>, Integer, List<String>> {
private Handler handler = null;
public HttpAsyncTask (Handler handler) {
this.handler = handler;
}
protected Void doInBackground(Void... params) {
//Perform your task
// When you know that task is finished , fire following code
if (null != handler) {
Message message = handler.obtainMessage();
message.obj = Any data you want to sent to the activity
message.what = 1 ; ( Optional )
handler.sendMessage(message);
}
}
Thus when sendMessage function is called from doInbackground.. your handleMessage in your activity will get triggered and then you should dismiss the progress dialog
Hope this will improve the performance issue what you are facing
Remove super.onPreExecute(); in onPreExecute() method and check .It might Help