I already have seen this question. But couldn't figure out what's the issue.
I am sending an email in background using BackgroundMail in my ImageSyncReciever class. But when email is sent my app crashes while giving me the below error
FATAL EXCEPTION: main
Process: com.thumbsol.accuratemobileassetsmanagament, PID: 7480
java.lang.IllegalArgumentException: View=com.android.internal.policy.impl.PhoneWindow$DecorView{300e55de V.E..... R.....I. 0,0-0,0} not attached to window manager
at android.view.WindowManagerGlobal.findViewLocked(WindowManagerGlobal.java:434)
at android.view.WindowManagerGlobal.removeView(WindowManagerGlobal.java:353)
at android.view.WindowManagerImpl.removeViewImmediate(WindowManagerImpl.java:116)
at android.app.Dialog.dismissDialog(Dialog.java:382)
at android.app.Dialog.dismiss(Dialog.java:365)
at com.creativityapps.gmailbackgroundlibrary.BackgroundMail$SendEmailTask.onPostExecute(BackgroundMail.java:302)
at com.creativityapps.gmailbackgroundlibrary.BackgroundMail$SendEmailTask.onPostExecute(BackgroundMail.java:265)
at android.os.AsyncTask.finish(AsyncTask.java:636)
at android.os.AsyncTask.access$500(AsyncTask.java:177)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:653)
at android.os.Handler.dispatchMessage(Handler.java:111)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5660)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:963)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:758)
Below is my code in which I am sending the email
if (response.body().getStatus().equals("OK")) {
snapManager.updateSnapStatus(AssetsManagementContract.SnapEntry.COLUMN_SITE_SNAP, snap.getSnapName(), Constants.SNAP_SYNCED);
Intent broadcastSyc = new Intent();
broadcastSyc.setAction(Common.GetSyncImageAction());
broadcastSyc.putExtra("STATUS", true);
mContext.sendBroadcast(broadcastSyc);
sendImage(mContext);
BackgroundMail.newBuilder(mContext)
.withUsername("gmail id")
.withPassword("pass")
.withMailto("gmail id")
.withType(BackgroundMail.TYPE_PLAIN)
.withSubject("New Meter Installation")
.withBody("Meter #" + msn + " is "+ com+ " and "+ status)
.send();
}
How can i resolve this issue? Any help would be highly appreciated
Note: The email is sent when the form is submitted and after saving I am not using any dialog.
Update 1
Below is the BackgroudMailer class function
public class SendEmailTask extends AsyncTask<String, Void, Boolean> {
private ProgressDialog progressDialog;
public SendEmailTask() { //error onPostExecute(BackgroundMail.java:265)
}
protected void onPreExecute() {
super.onPreExecute();
if(BackgroundMail.this.processVisibility) {
this.progressDialog = new ProgressDialog(BackgroundMail.this.mContext);
this.progressDialog.setMessage(BackgroundMail.this.sendingMessage);
this.progressDialog.setCancelable(false);
this.progressDialog.show();
}
}
protected Boolean doInBackground(String... arg0) {
try {
GmailSender sender = new GmailSender(BackgroundMail.this.username, BackgroundMail.this.password);
if(!BackgroundMail.this.attachments.isEmpty()) {
for(int i = 0; i < BackgroundMail.this.attachments.size(); ++i) {
if(!((String)BackgroundMail.this.attachments.get(i)).isEmpty()) {
sender.addAttachment((String)BackgroundMail.this.attachments.get(i));
}
}
}
sender.sendMail(BackgroundMail.this.subject, BackgroundMail.this.body, BackgroundMail.this.username, BackgroundMail.this.mailto, BackgroundMail.this.type);
} catch (Exception var4) {
var4.printStackTrace();
return Boolean.valueOf(false);
}
return Boolean.valueOf(true);
}
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
if(BackgroundMail.this.processVisibility) {
this.progressDialog.dismiss(); // error onPostExecute(BackgroundMail.java:302)
if(result.booleanValue()) {
if(!TextUtils.isEmpty(BackgroundMail.this.sendingMessageSuccess)) {
Toast.makeText(BackgroundMail.this.mContext, BackgroundMail.this.sendingMessageSuccess, 0).show();
}
if(BackgroundMail.this.onSuccessCallback != null) {
BackgroundMail.this.onSuccessCallback.onSuccess();
}
} else {
if(!TextUtils.isEmpty(BackgroundMail.this.sendingMessageError)) {
Toast.makeText(BackgroundMail.this.mContext, BackgroundMail.this.sendingMessageError, 0).show();
}
if(BackgroundMail.this.onFailCallback != null) {
BackgroundMail.this.onFailCallback.onFail();
}
}
}
}
}
The problem is I cannot edit it as the file is locked.
in onPostExecute you dismiss the dialog without checking if it is actually shown:
this.progressDialog.dismiss();
add a check of isShowing for that (and a null-check just in case..)
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog.dismiss();
}
Also I see that you use static references to contexts. That can lead to memory leaks, but that is just a side note.
Related
This question has been asked already but it doesn't have an answer and i'm looking for help in this.
I want to integrate stripe to my android firebase app.But I keep getting the error java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull. I am not using kotlin in my project but java so I'm not sure where kotlin comes from.
Error
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.myapp.app, PID: 26686
java.lang.IllegalArgumentException: Parameter specified as non-null is null: method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter clientSecret
at com.stripe.android.model.ConfirmPaymentIntentParams$Companion.createWithPaymentMethodCreateParams(Unknown Source:29)
at com.stripe.android.model.ConfirmPaymentIntentParams$Companion.createWithPaymentMethodCreateParams$default(ConfirmPaymentIntentParams.kt:420)
at com.stripe.android.model.ConfirmPaymentIntentParams.createWithPaymentMethodCreateParams(Unknown Source:14)
at com.myapp.app.PaymentPageActivity.lambda$startCheckout$0$PaymentPageActivity(PaymentPageActivity.java:84)
at com.myapp.app.-$$Lambda$PaymentPageActivity$lysPf2qYJjjVdPRqihuLblLplpI.onClick(Unknown Source:2)
//My code
// Configure the SDK with your Stripe publishable key so it can make requests to Stripe
stripe = new Stripe(
getApplicationContext(),
Objects.requireNonNull("stripe_key")
);
startCheckout();
}
private void startCheckout() {
// ...
// Hook up the pay button to the card widget and stripe instance
Button payButton = findViewById(R.id.payButton);
payButton.setOnClickListener((View view) -> {
CardInputWidget cardInputWidget = findViewById(R.id.cardInputWidget);
PaymentMethodCreateParams params = cardInputWidget.getPaymentMethodCreateParams();
if (params != null) {
ConfirmPaymentIntentParams confirmParams = ConfirmPaymentIntentParams
.createWithPaymentMethodCreateParams(params, paymentIntentClientSecret);
confirmParams.getPaymentMethodCreateParams();
final Context context = getApplicationContext();
stripe = new Stripe(
context,
PaymentConfiguration.getInstance(context).getPublishableKey()
);
stripe.confirmPayment(this, confirmParams);
}
});
}
// ...
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Handle the result of stripe.confirmPayment
stripe.onPaymentResult(requestCode, data, new PaymentResultCallback(PaymentPageActivity.this));
}
// ...
private final class PaymentResultCallback
implements ApiResultCallback<PaymentIntentResult> {
#NonNull private final WeakReference<PaymentPageActivity> activityRef;
PaymentResultCallback(#NonNull PaymentPageActivity activity) {
activityRef = new WeakReference<>(activity);
}
#Override
public void onSuccess(#NonNull PaymentIntentResult result) {
final PaymentPageActivity activity = activityRef.get();
if (activity == null) {
return;
}
PaymentIntent paymentIntent = result.getIntent();
PaymentIntent.Status status = paymentIntent.getStatus();
if (status == PaymentIntent.Status.Succeeded) {
// Payment completed successfully
Gson gson = new GsonBuilder().setPrettyPrinting().create();
Toast.makeText(PaymentPageActivity.this, "Paymen success", Toast.LENGTH_SHORT).show();
} else if (status == PaymentIntent.Status.RequiresPaymentMethod) {
// Payment failed
Toast.makeText(PaymentPageActivity.this, "Failed", Toast.LENGTH_SHORT).show();
}
}
#Override
public void onError(#NonNull Exception e) {
final PaymentPageActivity activity = activityRef.get();
if (activity == null) {
return;
}
// Payment request failed – allow retrying using the same payment method
Toast.makeText(PaymentPageActivity.this, "Error " +e.toString(), Toast.LENGTH_SHORT).show();
}
}
I have created 2 onTapEvent listener to add markers of different icons to my map through clicking of different buttons. However, I was only able to add 1 type of marker, the second button(add crowd) will crash my app after i clicked it.
Here is the example of my code for the buttons :
Set Destination:
private void initAddDestinationButton() {
m_setDetinationButton = (Button) findViewById(R.id.setDestinationButton);
m_setDetinationButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
/*
* Clear map if previous results are still on map,otherwise proceed to creating
* route
*/
if (map != null && m_mapRoute != null) {
map.removeMapObject(m_mapRoute);
m_mapRoute = null;
} else
{
addDestination();
}
}
});
}
private void addDestination() {
if (destinationMarker == null) {
image = new Image();
try {
image.setImageResource(R.drawable.letterx);
} catch (final IOException e) {
e.printStackTrace();
}
}
mapFragment.getMapGesture().removeOnGestureListener(addCrowdListener2);
mapFragment.getMapGesture().addOnGestureListener(setDestinationListener2, 1, true);
}
Add Crowd :
private void initAddCrowdButton() {
m_addCrowdButton = (Button) findViewById(R.id.addCrowdButton);
m_addCrowdButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view2) {
if (map != null && m_mapRoute != null) {
map.removeMapObject(m_mapRoute);
m_mapRoute = null;
} else
{
addCrowd();
}
}
});
}
private void addCrowd() {
if (blocked == null) {
image2 = new Image();
try {
image.setImageResource(R.drawable.marker);
} catch (final IOException e) {
e.printStackTrace();
}
}
mapFragment.getMapGesture().removeOnGestureListener(setDestinationListener2);
mapFragment.getMapGesture().addOnGestureListener(addCrowdListener2, 10, true);
}
Here are the 2 onTapEvent listeners that I declared:
private MapGesture.OnGestureListener addCrowdListener2 = new MapGesture.OnGestureListener.OnGestureListenerAdapter() {
#Override
public boolean onTapEvent(PointF pointF) {
GeoCoordinate e = map.pixelToGeo(pointF);
MapMarker b = new MapMarker(e, image2);
blockList.add(b);
b.setAnchorPoint(new PointF(image.getWidth()/2, image.getHeight()));
map.addMapObject(b);
blocked = blockList.get(blockList.size() - 1);
blockedPath = blocked.getCoordinate();
blockedRoad = RoadElement.getRoadElement(blockedPath, "eng" );
return super.onTapEvent(pointF);
}
};
private MapGesture.OnGestureListener setDestinationListener2 = new MapGesture.OnGestureListener.OnGestureListenerAdapter() {
#Override
public boolean onTapEvent(PointF pointF) {
GeoCoordinate endpoint = map.pixelToGeo(pointF);
MapMarker m = new MapMarker(endpoint,image);
markerList.add(m);
m.setAnchorPoint(new PointF(image.getWidth()/2, image.getHeight()));
map.addMapObject(m);
destinationMarker = markerList.get(markerList.size() - 1);
destination = destinationMarker.getCoordinate();
return super.onTapEvent(pointF);
}
};
i have declared the buttons inside OnEngineInitiaizatioCompleted(). So far, only Set Destination button runs normally. Clicking on Add Crowd will crash my app (clicked on it before and after clicking Set Destination, crash the app upon clicking)
Here is the stack trace from its crash :
02-26 22:22:33.907 2233-3776/com.google.android.googlequicksearchbox:search W/ErrorProcessor: onFatalError, processing error from engine(4)
com.google.android.apps.gsa.shared.speech.a.g: Error reading from input stream
at com.google.android.apps.gsa.staticplugins.recognizer.i.a.a(SourceFile:342)
at com.google.android.apps.gsa.staticplugins.recognizer.i.a$1.run(SourceFile:1367)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at com.google.android.apps.gsa.shared.util.concurrent.a.ak.run(SourceFile:66)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
at com.google.android.apps.gsa.shared.util.concurrent.a.ad$1.run(SourceFile:85)
Caused by: com.google.android.apps.gsa.shared.exception.GsaIOException: Error code: 393238 | Buffer overflow, no available space.
at com.google.android.apps.gsa.speech.audio.Tee.g(SourceFile:2531)
at com.google.android.apps.gsa.speech.audio.ap.read(SourceFile:555)
at java.io.InputStream.read(InputStream.java:101)
at com.google.android.apps.gsa.speech.audio.al.run(SourceFile:362)
at com.google.android.apps.gsa.speech.audio.ak$1.run(SourceFile:471)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at com.google.android.apps.gsa.shared.util.concurrent.a.ak.run(SourceFile:66)
at com.google.android.apps.gsa.shared.util.concurrent.a.ax.run(SourceFile:139)
at com.google.android.apps.gsa.shared.util.concurrent.a.ax.run(SourceFile:139)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
at java.lang.Thread.run(Thread.java:761)
at com.google.android.apps.gsa.shared.util.concurrent.a.ad$1.run(SourceFile:85)
and
java.lang.NullPointerException: Attempt to invoke virtual method 'void com.here.android.mpa.common.Image.setImageResource(int)' on a null object reference
at com.here.android.example.basicpositioningsolution.BasicPositioningActivity.addCrowd(BasicPositioningActivity.java:532)
at com.here.android.example.basicpositioningsolution.BasicPositioningActivity.access$1600(BasicPositioningActivity.java:87)
at com.here.android.example.basicpositioningsolution.BasicPositioningActivity$7.onClick(BasicPositioningActivity.java:521)
at android.view.View.performClick(View.java:5619)
at android.view.View$PerformClick.run(View.java:22295)
at android.os.Handler.handleCallback(Handler.java:754)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:163)
at android.app.ActivityThread.main(ActivityThread.java:6342)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:880)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:770)
Suppressed: java.lang.Throwable: HERE SDK Version: 3.6.0.523
at com.nokia.maps.MapsEngine$l.uncaughtException(MapsEngine.java:377)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1068)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:1063)
at java.lang.Thread.dispatchUncaughtException(Thread.java:1979)
I think your resource R.drawable.marker cannot be rendered by the SDK. What kind of image resource is it? Only bitmap resources are supported.
I basically just call this in the android:onClick function in my XML for this particular ImageView: android:onClick="SendGetStartedNotification". But because my function has two parameters, I get this error Method has incorrect signature. It wants me to removed the ParseUser class.
public void SendGetStartedNotification(View view, ParseUser user) {
// initiate installation query
ParseQuery<ParseInstallation> query = ParseInstallation.getQuery();
query.whereEqualTo("userId", user.getUserObject());
// send push notification
ParsePush push = new ParsePush();
push.setQuery(query);
push.setMessage(ParseUser.getCurrentUser().getUsername() + " " + "thinks you should create something!");
push.sendInBackground();
// send notification to NotificationsActivity
ParseObject notification = createGetStartedMessage(view, user);
send(notification);
}
The problem is my error message:
12-20 22:22:37.349 29251-29251/com.app.testE/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.app.test, PID: 29251
java.lang.IllegalStateException: Could not find method SendGetStartedNotification(View) in a parent or ancestor Context for android:onClick attribute defined on view class android.widget.ImageView with id 'messageGallerySave2'
at android.view.View$DeclaredOnClickListener.resolveMethod(View.java:4485)
at android.view.View$DeclaredOnClickListener.onClick(View.java:4449)
at android.view.View.performClick(View.java:5204)
at android.view.View$PerformClick.run(View.java:21153)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
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)
What are my alternatives? Setting an onClick listener programatically doesn't seem to be working either. What should I do?
Update: I'm using an AsyncTask to bring user information in my class.
private class GetParseUserInformationTask extends AsyncTask<Void, Design, ParseUser> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgressDialog = new ProgressDialog(GalleryActivity.this);
// Set progressdialog message
mProgressDialog.setMessage("Loading Designs...");
mProgressDialog.setIndeterminate(false);
// Show progressdialog
mProgressDialog.show();
}
#Override
protected ParseUser doInBackground(Void... params) {
ParseUser parseUser = null;
// gather User information and then fetch the designs for them
try {
parseUser = ParseHelper.GetUserInformation(userObjectId);
} catch (ParseException e) {
e.printStackTrace();
}
return parseUser;
}
#Override
protected void onPostExecute(ParseUser user) {
if(user == null) {
//todo: some error message
return;
}
((TextView)findViewById(R.id.fullName)).setText(user.getName());
((TextView)findViewById(R.id.bio)).setText(user.getBio());
((TextView)findViewById(R.id.websiteLink)).setText(user.getWebsiteLink());
((TextView)findViewById(R.id.username)).setText(user.getUsername());
((TextView)findViewById(R.id.saves_number)).setText(user.getFeedDesignSaves().toString());
((TextView)findViewById(R.id.designs_number)).setText(String.valueOf(ParseHelper.GetUserDesignsCount(user.getUserObject())));
((ImageView)findViewById(R.id.profile_picture)).setImageDrawable(Drawable.createFromPath(user.getProfilePictureURL()));
// asynchronously display the profile picture downloaded from parse
if(user.getProfilePictureURL() != null) {
profilePictureImageLoader.DisplayImage(user.getProfilePictureURL(), ((ImageView) findViewById(R.id.profile_picture)), null);
}
new GetParseUserDesignsTask().execute(user);
mProgressDialog.dismiss();
}
}
On Click listener on button.
imageView.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
// TODO Auto-generated method stub
SendGetStartedNotification(ParseUser user);
}
} );
Make your method like this:
public void SendGetStartedNotification(ParseUser user) {
// initiate installation query
ParseQuery<ParseInstallation> query = ParseInstallation.getQuery();
query.whereEqualTo("userId", user.getUserObject());
// send push notification
ParsePush push = new ParsePush();
push.setQuery(query);
push.setMessage(ParseUser.getCurrentUser().getUsername() + " " + "thinks you should create something!");
push.sendInBackground();
// send notification to NotificationsActivity
ParseObject notification = createGetStartedMessage(view, user);
send(notification);
}
I have an activity that is displayed in portrait only and in my tablet it causes the following:
android.view.WindowLeaked: Activity com.spicycurryman.getdisciplined10.app.InstalledAppActivity has leaked window com.android.internal.policy.impl.PhoneWindow$DecorView{53210b88 V.E..... R.....ID 0,0-1520,192} that was originally added here
at android.view.ViewRootImpl.<init>(ViewRootImpl.java:354)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:216)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:69)
at android.app.Dialog.show(Dialog.java:281)
at com.spicycurryman.getdisciplined10.app.InstalledAppActivity$LoadApplications.onPreExecute(InstalledAppActivity.java:306)
at android.os.AsyncTask.executeOnExecutor(AsyncTask.java:586)
at android.os.AsyncTask.execute(AsyncTask.java:534)
at com.spicycurryman.getdisciplined10.app.InstalledAppActivity.onCreate(InstalledAppActivity.java:105)
at android.app.Activity.performCreate(Activity.java:5104)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
at android.app.ActivityThread.access$600(ActivityThread.java:141)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
I am using an AsyncTask to load a listview of installed apps on the phone and using a progressdialog.
I have researched this problem:
Progress dialog and AsyncTask error
android.view.WindowLeaked exception
Android Error: Window Leaked in AsyncTask
I was able to produce this code so that the whole app doesn't crash and burn, but the exception is still thrown and the activity screen is kind of shaky after the button click and the whole transition is not really smooth.
#Override
protected void onPostExecute(Void result) {
apkList.setAdapter(new ApkAdapter(InstalledAppActivity.this, packageList1, packageManager));
try {
if ((this.pDialog != null) && this.pDialog.isShowing()) {
this.pDialog.dismiss();
}
} catch (final IllegalArgumentException e) {
// Handle or log or ignore
} catch (final Exception e) {
// Handle or log or ignore
} finally {
this.pDialog = null;
}
super.onPostExecute(result);
}
Dismissing the progress dialog or calling finish() doesn't really solve the problem either...
How would I fix this?
Here is most of the AsyncTask code:
private class LoadApplications extends AsyncTask<Void, Void, Void> {
private ProgressDialog pDialog;
List<PackageInfo> packageList1 = new ArrayList<PackageInfo>();
public LoadApplications(Context context){
Context mContext = context;
}
#Override
protected Void doInBackground(Void... params) {
List<PackageInfo> packageList = packageManager
.getInstalledPackages(PackageManager.GET_PERMISSIONS);
List<PackageInfo> packageList2 = packageManager
.getInstalledPackages(PackageManager.GET_PERMISSIONS);
for(PackageInfo pi : packageList) {
boolean b = isSystemPackage(pi);
boolean c = isSystemPackage1(pi);
boolean d = isSystemPackage2(pi);
if ((!b || !c ) && d ){
packageList1.add(pi);
}
}
//here you got email and message apps in the
for(PackageInfo pi : packageList) {
boolean b = isSystemPackage3(pi);
boolean c = isSystemPackage4(pi);
if (b || c){
packageList1.add(pi);
}
}
//sort by application name
final PackageItemInfo.DisplayNameComparator comparator = new PackageItemInfo.DisplayNameComparator(packageManager);
Collections.sort(packageList1, new Comparator<PackageInfo>() {
#Override
public int compare(PackageInfo lhs, PackageInfo rhs) {
return comparator.compare(lhs.applicationInfo, rhs.applicationInfo);
}
});
return null;
}
#Override
protected void onCancelled() {
super.onCancelled();
}
#Override
protected void onPreExecute() {
pDialog = new ProgressDialog(InstalledAppActivity.this);
pDialog.setMessage("Loading your apps...");
pDialog.show();
}
//Inefficient patch to prevent Window Manager error
#Override
protected void onPostExecute(Void result) {
apkList.setAdapter(new ApkAdapter(InstalledAppActivity.this, packageList1, packageManager));
try {
if ((this.pDialog != null) && this.pDialog.isShowing()) {
this.pDialog.dismiss();
}
} catch (final IllegalArgumentException e) {
// Handle or log or ignore
} catch (final Exception e) {
// Handle or log or ignore
} finally {
this.pDialog = null;
}
super.onPostExecute(result);
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
}
try this :
#Override
public Object onRetainNonConfigurationInstance() {
if (progressDialog != null && progressDialog.isShowing()) {
progressDialog = null;
}
if (asynTask!= null) {
asynTask.detach();
}
return ayncTask;
}
Declaring a non-static inner AsyncTask in your activity is not a good idea because it holds a reference to the activity and this could be a couse of the leak. However, various configuration changes could cause the OS to destroy and recreate the activity. There are a number of solutions and Rustam's anser is an example.
However, I prefer to user either AsyncTaskLoader or use some sort of asynchronous callback, like a broadcast. The asynchronous callback decouples your AsyncTask from the Activity.
My Android application allows users to update their Facebook status from a Fragment. I've implemented the following AsyncTask so they can log in:
public class updateFacebookTask extends AsyncTask<String, Void, Boolean> {
protected Boolean doInBackground(final String... message) {
Log.i(TAG, "Async UFT");
myFResult = false;
Looper.prepare();
if (loginAndPostToWall()) {
Log.i(TAG, "loginAndPostToWall Returned: " + myFResult);
myFResult = true;
} else {
Log.i(TAG, "loginAndPostToWall Returned: " + myFResult);
myFResult = false;
}
//Looper.loop();
return myFResult;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Log.i(TAG, "UFT - oPrE");
}
#Override
protected void onPostExecute(Boolean myFResult) {
super.onPostExecute(myFResult);
if (myFResult) {
Log.i(TAG, "UFT oPE - Success: " + myFResult);
} else {
Log.w(TAG, "UFT oPE - fail: " + myFResult);
}
}
The AsyncTask uses the method loginAndPostToWall() as below, Which implements a DialogListener as part of the Facebook sdk:
public boolean loginAndPostToWall() {
myFResult = false;
facebook.authorize(getActivity(), PERMISSIONS,
Facebook.FORCE_DIALOG_AUTH, new DialogListener() {
public void onComplete(Bundle values) {
Log.i(TAG, "LoginDialog Complete - Success");
myFResult = true;
}
public void onFacebookError(FacebookError error) {
Log.w(TAG,
"onFacebookError - Authentication with Facebook failed");
myFResult = false;
}
public void onError(DialogError error) {
Log.w(TAG,
"onError - Authentication with Facebook failed");
looper = false;
Log.i(TAG, "looper " + looper);
myFResult = false;
}
public void onCancel() {
Log.w(TAG,
"onCancel - Authentication with Facebook cancelled");
myFResult = false;
}
});
return myFResult;
}
I have two problems that I really need help with please:
LogInAndPostToWall immediately returns myFResult as false. What I want it to do is wait until the login by webView has returned onComplete (or an error) from the DialogListener. How can I get it to return myFResult at that point and not before?
If I include Looper.loop(); onPostExecute is never called. If I don't include Looper.prepare(); I get an error saying I can't create a handler without it. Am I supposed to call quit() somewhere?
I've been stuck on this for two days (!) and have read many, many SO posts - I've tried using runnables and logging which threads everything is running on etc, but no joy.
Thanks in advance for saving me...
loginAndPostToWall() should be executed on the UI thread, as it modifyes the UI. doInBackgorund() method got never executed on UI thread and you should NOT ever include Looper.prepare() or Looper.loop() code there.