I am pretty new to android development.

I have an app that reads from a usb to serial connection every second. The app then update the MainActivity's UI with the new data. My app also has a widget that is also updated with the new data as well. This works well however when the onDestroy() method is called the widget stops working.

I have seen several apps where the widget continues to work and update even though the app has never been started. At least not to my knowledge.

How is this done? I would like my widget to run and function without the app even running. Is this possible?

UPDATE:

Here is a snippet from my MainActivity's onCreate()

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    final HandlerThread hTh = new HandlerThread("HT");
    hTh.start();
    final long oneScd = 1000;
    final Handler handler = new Handler(hTh.getLooper());
    Runnable updateDisplay = new Runnable(){
        @Override
        public void run() {
            updateDisplay(GlobalSpeed._json);
        }
    };

    Runnable eachSec = new Runnable() {
        @Override
        public void run() {

            runOnUiThread(updateDisplay);
            handler.postDelayed(this, oneScd);
        }
    };
    handler.postDelayed(eachSec, oneScd);

Here is a my AppWidgetProvider code:

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[]      appWidgetIds) {
    try {
        updateWidgetContent(context, appWidgetManager);

    } catch (Exception e) {
        Log.e(DEBUG_TAG, "Failed", e);
    }
}

public void updateWidgetContent(final Context context, final AppWidgetManager appWidgetManager) {

Intent launchAppIntent = new Intent(context, SoleWidgetProvider.class);

service = PendingIntent.getActivity(context, 0, launchAppIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    hTh.start();
    final long oneScd = 4000;
    final Handler handler = new Handler(hTh.getLooper());

    Runnable eachSec = new Runnable(){
        @Override
        public void run() {

            String js;

            js = GlobalSpeed._json;

            RemoteViews remoteView = new RemoteViews(context.getPackageName(), R.layout.sole_widget_layout);
            remoteView.setTextViewText(R.id.wSpeed, js);//"Speed: " + String.valueOf(s.realSpeed())

            ComponentName componentName = new ComponentName(context, SoleWidgetProvider.class);

            appWidgetManager.updateAppWidget(componentName, remoteView);

            handler.postDelayed(this, oneScd);
        }
    };
    handler.postDelayed(eachSec, oneScd);
}

Here is my service that gets the response from the serial communication and sets the GlobalSpeed._json value.

public class WidgetUpdateService extends Service {
public static final String DEBUG_TAG = "SoleWidgetService";

public static String json;

private SerialComunicator serComm;
private Context context;

@Override
public void onStart(Intent intent, int startId){
    super.onStart(intent, startId);
    Log.d(DEBUG_TAG, "Sevice Started");
    serComm = new SerialComunicator(this);

    buildUpdate();
}


private void buildUpdate(){
    HandlerThread hTh = new HandlerThread("SHT");
    final long oneScd = 4000;
    hTh.start();
    final Handler handler = new Handler(hTh.getLooper());

    Runnable readSerial = new Runnable(){

        @Override
        public void run() {
            // TODO Auto-generated method stub

            GlobalSpeed._json = serComm.readDataFromSerial();

            handler.postDelayed(this, oneScd);
        }

    };
    handler.postDelayed(readSerial, oneScd);
}

public void displayToast(String msg){
    Toast.makeText(this, serComm.readDataFromSerial(), Toast.LENGTH_SHORT);
}



@Override
public IBinder onBind(Intent arg0) {
    // TODO Auto-generated method stub
    return null;
}

}

Hope this is enough code.

This all works fine, and when I go to the home screen and the app's onStop() method is called it works and the widget continues to up date. But when I remove the app from the recent apps and the onDestroy() method is called the widget ceases to update.

I would like the widget to function independent of the app. I this possible? I know of some widgets that SEEM to run independent of their app.

有帮助吗?

解决方案

You will need to write a service that runs in the background, which then updates the widget (and the app too) through an intent.

In android when an app is not in the foreground, it gets paused, so any code running also gets paused.

A service is independent of an app. Read up about services. You can have it start at boot, or have the widget trigger the service when it needs data.

One thing to consider though is updating data every second will drain the battery. A widget is usually intended to update data occasionally (every 30mins, hour etc), not every second.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top