Android修改浏览器书签和主页

    前一段时间开发了一个AppDemo软件,功能是在我开发的App中能直接修改手机自带浏览器的主页,增加,删除书签(书签缩图同步更换)等功能。过程坎坷,但总算按时完成了,今天就开发过程中遇到的问题做一个总结。

     首先遇到的第一个难点:清除浏览器的缓存数。我们知道只要打开浏览器,那么浏览器的缓存数据就会保存在/data/data/com.android.browser中


这个时候不管你是Back键退出还是手机自动重启,浏览器的缓存数据依然存在。那么问题来了,要想修改系统自带的浏览器主页首先必须想办法清除浏览器的数据。怎么清除呢?接触过设置模块的朋友会知道,长按APP菜单桌面顶端会出现一个AppInfo,把菜单托进去之后窗口中会出现一个CLEARDATE的东西,对了,这个功能按键就是清楚数据的一个东东。所以,进入设置后看看它是怎么处理的。进入设置查找之后你会发现,其实很简单:就是根据App的包名进行清楚数据的。
    首先看一下这个方法:
     
private  void initiateClearUserData() {
       // Invoke uninstall or clear user data based on sysPackage
       String packageName = "com.android.browser";//系统自带浏览器的包名
       Log.i(TAG, "Clearing user data for package : " +packageName);
       if (mClearDataObserver == null) {
           mClearDataObserver = new ClearUserDataObserver();
       }
       ActivityManager am = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
       boolean res = am.clearApplicationUserData(packageName,mClearDataObserver);
       
       if (!res) {
           // Clearing data failed for some obscure reason. Just log error fornow
           Log.i(TAG, "Couldnt clear application user data forpackage:"+packageName);
       }
    }


   看到这个方法估计你已经明白了,是不是就这个方法就行了呢,不!你要知道,Android系统的保护机制做的很好,当你改变系统数据时,会强加给你一个信息,就是说如果数据清除了会发送一个广播通知系统。看这个ClearUserDataObserver()方法
   
class ClearUserDataObserver extends IPackageDataObserver.Stub{
       public voidonRemoveCompleted(final String packageName, final booleansucceeded) {
          finalMessage msg = mHandler.obtainMessage(CLEAR_USER_DATA);
          msg.arg1 =succeeded ? OP_SUCCESSFUL : OP_FAILED;
         mHandler.sendMessage(msg);
       }
    }


  CLEAR_USER_DATA这个标志位是干嘛用的呢,接着代码往下看

     
public static final boolean showShutdownDialog = false;
    privatestatic final String TAG = "llcs";
    privateClearUserDataObserver mClearDataObserver;
    privatestatic final int CLEAR_USER_DATA = 1;
    privatestatic final int OP_SUCCESSFUL = 1;
    privatestatic final int OP_FAILED = 2;
    private Handler mHandler = new Handler() {
       public void handleMessage(Message msg) {
           // If the fragment is gone, don't process any more messages.
           
           Log.d(TAG, "handle message : " + msg.what);
           switch (msg.what) {
               case CLEAR_USER_DATA:
                   processClearMsg(msg);
                   break;
               
               default:
                   break;
           }
       }
    };


       private void processClearMsg(Message msg) {
       int result = msg.arg1;
       Log.i(TAG, "Cleared user data result:" + result);
       //String packageName = mAppEntry.info.packageName;
       String packageName = "com.android.browser";
       if(result == OP_SUCCESSFUL) {
           Log.i(TAG, "Cleared user data for package : "+packageName);
           //mState.requestSize(mAppEntry.info.packageName);
           // M ALPS00235193: send the clear success broadcast {@
           Intent packageDataCleared = newIntent(Intent.ACTION_SETTINGS_PACKAGE_DATA_CLEARED);
           packageDataCleared.putExtra("packageName", packageName);
           this.sendBroadcast(packageDataCleared);
           // @}
       } else {
           Log.i(TAG, "fail to clear user data for package : " +packageName);
       }
       //checkForceStop();
    }


 好了,到这里一切都明白了。根据App的包名然后处理数据最后把清除成功的信息通过广播发送出去.ACTION_SETTINGS_PACKAGE_DATA_CLEARED这个标志位就是模块数据被清理。然后通过广播发送出去。看一下清除之后再查看/data/data/com.android.browser下所包含的东西就没有了。


OK!不做过多解释,只要调用initiateClearUserData()方法就可以清除浏览器的缓存数据了。同样的道理,想要清楚其它模块的数据只要替换一下包名即可。清除缓存数据处理了,那么修改主页就简单多了。我的处理方式是写一个Settings.System.CHANGED_INTERNET,Settings.System.putString(MainActivity.this.getContentResolver(),Settings.System.CHANGED_INTERNET,"http://www.google.com");然后在浏览器中接收这个字符串替换原来的即可。
注意:这个Settings值需要自己定义,定义的路径在:frameworks/base/core/java/android/provider/Settings.java

   第二个难点:修改书签时书签缩略图同步改变的问题
     这个功能刚开始没有一点头绪,特别是书签缩略图同步改变的问题,还好浏览器的数据库是共用的,这样就好办多了,只有找到相应的字段就行了。
    首先看一下怎么增加书签:假设此时添加的是baidu书签

  
 private voidinsertBookMark() {
       Resourcesres = this.getResources();
       TypedArraypreloads = res.obtainTypedArray(R.array.bookmark_preloads);
      ContentValues inputValue = new ContentValues();
       //Bookmark值为1
      inputValue.put(Browser.BookmarkColumns.BOOKMARK, 1);
       //添加书签Title
      inputValue.put(Browser.BookmarkColumns.TITLE, "baidu");
       //添加书签URL
      inputValue.put(Browser.BookmarkColumns.URL,
            "http://www.baidu.com/");
       intfaviconId = preloads.getResourceId(0, 0);
       int thumbId = preloads.getResourceId(1, 0);
       byte[] thumb= null, favicon = null;
       try {
           thumb = readRaw(res, thumbId);
       } catch (IOException e) {
       }
       try {
           favicon = readRaw(res, faviconId);
       } catch (IOException e) {
       }
      inputValue.put(Browser.BookmarkColumns.FAVICON,
            favicon);
      //此为缩略图显示的图片
      inputValue.put(Browser.BookmarkColumns.THUMBNAIL,
            thumb);
       
       //向浏览器添加该书签
      ContentResolver contentResolver = getContentResolver();
      contentResolver.insert(Browser.BOOKMARKS_URI, inputValue);
      Toast.makeText(this, "添加成功!", Toast.LENGTH_LONG).show();
    }
   private byte[]readRaw(Resources res, int thumbId)throws IOException {
       if (thumbId == 0) {
            return null;
        }
        InputStream is = res.openRawResource(thumbId);
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] buf = new byte[4096];
            int read;
            while ((read = is.read(buf)) > 0) {
                bos.write(buf, 0, read);
            }
            bos.flush();
            return bos.toByteArray();
        } finally {
            is.close();
        }
        //return null;
    }


   添加时有三点很关键:1 添加书签Title 。2添加书签URL 。 3 缩略图显示的图片 然后通过contentResolver.insert()方法添加到数据库中。1和2 不多数关键是3的实现。看一下这个东西R.array.bookmark_preloads。这个是什么?是浏览器所有增加书签的数组集合。
<?xml version="1.0" encoding="utf-8"?>
<resources>
    
  <!--需要把raw文件中的图片全部加入 add by lyj 20160119 -->
    <array name="bookmark_preloads"> 
        <item>@raw/site_navigation_default_default3</item> <!--baidu name -->
        <item>@raw/site_navigation_default_default3</item> <!--baidu name -->
        <item>@raw/favicon_google</item>
        <item>@raw/thumb_google</item>
        <item>@raw/favicon_picasa</item>
        <item>@raw/thumb_picasa</item>
        <item>@raw/favicon_yahoo</item>
        <item>@raw/thumb_yahoo</item>
        <item>@raw/favicon_msn</item>
        <item>@raw/thumb_msn</item>
        <item>@raw/favicon_twitter</item>
        <item>@raw/thumb_twitter</item>
        <item>@raw/favicon_facebook</item>
        <item>@raw/thumb_facebook</item>
        <item>@raw/favicon_wikipedia</item>
        <item>@raw/thumb_wikipedia</item>
        <item>@raw/favicon_ebay</item>
        <item>@raw/thumb_ebay</item>
        <item>@raw/favicon_cnn</item>
        <item>@raw/thumb_cnn</item>
        <item>@raw/favicon_nytimes</item>
        <item>@raw/thumb_nytimes</item>
        <item>@raw/favicon_espn</item>
        <item>@raw/thumb_espn</item>
        <item>@raw/favicon_amazon</item>
        <item>@raw/thumb_amazon</item>
        <item>@raw/favicon_weatherchannel</item>
        <item>@raw/thumb_weatherchannel</item>
        <item>@raw/favicon_bbc</item>
        <item>@raw/thumb_bbc</item>
    </array>
</resources>

有书签数组了,那个缩略图放哪呢?在res/目录下建一个raw文件,把所有能用到的书签图片都放进去即可。


  然后看一下删除书签:
 
 private void deleteBookMark() {

      ContentResolver contentResolver = getContentResolver();

       // 删除书签,String数组第一个对应TITLE,第二个对应URL。

       int number =contentResolver.delete(Browser.BOOKMARKS_URI,
            Browser.BookmarkColumns.TITLE + "=? and "
                   +Browser.BookmarkColumns.URL + "=?", new String[] {
                   "Google","http://www.google.com/" });
      Log.i("lyj_bro", "number = " + number);
      Toast.makeText(this, "删除成功!", Toast.LENGTH_LONG).show();

    }

   可以看到删除是通过URL进行删除的。删除后缩略图什么的会一并删除的。这个很简单。
   同时还可以获取手机浏览器中所有的书签:
    case R.id.get_homebook://获取所有书签的按键
         listView.setAdapter(new ArrayAdapter(this,
            android.R.layout.simple_expandable_list_item_1, getData()));
          break;
     然后看这个方法getData():
    
private List getData() {

       List data =new ArrayList();
       //data.add
      ContentResolver contentResolver = getContentResolver();
       Cursorcursor = contentResolver.query(Browser.BOOKMARKS_URI, null,
             null, null,null);

       while(cursor.moveToNext()) {
          if(cursor.getString(
               cursor.getColumnIndex(Browser.BookmarkColumns.BOOKMARK))
               .equals("1")) {
            data.add(cursor.getString(cursor
                  .getColumnIndex(BookmarkColumns.TITLE)));
          }
       }

       returndata;
    }

   需要在Oncreate()方法里加上
   this.makeFileDir();
   再看这个方法makeFileDir():
     
 public voidmakeFileDir() {
       FilebookMarkFile = newFile(Environment.getExternalStorageDirectory()
            .getPath());
       try {
          if(!bookMarkFile.exists()) {
            bookMarkFile.mkdir();
          }
          FileWriterfw = new FileWriter(bookMarkFile + File.separator
                + "my.txt",true);
         Log.i("lyj_bro", "fw  = " + fw );
         ContentResolver contentResolver = getContentResolver();
          Cursorcursor = contentResolver.query(Browser.BOOKMARKS_URI, null,
                null, null,null);

          while(cursor.moveToNext()) {

             if(cursor
                  .getString(
                        cursor.getColumnIndex(Browser.BookmarkColumns.BOOKMARK))
                  .equals("1")) {
               fw.write(cursor.getString(cursor
                     .getColumnIndex(BookmarkColumns.TITLE)) + "\n");
               fw.write(cursor.getString(cursor
                     .getColumnIndex(BookmarkColumns.URL)) + "\n");
             }
          }

         fw.close();
       } catch(Exception e) {
          // TODOAuto-generated catch block
         e.printStackTrace();
       }

    }

   OK!这个功能不用解释,一看就明白了。
   到这里一切就结束了。总之,看似简单的功能但用的东西却很多。总结起来供大家学习。


  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值