Skip to content

Instantly share code, notes, and snippets.

@li2
Last active March 20, 2018 11:59
Show Gist options
  • Save li2/6a7fb601db24cb691db4 to your computer and use it in GitHub Desktop.
Save li2/6a7fb601db24cb691db4 to your computer and use it in GitHub Desktop.
Auto run a shell script when SDCard is plugged in android device. 实现方式:启动一个 service,由 service 动态注册监听 sdcard 插拔事件的 receiver,当接收到系统发出的插拔事件的 broadcast 后,执行相应的操作。#tags: android-service
public class SDcardService extends Service {
@Override
public IBinder onBind(Intent intent) {
// Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
intentFilter.addAction (Intent.ACTION_MEDIA_UNMOUNTED);
intentFilter.addAction (Intent.ACTION_MEDIA_REMOVED);
intentFilter.addAction (Intent.ACTION_MEDIA_BAD_REMOVAL);
intentFilter.addDataScheme ("file");
registerReceiver (broadcastRec, intentFilter);
Toast.makeText(this, "SDcard Plug/Unplug Service was Created", Toast.LENGTH_LONG).show();
}
@Override
public void onStart(Intent intent, int startId) {
// For time consuming an long tasks you can launch a new thread here...
Toast.makeText(this, "SDcard Plug/Unplug Service Started", Toast.LENGTH_LONG).show();
}
@Override
public void onDestroy() {
Toast.makeText(this, "SDcard Plug/Unplug Service Destroyed", Toast.LENGTH_LONG).show();
}
private final BroadcastReceiver broadcastRec = new BroadcastReceiver (){
public void onReceive(Context context, Intent intent) {
String path_extsd = getExternalSDCardPath();
String filename_autorun_plug = "autorun_plug.sh";
String filename_autorun_unplug = "autorun_unplug.sh";
String path_autorun_plug = path_extsd + "/" + filename_autorun_plug;
String path_autorun_unplug = path_extsd + "/" + filename_autorun_unplug;
File file_autorun_plug = new File(path_autorun_plug);
File file_autorun_unplug = new File(path_autorun_unplug);
if (intent.getAction().equals(Intent.ACTION_MEDIA_REMOVED)) {
dispmsg("ACTION_MEDIA_REMOVED");
Utils.rootExecCmdRetExitValue(filename_autorun_unplug);
} else if (intent.getAction().equals(Intent.ACTION_MEDIA_MOUNTED)){
dispmsg("ACTION_MEDIA_MOUNTED: " + path_extsd);
if(!file_autorun_unplug.exists()){
dispmsg(String.format("%s not exist.", path_autorun_unplug));
} else {
Utils.rootExecCmdRetExitValue("mount -o remount rw /system");
Utils.rootExecCmdRetExitValue(String.format("busybox cp %s /system/xbin/", path_autorun_unplug));
Utils.rootExecCmdRetExitValue(String.format("chmod 777 /system/xbin/%s", filename_autorun_unplug));
}
if(!file_autorun_plug.exists()){
dispmsg(String.format("%s not exist.", path_autorun_plug));
} else {
Utils.rootExecCmdRetExitValue("mount -o remount rw /system");
Utils.rootExecCmdRetExitValue(String.format("busybox cp %s /system/xbin/", path_autorun_plug));
Utils.rootExecCmdRetExitValue(String.format("chmod 777 /system/xbin/%s", filename_autorun_plug));
Utils.rootExecCmdRetExitValue(filename_autorun_plug);
}
}
}
};
private void dispmsg(String msg){
Toast.makeText(mitac.autorunSD.SDcardService.this, msg, Toast.LENGTH_LONG).show();
}
public static String getExternalSDCardPath() {
if (Utils.execCmdRetOut("cat /proc/mounts").contains("external_sd")){
return "/mnt/external_sd";
} else {
// TODO the external sdcard path?
}
//Environment.getExternalStorageDirectory().getPath() always return /mnt/sdcard
return null;
}
}

自动执行外置SDcard中特定名称的脚本文件


AutorunSDScript.apk 使用说明 功能:自动执行外置SDcard中特定名称的脚本文件。 适用:需要执行一批adb命令的场景,把命令写入脚本,方便非软件人员小范围测试。

  1. 首先需要破解机器的root权限(必须通过其它工具)Android device has already rooted;
  2. 在外置SDcard根目录中放入脚本文件 autorun_plug.sh 和 autorun_unplug.sh;
  3. 当插入SDcard时,autorun_plug.sh 自动执行;
  4. 当拔出SDcard时,autorun_unplug.sh 自动执行;
  5. 根据需要你可以只使用一个脚本;
  6. app注册了一个service监控SDcard插拔的动作,所以app不需要保持在前台。"

思路


  1. 首先注册一个service,参考Android Service Example

  2. 然后在service中注册一个broadcast listener,用于监听external sdcard插拔事件,参考android how to listen for the upper application sdcard plug event

  3. 最后在java中执行unix命令,参考How to execute system commands (linux/bsd) using Java

源码


已上传GitHub

GitHub使用入门指南


by li2- 2014-04-11 沪北

<application
<service
android:name="mitac.autorunSD.SDcardService"
android:enabled="true"
android:exported="true" >
</service>
<receiver
android:name="mitac.autorunSD.sdcardEvent">
<intent-filter>
<action android:name="android.intent.action.ACTION_MEDIA_REMOVED" />
<action android:name="android.intent.action.ACTION_MEDIA_MOUNTED" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
public class Utils {
public static String execCmdRetOut(String cmd){
try {
Process mProcess = Runtime.getRuntime().exec(cmd);
try {
mProcess.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
return e.getMessage();
}
String out = new String("");
BufferedInputStream in = new BufferedInputStream(mProcess.getInputStream());
BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
String lineStr;
while ((lineStr = inBr.readLine()) != null) {
out += lineStr;
}
in.close();
inBr.close();
return out ;
} catch (IOException e) {
e.printStackTrace();
return e.getMessage();
}
}
public static String execCmdRetErr(String cmd){
try {
Process mProcess = Runtime.getRuntime().exec(cmd);
try {
mProcess.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
return e.getMessage();
}
String out = new String("");
BufferedInputStream in = new BufferedInputStream(mProcess.getErrorStream());
BufferedReader inBr = new BufferedReader(new InputStreamReader(in));
String lineStr;
while ((lineStr = inBr.readLine()) != null) {
out += lineStr;
}
in.close();
inBr.close();
return out ;
} catch (IOException e) {
e.printStackTrace();
return e.getMessage();
}
}
public static int execCmdRetExitValue(String cmd){
try {
Process mProcess = Runtime.getRuntime().exec(cmd);
return mProcess.waitFor();
} catch (Exception e) {
e.printStackTrace();
return -1;
}
}
public static int rootExecCmdRetExitValue(String cmd){
try {
Process mProcess = Runtime.getRuntime().exec("su");
DataOutputStream stream = new DataOutputStream(mProcess.getOutputStream());
stream.writeBytes(cmd + "\n");
stream.writeBytes("exit\n");
stream.flush();
return mProcess.waitFor();
} catch (IOException e) {
e.printStackTrace();
Log.d("rootExecCmd", e.getMessage());
return -1;
} catch (InterruptedException e) {
e.printStackTrace();
Log.d("rootExecCmd", e.getMessage());
return -1;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment