Tổng hợp Làm ứng dụng widget - giao diện chạy nền trong android

Thảo luận trong 'Android nâng cao' bắt đầu bởi thanhlong90.it, 31/10/13.

  1. thanhlong90.it

    thanhlong90.it Admin Support

    Lượt xem: 25,736
    Chào các bạn, trong bài này Long xin hướng dẫn các bạn một mảng khác trong lập trình ứng dụng android. Như các bạn thấy trên nền chính (giao diện desktop) của hệ điều hành android có các ứng dụng như là đồng hồ, dự báo thời tiết, bộ điều khiển hệ thống bật tắt wifi, tăng giảm độ sáng, định vị ... tất cả đó đều được gọi là ứng dụng chạy nên widget. Đây là một mảng mới trên android cũng khá thú vị và hôm nay Long sẽ giới thiệu 1 demo nhỏ nói về vấn đề này.

    1) Source code demo lập trình android:
    - Click vào đây để download source code demo

    2) Giới thiệu thêm về widget:
    - Widget là một ứng dụng chạy nền (ngay trên deskop).
    - Để kéo một widget ra ngoài nền desktop của android, bạn phải vào menu và chọn tab "Widget"
    - Widget không phải là 1 Activity.
    - Widget được khai báo trong tập tin AndroidMenifest.xml trong cặp thẻ <receiver>
    - Thông thường sử dụng 1 service chạy ngầm để quản lý một widget

    3) Video hướng dẫn:


    4) Hướng dẫn code:
    - res/values/strings.xml
    PHP:
    <?xml version="1.0" encoding="utf-8"?>
    <resources>
     
        <string name="parsed_data">http://android.vn\nHướng dẫn bởi thanhlong90.it</string>
        <string name="app_name">DemoAndroidWidget</string>
        <string name="action_settings">Settings</string>
        <string name="hello_world">Hello world!</string>
        <string name="statictext">Static Text</string>
     
    </resources>
    - res/layout/widget_layout.xml
    PHP:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="8dip"
        android:background="@drawable/myshape"
        android:orientation="vertical" >
     
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:gravity="center"
            android:text="@string/parsed_data"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textStyle="bold" />
     
        <TextView
            android:id="@+id/update"
            style="@android:style/TextAppearance.Medium"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:layout_margin="4dip"
            android:gravity="center_horizontal|center_vertical"
            android:text="@string/statictext" />
     
    </LinearLayout>
    - res/layout/widgetsimple_layout.xml
    PHP:
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/layout"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="8dip"
        android:background="@drawable/mysimpleshape"
        android:orientation="vertical" >
     
        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="5dp"
            android:gravity="center"
            android:text="@string/parsed_data"
            android:textAppearance="?android:attr/textAppearanceMedium" >
        </TextView>
     
        <TextView
            android:id="@+id/update"
            style="@android:style/TextAppearance.Medium"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:layout_gravity="center"
            android:layout_margin="4dip"
            android:gravity="center_horizontal|center_vertical"
            android:text="@string/statictext" >
        </TextView>
     
    </LinearLayout>
    - res/xml/widget_info.xml
    PHP:
    <?xml version="1.0" encoding="utf-8"?>
    <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
        android:initialLayout="@layout/widget_layout"
        android:minHeight="72dp"
        android:minWidth="146dp"
        android:resizeMode="horizontal|vertical"
        android:updatePeriodMillis="180000" >
     
    </appwidget-provider>
    - res/xml/widgetsimple_info.xml
    PHP:
    <?xml version="1.0" encoding="utf-8"?>
    <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
        android:initialLayout="@layout/widgetsimple_layout"
        android:minHeight="72dp"
        android:minWidth="146dp"
        android:resizeMode="horizontal|vertical"
        android:updatePeriodMillis="180000" >
     
    </appwidget-provider>
    - MyWidgetProvider.java
    PHP:
    package thanhlong90.it.demoandroidwidget;
     
    import android.appwidget.AppWidgetManager;
    import android.appwidget.AppWidgetProvider;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.util.Log;
     
    public class 
    MyWidgetProvider extends AppWidgetProvider {
     
        private static final 
    String LOG "de.vogella.android.widget.example";
     
        @
    Override
        
    public void onUpdate(Context contextAppWidgetManager appWidgetManagerint[] appWidgetIds) {
     
            
    Log.v(LOG"onUpdate method called");
            
    // Get all ids
            
    ComponentName thisWidget = new ComponentName(contextMyWidgetProvider.class);
            
    int[] allWidgetIds appWidgetManager.getAppWidgetIds(thisWidget);
     
            
    // Build the intent to call the service
            
    Intent intent = new Intent(context.getApplicationContext(), UpdateWidgetService.class);
            
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDSallWidgetIds);
     
            
    // Update the widgets via the service
            
    context.startService(intent);
        }
    }
    - MyWidgetProviderSimple.java
    PHP:
    package thanhlong90.it.demoandroidwidget;
     
    import java.util.Random;
     
    import android.app.PendingIntent;
    import android.appwidget.AppWidgetManager;
    import android.appwidget.AppWidgetProvider;
    import android.content.ComponentName;
    import android.content.Context;
    import android.content.Intent;
    import android.util.Log;
    import android.widget.RemoteViews;
     
    public class 
    MyWidgetProviderSimple extends AppWidgetProvider {
     
        @
    Override
        
    public void onUpdate(Context contextAppWidgetManager appWidgetManagerint[] appWidgetIds) {
     
            
    // Get all ids
            
    ComponentName thisWidget = new ComponentName(contextMyWidgetProviderSimple.class);
            
    int[] allWidgetIds appWidgetManager.getAppWidgetIds(thisWidget);
     
            for (
    int widgetId allWidgetIds) {
                
    // Create some random data
                
    int number = (new Random().nextInt(100));
     
                
    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widgetsimple_layout);
                
    Log.w("WidgetExample"String.valueOf(number));
                
    // Set the text to the view with the id R.id.update
                // instead of -1
                
    remoteViews.setTextViewText(R.id.updateString.valueOf(number));
     
                
    // Register an onClickListener
                
    Intent intent = new Intent(contextMyWidgetProviderSimple.class);
     
                
    intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
                
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDSallWidgetIds);
     
                
    PendingIntent pendingIntent PendingIntent.getBroadcast(context0intentPendingIntent.FLAG_UPDATE_CURRENT);
                
    remoteViews.setOnClickPendingIntent(R.id.updatependingIntent);
                
    appWidgetManager.updateAppWidget(widgetIdremoteViews);
            }
        }
    }
    - UpdateWidgetService.java
    PHP:
    package thanhlong90.it.demoandroidwidget;
     
    import java.util.Random;
     
    import android.app.PendingIntent;
    import android.app.Service;
    import android.appwidget.AppWidgetManager;
    import android.content.ComponentName;
    import android.content.Intent;
    import android.os.IBinder;
    import android.util.Log;
    import android.widget.RemoteViews;
     
    public class 
    UpdateWidgetService extends Service {
        private static final 
    String LOG "thanhlong90.it.demoandroidwidget.UpdateWidgetService";
     
        @
    Override
        
    public void onStart(Intent intentint startId) {
            
    Log.i(LOG"Called");
     
            
    // Create some random data
            
    AppWidgetManager appWidgetManager AppWidgetManager.getInstance(this.getApplicationContext());
     
            
    int[] allWidgetIds intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
     
            
    ComponentName thisWidget = new ComponentName(getApplicationContext(), MyWidgetProvider.class);
            
    int[] allWidgetIds2 appWidgetManager.getAppWidgetIds(thisWidget);
            
    Log.w(LOG"From Intent" String.valueOf(allWidgetIds.length));
            
    Log.w(LOG"Direct" String.valueOf(allWidgetIds2.length));
     
            for (
    int widgetId allWidgetIds) {
                
    // Create some random data
                
    int number = (new Random().nextInt(100));
     
                
    RemoteViews remoteViews = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.widget_layout);
                
    Log.w("WidgetExample"String.valueOf(number));
                
    // Set the text
                
    remoteViews.setTextViewText(R.id.update"Random: " String.valueOf(number));
     
                
    // Register an onClickListener
                
    Intent clickIntent = new Intent(this.getApplicationContext(), MyWidgetProvider.class);
     
                
    clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
                
    clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDSallWidgetIds);
     
                
    PendingIntent pendingIntent PendingIntent.getBroadcast(getApplicationContext(), 0clickIntentPendingIntent.FLAG_UPDATE_CURRENT);
                
    remoteViews.setOnClickPendingIntent(R.id.updatependingIntent);
                
    appWidgetManager.updateAppWidget(widgetIdremoteViews);
            }
            
    stopSelf();
            
    // super.onStart(intent, startId);
        
    }
     
        @
    Override
        
    public IBinder onBind(Intent intent) {
            return 
    null;
        }
    }
    5) Hình ảnh kết quả demo:
    device-2013-10-31-095743

    Bài viết đăng lên diễn đàn khác vui lòng ghi rõ nguồn: Android.vn
    Pass giải nén: http://android.vn
    Support:
    - Skype: thanhlong90.it.support
    - Gmail: thanhlong90.it@gmail.com
    Chúc các bạn thành công!
    thanhlong90.it, widget, service, provider, hướng dẫn, ví dụ, demo, example, tutorial
    ishy159, Nguyễn Đình Bắch28192 thích bài này.
  2. sedaok

    sedaok New Member

    Long có thể giải thích các lớp đc ko
  3. thanhlong90.it

    thanhlong90.it Admin Support Staff Member

    Long sẽ quay clip và hướng dẫn trên clip luôn bạn nhé!
    linkgosedaok thích bài này.
  4. bmd_duc

    bmd_duc New Member

    thế thì mấy cái ứng dụng nó hiển thị ở góc màn hình như ứng dụng xem dung lượng pin hay hiện lên khi download thì nó làm thế nào
  5. thanhlong90.it

    thanhlong90.it Admin Support Staff Member

    cái biểu tượng pin mà phần mặc định ở của android, còn phần muốn thông báo như có gmail mới ... thì bạn tìm hiểu "notification" nhé
    bmd_duc thích bài này.
  6. bmd_duc

    bmd_duc New Member

    mình đã xem về notification và hiển thị trên statusbar, tuy nhiên có 1 thắc mắc là nếu như trên notification và statusbar hiển thị nhiều ảnh ở nhiều mức độ khác nhau (như wifi 5 vạch), thì nó dùng cách nào vậy? dùng lệnh if 5 lần hay có cách nào tối ưu hơn
  7. vistaghost

    vistaghost New Member

    cho mình hỏi chút là, sau khi run thi nó không tạo ra file apk, mà cài luôn vào máy phải không nhỉ ? sau đó mình phải vào tiện ích để lấy nó ra màn hình?

    Mình dùng Android studio, khi làm theo tutorial của bạn, khi run nó chạy như là cài apk và chạy lên thì bị force to stop.
  8. brucelee

    brucelee New Member

    Sau khi chạy source code trên phải vào mục tiện ích để đưa widget ra desktop,vậy cho mình hỏi muốn widget hiển thị ngay sau khi chạy source code thì làm ntn? cảm ơn m.n nhiều!
  9. googlecomvn

    googlecomvn lịch việt chuyên nghiệp lichvietpro.com

    Mình đã làm widget rồi nhưng khi vào taskmanager của smartphone để giải phóng mem thì widget không cập nhật thông tin nữa mà 30 phút nó mới cập nhật. Có cách nào giải quyết vấn đề này ko các bạn

Chia sẻ trang này