Android桌面Widget

写这篇博客主要是为了纪念一下我转做App之后的第一个应用,当时确实很多都不懂,一点一点开始研究,虽然写的很一般,但是当时真的很用心在做,连续做了2周,每天加班都在10点以后,全公司最后走的就是我,现在想想真的不错。
这个应用的需求改了又改,改了又改,经过无数次的需求修改,终于确定下来了,首先桌面要有一个widget负责定时显示图片内容,图片地址给出来的很多张图片,每张图片的显示时间也不同,对应每个图片还有不同的消息内容,如果是应用那么就去打开应用,如果是网页就去打开网页,数据为每12小时获取一次,图片要在wifi的情况下获得,原本还有获得手机的各种状态,包括地理位置,mac地址,蓝牙地址,如果有卡的话要获得基站信息,ip地址等发给后台,而且时间很短,10分钟发一次,由于这样做太费电,所以后面的需求被拿掉了。
需求就这么多,说说实现吧,widget在开机时接收到开机广播,去拿图片,并使用handler做12小时延迟操作,拿到数据后,放到一个list里面,然后通过list里面的对象获得图片地址,然后去下载每张图片,保存在本地,如果下次拿到数据后图片已经有了就不再去下载。
有的同学会说还有什么下载现在网上N多的显示网络图片的框架,improt进来直接用多方便,对不起我到现在还不知道widget中imageview怎么来设置网络图片,至少我找到的还不支持这种设置,如果有同学做过,请千万告诉我,省得写download图片的代码,好了话不多说开始上代码。
如果你想在桌面上生成一个widget,那么在AndroidManifest里面需要定义一个receiver,并且包含meta-data为

        <receiver android:name=".LogoAppWidgetProvider">
            <intent-filter>
                <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
                <action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
                <action android:name="android.net.wifi.STATE_CHANGE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/adv_widget_provider" />
        </receiver>

这里面resource = @xml/adv_widget_provider就是用来获得布局的

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/adv_service_layout"
    android:minHeight="30dp"
    android:minWidth="250dp"
    android:previewImage="@drawable/ic_launcher" >
</appwidget-provider>

简单说说第一行布局文件,用来绘制你的widget的形体,后面的就是宽高,最下面的是你这个widget在launcher里面注册的图标样式,其中我要吐槽一下,金立做的launcher实在是让人发指,定制的launcher的大小完全和其他手机不同,我在其他手机上面写一行的数据,到了他这就是2行,而且左右两边无法对齐,好了这不是重点。
@layout/adv_service_layout

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@android:color/transparent"
    android:gravity="center"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/adv_imageview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitXY" />
</LinearLayout>

这个没什么了,就一个imageview
后面就是Java代码了,首先是Application

public class LogoApplication extends Application {
    public static List<LogoInfo> logoinfolist = new ArrayList<LogoInfo>();
    public static List<LogoInfo> tempLogoInfoList = new ArrayList<LogoInfo>();
    public static int logoinfolistLength;
    public static int logoeverytime;
    public static RequestQueue queues;
    public static String picPath = "/sdcard/LogoWidget/";
    public static List<String> picNameList = new ArrayList<String>();

    public void onCreate() {
        super.onCreate();
        queues = Volley.newRequestQueue(getApplicationContext());
        mHandler.sendEmptyMessage(0);
        startService(new Intent(LogoApplication.this, DownloadPicFromClient.class));
    }


    Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            try {
                startService(new Intent(LogoApplication.this, LogoService.class));
            } catch (Exception e) {
                mHandler.sendEmptyMessageDelayed(0, 12 * 60 * 60 * 1000);
            }
            mHandler.sendEmptyMessageDelayed(0, 12 * 60 * 60 * 1000);
        }
    };

    public static RequestQueue getHttpQueues() {
        return queues;
    }
}

代码没什么难度,这里用初始化Volley,然后生命一个Handler每12小时拿一次数据,
后面还要写一个

public class LogoAppWidgetProvider extends AppWidgetProvider {
    private static final String TAG = "LogoAppWidgetProvider";
    public static final String ACTION_APPWIDGET_UPDATE = "android.appwidget.action.APPWIDGET_UPDATE";
    // android:debuggable="false"
    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        Intent stateintent = new Intent(context, LogoService.class);
        context.startService(stateintent);
    }

    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {
    }

    @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
    }

    @Override
    public void onEnabled(Context context) {

    }

    @Override
    public void onDisabled(Context context) {
        //context.stopService(new Intent(context, LogoService.class));
    }
}

这个是保证Application启动之后wifi没有打开,一旦wifi打开程序会在重新去拿数据
DownloadPicFromClient.java

public class GetDataFromClient implements HttpResponseListener {

    private final static String loadJson = "https://cloud.yuyutechnology.com/adserver/adversFetch.do?deviceId=123&init=true&advertuserId=7";//pro
    // private final static String loadJson = "https://cloud888.yuyutechnology.com/adserver/adversFetch.do?deviceId=123&init=true&advertuserId=7";//test
    private final static String TAG_CHECK = "tag_check";

    public static GetDataFromClient getInstace() {
        return new GetDataFromClient();
    }

    public static void getdataFromClient(Context context) {
        if (CheckWifiConnect.isNetworkConnected(context)) {
            if (CheckWifiConnect.isWifiConnected(context)) {
                if (!CheckWifiConnect.isMobileConnected(context)) {
                    VolleyRequest volleyRequest = new VolleyRequest();
                    volleyRequest.setHttpResponseListener(getInstace());
                    volleyRequest.RequestPost(loadJson, TAG_CHECK);
                }
            }
        }
    }

    @Override
    public void httpResponse(String data) {
        LG.e(GetDataFromClient.class, data);
        dataToObject(data);
    }

    public void dataToObject(String data) {
        if (data == null)
            return;
        try {
            JSONArray valarray = new JSONArray(data);
            LogoApplication.logoinfolistLength = valarray.length();
            LogoApplication.logoeverytime = Integer.parseInt(valarray.getJSONObject(0)
                    .getString("adImageShowInterval"));
            LogoApplication.tempLogoInfoList.clear();
            for (int i = 0; i < valarray.length(); i++) {
                JSONObject arr = valarray.getJSONObject(i);
                LogoInfo advinfo = new LogoInfo();
                advinfo.adAppActionPackageName = arr
                        .optString("adAppActionPackageName");
                advinfo.adAppActionClassName = arr
                        .optString("adAppActionClassName");
                advinfo.adBrowserAction = arr
                        .optString("adBrowserAction");
                advinfo.adImageUrl = arr.optString("adImageUrl");
                LogoApplication.tempLogoInfoList.add(advinfo);
            }
            EventBus.getDefault().post(LogoApplication.tempLogoInfoList);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public void httpREsponseError(VolleyError error) {
    }
}

获得数据放入到一个静态的list里面后续下载图片以及播放图片都要用到,这里面拿到图片之后就使用EventBus发送通知去下载图片
DownloadPicFromClient.java

public class DownloadPicFromClient extends Service {
    Context context;
    public static int i = 0;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        context = getApplicationContext();
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        if (!EventBus.getDefault().isRegistered(this))
            EventBus.getDefault().register(this);
    }

    public void onEventMainThread(List<LogoInfo> logoinfolist) {
        if (CheckWifiConnect.isNetworkConnected(context)) {
            if (CheckWifiConnect.isWifiConnected(context)) {
                for (int i = 0; i < logoinfolist.size(); i++) {
                    File file = new File(logoinfolist.get(i).adImageUrl.trim());
                    String fileName = file.getName();
                    File sdFile = new File(LogoApplication.picPath + fileName);
                    boolean iAllPic = true;
                    if (!sdFile.exists()) {
                        iAllPic = false;
                        MyAsynaTask mTask = new MyAsynaTask(logoinfolist.get(i));
                        mTask.execute(logoinfolist.get(i).adImageUrl);
                    } else {
                        logoinfolist.get(i).downPicName = fileName;
                    }
                    if (iAllPic)
                        EventBus.getDefault().post("play advertisement");
                }
            }
        }
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        startService(new Intent(this, LogoService.class));
    }

    public class MyAsynaTask extends AsyncTask<String, Integer, Bitmap> {
        LogoInfo logoInfo;

        public MyAsynaTask(LogoInfo logoInfo) {
            this.logoInfo = logoInfo;
        }

        @Override
        protected void onPreExecute() {
            // TODO Auto-generated method stub
            super.onPreExecute();
        }

        @Override
        protected Bitmap doInBackground(String... params) {
            // TODO Auto-generated method stub
            Bitmap bitmap = null;
            try {
                URL url = new URL(params[0]);
                HttpURLConnection connection = (HttpURLConnection) url
                        .openConnection();
                connection.setDoInput(true);
                connection.connect();
                InputStream inputStream = connection.getInputStream();
                bitmap = BitmapFactory.decodeStream(inputStream);
                inputStream.close();
            } catch (Exception e) {
                // TODO: handle exception
            }
            return bitmap;
        }

        @Override
        protected void onProgressUpdate(Integer... values) {
            // TODO Auto-generated method stub
        }

        @Override
        protected void onPostExecute(Bitmap result) {
            // TODO Auto-generated method stub
            super.onPostExecute(result);
            boolean isFullBitmap = true;
            this.logoInfo.picbitmap = result;
            for (int j = 0; j < LogoApplication.tempLogoInfoList.size(); j++) {
                if (LogoApplication.tempLogoInfoList.get(j).picbitmap == null) {
                    isFullBitmap = false;
                    break;
                }
            }
            File file = new File(this.logoInfo.adImageUrl.trim());
            String fileName = file.getName();
            this.logoInfo.downPicName = fileName;
            File sdFile = new File(LogoApplication.picPath + fileName);
            if (!sdFile.exists() && result != null) {
                LG.e(DownloadPicFromClient.class, "this.logoInfo.adImageUrl = " + this.logoInfo.adImageUrl);
                saveCroppedImage(result, this.logoInfo.adImageUrl);
            }
            if (isFullBitmap) {
                getFileCountAndName();
                EventBus.getDefault().post("play advertisement");
            }
        }
    }

    private void saveCroppedImage(Bitmap bmp, String picUrl) {
        File file = new File("/sdcard/LogoWidget");
        if (!file.exists())
            file.mkdir();
        file = new File(("/sdcard/" + picUrl).trim());
        String fileName = file.getName();
        String mName = fileName.substring(0, fileName.lastIndexOf("."));
        String sName = fileName.substring(fileName.lastIndexOf("."));
        String newFilePath = LogoApplication.picPath + mName + sName;
        file = new File(newFilePath);
        if (fileIsExists(newFilePath)) {
        } else {
            try {
                file.createNewFile();
                FileOutputStream fos = new FileOutputStream(file);
                bmp.compress(Bitmap.CompressFormat.JPEG, 50, fos);
                fos.flush();
                fos.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

    public void getFileCountAndName() {
        getFiles(LogoApplication.picPath);
    }

    public boolean fileIsExists(String strFile) {
        try {
            File f = new File(strFile);
            if (!f.exists()) {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    private void getFiles(String string) {
        // TODO Auto-generated method stub
        File file = new File(string);
        File[] files = file.listFiles();
        for (int j = 0; j < files.length; j++) {
            String name = files[j].getName();
            if (files[j].isDirectory()) {
                String dirPath = files[j].toString().toLowerCase();
                Log.d("shifuqiang", "dirPath" + dirPath);
                getFiles(dirPath + "/");
            } else if (files[j].isFile() & name.endsWith(".jpg") || name.endsWith(".png") || name.endsWith(".bmp") || name.endsWith(".gif") || name.endsWith(".jpeg")) {
                Log.d("shifuqiang", "FileName===" + files[j].getName());
                LogoApplication.picNameList.add(files[j].getName());
                i++;
            }
        }
        deletePicFromSDCard(LogoApplication.picNameList);
    }

    public void deletePicFromSDCard(List<String> picName) {
        for (int i = 0; i < picName.size(); i++) {
            boolean sdExitPic = false;
            for (int j = 0; j < LogoApplication.tempLogoInfoList.size(); j++) {
                if (LogoApplication.tempLogoInfoList.get(j).adImageUrl.contains((CharSequence) picName.get(i))) {
                    sdExitPic = true;
                    break;
                }
            }
            if (!sdExitPic) {
                deleteFileFromSDEx(picName.get(i));
            }
        }
    }

    public void deleteFileFromSDEx(String fileName) {
        File deletefile = new File(LogoApplication.picPath + fileName);
        deletefile.delete();
    }
}

代码虽然有点长,也是当时不太规范,所以写的乱七八糟的,但是通过名字都能知道是什么意思就不多说了
下载完之后就去播放图片

public class LogoService extends Service {
    private static final String TAG = "LogoService";
    RemoteViews views;
    List<PackageInfo> list;
    PackageManager packageManager;
    Context mcontext;
    int playcount;

    @Override
    public void onCreate() {
        super.onCreate();
        views = new RemoteViews(getPackageName(), R.layout.adv_service_layout);
        packageManager = this.getPackageManager();
        mcontext = getApplicationContext();
    }

    @Override
    public void onStart(Intent intent, int startId) {
        super.onStart(intent, startId);
        GetDataFromClient.getdataFromClient(getApplicationContext());
        if (!EventBus.getDefault().isRegistered(this))
            EventBus.getDefault().register(this);
        if (null == views)
            views = new RemoteViews(getPackageName(), R.layout.adv_service_layout);
    }

    public void onEventMainThread(String playAdvertisement) {
        if (null == views)
            views = new RemoteViews(getPackageName(), R.layout.adv_service_layout);
        views.setImageViewResource(R.id.adv_imageview, R.drawable.define_head);
        if (mHander.hasMessages(0))
            mHander.removeCallbacksAndMessages(null);
        LogoApplication.logoinfolist.clear();
        for (int i = 0; i < LogoApplication.tempLogoInfoList.size(); i++) {
            LogoApplication.logoinfolist.add(LogoApplication.tempLogoInfoList.get(i));
        }
        if (LogoApplication.logoinfolist.size() == 1) {
            refreshWidget();
        } else if (LogoApplication.logoinfolist.size() > 1) {
            mHander.sendEmptyMessage(0);
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
        mHander.removeCallbacksAndMessages(null);
        startService(new Intent(this, LogoService.class));
    }

    Handler mHander = new Handler() {
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            refreshWidget();
            LG.e(LogoService.class, "handler post");
            mHander.sendEmptyMessageDelayed(0, 5000);
        }
    };

    public void getBitMapFromSDCard(String path, RemoteViews views) {
        File mFile = new File(path);
        if (mFile.exists()) {
            Bitmap bitmap = BitmapFactory.decodeFile(path);
            views.setImageViewBitmap(R.id.adv_imageview, bitmap);
        }
    }

    public void refreshWidget() {
        if (LogoApplication.logoinfolist == null
                || LogoApplication.logoinfolist.isEmpty())
            return;
        if (null == views)
            views = new RemoteViews(getPackageName(), R.layout.adv_service_layout);
        if (LogoApplication.logoinfolist.get(playcount
                % LogoApplication.logoinfolist.size()).picbitmap != null) {
            views.setImageViewBitmap(R.id.adv_imageview, LogoApplication.logoinfolist.get(playcount
                    % LogoApplication.logoinfolist.size()).picbitmap);
        } else {
            String sdPicPath = LogoApplication.picPath + LogoApplication.logoinfolist.get(playcount
                    % LogoApplication.logoinfolist.size()).downPicName;
            getBitMapFromSDCard(sdPicPath, views);
        }
        list = packageManager.getInstalledPackages(0);
        boolean hasadvpackage = false;
        for (PackageInfo packageInfo : list) {
            if (packageInfo.packageName
                    .equals(LogoApplication.logoinfolist.get(playcount
                            % LogoApplication.logoinfolist.size()).adAppActionPackageName)) {
                hasadvpackage = true;
                break;
            }
        }
        Intent mintented = new Intent();
        if (hasadvpackage) {
            PackageManager packageManager = this.getPackageManager();
            mintented = packageManager.getLaunchIntentForPackage("com.yuyu.android.pcam");
        } else {
            Uri uri = Uri.parse(LogoApplication.logoinfolist.get(playcount
                    % LogoApplication.logoinfolist.size()).adBrowserAction);
            mintented.setAction(Intent.ACTION_VIEW);
            mintented.setData(uri);
        }
        mintented.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
        PendingIntent pendingIntent = PendingIntent.getActivity(
                getApplicationContext(), 0, mintented, 0);
        views.setOnClickPendingIntent(R.id.adv_imageview, pendingIntent);
        AppWidgetManager appWidgetManager = AppWidgetManager
                .getInstance(getApplicationContext());
        ComponentName componentName = new ComponentName(
                getApplicationContext(), LogoAppWidgetProvider.class);
        appWidgetManager.updateAppWidget(componentName, views);
        playcount++;
    }
}

剩下的就是一些bean,接口类,和帮助类了
CheckWifiConnect.java

public static boolean isNetworkConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mNetworkInfo = mConnectivityManager
                    .getActiveNetworkInfo();
            if (mNetworkInfo != null) {
                return mNetworkInfo.isAvailable();
            }
        }
        return false;
    }
    public static boolean isWifiConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mWiFiNetworkInfo = mConnectivityManager
                    .getNetworkInfo(ConnectivityManager.TYPE_WIFI);
            if (mWiFiNetworkInfo != null) {
                return mWiFiNetworkInfo.isConnected();
            }
        }
        return false;
    }
    public static boolean isMobileConnected(Context context) {
        if (context != null) {
            ConnectivityManager mConnectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo mMobileNetworkInfo = mConnectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
            if (mMobileNetworkInfo != null) {
                return mMobileNetworkInfo.isConnected();
            }
        }
        return false;
    }

HttpResponseListener.java

public interface HttpResponseListener {
    void httpResponse(String jsonObject);
    void httpREsponseError(VolleyError error);
}

LogoInfo.java

public class LogoInfo {
    String adId;
    String adName;
    String adSerialNumber;
    String advertiserId;
    String adStartTime;
    String adEndTime;
    String adAppActionPackageName;
    String adAppActionClassName;
    String adAppStoreAction;
    String adBrowserAction;
    String adImageUrl;
    String adImageShowInterval;
    String adState;
    String adDurationTime;
    String DelayedStartTime;
    String DelayedEndTime;
    public Bitmap picbitmap;
    public String downPicName;
}

网络数据请求封装类VolleyRequest.java

public class VolleyRequest {
    public StringRequest stringRequest;
    public HttpResponseListener httpResponseListener;
    public void setHttpResponseListener(
            HttpResponseListener httpResponseListener) {
        this.httpResponseListener = httpResponseListener;
    }
    public void RequestPost(String url, String tag) {
        LogoApplication.getHttpQueues().cancelAll(tag);
        stringRequest = new StringRequest(url,  
                new Response.Listener<String>() {  
                    @Override  
                    public void onResponse(String response) {
                        httpResponseListener.httpResponse(response);
                    }  
                }, new Response.ErrorListener() {  
                    @Override  
                    public void onErrorResponse(VolleyError error) {   
                        httpResponseListener.httpREsponseError(error);
                    }  
                });  
        stringRequest.setTag(tag);
        LogoApplication.getHttpQueues().add(stringRequest);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值