Android Open Source - slf4android Notify Developer Handler






From Project

Back to project page slf4android.

License

The source code is released under:

MIT License

If you think the Android project slf4android listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

package pl.brightinventions.slf4android;
// w w  w.  j a  v a2s . c om
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.hardware.SensorManager;
import android.os.AsyncTask;
import android.os.Looper;
import android.util.Log;

import com.squareup.seismic.ShakeDetector;

import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Filter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogRecord;

public class NotifyDeveloperHandler extends Handler {
    private static final String TAG = NotifyDeveloperHandler.class.getSimpleName();
    private final Context context;
    private final List<String> emailAddress;
    private final WeakReference<ActivityStateListener> activityState;
    private final ShakeDetector shakeDetector;
    private String emailSubject;
    private String emailBody;
    private Filter filter;
    private AlertDialog dialog;
    private android.os.Handler mailLoopHandler = new android.os.Handler(Looper.getMainLooper());
    private ArrayList<String> attachmentClassList;

    NotifyDeveloperHandler(Application context, Iterable<String> emailAddress, ActivityStateListener activityState) {
        this(context, emailAddress, LogLevel.ERROR, activityState);
    }

    NotifyDeveloperHandler(Application context, Iterable<String> emailAddress, LogLevel minLevel, final ActivityStateListener stateListener) {
        this.context = context;
        this.emailAddress = Lists.newArrayList(emailAddress);
        this.filter = new AtLeastFilter(minLevel);
        this.activityState = new WeakReference<ActivityStateListener>(stateListener);
        this.attachmentClassList = new ArrayList<String>();
        this.shakeDetector = new ShakeDetector(new ShakeDetector.Listener() {
            @Override
            public void hearShake() {
                ActivityStateListener listener = activityState.get();
                if (listener != null) {
                    if (listener.isAppInForeground()) {
                        beginPublishOnMainThread(new LogRecord(Level.INFO, "Report a problem with app"));
                    } else {
                        Log.i(TAG, "Ignore shake event - the app appears to be in background");
                    }
                } else {
                    Log.i(TAG, "Ignore shake event - can't detect if app is in foreground (API < 14)");
                }
            }
        });
        this.emailSubject = context.getString(R.string.slf4android_email_subject) + context.getPackageName();
        this.emailBody = context.getString(R.string.slf4android_email_extra_text);
    }

    private void beginPublishOnMainThread(LogRecord record) {
        mailLoopHandler.post(new ShowDialogBecauseOfRecord(pl.brightinventions.slf4android.LogRecord.fromRecord(record)));
    }

    public void setMinLogLevel(LogLevel logLevel) {
        setFilter(new AtLeastFilter(logLevel));
    }

    public void setFilter(Filter filter) {
        if (filter == null) {
            throw new IllegalArgumentException("Filter must not be null");
        }
        this.filter = filter;
    }

    @Override
    public void close() {
        mailLoopHandler.removeCallbacksAndMessages(null);
        if (dialog != null) {
            dialog.dismiss();
        }
        shakeDetector.stop();
    }

    @Override
    public void flush() {
    }

    @Override
    public void publish(LogRecord record) {
        if (filter.isLoggable(record)) {
            beginPublishOnMainThread(record);
        }
    }

    private boolean isQuestionPending() {
        return dialog != null && dialog.isShowing();
    }

    private void destroyDialog() {
        if (dialog != null) {
            dialog.dismiss();
            dialog = null;
        }
    }

    public void addAttachmentClass(Class<? extends AsyncTask<Context, Void, File>> attachmentClass) {
        if (attachmentClass == null) {
            throw new IllegalArgumentException("attachmentClass must not be null");
        }
        try {
            attachmentClass.newInstance();
        } catch (InstantiationException e) {
            throw new IllegalArgumentException("Can't create attachment factory from class " + attachmentClass, e);
        } catch (IllegalAccessException e) {
            throw new IllegalArgumentException("Can't create attachment factory from class " + attachmentClass, e);
        }
        attachmentClassList.add(attachmentClass.getName());
    }

    public void notifyWhenDeviceIsShaken() {
        if (activityState.get() != null) {
            SensorManager manager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
            if (manager == null) {
                Log.w(TAG, "Sensor manager is null will not install shake reporter");
            } else {
                if (!shakeDetector.start(manager)) {
                    Log.w(TAG, "Failed to start shake detector");
                }
            }
        } else {
            Log.w(TAG, "Will not notify on shake - can't detect if app is in foreground (API < 14)");
        }

    }

    private ArrayList<String> getAttachmentClassList() {
        return attachmentClassList;
    }

    private class ShowDialogBecauseOfRecord implements Runnable {
        private final pl.brightinventions.slf4android.LogRecord record;

        public ShowDialogBecauseOfRecord(pl.brightinventions.slf4android.LogRecord record) {
            this.record = record;
        }

        @Override
        public void run() {
            if (isQuestionPending()) {
                return;
            }

            destroyDialog();

            Context currentActivity = obtainActivityContext();
            if (currentActivity != null) {
                dialog = NotifyDeveloperDialogDisplayActivity.showDialogIn(currentActivity,
                        record,
                        emailAddress,
                        emailSubject,
                        emailBody,
                        getAttachmentClassList());
            } else {
                Intent showDialogActivityIntent = NotifyDeveloperDialogDisplayActivity.showIntent(context,
                        record,
                        emailAddress,
                        emailSubject,
                        emailBody,
                        getAttachmentClassList());
                context.startActivity(showDialogActivityIntent);
            }
        }

        private Activity obtainActivityContext() {
            ActivityStateListener activityStateListener = activityState.get();
            Activity activity = null;
            if (activityStateListener != null) {
                activity = activityStateListener.getLastUsedActivity();
            }
            return activity;
        }
    }

    public NotifyDeveloperHandler withSubject(String subject){
        this.emailSubject = subject;
        return this;
    }

    public NotifyDeveloperHandler withBody(String body){
        this.emailBody = body;
        return this;
    }
}




Java Source Code List

com.squareup.seismic.ShakeDetector.java
org.slf4j.impl.StaticLoggerBinder.java
pl.brightinventions.slf4android.ActivityStateListener.java
pl.brightinventions.slf4android.AndroidLoggerAdapter.java
pl.brightinventions.slf4android.AndroidLoggerFactory.java
pl.brightinventions.slf4android.AtLeastFilter.java
pl.brightinventions.slf4android.ConstLoggerValueSupplier.java
pl.brightinventions.slf4android.DateValueSupplier.java
pl.brightinventions.slf4android.Disposable.java
pl.brightinventions.slf4android.EmailErrorReport.java
pl.brightinventions.slf4android.FileHandlerExpose.java
pl.brightinventions.slf4android.FileLogHandlerConfiguration.java
pl.brightinventions.slf4android.FileLogHandler.java
pl.brightinventions.slf4android.HandlerFormatterCompiler.java
pl.brightinventions.slf4android.LevelValueSupplier.java
pl.brightinventions.slf4android.ListLogRecordFormatter.java
pl.brightinventions.slf4android.Lists.java
pl.brightinventions.slf4android.LogLevel.java
pl.brightinventions.slf4android.LogRecordFormatterUtilFormatterAdapter.java
pl.brightinventions.slf4android.LogRecordFormatter.java
pl.brightinventions.slf4android.LogRecord.java
pl.brightinventions.slf4android.LogcatHandler.java
pl.brightinventions.slf4android.LoggerConfiguration.java
pl.brightinventions.slf4android.LoggerNameValueSupplier.java
pl.brightinventions.slf4android.LoggerPatternConfiguration.java
pl.brightinventions.slf4android.LoggerPatternValueSupplier.java
pl.brightinventions.slf4android.LoggerPattern.java
pl.brightinventions.slf4android.MakeScreenShotAsyncTask.java
pl.brightinventions.slf4android.MessageValueSupplier.java
pl.brightinventions.slf4android.NotifyDeveloperDialogDisplayActivity.java
pl.brightinventions.slf4android.NotifyDeveloperHandler.java
pl.brightinventions.slf4android.ReadLogcatEntriesAsyncTask.java
pl.brightinventions.slf4android.ThreadValueSupplier.java
pl.brightinventions.slf4android.androidTest.FileHandlerTests.java
pl.brightinventions.slf4android.androidTest.LoggerAdapterTests.java
pl.brightinventions.slf4android.androidTest.NotifyDeveloperHandlerTests.java
pl.brightinventions.slf4android.androidTest.TestActivity.java
pl.brightinventions.slf4android.roboelectric.HandlerFormatterCompilerTests.java
pl.brightinventions.slf4android.roboelectric.MessageValueSupplierTests.java
pl.brightinventions.slf4android.roboelectric.RoboelectricTest.java
pl.brightinventions.slf4android.roboelectric.RobolectricTestRunner.java