Android桌面Widget
来源:互联网 发布:mac 音乐 编辑:程序博客网 时间:2024/04/30 01:47
写这篇博客主要是为了纪念一下我转做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); }}
- android widget桌面时钟
- 【Android】创建桌面widget
- Android桌面widget
- android 桌面widget开发
- Android桌面Widget
- Android 桌面组件【widget】初探
- Android 桌面组件【widget】初探
- Android 桌面组件【app widget】
- Android 桌面组件【widget】初探
- Android 桌面组件【widget】初探
- Android 桌面组件【widget】初探
- Android进阶之widget桌面
- Android 桌面组件【widget】初探
- 【Android】桌面Widget动态刷新
- Android 桌面组件widget初探
- Android 桌面组件【widget】 初学
- Android widget 桌面组件开发
- Android widget 桌面组件开发
- 论周芷若
- 一元线性回归
- GoJS的一些使用技巧
- 取余-美分找零钱问题
- Java实现的对无序数组进行的二分查找法
- Android桌面Widget
- magic机器与深度学习机器人问题指令
- c语言实现链表及其基本操作
- js中apply方法的使用
- 分享一些自己的学习方法
- Codeforces Beta Round #22 (Div. 2 Only)-C. System Administrator
- Activity启动的时候弹出popupwindow
- 通过WiFi连接Android手机,进行ADB调试
- JavaScript-------02