author | Xiaoliang Wang <xiaoliang.wang@amlogic.com> | 2014-12-04 08:39:36 (GMT) |
---|---|---|
committer | Xiaoliang Wang <xiaoliang.wang@amlogic.com> | 2014-12-05 01:59:16 (GMT) |
commit | 3d68fc67ed3f106f7b79f895978780cf72069677 (patch) | |
tree | b64d9c1a932e595a7d97020087f86498e109d4f2 | |
parent | 8f49d03eb1a8be3d346f7ca8cfb1eed94e4e336b (diff) | |
download | AppInstaller-3d68fc67ed3f106f7b79f895978780cf72069677.zip AppInstaller-3d68fc67ed3f106f7b79f895978780cf72069677.tar.gz AppInstaller-3d68fc67ed3f106f7b79f895978780cf72069677.tar.bz2 |
change appinstaller for android 5.0
Change-Id: I5610e486977d2cf8b47a40c27a6b4be2ca336a33
34 files changed, 1313 insertions, 1451 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 26793d5..f37e6a7 100755..100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,26 +1,25 @@ <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" - android:sharedUserId="android.uid.system" - android:versionCode="1" - android:versionName="1.0" package="com.gsoft.appinstall"> - <original-package android:name="com.gsoft.appinstall" /> + android:sharedUserId="android.uid.system" + android:versionCode="1" + android:versionName="1.0" package="com.droidlogic.appinstall"> + + <supports-screens android:largeScreens="true" android:smallScreens="true" android:resizeable="true" android:normalScreens="true"></supports-screens> + <uses-permission android:name="android.permission.WAKE_LOCK" /> + <uses-permission android:name="android.permission.INSTALL_PACKAGES"></uses-permission> + <uses-permission android:name="android.permission.DELETE_PACKAGES"></uses-permission> + <uses-permission android:name="android.permission.CLEAR_APP_USER_DATA"></uses-permission> + <uses-permission android:name="android.permission.CLEAR_APP_CACHE"></uses-permission> + <original-package android:name="com.droidlogic.appinstall" /> + <application android:icon="@mipmap/icon" android:label="@string/app_name" android:debuggable="false"> <activity android:name=".main" - android:configChanges="orientation|fontScale|screenSize|screenLayout" - android:label="@string/app_name"> + android:configChanges="orientation|fontScale|screenSize|screenLayout" + android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> - </application> - - -<supports-screens android:largeScreens="true" android:smallScreens="true" android:resizeable="true" android:normalScreens="true"></supports-screens> -<uses-permission android:name="android.permission.WAKE_LOCK" /> -<uses-permission android:name="android.permission.INSTALL_PACKAGES"></uses-permission> -<uses-permission android:name="android.permission.DELETE_PACKAGES"></uses-permission> -<uses-permission android:name="android.permission.CLEAR_APP_USER_DATA"></uses-permission> -<uses-permission android:name="android.permission.CLEAR_APP_CACHE"></uses-permission> -</manifest> +</manifest>
\ No newline at end of file diff --git a/res/drawable-hdpi/exit_focus.png b/res/drawable-hdpi/exit_focus.png index a60439a..a60439a 100755..100644 --- a/res/drawable-hdpi/exit_focus.png +++ b/res/drawable-hdpi/exit_focus.png diff --git a/res/drawable-hdpi/exit_state.xml b/res/drawable-hdpi/exit_state.xml index 6089501..6089501 100755..100644 --- a/res/drawable-hdpi/exit_state.xml +++ b/res/drawable-hdpi/exit_state.xml diff --git a/res/drawable-hdpi/exit_unfocus.png b/res/drawable-hdpi/exit_unfocus.png index 8a917b8..8a917b8 100755..100644 --- a/res/drawable-hdpi/exit_unfocus.png +++ b/res/drawable-hdpi/exit_unfocus.png diff --git a/res/drawable-hdpi/godir_focus.png b/res/drawable-hdpi/godir_focus.png index 9332581..9332581 100755..100644 --- a/res/drawable-hdpi/godir_focus.png +++ b/res/drawable-hdpi/godir_focus.png diff --git a/res/drawable-hdpi/godir_state.xml b/res/drawable-hdpi/godir_state.xml index b9d509a..b9d509a 100755..100644 --- a/res/drawable-hdpi/godir_state.xml +++ b/res/drawable-hdpi/godir_state.xml diff --git a/res/drawable-hdpi/godir_unfocus.png b/res/drawable-hdpi/godir_unfocus.png index e28753d..e28753d 100755..100644 --- a/res/drawable-hdpi/godir_unfocus.png +++ b/res/drawable-hdpi/godir_unfocus.png diff --git a/res/drawable-hdpi/installstate.xml b/res/drawable-hdpi/installstate.xml index 7421548..7421548 100755..100644 --- a/res/drawable-hdpi/installstate.xml +++ b/res/drawable-hdpi/installstate.xml diff --git a/res/drawable-hdpi/item_img_sel.png b/res/drawable-hdpi/item_img_sel.png index 3046343..3046343 100755..100644 --- a/res/drawable-hdpi/item_img_sel.png +++ b/res/drawable-hdpi/item_img_sel.png diff --git a/res/drawable-hdpi/item_img_unsel.png b/res/drawable-hdpi/item_img_unsel.png index 368e489..368e489 100755..100644 --- a/res/drawable-hdpi/item_img_unsel.png +++ b/res/drawable-hdpi/item_img_unsel.png diff --git a/res/drawable-mdpi/exit_focus.png b/res/drawable-mdpi/exit_focus.png index a60439a..a60439a 100755..100644 --- a/res/drawable-mdpi/exit_focus.png +++ b/res/drawable-mdpi/exit_focus.png diff --git a/res/drawable-mdpi/exit_state.xml b/res/drawable-mdpi/exit_state.xml index 6089501..6089501 100755..100644 --- a/res/drawable-mdpi/exit_state.xml +++ b/res/drawable-mdpi/exit_state.xml diff --git a/res/drawable-mdpi/exit_unfocus.png b/res/drawable-mdpi/exit_unfocus.png index 8a917b8..8a917b8 100755..100644 --- a/res/drawable-mdpi/exit_unfocus.png +++ b/res/drawable-mdpi/exit_unfocus.png diff --git a/res/drawable-mdpi/godir_focus.png b/res/drawable-mdpi/godir_focus.png index 9332581..9332581 100755..100644 --- a/res/drawable-mdpi/godir_focus.png +++ b/res/drawable-mdpi/godir_focus.png diff --git a/res/drawable-mdpi/godir_state.xml b/res/drawable-mdpi/godir_state.xml index b9d509a..b9d509a 100755..100644 --- a/res/drawable-mdpi/godir_state.xml +++ b/res/drawable-mdpi/godir_state.xml diff --git a/res/drawable-mdpi/godir_unfocus.png b/res/drawable-mdpi/godir_unfocus.png index e28753d..e28753d 100755..100644 --- a/res/drawable-mdpi/godir_unfocus.png +++ b/res/drawable-mdpi/godir_unfocus.png diff --git a/res/drawable-mdpi/installstate.xml b/res/drawable-mdpi/installstate.xml index c63574a..c63574a 100755..100644 --- a/res/drawable-mdpi/installstate.xml +++ b/res/drawable-mdpi/installstate.xml diff --git a/res/drawable-mdpi/item_img_sel.png b/res/drawable-mdpi/item_img_sel.png index 3046343..3046343 100755..100644 --- a/res/drawable-mdpi/item_img_sel.png +++ b/res/drawable-mdpi/item_img_sel.png diff --git a/res/drawable-mdpi/item_img_unsel.png b/res/drawable-mdpi/item_img_unsel.png index 368e489..368e489 100755..100644 --- a/res/drawable-mdpi/item_img_unsel.png +++ b/res/drawable-mdpi/item_img_unsel.png diff --git a/res/layout/listitem.xml b/res/layout/listitem.xml index 8c537b4..8c537b4 100755..100644 --- a/res/layout/listitem.xml +++ b/res/layout/listitem.xml diff --git a/res/layout/main.xml b/res/layout/main.xml index 2169a99..602258b 100755..100644 --- a/res/layout/main.xml +++ b/res/layout/main.xml @@ -4,53 +4,54 @@ android:layout_width="fill_parent" android:layout_height="fill_parent" android:weightSum="1"> - <LinearLayout - android:id="@+id/LinearLayout01" - android:layout_width="match_parent" - android:weightSum="1" - android:layout_height="60dp"> - <TextView - android:id="@+id/Dir" - android:background="@android:drawable/edit_text" - android:textColor="#000" - android:layout_width="wrap_content" - android:layout_weight="1" - android:editable="true" - android:singleLine="true" - android:inputType="textUri" - android:text="@string/defpath" - android:gravity="left|center_vertical" - android:layout_height="match_parent" - android:layout_gravity="left" - android:textSize="24sp"> - </TextView> - <ImageButton - android:background="@drawable/exit_state" - android:id="@+id/Exit" - android:layout_height="50dp" - android:layout_marginRight="5dp" - android:layout_width="50dp" - android:layout_gravity="right|center_vertical"> - </ImageButton> - </LinearLayout> - <FrameLayout - android:id="@+id/FrameLayout01" - android:layout_width="match_parent" - android:layout_height="match_parent"> - <com.gsoft.appinstall.CheckAbleList - android:layout_width="match_parent" - android:focusable="true" - android:focusableInTouchMode="true" - android:id="@+id/APKList" - android:layout_weight="1" - android:layout_height="match_parent"> - </com.gsoft.appinstall.CheckAbleList> - <TextView - android:layout_height="match_parent" - android:layout_width="match_parent" - android:gravity="center" - android:id="@+id/ScanInfo" - android:visibility="invisible"> - </TextView> - </FrameLayout> -</LinearLayout> + + <LinearLayout + android:id="@+id/LinearLayout01" + android:layout_width="match_parent" + android:weightSum="1" + android:layout_height="60dp"> + <TextView + android:id="@+id/Dir" + android:background="@android:drawable/edit_text" + android:textColor="#000" + android:layout_width="wrap_content" + android:layout_weight="1" + android:editable="true" + android:singleLine="true" + android:inputType="textUri" + android:text="@string/defpath" + android:gravity="left|center_vertical" + android:layout_height="match_parent" + android:layout_gravity="left" + android:textSize="24sp"> + </TextView> + <ImageButton + android:background="@drawable/exit_state" + android:id="@+id/Exit" + android:layout_height="50dp" + android:layout_marginRight="5dp" + android:layout_width="50dp" + android:layout_gravity="right|center_vertical"> + </ImageButton> + </LinearLayout> + <FrameLayout + android:id="@+id/FrameLayout01" + android:layout_width="match_parent" + android:layout_height="match_parent"> + <com.droidlogic.appinstall.CheckAbleList + android:layout_width="match_parent" + android:focusable="true" + android:focusableInTouchMode="true" + android:id="@+id/APKList" + android:layout_weight="1" + android:layout_height="match_parent"> + </com.droidlogic.appinstall.CheckAbleList> + <TextView + android:layout_height="match_parent" + android:layout_width="match_parent" + android:gravity="center" + android:id="@+id/ScanInfo" + android:visibility="invisible"> + </TextView> + </FrameLayout> +</LinearLayout>
\ No newline at end of file diff --git a/res/mipmap-hdpi/icon.png b/res/mipmap-hdpi/icon.png index a47ccdb..a47ccdb 100755..100644 --- a/res/mipmap-hdpi/icon.png +++ b/res/mipmap-hdpi/icon.png diff --git a/res/mipmap-mdpi/icon.png b/res/mipmap-mdpi/icon.png index 439c901..439c901 100755..100644 --- a/res/mipmap-mdpi/icon.png +++ b/res/mipmap-mdpi/icon.png diff --git a/res/mipmap-xhdpi/icon.png b/res/mipmap-xhdpi/icon.png index 380bd85..380bd85 100755..100644 --- a/res/mipmap-xhdpi/icon.png +++ b/res/mipmap-xhdpi/icon.png diff --git a/res/mipmap-xxhdpi/icon.png b/res/mipmap-xxhdpi/icon.png index 784e782..784e782 100755..100644 --- a/res/mipmap-xxhdpi/icon.png +++ b/res/mipmap-xxhdpi/icon.png diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml index c1972ef..c1972ef 100755..100644 --- a/res/values-zh-rCN/strings.xml +++ b/res/values-zh-rCN/strings.xml diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml index 6661a21..6661a21 100755..100644 --- a/res/values-zh-rTW/strings.xml +++ b/res/values-zh-rTW/strings.xml diff --git a/res/values/strings.xml b/res/values/strings.xml index 975ed4a..975ed4a 100755..100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml diff --git a/src/com/droidlogic/appinstall/CheckAbleList.java b/src/com/droidlogic/appinstall/CheckAbleList.java new file mode 100644 index 0000000..e6f4a38 --- a/dev/null +++ b/src/com/droidlogic/appinstall/CheckAbleList.java @@ -0,0 +1,63 @@ +package com.droidlogic.appinstall; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.SoundEffectConstants; +import android.view.View; +import android.widget.*; +import android.view.KeyEvent; +import android.util.Log; + +public class CheckAbleList extends ListView { + private static final String TAG = "CheckAbleList"; + protected OnItemClickListener m_localClickListener = null; + public CheckAbleList (Context context) { + super (context); + // TODO Auto-generated constructor stub + } + public CheckAbleList (Context context, AttributeSet attrs) { + super (context, attrs); + } + + public CheckAbleList (Context context, AttributeSet attrs, int defStyle) { + super (context, attrs, defStyle); + } + + public void setOnItemClickListener (OnItemClickListener listener) { + super.setOnItemClickListener (listener); + m_localClickListener = listener; + } + + public boolean performItemClick (View view, int position, long id) { + //i don't want to set the item checked when i click a item + if (m_localClickListener != null) { + playSoundEffect (SoundEffectConstants.CLICK); + m_localClickListener.onItemClick (this, view, position, id); + return true; + } + return false; + } + + public void setAllItemChecked (boolean value) { + int i = 0; + for (; i < this.getCount(); i++) { + setItemChecked (i, value); + getAdapter().getView (i, getChildAt (i), this); //for redraw + } + } + + public boolean onKeyDown (int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) { + int PosInList = 0; + PosInList = this.getSelectedItemPosition(); + if (!isItemChecked (PosInList)) { + setItemChecked (PosInList, true); + } + else { + setItemChecked (PosInList, false); + } + Log.e (TAG, "--------------------------------------------RC is checked"); + } + return super.onKeyDown (keyCode, event); + } +} diff --git a/src/com/droidlogic/appinstall/PackageAdapter.java b/src/com/droidlogic/appinstall/PackageAdapter.java new file mode 100644 index 0000000..c87bd2d --- a/dev/null +++ b/src/com/droidlogic/appinstall/PackageAdapter.java @@ -0,0 +1,220 @@ +package com.droidlogic.appinstall; + +import java.util.ArrayList; +import android.content.res.AssetManager; +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.ImageView; +import android.widget.ListView; +import android.widget.TextView; +import android.os.UserHandle; + +class APKInfo extends Object { + static protected PackageManager pkgmgr = null; + + APKInfo (Context pcontext, String apkpath) { + pkgmgr = pcontext.getPackageManager(); + PackageInfo pPkgInfo = pkgmgr.getPackageArchiveInfo (apkpath, PackageManager.GET_ACTIVITIES); + if (pPkgInfo != null) { + //get package's name in system + String[] curpkgnames = pkgmgr.canonicalToCurrentPackageNames (new String[] {pPkgInfo.packageName}); + if ( (curpkgnames != null) && (curpkgnames.length > 0) && (curpkgnames[0] != null)) { + pCurPkgName = curpkgnames[0]; + } + else { + pCurPkgName = pPkgInfo.packageName; + } + Resources pPkgRes = null; + AssetManager assmgr = new AssetManager(); + if (0 != assmgr.addAssetPath (apkpath)) { + pPkgRes = new Resources (assmgr, pcontext.getResources().getDisplayMetrics(), pcontext.getResources().getConfiguration()); + } + if (pPkgRes != null) { + getApplicationName_Internal (pPkgRes, pPkgInfo); + getApkIcon_Internal (pPkgRes, pPkgInfo); + filepath = apkpath; + } + assmgr.close(); + } + } + + public boolean beValid() { + if (filepath == null) { + return false; + } + else { + return true; + } + } + + public String filepath; + public String pCurPkgName = null; + public CharSequence pAppName = null; + public Drawable pAppIcon = null; + public boolean bIsinstalled = false; + + public boolean checkInstalled() { + ApplicationInfo appinfo = null; + try { + appinfo = pkgmgr.getApplicationInfo (pCurPkgName, PackageManager.GET_META_DATA); + } + catch (NameNotFoundException e) { + appinfo = null; + } + if (appinfo == null) { + bIsinstalled = false; + } + else { + bIsinstalled = true; + } + return bIsinstalled; + } + public boolean isInstalled() { + return bIsinstalled; + } + public CharSequence getApplicationName() { + return pAppName; + } + public Drawable getApkIcon() { + return pAppIcon; + } + + public CharSequence getApplicationName_Internal (Resources PkgRes, PackageInfo PkgInfo) { + if (pAppName == null) { + if (PkgRes != null) { + try { + pAppName = PkgRes.getText (PkgInfo.applicationInfo.labelRes); + } + catch (Resources.NotFoundException resnotfound) { + pAppName = pCurPkgName; + } + } + else { + pAppName = pCurPkgName; + } + } + return pAppName; + } + + public Drawable getApkIcon_Internal (Resources PkgRes, PackageInfo PkgInfo) { + if (pAppIcon == null) { + if (PkgRes != null) { + try { + pAppIcon = PkgRes.getDrawable (PkgInfo.applicationInfo.icon); + } + catch (Resources.NotFoundException resnotfound) { + pAppIcon = pkgmgr.getApplicationIcon (PkgInfo.applicationInfo); + } + } + else { + pAppIcon = pkgmgr.getApplicationIcon (PkgInfo.applicationInfo); + } + } + return pAppIcon; + } + +} + + +public class PackageAdapter extends BaseAdapter { + + protected int m_Layout_APKListItem; + protected int m_TextView_AppName; + protected int m_TextView_FileName; + protected int m_ImgView_APPIcon; + protected int m_CheckBox_InstallState; + protected int m_CheckBox_SelState; + private LayoutInflater mInflater; + protected ArrayList<APKInfo> m_apklist = null; + protected ListView m_list = null; + + PackageAdapter (Context context, int Layout_Id, int text_app_id, int text_filename_id, int checkbox_id, int img_appicon_id, int checkbox_sel_id, ArrayList<APKInfo> apklist, ListView list) { + mInflater = LayoutInflater.from (context); + m_Layout_APKListItem = Layout_Id; + m_TextView_FileName = text_filename_id; + m_TextView_AppName = text_app_id; + m_CheckBox_InstallState = checkbox_id; + m_ImgView_APPIcon = img_appicon_id; + m_CheckBox_SelState = checkbox_sel_id; + m_apklist = apklist; + m_list = list; + } + + public int getCount() { + if (m_apklist != null) { + return m_apklist.size(); + } + else { + return 0; + } + } + + public Object getItem (int position) { + if (m_apklist != null) { + return m_apklist.get (position); + } + else { + return null; + } + } + + public long getItemId (int position) { + return position; + } + + + class SelStateListener implements CompoundButton.OnCheckedChangeListener { + int PosInList = 0; + SelStateListener (int pos) { + PosInList = pos; + } + + public void onCheckedChanged (CompoundButton buttonView, boolean isChecked) { + if (m_list.isItemChecked (PosInList) != isChecked) { + m_list.setItemChecked (PosInList, isChecked); + } + } + } + + public View getView (int position, View convertView, ViewGroup parent) { + View layoutview = null; + if (convertView == null) { + layoutview = mInflater.inflate (m_Layout_APKListItem, parent, false); + } + else { + layoutview = convertView; + } + TextView FileName = (TextView) layoutview.findViewById (m_TextView_FileName); + TextView AppName = (TextView) layoutview.findViewById (m_TextView_AppName); + CheckBox InstallState = (CheckBox) layoutview.findViewById (m_CheckBox_InstallState); + ImageView Appicon = (ImageView) layoutview.findViewById (m_ImgView_APPIcon); + CheckBox SelState = (CheckBox) layoutview.findViewById (m_CheckBox_SelState); + SelState.setOnCheckedChangeListener (new SelStateListener (position)); + APKInfo pinfo = (APKInfo) getItem (position); + FileName.setText (pinfo.filepath); + AppName.setText (pinfo.getApplicationName()); + InstallState.setChecked (pinfo.checkInstalled()); + Appicon.setImageDrawable (pinfo.getApkIcon()); + SelState.setChecked (m_list.isItemChecked (position)); + return layoutview; + } + + public boolean hasStableIds() { + return true; + } + +} diff --git a/src/com/droidlogic/appinstall/main.java b/src/com/droidlogic/appinstall/main.java new file mode 100644 index 0000000..96dd4a3 --- a/dev/null +++ b/src/com/droidlogic/appinstall/main.java @@ -0,0 +1,964 @@ +package com.droidlogic.appinstall; + + +import java.io.File; +import java.io.FileFilter; +import java.util.ArrayList; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.Dialog; +import android.app.ProgressDialog; +import android.content.ComponentName; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.widget.AdapterView; +import android.widget.AdapterView.OnItemSelectedListener; +import android.widget.Button; +import android.widget.EditText; +import android.widget.ImageButton; +import android.widget.ListView; +import android.widget.TextView.BufferType; +import android.widget.TextView; +import android.widget.Toast; +import android.content.pm.IPackageInstallObserver; +import android.content.pm.IPackageDeleteObserver; +import android.os.PowerManager; +import android.os.HandlerThread; +import android.provider.Settings; +import android.content.Context; +import android.view.KeyEvent; +import android.content.res.Configuration; +import android.content.DialogInterface; +import java.lang.String; +import android.os.StatFs; +import android.os.Environment; +import android.content.BroadcastReceiver; +import android.content.IntentFilter; + + + +public class main extends Activity { + private String TAG = "Appinstall"; + private String mVersion = "V1.1.3"; + private String mReleaseDate = "2012.04.01"; + + private static final String ROOT_PATH = "/storage"; + private static final String SHEILD_EXT_STOR = Environment.getExternalStorageDirectory().getPath() + "/external_storage"; //"/storage/sdcard0/external_storage"; + private static final String NAND_PATH = Environment.getExternalStorageDirectory().getPath();//"/storage/sdcard0"; + private static final String SD_PATH = "/storage/external_storage/sdcard1"; + private static final String USB_PATH = "/storage/external_storage"; + + //UI INFO + protected String mScanRoot = null; + protected CheckAbleList m_list = null; + protected TextView m_info = null; + protected PackageAdapter pkgadapter = null; + protected TextView m_DirEdit = null; + protected OperationDialog mScanDiag = null; + protected OperationDialog mHandleDiag = null; + + //DATA + protected ArrayList<APKInfo> mApkList = new ArrayList<APKInfo>(); + protected boolean m_configchanged = false; + public final static int END_OPERATION = 0; + public final static int NEW_APK = 1; + public final static int HANDLE_PKG_NEXT = 2; + public final static int HANDLE_PKG_FAIL = 3; + private static final int DLG_UNKNOWN_APPS = 1; + private PowerManager.WakeLock mScreenLock = null; + protected ScanOperation m_scanop = new ScanOperation(); + protected InstallOperation m_installop = new InstallOperation(); + protected String mDevs[] = null; + + //the status of app + private static int SCAN_APKS = 0; + private static int VIEW_APKS = 1; + private static int INSTALL_APKS = 2; + protected int mStatus = -1; + + /** Called when the activity is first created. */ + @Override + public void onCreate (Bundle savedInstanceState) { + super.onCreate (savedInstanceState); + setContentView (R.layout.main); + //keep system awake + mScreenLock = ( (PowerManager) this.getSystemService (Context.POWER_SERVICE)).newWakeLock (PowerManager.SCREEN_BRIGHT_WAKE_LOCK, TAG); + m_info = (TextView) findViewById (R.id.ScanInfo); + m_info.setText (R.string.no_apk_found); + m_info.setVisibility (android.view.View.INVISIBLE); + //init the listview + m_list = (CheckAbleList) findViewById (R.id.APKList); + m_list.setChoiceMode (ListView.CHOICE_MODE_MULTIPLE); + //create dialog process dialog + mScanDiag = new OperationDialog (this, m_scanop, getResources().getString (R.string.scanning_init)); + mHandleDiag = new OperationDialog (this, m_installop, getResources().getString (R.string.handling_selected_package_init)); + pkgadapter = new PackageAdapter (this, R.layout.listitem, R.id.appname, R.id.apk_filepath, R.id.InstallState, R.id.APKIcon, R.id.Select, mApkList, m_list); + m_list.setOnItemClickListener (new AdapterView.OnItemClickListener() { + public void onItemClick (AdapterView<?> parent, View view, int position, long id) { + APKInfo apkinfo = mApkList.get (position); + /*if(apkinfo.isInstalled() == true) + uninstall_apk(apkinfo.pCurPkgName); + else*/ + install_apk (apkinfo.filepath); + } + }); + //change dir button + m_DirEdit = (TextView) findViewById (R.id.Dir); + m_DirEdit.setText (" ", TextView.BufferType.NORMAL); + m_DirEdit.setOnClickListener (new View.OnClickListener() { + public void onClick (View v) { + showChooseDev(); + } + }); + //exit button + ImageButton hexit = (ImageButton) findViewById (R.id.Exit); + hexit.setOnClickListener (new View.OnClickListener() { + public void onClick (View v) { + main.this.finish(); + } + } + ); + hexit.requestFocus(); + showChooseDev(); + } + + private BroadcastReceiver mMountReceiver = new BroadcastReceiver() { + @Override + public void onReceive (Context context, Intent intent) { + String action = intent.getAction(); + String data = intent.getDataString(); + if (action == null) { + return; + } + if (mScanRoot == null) { + return; + } + if (action.equals (Intent.ACTION_MEDIA_UNMOUNTED)) { + int index = data.indexOf (ROOT_PATH); + if (index >= 0) { + String path = data.substring (index); + if (path.equals (mScanRoot)) { + m_list.setAdapter (null); + mApkList.clear(); + } + } + else { //exception handle + startScanOp(); + } + } + else if (action.equals (Intent.ACTION_MEDIA_MOUNTED)) { + int index = data.indexOf (ROOT_PATH); + if (index >= 0) { + String path = data.substring (index); + if (path.equals (mScanRoot)) { + startScanOp(); + } + } + else { //exception handle + startScanOp(); + } + } + } + }; + + public void onResume() { + Log.d (TAG, "onResume"); + pkgadapter.notifyDataSetChanged(); + m_scanop.setHandler (mainhandler); + m_installop.setHandler (mainhandler); + IntentFilter intentFilter = new IntentFilter (Intent.ACTION_MEDIA_MOUNTED); + intentFilter.addAction (Intent.ACTION_MEDIA_EJECT); + intentFilter.addAction (Intent.ACTION_MEDIA_UNMOUNTED); + intentFilter.addDataScheme ("file"); + registerReceiver (mMountReceiver, intentFilter); + super.onResume(); + } + + public void onPause() { + //disable the operation message + m_scanop.setHandler (null); + m_installop.setHandler (null); + mainhandler.removeMessages (END_OPERATION); + mainhandler.removeMessages (NEW_APK); + mainhandler.removeMessages (HANDLE_PKG_NEXT); + //diable dialog + if (mScanDiag != null) { + mScanDiag.dismiss(); + } + if (mHandleDiag != null) { + mHandleDiag.dismiss(); + } + //unregisterReceiver(mMountReceiver); + //release the wakelock + super.onPause(); + } + public void onStop() { + if (mMountReceiver != null) { + unregisterReceiver (mMountReceiver); + mMountReceiver = null; + } + super.onStop(); + } + protected void onDestroy() { + if (m_configchanged == false) { + m_scanop.stop(); + m_installop.stop(); + } + Log.d (TAG, "onDestroy"); + KeepSystemAwake (false); + super.onDestroy(); + } + + protected void KeepSystemAwake (boolean bkeep) { + if (bkeep == true) { + if (mScreenLock.isHeld() == false) { + mScreenLock.acquire(); + } + } + else { + if (mScreenLock.isHeld() == true) { + mScreenLock.release(); + } + } + } + + public Handler mainhandler = new Handler() { + public void handleMessage (Message msg) { + // TODO Auto-generated method stub + switch (msg.what) { + case END_OPERATION: + if (msg.arg1 != mStatus) { + Log.e (TAG, "mStatus " + String.valueOf (mStatus) + "!= endoperation " + String.valueOf (msg.arg1)); + } + if (mStatus == SCAN_APKS) { + if (mScanDiag != null) { + mScanDiag.dismiss(); + } + if (mApkList.size() > 0) { + m_list.setAdapter (pkgadapter); + m_list.setVisibility (android.view.View.VISIBLE); + m_info.setVisibility (android.view.View.INVISIBLE); + } + else { + m_list.setVisibility (android.view.View.INVISIBLE); + m_info.setVisibility (android.view.View.VISIBLE); + } + } + else { + Log.d (TAG, "END_HANDLE_PKG"); + if (mHandleDiag != null) { + mHandleDiag.dismiss(); + } + pkgadapter.notifyDataSetChanged(); + } + mStatus = VIEW_APKS; + KeepSystemAwake (false); + break; + case NEW_APK: + showScanDiag (msg.arg1, msg.arg2); + break; + case HANDLE_PKG_NEXT: + Log.d (TAG, "HANDLE_PKG_NEXT"); + String hanlemsg = msg.getData().getString ("showstr"); + showHandleDiag (hanlemsg, (int) msg.arg1 + 1, msg.arg2); + break; + case HANDLE_PKG_FAIL: + Log.d (TAG, "HANDLE_PKG_FAIL"); + String failemsg = msg.getData().getString ("showstr"); + Toast.makeText (main.this, failemsg, Toast.LENGTH_SHORT).show(); + break; + default: + break; + } + } + }; + + //option menu + protected final int MENU_INSTALL = 0; + protected final int MENU_UNINSTALL = 1; + protected final int MENU_SELECT_ALL = 2; + protected final int MENU_UNSELECT_ALL = 3; + protected final int MENU_FRESH = 4; + protected final int MENU_ABOUT = 5; + public boolean onCreateOptionsMenu (Menu menu) { + menu.add (0, MENU_INSTALL, 0, R.string.install); + menu.add (0, MENU_UNINSTALL, 0, R.string.uninstall); + menu.add (0, MENU_SELECT_ALL, 0, R.string.selectall); + menu.add (0, MENU_UNSELECT_ALL, 0, R.string.unselect_all); + menu.add (0, MENU_FRESH, 0, R.string.refresh); + menu.add (0, MENU_ABOUT, 0, R.string.about); + return true; + } + + private final int opInstall = 0; + private final int opUninstall = 1; + private int menuSelect = opInstall; + + public boolean onOptionsItemSelected (MenuItem item) { + switch (item.getItemId()) { + case MENU_INSTALL: + if (!isInstallingUnknownAppsAllowed()) { + //ask user to enable setting first + showDialogInner (DLG_UNKNOWN_APPS); + return true; + } + menuSelect = opInstall; + startHandleOp(); + return true; + case MENU_UNINSTALL: + menuSelect = opUninstall; + startHandleOp(); + return true; + case MENU_SELECT_ALL: + m_list.setAllItemChecked (true); + return true; + case MENU_UNSELECT_ALL: + m_list.setAllItemChecked (false); + return true; + case MENU_FRESH: + m_list.setAdapter (null); + startScanOp(); + return true; + case MENU_ABOUT: + String aboutinfo = getResources().getString (R.string.about_appInstaller); + aboutinfo += getResources().getString (R.string.about_version) + mVersion + " "; + aboutinfo += getResources().getString (R.string.about_date) + mReleaseDate + " "; + AlertDialog.Builder builder = new AlertDialog.Builder (this); + builder.setMessage (aboutinfo); + AlertDialog about = builder.create(); + about.show(); + return true; + } + return false; + } + + public void onConfigurationChanged (Configuration newConfig) { + super.onConfigurationChanged (newConfig); + } + + //user functions + public void showChooseDev() { + int dev_usb_count = 0; + int dev_cd_count = 0; + int devCnt = 0; + int selid = 0; + String internal = getString (R.string.memory_device_str); + String sdcard = getString (R.string.sdcard_device_str); + String usb = getString (R.string.usb_device_str); + String cdrom = getString (R.string.cdrom_device_str); + String sdcardExt = getString (R.string.ext_sdcard_device_str); + String DeviceArray[] = {internal, sdcard, usb, cdrom, sdcardExt}; + //init dev count + File pfile = new File (USB_PATH); + File[] files = pfile.listFiles(); + mDevs = new String[files.length + 1]; //+1 indicate NAND_PATH + File dir = new File (NAND_PATH); + if (dir.exists() && dir.isDirectory()) { + mDevs[devCnt] = dir.toString(); + } + dir = new File (SD_PATH); + if (dir.exists() && dir.isDirectory()) { + devCnt++; + mDevs[devCnt] = dir.toString(); + } + dir = new File (USB_PATH); + if (dir.exists() && dir.isDirectory()) { + if (dir.listFiles() != null) { + for (File file : dir.listFiles()) { + if (file.isDirectory()) { + String devname = null; + String path = file.getAbsolutePath(); + if ( (path.startsWith (USB_PATH + "/sd") || path.startsWith (USB_PATH + "/sr")) && !path.equals (SD_PATH)) { + devCnt++; + mDevs[devCnt] = file.toString(); + } + } + } + } + } + dir = new File (ROOT_PATH); + if (dir.exists() && dir.isDirectory()) { + if (dir.listFiles() != null) { + for (File file : dir.listFiles()) { + if (file.isDirectory()) { + String devname = null; + String path = file.getAbsolutePath(); + if (path.startsWith (ROOT_PATH + "/udisk")) { + String stateStr = Environment.getStorageState (new File (path)); + if (stateStr.equals (Environment.MEDIA_MOUNTED)) { + devCnt++; + mDevs[devCnt] = file.toString(); + } + } + } + } + } + } + int len = devCnt + 1; + mDevStrs = new String[len]; + for (int idx = 0; idx < len; idx++) { + if (mDevs[idx] == null) { + Log.e (TAG, "showChooseDev err, mDevs[" + idx + "]==null."); + continue; + } + if (mDevs[idx].equals (NAND_PATH)) { + mDevStrs[idx] = DeviceArray[1]; + } + else if ( (mDevs[idx].startsWith (USB_PATH + "/sd") || mDevs[idx].startsWith (ROOT_PATH + "/udisk")) && !mDevs[idx].equals (SD_PATH)) { + dev_usb_count++; + char data = (char) ('A' + dev_usb_count - 1); + mDevStrs[idx] = DeviceArray[2] + "(" + data + ":)" ; + } + else if (mDevs[idx].startsWith (USB_PATH + "/sr") && !mDevs[idx].equals (SD_PATH)) { + dev_cd_count++; + char data = (char) ('A' + dev_cd_count - 1); + mDevStrs[idx] = DeviceArray[3] + "(" + data + ":)" ; + } + else if (mDevs[idx].equals (SD_PATH)) { + mDevStrs[idx] = DeviceArray[4]; + } + else { + mDevStrs[idx] = mDevs[idx]; + } + if (mDevs[idx].equals (mScanRoot)) { + selid = idx; + } + } + //show dialog to choose dialog + new AlertDialog.Builder (main.this) + .setTitle (R.string.alertdialog_title) + .setSingleChoiceItems (mDevStrs, selid, new DialogInterface.OnClickListener() { + public void onClick (DialogInterface dialog, int which) { + dialog.dismiss(); + //updatePathName(mDevs[which]); + m_DirEdit.setText (mDevStrs[which]); + String devpath = mDevs[which] == null ? null : mDevs[which].toString(); + if (devpath == null) { + Toast.makeText (main.this, "invalid dir path", Toast.LENGTH_SHORT).show(); + return; + } + File pfile = new File (devpath); + if (pfile != null && pfile.isDirectory() == true) { + //if((mScanRoot == null) || (mScanRoot.compareTo(devpath) != 0)) + { + mScanRoot = devpath; + startScanOp(); + } + //else + //Toast.makeText(main.this, "same dir path", Toast.LENGTH_SHORT).show(); + } + else { + Toast.makeText (main.this, "invalid dir path", Toast.LENGTH_SHORT).show(); + } + } + }) + .setOnCancelListener (new DialogInterface.OnCancelListener() { + public void onCancel (DialogInterface dialog) { + if (mScanRoot == null) { + main.this.finish(); + } + } + }) + .show(); + } + + protected String mDevStrs[] = null; + private void updatePathName (String dev) { + String internal = getString (R.string.memory_device_str); + String sdcard = getString (R.string.sdcard_device_str); + String usb = getString (R.string.usb_device_str); + String cdrom = getString (R.string.cdrom_device_str); + String sdcardExt = getString (R.string.ext_sdcard_device_str); + String str = ""; + if (dev == null) { + Log.e (TAG, "updatePathName error, dev=null"); + return; + } + if (dev.equals (NAND_PATH)) { + str = sdcard; + } + else if ( (dev.startsWith (USB_PATH + "/sd") || dev.startsWith (ROOT_PATH + "/udisk")) && !dev.equals (SD_PATH)) { + str = usb; + } + else if (dev.startsWith (USB_PATH + "/sr") && !dev.equals (SD_PATH)) { + str = cdrom; + } + else if (dev.equals (SD_PATH)) { + str = sdcardExt; + } + else { + str = dev; + } + m_DirEdit.setText (str); + } + + //=================================================================== + //functions for installing and uninstalling + public void install_apk (String apk_filepath) { + Intent installintent = new Intent(); + installintent.setComponent (new ComponentName ("com.android.packageinstaller", "com.android.packageinstaller.PackageInstallerActivity")); + installintent.setAction (Intent.ACTION_VIEW); + installintent.setData (Uri.fromFile (new File (apk_filepath))); + startActivity (installintent); + } + + public void uninstall_apk (String apk_pkgname) { + Intent uninstallintent = new Intent(); + uninstallintent.setComponent (new ComponentName ("com.android.packageinstaller", "com.android.packageinstaller.UninstallerActivity")); + uninstallintent.setAction (Intent.ACTION_VIEW); + uninstallintent.setData (Uri.fromParts ("package", apk_pkgname, null)); + startActivity (uninstallintent); + } + + //=================================================================== + //base class for operations thread + class OperationThread { + protected Handler m_handler = null; + protected boolean m_bstop = false; + protected boolean m_bOpEnd = false; + protected Object m_syncobj = new Object(); + protected int m_iOp = 0; + public void start() { //overide it to new and start a thread + m_bstop = false; + m_bOpEnd = false; + } + + public void stop() { + synchronized (m_syncobj) { + m_bstop = true; + } + } + + public boolean isOpEnd() { + synchronized (m_syncobj) { + return m_bOpEnd; + } + } + + public void setHandler (Handler phandler) { + synchronized (m_syncobj) { + m_handler = phandler; + } + } + + public void sendEndMsg() { + if (m_handler != null) { + Message endmsg = Message.obtain(); + endmsg.what = END_OPERATION; + endmsg.arg1 = m_iOp; + m_handler.sendMessage (endmsg); + } + } + }; + + class OperationDialog extends ProgressDialog { + public boolean m_bOpStop; + public OperationThread m_pOp; + public CharSequence m_sInitMsg; + public OperationDialog (Context context, OperationThread operation, CharSequence initMessage) { + super (context); + m_bOpStop = false; + m_pOp = operation; + setCancelable (false); + m_sInitMsg = initMessage; + } + + public void start() { + //show with empty message + m_bOpStop = false; + setMessage (m_sInitMsg); + this.show();//first show() is invert-action to dismiss() + this.show();//second show() is invert-action to hide() + } + + public void setMessage (CharSequence message) { + if (m_bOpStop == true) { + return; + } + else { + super.setMessage (message); + } + } + + public void dismiss() { + hide();//first to hide() it and in start to show() it , this is let the animation in dialog to restart + super.dismiss(); + } + + /* + public boolean onTouchEvent (MotionEvent event) + { + m_pOp.stop(); + setMessage("stopping...\n"); + m_bOpStop = true; + return true; + } + */ + public boolean onKeyDown (int keyCode, KeyEvent event) { + if (keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_POWER) { + m_pOp.stop(); + setMessage ("stopping...\n"); + m_bOpStop = true; + } + return super.onKeyDown (keyCode, event); + } + + }; + + // Check free space for installation + private static long checkFreeSpace (String path) { + long nSDFreeSize = 0; + if (path != null) { + StatFs statfs = new StatFs (path); + long nBlocSize = statfs.getBlockSize(); + long nAvailaBlock = statfs.getAvailableBlocks(); + nSDFreeSize = nAvailaBlock * nBlocSize; + } + return (nSDFreeSize / (1024 * 1024)); + } + + //=================================================================== + //functions for installing and uninstalling in slient mode + class InstallOperation extends OperationThread { + public long [] m_checkeditems = null; + protected installthread m_thread; + private long m_handleitem; + private Handler m_selfhandler; + protected ApkHandleTask m_apkhandltsk = new ApkHandleTask(); + InstallOperation() { + super(); + m_iOp = INSTALL_APKS; + } + public void start() { //overide it to new and start a thread + super.start(); + m_handleitem = 0; + m_thread = new installthread ("multi-apk-handler"); + m_thread.start(); + } + + class installthread extends HandlerThread { + installthread (String name) { + super (name); + } + protected void onLooperPrepared() { + synchronized (m_syncobj) { + m_selfhandler = new Handler(); + m_selfhandler.post (m_apkhandltsk); + m_handleitem = 0; + } + } + } + + class ApkHandleTask implements Runnable { + class PackageInstallObserver extends IPackageInstallObserver.Stub { + String apkpath = null; + public void packageInstalled (String packageName, int returnCode) { + Log.d (TAG, "packageInstalled " + String.valueOf (returnCode)); + synchronized (m_syncobj) { + if (returnCode != 1) { //fail + Message endmsg = Message.obtain(); + endmsg.what = HANDLE_PKG_FAIL; + Bundle data = new Bundle(); + data.putString ("showstr", "Install " + apkpath + " fail!"); + endmsg.setData (data); + m_handler.sendMessage (endmsg); + } + m_handleitem++; + m_selfhandler.post (m_apkhandltsk); + } + } + } + + class PackageDeleteObserver extends IPackageDeleteObserver.Stub { + String pkgpath = null; + public void packageDeleted (String packageName, int returnCode) { + Log.d (TAG, "packageDeleted " + String.valueOf (returnCode)); + synchronized (m_syncobj) { + if (returnCode != PackageManager.DELETE_SUCCEEDED) { + Message endmsg = Message.obtain(); + endmsg.what = HANDLE_PKG_FAIL; + Bundle data = new Bundle(); + data.putString ("showstr", "Uninstall " + pkgpath + " fail!"); + endmsg.setData (data); + m_handler.sendMessage (endmsg); + } + m_handleitem++; + m_selfhandler.post (m_apkhandltsk); + } + } + } + public void install_apk_slient (String apk_filepath) { + PackageManager pm = getPackageManager(); + PackageInstallObserver observer = new PackageInstallObserver(); + observer.apkpath = apk_filepath; + pm.installPackage (Uri.fromFile (new File (apk_filepath)), observer, pm.INSTALL_REPLACE_EXISTING, null); + } + public void uninstall_apk_slient (String apk_pkgname) { + PackageDeleteObserver observer = new PackageDeleteObserver(); + observer.pkgpath = apk_pkgname; + PackageManager pm = getPackageManager(); + pm.deletePackage (apk_pkgname, observer, 0); + } + public void run() { + synchronized (m_syncobj) { + if ( (m_bstop == true) || m_handleitem == m_checkeditems.length) { + sendEndMsg(); + m_bOpEnd = true; + m_thread.quit(); + return ; + } + } + String hanlemsg = null; + int actionid; + String actionpara = null; + APKInfo pinfo = mApkList.get ( (int) m_checkeditems[ (int) m_handleitem]); + if (pinfo != null) { + //if(pinfo.isInstalled()==false) + if (menuSelect == opInstall) { + actionid = 0; + actionpara = pinfo.filepath; + hanlemsg = "Installing \""; + } + else { + actionid = 1; + actionpara = pinfo.pCurPkgName; + hanlemsg = "Uninstalling \""; + } + hanlemsg += pinfo.pAppName + "\"\n"; + synchronized (m_syncobj) { + if (m_handler != null) { + Message endmsg = Message.obtain(); + endmsg.what = HANDLE_PKG_NEXT; + endmsg.arg1 = (int) m_handleitem; + endmsg.arg2 = m_checkeditems.length; + Bundle data = new Bundle(); + data.putString ("showstr", hanlemsg); + endmsg.setData (data); + m_handler.sendMessageDelayed (endmsg, 2000); //add a delay, for systeme need time to release cache. + } + } + if (actionid == 0) { + boolean hasSpace = checkFreeSpace ("/data/app") > 50; + if (!hasSpace) { + Log.w (TAG, "no enough space for installation, force stop!"); + Message endmsg = Message.obtain(); + endmsg.what = HANDLE_PKG_FAIL; + Bundle data = new Bundle(); + data.putString ("showstr", getResources().getString (R.string.no_space)); + endmsg.setData (data); + m_handler.sendMessage (endmsg); + sendEndMsg(); + m_bOpEnd = true; + m_thread.quit(); + return ; + } + install_apk_slient (actionpara); + } + else { + uninstall_apk_slient (actionpara); + } + Log.d (TAG, "install a singel apk end"); + } + else { + Log.e (TAG, "got a null apkinfo, this is strange!"); + } + } + } + } + + public void startHandleOp() { + long [] checkeditems = m_list.getCheckedItemIds(); + if (checkeditems.length == 0) { + Toast.makeText (main.this, R.string.no_select_apks , Toast.LENGTH_SHORT).show(); + } + else { + KeepSystemAwake (true); + mStatus = INSTALL_APKS; + m_installop.m_checkeditems = checkeditems.clone(); + mHandleDiag.start(); + m_installop.setHandler (mainhandler); + m_installop.start(); + } + } + + protected void showHandleDiag (String handlemsg, int curpkg, int totalpkg) { + String msg = getResources().getString (R.string.handling_selected_package); + msg += String.valueOf (curpkg) + "/" + String.valueOf (totalpkg) + "\n"; + msg += handlemsg; + mHandleDiag.setMessage (msg); + // mHandleDiag.show(); + } + + //=================================================================== + //functions for scanning apks + protected void startScanOp() { + KeepSystemAwake (true); + mStatus = SCAN_APKS; + mScanDiag.start(); + showScanDiag (0, 0); + m_scanop.start(); + m_scanop.setHandler (mainhandler); + } + + class ScanOperation extends OperationThread { + protected scanthread m_thread; + ScanOperation() { + super(); + m_iOp = SCAN_APKS; + } + public void start() { //overide it to new and start a thread + super.start(); + m_thread = new scanthread(); + m_thread.start(); + } + + class scanthread extends Thread { + public void run() { + scandir (mScanRoot); + synchronized (m_syncobj) { + sendEndMsg(); + m_bOpEnd = true; + } + } + + class APKFileter implements FileFilter { + public boolean accept (File arg0) { + if (arg0.isDirectory() == true) { + return true; + } + String filename = arg0.getName(); + String filenamelowercase = filename.toLowerCase(); + return filenamelowercase.endsWith (".apk"); + } + } + protected void scandir (String directory) { + int dirs = 0, apks = 0; + //clear the apklist + mApkList.clear(); + //to scan dirs + ArrayList<String> pdirlist = new ArrayList<String>(); + pdirlist.add (directory); + while (pdirlist.isEmpty() == false) { + synchronized (m_syncobj) { + if (m_bstop == true) { + break; + } + dirs++; + if (m_handler != null) { + Message dirmsg = Message.obtain(); + dirmsg.what = NEW_APK; + dirmsg.arg1 = dirs; + dirmsg.arg2 = apks; + m_handler.sendMessage (dirmsg); + } + } + String headpath = pdirlist.remove (0); + File pfile = new File (headpath); + if (pfile.exists() == true) { + //list files and dirs in this directory + File[] files = pfile.listFiles (new APKFileter()); + if (files != null && (files.length > 0)) { + int i = 0; + for (; i < files.length; i++) { + //shield /sdcard/external_sdcard if select /sdcard to search with virtaul external_sdcard + String str = null; + str = files[i].toString(); + if (str.compareTo (SHEILD_EXT_STOR) == 0) { + continue; + } + synchronized (m_syncobj) { + if (m_bstop == true) { + break; + } + } + File pcurfile = files[i]; + if (pcurfile.isDirectory()) { + pdirlist.add (pcurfile.getAbsolutePath()); + } + else { + APKInfo apkinfo = new APKInfo (main.this, pcurfile.getAbsolutePath()); + if (apkinfo.beValid() == true) { + mApkList.add (apkinfo); + apks++; + synchronized (m_syncobj) { + if (m_handler != null) { + Message apkmsg = Message.obtain(); + apkmsg.what = NEW_APK; + apkmsg.arg1 = dirs; + apkmsg.arg2 = apks; + m_handler.sendMessage (apkmsg); + } + } + } + } + } + } + } + } + } + } + }; + + protected void showScanDiag (int dirs, int apks) { + String msg = getResources().getString (R.string.scanning); + msg += "dir : " + String.valueOf (dirs) + "\n"; + msg += "apk : " + String.valueOf (apks) + "\n"; + mScanDiag.setMessage (msg); + // mScanDiag.show(); + } + + + + private void showDialogInner (int id) { + // TODO better fix for this? Remove dialog so that it gets created again + removeDialog (id); + showDialog (id); + } + + @Override + public Dialog onCreateDialog (int id, Bundle bundle) { + switch (id) { + case DLG_UNKNOWN_APPS: + return new AlertDialog.Builder (this) + .setTitle (R.string.unknown_apps_dlg_title) + .setMessage (R.string.unknown_apps_dlg_text) + .setNegativeButton (R.string.cancel, new DialogInterface.OnClickListener() { + public void onClick (DialogInterface dialog, int which) { + } + }) + .setPositiveButton (R.string.settings, new DialogInterface.OnClickListener() { + public void onClick (DialogInterface dialog, int which) { + launchSettingsAppAndFinish(); + } + }) .create(); + } + return null; + } + + private void launchSettingsAppAndFinish() { + //Create an intent to launch SettingsTwo activity + Intent launchSettingsIntent = new Intent (Settings.ACTION_SECURITY_SETTINGS); + startActivity (launchSettingsIntent); + } + + private boolean isInstallingUnknownAppsAllowed() { + return Settings.Secure.getInt (getContentResolver(), + Settings.Secure.INSTALL_NON_MARKET_APPS, 0) > 0; + } + +} + + + + diff --git a/src/com/gsoft/appinstall/CheckAbleList.java b/src/com/gsoft/appinstall/CheckAbleList.java deleted file mode 100755 index 44cd42e..0000000 --- a/src/com/gsoft/appinstall/CheckAbleList.java +++ b/dev/null @@ -1,67 +0,0 @@ -package com.gsoft.appinstall;
-
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.SoundEffectConstants;
-import android.view.View;
-import android.widget.*;
-import android.view.KeyEvent;
-import android.util.Log;
-
-public class CheckAbleList extends ListView {
- private static final String TAG = "CheckAbleList";
- protected OnItemClickListener m_localClickListener = null;
- public CheckAbleList(Context context) {
- super(context);
- // TODO Auto-generated constructor stub
- }
- public CheckAbleList(Context context, AttributeSet attrs) {
- super(context,attrs);
- }
-
- public CheckAbleList(Context context, AttributeSet attrs, int defStyle)
- {
- super(context,attrs,defStyle);
- }
-
- public void setOnItemClickListener(OnItemClickListener listener)
- {
- super.setOnItemClickListener( listener);
- m_localClickListener = listener;
- }
-
- public boolean performItemClick(View view, int position, long id)
- {
- //i don't want to set the item checked when i click a item
- if (m_localClickListener != null) {
- playSoundEffect(SoundEffectConstants.CLICK);
- m_localClickListener.onItemClick(this, view, position, id);
- return true;
- }
-
- return false;
- }
-
- public void setAllItemChecked(boolean value)
- {
- int i = 0;
- for(;i<this.getCount();i++)
- {
- setItemChecked(i,value);
- getAdapter().getView(i,getChildAt(i),this);//for redraw
- }
- }
-
- public boolean onKeyDown(int keyCode, KeyEvent event){
- if(keyCode == KeyEvent.KEYCODE_DPAD_RIGHT){
- int PosInList = 0;
- PosInList = this.getSelectedItemPosition();
- if(!isItemChecked(PosInList))
- setItemChecked(PosInList,true);
- else
- setItemChecked(PosInList,false);
- Log.e(TAG,"--------------------------------------------RC is checked");
- }
- return super.onKeyDown(keyCode,event);
- }
-}
diff --git a/src/com/gsoft/appinstall/PackageAdapter.java b/src/com/gsoft/appinstall/PackageAdapter.java deleted file mode 100755 index 5f036fc..0000000 --- a/src/com/gsoft/appinstall/PackageAdapter.java +++ b/dev/null @@ -1,234 +0,0 @@ -package com.gsoft.appinstall;
-
-import java.util.ArrayList;
-import android.content.res.AssetManager;
-import android.content.Context;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.graphics.drawable.Drawable;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.TextView;
-import android.os.UserHandle;
-
-class APKInfo extends Object
-{
- static protected PackageManager pkgmgr = null;
-
- APKInfo(Context pcontext, String apkpath)
- {
- pkgmgr = pcontext.getPackageManager();
- PackageInfo pPkgInfo = pkgmgr.getPackageArchiveInfo(apkpath, PackageManager.GET_ACTIVITIES);
- if(pPkgInfo!=null)
- {
- //get package's name in system
- String[] curpkgnames = pkgmgr.canonicalToCurrentPackageNames(new String[]{pPkgInfo.packageName});
- if( (curpkgnames!=null) && (curpkgnames.length > 0) && (curpkgnames[0]!=null) )
- pCurPkgName = curpkgnames[0];
- else
- pCurPkgName = pPkgInfo.packageName;
-
- Resources pPkgRes = null;
- AssetManager assmgr = new AssetManager();
- if(0 != assmgr.addAssetPath(apkpath))
- pPkgRes = new Resources(assmgr, pcontext.getResources().getDisplayMetrics(), pcontext.getResources().getConfiguration());
- if(pPkgRes!=null)
- {
- getApplicationName_Internal(pPkgRes,pPkgInfo);
- getApkIcon_Internal(pPkgRes,pPkgInfo);
- filepath = apkpath;
- }
- assmgr.close();
- }
- }
-
- public boolean beValid()
- {
- if(filepath == null)
- return false;
- else
- return true;
- }
-
- public String filepath;
- public String pCurPkgName = null;
- public CharSequence pAppName = null;
- public Drawable pAppIcon = null;
- public boolean bIsinstalled = false;
-
- public boolean checkInstalled()
- {
- ApplicationInfo appinfo = null;
- try {
- appinfo = pkgmgr.getApplicationInfo(pCurPkgName,PackageManager.GET_META_DATA);
- } catch (NameNotFoundException e) {
- appinfo = null;
- }
-
- if(appinfo == null)
- bIsinstalled = false;
- else
- bIsinstalled = true;
- return bIsinstalled;
- }
- public boolean isInstalled()
- {
- return bIsinstalled;
- }
- public CharSequence getApplicationName()
- {
- return pAppName;
- }
- public Drawable getApkIcon()
- {
- return pAppIcon;
- }
-
- public CharSequence getApplicationName_Internal(Resources PkgRes,PackageInfo PkgInfo)
- {
- if(pAppName == null)
- {
- if(PkgRes!=null)
- {
- try
- {
- pAppName = PkgRes.getText(PkgInfo.applicationInfo.labelRes);
- }
- catch (Resources.NotFoundException resnotfound)
- {
- pAppName = pCurPkgName;
- }
- }
- else
- pAppName = pCurPkgName;
- }
- return pAppName;
- }
-
- public Drawable getApkIcon_Internal(Resources PkgRes,PackageInfo PkgInfo)
- {
- if(pAppIcon == null)
- {
- if(PkgRes!=null)
- {
- try
- {
- pAppIcon = PkgRes.getDrawable(PkgInfo.applicationInfo.icon);
- }
- catch (Resources.NotFoundException resnotfound)
- {
- pAppIcon = pkgmgr.getApplicationIcon(PkgInfo.applicationInfo);
- }
- }
- else
- pAppIcon = pkgmgr.getApplicationIcon(PkgInfo.applicationInfo);
- }
- return pAppIcon;
- }
-
-}
-
-
-public class PackageAdapter extends BaseAdapter {
-
- protected int m_Layout_APKListItem;
- protected int m_TextView_AppName;
- protected int m_TextView_FileName;
- protected int m_ImgView_APPIcon;
- protected int m_CheckBox_InstallState;
- protected int m_CheckBox_SelState;
- private LayoutInflater mInflater;
- protected ArrayList<APKInfo> m_apklist = null;
- protected ListView m_list = null;
-
- PackageAdapter(Context context,int Layout_Id,int text_app_id,int text_filename_id,int checkbox_id,int img_appicon_id,int checkbox_sel_id,ArrayList<APKInfo> apklist,ListView list)
- {
- mInflater = LayoutInflater.from(context);
- m_Layout_APKListItem = Layout_Id;
- m_TextView_FileName = text_filename_id;
- m_TextView_AppName = text_app_id;
- m_CheckBox_InstallState = checkbox_id;
- m_ImgView_APPIcon = img_appicon_id;
- m_CheckBox_SelState = checkbox_sel_id;
- m_apklist = apklist;
- m_list = list;
- }
-
- public int getCount() {
- if(m_apklist != null)
- return m_apklist.size();
- else
- return 0;
- }
-
- public Object getItem(int position) {
- if(m_apklist != null)
- return m_apklist.get(position);
- else
- return null;
- }
-
- public long getItemId(int position) {
- return position;
- }
-
-
- class SelStateListener implements CompoundButton.OnCheckedChangeListener
- {
- int PosInList = 0;
- SelStateListener(int pos)
- {
- PosInList = pos;
- }
-
- public void onCheckedChanged (CompoundButton buttonView, boolean isChecked)
- {
- if(m_list.isItemChecked(PosInList) != isChecked)
- m_list.setItemChecked(PosInList, isChecked);
- }
- }
-
- public View getView(int position, View convertView, ViewGroup parent) {
- View layoutview = null;
- if(convertView==null)
- {
- layoutview = mInflater.inflate(m_Layout_APKListItem,parent,false);
- }
- else
- {
- layoutview = convertView;
- }
- TextView FileName = (TextView)layoutview.findViewById(m_TextView_FileName);
- TextView AppName = (TextView)layoutview.findViewById(m_TextView_AppName);
- CheckBox InstallState = (CheckBox)layoutview.findViewById(m_CheckBox_InstallState);
- ImageView Appicon = (ImageView)layoutview.findViewById(m_ImgView_APPIcon);
- CheckBox SelState = (CheckBox)layoutview.findViewById(m_CheckBox_SelState);
- SelState.setOnCheckedChangeListener(new SelStateListener(position));
-
- APKInfo pinfo = (APKInfo)getItem(position);
- FileName.setText(pinfo.filepath);
- AppName.setText(pinfo.getApplicationName());
- InstallState.setChecked(pinfo.checkInstalled());
- Appicon.setImageDrawable(pinfo.getApkIcon());
- SelState.setChecked(m_list.isItemChecked(position));
-
- return layoutview;
- }
-
- public boolean hasStableIds() {
- return true;
- }
-
-}
diff --git a/src/com/gsoft/appinstall/main.java b/src/com/gsoft/appinstall/main.java deleted file mode 100755 index 5da66c8..0000000 --- a/src/com/gsoft/appinstall/main.java +++ b/dev/null @@ -1,1084 +0,0 @@ -package com.gsoft.appinstall; - - -import java.io.File; -import java.io.FileFilter; -import java.util.ArrayList; - -import android.app.Activity; -import android.app.AlertDialog; -import android.app.Dialog; -import android.app.ProgressDialog; -import android.content.ComponentName; -import android.content.Intent; -import android.content.pm.PackageManager; -import android.net.Uri; -import android.os.Bundle; -import android.os.Handler; -import android.os.Message; -import android.util.Log; -import android.view.Menu; -import android.view.MenuItem; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewGroup; -import android.widget.AdapterView; -import android.widget.AdapterView.OnItemSelectedListener; -import android.widget.Button; -import android.widget.EditText; -import android.widget.ImageButton; -import android.widget.ListView; -import android.widget.TextView.BufferType; -import android.widget.TextView; -import android.widget.Toast; -import android.content.pm.IPackageInstallObserver; -import android.content.pm.IPackageDeleteObserver; -import android.os.PowerManager; -import android.os.HandlerThread; -import android.provider.Settings; -import android.content.Context; -import android.view.KeyEvent; -import android.content.res.Configuration; -import android.content.DialogInterface; -import java.lang.String; -import android.os.StatFs; -import android.os.Environment; -import android.content.BroadcastReceiver; -import android.content.IntentFilter; - - - -public class main extends Activity { - private String TAG = "com.gsoft.appinstall"; - private String mVersion = "V1.1.3"; - private String mReleaseDate = "2012.04.01"; - - private static final String ROOT_PATH = "/storage"; - private static final String SHEILD_EXT_STOR = Environment.getExternalStorageDirectory().getPath()+"/external_storage";//"/storage/sdcard0/external_storage"; - private static final String NAND_PATH = Environment.getExternalStorageDirectory().getPath();//"/storage/sdcard0"; - private static final String SD_PATH = "/storage/external_storage/sdcard1"; - private static final String USB_PATH ="/storage/external_storage"; - - //UI INFO - protected String mScanRoot = null; - protected CheckAbleList m_list = null; - protected TextView m_info = null; - protected PackageAdapter pkgadapter = null; - protected TextView m_DirEdit = null; - protected OperationDialog mScanDiag = null; - protected OperationDialog mHandleDiag = null; - - //DATA - protected ArrayList<APKInfo> mApkList = new ArrayList<APKInfo>(); - protected boolean m_configchanged = false; - public final static int END_OPERATION = 0; - public final static int NEW_APK = 1; - public final static int HANDLE_PKG_NEXT = 2; - public final static int HANDLE_PKG_FAIL = 3; - private static final int DLG_UNKNOWN_APPS = 1; - private PowerManager.WakeLock mScreenLock = null; - protected ScanOperation m_scanop = new ScanOperation(); - protected InstallOperation m_installop = new InstallOperation(); - protected String mDevs[] = null; - - //the status of app - private static int SCAN_APKS = 0; - private static int VIEW_APKS = 1; - private static int INSTALL_APKS = 2; - protected int mStatus = -1; - - /** Called when the activity is first created. */ - @Override - public void onCreate(Bundle savedInstanceState) - { - super.onCreate(savedInstanceState); - setContentView(R.layout.main); - - //keep system awake - mScreenLock = ((PowerManager)this.getSystemService(Context.POWER_SERVICE)).newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,TAG); - m_info = (TextView)findViewById(R.id.ScanInfo); - m_info.setText(R.string.no_apk_found); - m_info.setVisibility(android.view.View.INVISIBLE); - //init the listview - m_list = (CheckAbleList)findViewById(R.id.APKList); - m_list.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); - - //create dialog process dialog - mScanDiag = new OperationDialog(this,m_scanop,getResources().getString(R.string.scanning_init)); - mHandleDiag = new OperationDialog(this,m_installop,getResources().getString(R.string.handling_selected_package_init)); - pkgadapter = new PackageAdapter(this,R.layout.listitem,R.id.appname,R.id.apk_filepath,R.id.InstallState,R.id.APKIcon,R.id.Select,mApkList,m_list); - - m_list.setOnItemClickListener(new AdapterView.OnItemClickListener() - { - public void onItemClick(AdapterView<?> parent, View view,int position, long id) - { - APKInfo apkinfo = mApkList.get(position); - /*if(apkinfo.isInstalled() == true) - uninstall_apk(apkinfo.pCurPkgName); - else*/ - install_apk(apkinfo.filepath); - } - }); - - //change dir button - m_DirEdit = (TextView)findViewById(R.id.Dir); - m_DirEdit.setText(" ",TextView.BufferType.NORMAL); - m_DirEdit.setOnClickListener(new View.OnClickListener() - { - public void onClick(View v) - { - showChooseDev(); - } - }); - - //exit button - ImageButton hexit = (ImageButton)findViewById(R.id.Exit); - hexit.setOnClickListener(new View.OnClickListener() - { - public void onClick(View v) - { - main.this.finish(); - } - } - ); - hexit.requestFocus(); - showChooseDev(); - } - - private BroadcastReceiver mMountReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - String data = intent.getDataString(); - if (action == null) - return; - - if(mScanRoot == null) - return; - - if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) { - int index=data.indexOf(ROOT_PATH); - if(index>=0) - { - String path=data.substring(index); - if(path.equals(mScanRoot)) { - m_list.setAdapter(null); - mApkList.clear(); - } - } - else //exception handle - startScanOp(); - } - else if(action.equals(Intent.ACTION_MEDIA_MOUNTED)) { - int index=data.indexOf(ROOT_PATH); - if(index>=0) - { - String path=data.substring(index); - if(path.equals(mScanRoot)) { - startScanOp(); - } - } - else //exception handle - startScanOp(); - } - } - }; - - public void onResume() - { - Log.d(TAG,"onResume"); - pkgadapter.notifyDataSetChanged(); - m_scanop.setHandler(mainhandler); - m_installop.setHandler(mainhandler); - - IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED); - intentFilter.addAction(Intent.ACTION_MEDIA_EJECT); - intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED); - intentFilter.addDataScheme("file"); - registerReceiver(mMountReceiver, intentFilter); - super.onResume(); - } - - public void onPause() - { - //disable the operation message - m_scanop.setHandler(null); - m_installop.setHandler(null); - - mainhandler.removeMessages(END_OPERATION); - mainhandler.removeMessages(NEW_APK); - mainhandler.removeMessages(HANDLE_PKG_NEXT); - //diable dialog - if(mScanDiag!=null) - { - mScanDiag.dismiss(); - } - if(mHandleDiag!=null) - { - mHandleDiag.dismiss(); - } - - //unregisterReceiver(mMountReceiver); - - //release the wakelock - super.onPause(); - } - public void onStop() - { - if(mMountReceiver != null) { - unregisterReceiver(mMountReceiver); - mMountReceiver = null; - } - super.onStop(); - } - protected void onDestroy() - { - if(m_configchanged == false) - { - m_scanop.stop(); - m_installop.stop(); - } - Log.d(TAG,"onDestroy"); - KeepSystemAwake(false); - super.onDestroy(); - } - - protected void KeepSystemAwake(boolean bkeep) - { - if(bkeep == true) - { - if(mScreenLock.isHeld() == false) - mScreenLock.acquire(); - } - else - { - if(mScreenLock.isHeld() == true) - mScreenLock.release(); - } - } - - public Handler mainhandler = new Handler() - { - public void handleMessage(Message msg) { - // TODO Auto-generated method stub - switch(msg.what) - { - case END_OPERATION: - if(msg.arg1 != mStatus) - { - Log.e(TAG,"mStatus "+String.valueOf(mStatus)+"!= endoperation "+String.valueOf(msg.arg1)); - } - if(mStatus == SCAN_APKS) - { - if(mScanDiag != null) - mScanDiag.dismiss(); - - if(mApkList.size() > 0) - { - m_list.setAdapter(pkgadapter); - m_list.setVisibility(android.view.View.VISIBLE); - m_info.setVisibility(android.view.View.INVISIBLE); - } - else - { - m_list.setVisibility(android.view.View.INVISIBLE); - m_info.setVisibility(android.view.View.VISIBLE); - } - } - else - { - Log.d(TAG,"END_HANDLE_PKG"); - if(mHandleDiag != null) - mHandleDiag.dismiss(); - pkgadapter.notifyDataSetChanged(); - } - mStatus = VIEW_APKS; - KeepSystemAwake(false); - break; - case NEW_APK: - showScanDiag(msg.arg1,msg.arg2); - break; - case HANDLE_PKG_NEXT: - Log.d(TAG,"HANDLE_PKG_NEXT"); - String hanlemsg = msg.getData().getString("showstr"); - showHandleDiag(hanlemsg,(int)msg.arg1+1,msg.arg2); - break; - case HANDLE_PKG_FAIL: - Log.d(TAG,"HANDLE_PKG_FAIL"); - String failemsg = msg.getData().getString("showstr"); - Toast.makeText(main.this, failemsg, Toast.LENGTH_SHORT).show(); - break; - default: - break; - } - } - }; - - //option menu - protected final int MENU_INSTALL = 0; - protected final int MENU_UNINSTALL = 1; - protected final int MENU_SELECT_ALL = 2; - protected final int MENU_UNSELECT_ALL = 3; - protected final int MENU_FRESH = 4; - protected final int MENU_ABOUT = 5; - public boolean onCreateOptionsMenu(Menu menu) - { - menu.add(0, MENU_INSTALL, 0, R.string.install); - menu.add(0, MENU_UNINSTALL, 0, R.string.uninstall); - menu.add(0, MENU_SELECT_ALL, 0, R.string.selectall); - menu.add(0, MENU_UNSELECT_ALL, 0, R.string.unselect_all); - menu.add(0, MENU_FRESH, 0, R.string.refresh); - menu.add(0, MENU_ABOUT, 0, R.string.about); - return true; - } - - private final int opInstall = 0; - private final int opUninstall = 1; - private int menuSelect = opInstall; - - public boolean onOptionsItemSelected(MenuItem item) - { - switch (item.getItemId()) - { - case MENU_INSTALL: - if(!isInstallingUnknownAppsAllowed()) { - //ask user to enable setting first - showDialogInner(DLG_UNKNOWN_APPS); - return true; - } - menuSelect = opInstall; - startHandleOp(); - return true; - case MENU_UNINSTALL: - menuSelect = opUninstall; - startHandleOp(); - return true; - case MENU_SELECT_ALL: - m_list.setAllItemChecked(true); - return true; - case MENU_UNSELECT_ALL: - m_list.setAllItemChecked(false); - return true; - case MENU_FRESH: - m_list.setAdapter(null); - startScanOp(); - return true; - case MENU_ABOUT: - String aboutinfo = getResources().getString(R.string.about_appInstaller); - aboutinfo += getResources().getString(R.string.about_version)+mVersion+" "; - aboutinfo += getResources().getString(R.string.about_date)+mReleaseDate+" "; - AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setMessage(aboutinfo); - AlertDialog about = builder.create(); - about.show(); - return true; - } - return false; - } - - public void onConfigurationChanged (Configuration newConfig) - { - super.onConfigurationChanged(newConfig); - } - - //user functions - public void showChooseDev() - { - int dev_usb_count=0; - int dev_cd_count=0; - int devCnt = 0; - int selid = 0; - String internal = getString(R.string.memory_device_str); - String sdcard = getString(R.string.sdcard_device_str); - String usb = getString(R.string.usb_device_str); - String cdrom = getString(R.string.cdrom_device_str); - String sdcardExt = getString(R.string.ext_sdcard_device_str); - String DeviceArray[]={internal,sdcard,usb,cdrom,sdcardExt}; - - //init dev count - File pfile = new File(USB_PATH); - File[] files = pfile.listFiles(); - mDevs = new String[files.length+1];//+1 indicate NAND_PATH - - File dir = new File(NAND_PATH); - if (dir.exists() && dir.isDirectory()) { - mDevs[devCnt]=dir.toString(); - } - - dir = new File(SD_PATH); - if (dir.exists() && dir.isDirectory()) { - devCnt++; - mDevs[devCnt]=dir.toString(); - } - - dir = new File(USB_PATH); - if (dir.exists() && dir.isDirectory()) { - if (dir.listFiles() != null) { - for (File file : dir.listFiles()) { - if (file.isDirectory()) { - String devname = null; - String path = file.getAbsolutePath(); - if ((path.startsWith(USB_PATH+"/sd")||path.startsWith(USB_PATH+"/sr"))&&!path.equals(SD_PATH)) { - devCnt++; - mDevs[devCnt]=file.toString(); - } - } - } - } - } - - int len = devCnt+1; - mDevStrs=new String[len]; - for(int idx=0;idx<len;idx++) - { - if(mDevs[idx]==null) - { - Log.e(TAG,"showChooseDev err, mDevs["+idx+"]==null."); - continue; - } - - if (mDevs[idx].equals(NAND_PATH)) - { - mDevStrs[idx]=DeviceArray[1]; - } - else if (mDevs[idx].startsWith(USB_PATH+"/sd")&&!mDevs[idx].equals(SD_PATH)) - { - dev_usb_count++; - char data = (char) ('A' +dev_usb_count-1); - mDevStrs[idx] = DeviceArray[2] +"(" +data + ":)" ; - } - else if (mDevs[idx].startsWith(USB_PATH+"/sr")&&!mDevs[idx].equals(SD_PATH)) - { - dev_cd_count++; - char data = (char) ('A' +dev_cd_count-1); - mDevStrs[idx] = DeviceArray[3] +"(" +data + ":)" ; - } - else if (mDevs[idx].equals(SD_PATH)) - { - mDevStrs[idx]=DeviceArray[4]; - } - else - { - mDevStrs[idx]=mDevs[idx]; - } - - if(mDevs[idx].equals(mScanRoot)) - selid = idx; - } - - //show dialog to choose dialog - new AlertDialog.Builder(main.this) - .setTitle(R.string.alertdialog_title) - .setSingleChoiceItems(mDevStrs, selid, new DialogInterface.OnClickListener() - { - public void onClick(DialogInterface dialog, int which) - { - dialog.dismiss(); - //updatePathName(mDevs[which]); - m_DirEdit.setText(mDevStrs[which]); - String devpath = mDevs[which]==null? null : mDevs[which].toString(); - - if(devpath==null) - { - Toast.makeText(main.this, "invalid dir path", Toast.LENGTH_SHORT).show(); - return; - } - - File pfile = new File(devpath); - if( pfile!=null && pfile.isDirectory()==true ) - { - //if((mScanRoot == null) || (mScanRoot.compareTo(devpath) != 0)) - { - mScanRoot = devpath; - startScanOp(); - } - //else - //Toast.makeText(main.this, "same dir path", Toast.LENGTH_SHORT).show(); - } - else - { - Toast.makeText(main.this, "invalid dir path", Toast.LENGTH_SHORT).show(); - } - } - }) - .setOnCancelListener(new DialogInterface.OnCancelListener() - { - public void onCancel(DialogInterface dialog) - { - if(mScanRoot == null) - main.this.finish(); - } - }) - .show(); - - } - - protected String mDevStrs[] = null; - private void updatePathName(String dev) - { - String internal = getString(R.string.memory_device_str); - String sdcard = getString(R.string.sdcard_device_str); - String usb = getString(R.string.usb_device_str); - String cdrom = getString(R.string.cdrom_device_str); - String sdcardExt = getString(R.string.ext_sdcard_device_str); - String str=""; - - if(dev==null) - { - Log.e(TAG,"updatePathName error, dev=null"); - return; - } - - if(dev.equals(NAND_PATH)) - { - str=sdcard; - } - else if (dev.startsWith(USB_PATH+"/sd")&&!dev.equals(SD_PATH)) - { - str=usb; - } - else if (dev.startsWith(USB_PATH+"/sr")&&!dev.equals(SD_PATH)) - { - str=cdrom; - } - else if(dev.equals(SD_PATH)) - { - str=sdcardExt; - } - else - { - str=dev; - } - m_DirEdit.setText(str); - } - - //=================================================================== - //functions for installing and uninstalling - public void install_apk(String apk_filepath) - { - Intent installintent = new Intent(); - installintent.setComponent(new ComponentName("com.android.packageinstaller","com.android.packageinstaller.PackageInstallerActivity")); - installintent.setAction(Intent.ACTION_VIEW); - installintent.setData(Uri.fromFile(new File(apk_filepath))); - startActivity(installintent); - } - - public void uninstall_apk(String apk_pkgname) - { - Intent uninstallintent = new Intent(); - uninstallintent.setComponent(new ComponentName("com.android.packageinstaller","com.android.packageinstaller.UninstallerActivity")); - uninstallintent.setAction(Intent.ACTION_VIEW); - uninstallintent.setData(Uri.fromParts("package",apk_pkgname,null)); - startActivity(uninstallintent); - } - - //=================================================================== - //base class for operations thread - class OperationThread - { - protected Handler m_handler = null; - protected boolean m_bstop = false; - protected boolean m_bOpEnd = false; - protected Object m_syncobj = new Object(); - protected int m_iOp = 0; - public void start() //overide it to new and start a thread - { - m_bstop = false; - m_bOpEnd = false; - } - - public void stop() - { - synchronized (m_syncobj) - { - m_bstop = true; - } - } - - public boolean isOpEnd() - { - synchronized (m_syncobj) - { - return m_bOpEnd; - } - } - - public void setHandler(Handler phandler) - { - synchronized (m_syncobj) - { - m_handler = phandler; - } - } - - public void sendEndMsg() - { - if(m_handler != null) - { - Message endmsg = Message.obtain(); - endmsg.what = END_OPERATION; - endmsg.arg1 = m_iOp; - m_handler.sendMessage(endmsg); - } - } - }; - - class OperationDialog extends ProgressDialog - { - public boolean m_bOpStop; - public OperationThread m_pOp; - public CharSequence m_sInitMsg; - public OperationDialog(Context context,OperationThread operation,CharSequence initMessage) - { - super(context); - m_bOpStop = false; - m_pOp = operation; - setCancelable(false); - m_sInitMsg = initMessage; - } - - public void start() - { - //show with empty message - m_bOpStop = false; - setMessage(m_sInitMsg); - this.show();//first show() is invert-action to dismiss() - this.show();//second show() is invert-action to hide() - } - - public void setMessage(CharSequence message) - { - if(m_bOpStop == true) - return; - else - super.setMessage(message); - } - - public void dismiss() - { - hide();//first to hide() it and in start to show() it , this is let the animation in dialog to restart - super.dismiss(); - } - -/* - public boolean onTouchEvent (MotionEvent event) - { - m_pOp.stop(); - setMessage("stopping...\n"); - m_bOpStop = true; - return true; - } -*/ - public boolean onKeyDown(int keyCode, KeyEvent event) - { - if(keyCode == KeyEvent.KEYCODE_BACK || keyCode == KeyEvent.KEYCODE_POWER) - { - m_pOp.stop(); - setMessage("stopping...\n"); - m_bOpStop = true; - } - return super.onKeyDown(keyCode,event); - } - - }; - - // Check free space for installation - private static long checkFreeSpace(String path) { - long nSDFreeSize = 0; - if (path != null) { - StatFs statfs = new StatFs(path); - - long nBlocSize = statfs.getBlockSize(); - long nAvailaBlock = statfs.getAvailableBlocks(); - nSDFreeSize = nAvailaBlock * nBlocSize; - } - return (nSDFreeSize / (1024 * 1024)); - - } - - //=================================================================== - //functions for installing and uninstalling in slient mode - class InstallOperation extends OperationThread - { - public long [] m_checkeditems = null; - protected installthread m_thread; - private long m_handleitem; - private Handler m_selfhandler; - protected ApkHandleTask m_apkhandltsk = new ApkHandleTask(); - InstallOperation() - { - super(); - m_iOp = INSTALL_APKS; - } - public void start() //overide it to new and start a thread - { - super.start(); - m_handleitem = 0; - m_thread = new installthread("multi-apk-handler"); - m_thread.start(); - } - - class installthread extends HandlerThread - { - installthread(String name) - { - super(name); - } - protected void onLooperPrepared() - { - synchronized(m_syncobj) - { - m_selfhandler = new Handler(); - m_selfhandler.post(m_apkhandltsk); - m_handleitem = 0; - } - } - } - - class ApkHandleTask implements Runnable - { - class PackageInstallObserver extends IPackageInstallObserver.Stub { - String apkpath = null; - public void packageInstalled(String packageName, int returnCode) { - Log.d(TAG,"packageInstalled "+String.valueOf(returnCode)); - synchronized(m_syncobj) - { - if(returnCode!=1)//fail - { - Message endmsg = Message.obtain(); - endmsg.what = HANDLE_PKG_FAIL; - Bundle data = new Bundle(); - data.putString("showstr","Install "+apkpath+" fail!"); - endmsg.setData(data); - m_handler.sendMessage(endmsg); - } - m_handleitem++; - m_selfhandler.post(m_apkhandltsk); - } - } - } - - class PackageDeleteObserver extends IPackageDeleteObserver.Stub { - String pkgpath = null; - public void packageDeleted(String packageName, int returnCode) - { - Log.d(TAG,"packageDeleted "+String.valueOf(returnCode)); - synchronized(m_syncobj) - { - if (returnCode != PackageManager.DELETE_SUCCEEDED) - { - Message endmsg = Message.obtain(); - endmsg.what = HANDLE_PKG_FAIL; - Bundle data = new Bundle(); - data.putString("showstr","Uninstall "+pkgpath+" fail!"); - endmsg.setData(data); - m_handler.sendMessage(endmsg); - } - m_handleitem++; - m_selfhandler.post(m_apkhandltsk); - } - } - } - public void install_apk_slient(String apk_filepath) - { - PackageManager pm = getPackageManager(); - PackageInstallObserver observer = new PackageInstallObserver(); - observer.apkpath = apk_filepath; - pm.installPackage(Uri.fromFile(new File(apk_filepath)), observer, pm.INSTALL_REPLACE_EXISTING, null); - } - public void uninstall_apk_slient(String apk_pkgname) - { - PackageDeleteObserver observer = new PackageDeleteObserver(); - observer.pkgpath = apk_pkgname; - PackageManager pm = getPackageManager(); - pm.deletePackage(apk_pkgname, observer, 0); - } - public void run() - { - synchronized(m_syncobj) - { - if((m_bstop == true) || m_handleitem == m_checkeditems.length) - { - sendEndMsg(); - m_bOpEnd = true; - m_thread.quit(); - return ; - } - } - String hanlemsg = null; - int actionid; - String actionpara = null; - APKInfo pinfo = mApkList.get((int)m_checkeditems[(int) m_handleitem]); - if(pinfo != null) - { - //if(pinfo.isInstalled()==false) - if(menuSelect == opInstall) - { - actionid = 0; - actionpara = pinfo.filepath; - hanlemsg = "Installing \""; - } - else - { - actionid = 1; - actionpara = pinfo.pCurPkgName; - hanlemsg = "Uninstalling \""; - } - hanlemsg += pinfo.pAppName+"\"\n"; - - synchronized(m_syncobj) - { - if(m_handler!=null) - { - Message endmsg = Message.obtain(); - endmsg.what = HANDLE_PKG_NEXT; - endmsg.arg1 = (int)m_handleitem; - endmsg.arg2 = m_checkeditems.length; - Bundle data = new Bundle(); - data.putString("showstr",hanlemsg); - endmsg.setData(data); - m_handler.sendMessageDelayed(endmsg,2000);//add a delay, for systeme need time to release cache. - } - } - - if(actionid == 0) { - boolean hasSpace = checkFreeSpace("/data/app") > 50; - if (!hasSpace) { - Log.w(TAG,"no enough space for installation, force stop!"); - - Message endmsg = Message.obtain(); - endmsg.what = HANDLE_PKG_FAIL; - Bundle data = new Bundle(); - data.putString("showstr", getResources().getString(R.string.no_space)); - endmsg.setData(data); - m_handler.sendMessage(endmsg); - - sendEndMsg(); - m_bOpEnd = true; - m_thread.quit(); - return ; - } - - install_apk_slient(actionpara); - } - else - uninstall_apk_slient(actionpara); - Log.d(TAG,"install a singel apk end"); - } - else - Log.e(TAG,"got a null apkinfo, this is strange!"); - } - } - } - - public void startHandleOp() - { - long [] checkeditems = m_list.getCheckedItemIds(); - if(checkeditems.length == 0) - Toast.makeText(main.this, R.string.no_select_apks , Toast.LENGTH_SHORT).show(); - else - { - KeepSystemAwake(true); - mStatus = INSTALL_APKS; - m_installop.m_checkeditems = checkeditems.clone(); - mHandleDiag.start(); - m_installop.setHandler(mainhandler); - m_installop.start(); - } - } - - protected void showHandleDiag(String handlemsg,int curpkg,int totalpkg) - { - String msg = getResources().getString(R.string.handling_selected_package); - msg += String.valueOf(curpkg)+"/"+String.valueOf(totalpkg)+"\n"; - msg += handlemsg; - mHandleDiag.setMessage(msg); - // mHandleDiag.show(); - } - - //=================================================================== - //functions for scanning apks - protected void startScanOp() - { - KeepSystemAwake(true); - mStatus = SCAN_APKS; - mScanDiag.start(); - showScanDiag(0,0); - m_scanop.start(); - m_scanop.setHandler(mainhandler); - } - - class ScanOperation extends OperationThread - { - protected scanthread m_thread; - ScanOperation() - { - super(); - m_iOp = SCAN_APKS; - } - public void start() //overide it to new and start a thread - { - super.start(); - m_thread = new scanthread(); - m_thread.start(); - } - - class scanthread extends Thread - { - public void run() - { - scandir(mScanRoot); - synchronized(m_syncobj) - { - sendEndMsg(); - m_bOpEnd = true; - } - } - - class APKFileter implements FileFilter - { - public boolean accept(File arg0){ - if(arg0.isDirectory() == true) - return true; - - String filename = arg0.getName(); - String filenamelowercase = filename.toLowerCase(); - return filenamelowercase.endsWith(".apk"); - } - } - protected void scandir(String directory) - { - int dirs = 0,apks = 0; - //clear the apklist - mApkList.clear(); - - //to scan dirs - ArrayList<String> pdirlist = new ArrayList<String>(); - pdirlist.add(directory); - - while(pdirlist.isEmpty() == false) - { - synchronized(m_syncobj) - { - if(m_bstop == true) - break; - dirs++; - if(m_handler!=null) - { - Message dirmsg = Message.obtain(); - dirmsg.what = NEW_APK; - dirmsg.arg1 = dirs; - dirmsg.arg2 = apks; - m_handler.sendMessage(dirmsg); - } - } - - String headpath = pdirlist.remove(0); - File pfile = new File(headpath); - if(pfile.exists() == true) - { - //list files and dirs in this directory - File[] files = pfile.listFiles(new APKFileter()); - if(files != null && (files.length > 0)) - { - int i = 0; - for(;i<files.length;i++) - { - //shield /sdcard/external_sdcard if select /sdcard to search with virtaul external_sdcard - String str=null; - str=files[i].toString(); - if(str.compareTo(SHEILD_EXT_STOR) == 0) - { - continue; - } - - synchronized(m_syncobj) - { - if(m_bstop == true) - break; - } - - File pcurfile = files[i]; - if(pcurfile.isDirectory()) - pdirlist.add(pcurfile.getAbsolutePath()); - else - { - APKInfo apkinfo = new APKInfo(main.this,pcurfile.getAbsolutePath()); - if(apkinfo.beValid() == true) - { - mApkList.add(apkinfo); - apks++; - synchronized(m_syncobj) - { - if( m_handler!=null ) - { - Message apkmsg = Message.obtain(); - apkmsg.what = NEW_APK; - apkmsg.arg1 = dirs; - apkmsg.arg2 = apks; - m_handler.sendMessage(apkmsg); - } - } - } - } - } - } - } - } - } - } - }; - - protected void showScanDiag(int dirs,int apks) - { - String msg = getResources().getString(R.string.scanning); - msg += "dir : "+String.valueOf(dirs)+"\n"; - msg += "apk : "+String.valueOf(apks)+"\n"; - mScanDiag.setMessage(msg); - // mScanDiag.show(); - } - - - - private void showDialogInner(int id) { - // TODO better fix for this? Remove dialog so that it gets created again - removeDialog(id); - showDialog(id); - } - - @Override - public Dialog onCreateDialog(int id, Bundle bundle) { - switch (id) { - case DLG_UNKNOWN_APPS: - return new AlertDialog.Builder(this) - .setTitle(R.string.unknown_apps_dlg_title) - .setMessage(R.string.unknown_apps_dlg_text) - .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - }}) - .setPositiveButton(R.string.settings, new DialogInterface.OnClickListener() { - public void onClick(DialogInterface dialog, int which) { - launchSettingsAppAndFinish(); - } - }) .create(); - } - - return null; - } - - private void launchSettingsAppAndFinish() { - //Create an intent to launch SettingsTwo activity - Intent launchSettingsIntent = new Intent(Settings.ACTION_SECURITY_SETTINGS); - startActivity(launchSettingsIntent); - } - - private boolean isInstallingUnknownAppsAllowed() { - return Settings.Secure.getInt(getContentResolver(), - Settings.Secure.INSTALL_NON_MARKET_APPS, 0) > 0; - } - -} - - - - |