#android #processbuilder
#Android #processbuilder
Вопрос:
Моя ситуация такова, что у меня есть более 100 устройств Android для обновления, которые подключены не к Интернету, а к локальной сети. Что я пытаюсь сделать, так это использовать process builder для доступа к apk в локальной сети и установки apk без вмешательства пользователя.
В настоящее время устройства не укоренены, однако, поскольку мне все равно придется использовать их для этого обновления, все они могут быть укоренены, если потребуется.
В настоящее время я просто запускаю процесс onCreate нового приложения, когда я получу рабочий код, у меня будет просто приложение в качестве фоновой службы, которое периодически проверяет сеть на наличие нового файла.
Это то, что я пробовал, но получаю ошибку ввода-вывода, а затем список местоположений на устройстве, в которых устройство ищет файл.
import java.io.IOException;
import java.io.InputStream;
import org.apache.commons.io.IOUtils;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ProcessBuilder pb = new ProcessBuilder("su","-c", "'pm install -r http://192.168.0.17:8080/updateTest/my.apk'");
try {
Process shell = pb.start();
InputStream shellIn = shell.getInputStream();
String response = IOUtils.toString(shellIn, "UTF-8");
Log.w("myApp.update", response);
shellIn.close();
shell.destroy();
} catch (IOException ex) {
Log.w("myApp.update", "failed" ex);
}
}
}
и сообщение logcat:
06-26 17:00:37.886: E/myApp.update(11072): failedjava.io.IOException: Error running exec(). Command: [su, -c, 'pm install -r http://192.168.0.17:8080/updateTest/myapp.apk'] Working Directory: null Environment: [ANDROID_SOCKET_zygote=9, SECONDARY_STORAGE=/storage/extSdCard:/storage/UsbDriveA:/storage/UsbDriveB:/storage/UsbDriveC:/storage/UsbDriveD:/storage/UsbDriveE:/storage/UsbDriveF, OMX_STE_ENS_COMPONENTS_DIR=/system/lib/ste_omxcomponents/, OMX_BELLAGIO_LOADER_REGISTRY=/system/omxloaders, ANDROID_BOOTLOGO=1, EXTERNAL_STORAGE=/storage/sdcard0, ANDROID_ASSETS=/system/app, ASEC_MOUNTPOINT=/mnt/asec, PATH=/system/sbin:/system/bin:/system/xbin:/sbin:/bin:/vendor/bin, LOOP_MOUNTPOINT=/mnt/obb, BOOTCLASSPATH=/system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/framework2.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar:/system/framework/sec_edm.jar:/system/framework/seccamera.jar, ANDROID_DATA=/data, ANDROID_ROOT=/system, LD_LIBRARY_PATH=/system/lib:/lib:/usr/lib:/system/lib/ste_omxcomponents/:/vendor/lib, ANDROID_PROPERTY_WORKSPACE=8,66560]
Итак, у кого-нибудь есть какие-либо идеи или опыт в этом?
Обновить
Хорошо, теперь я сначала беру файл, а затем пытаюсь установить, используя приведенный ниже код:
public class MainActivity extends ActionBarActivity {
private long enqueue;
private DownloadManager dm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
long downloadId = intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, 0);
Query query = new Query();
query.setFilterById(enqueue);
Cursor c = dm.query(query);
if (c.moveToFirst()) {
int columnIndex = c
.getColumnIndex(DownloadManager.COLUMN_STATUS);
if (DownloadManager.STATUS_SUCCESSFUL == c
.getInt(columnIndex)) {
//ImageView view = (ImageView) findViewById(R.id.imageView1);
String uriString = c
.getString(c
.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
// view.setImageURI(Uri.parse(uriString));
installapk();
}
}
}
}
private void installapk() {
ProcessBuilder pb = new ProcessBuilder("su","-c", "pm install -r " Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) "/sr.apk");
try {
Process shell = pb.start();
InputStream shellIn = shell.getInputStream();
String response = IOUtils.toString(shellIn, "UTF-8");
Log.e("myApp.update", response);
shellIn.close();
shell.destroy();
} catch (IOException ex) {
Log.e("myApp.update", "failed" ex);
}
}
};
registerReceiver(receiver, new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE));
onClick();
}
public void onClick() {
dm = (DownloadManager) this.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request req = new DownloadManager.Request(Uri.parse("http://192.168.0.62:12345/sr.apk"));
req.setTitle("sr.apk")
.setDescription("Downloading ....")
// download the package to the /sdcard/downlaod path.
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "sr.apk");
enqueue = dm.enqueue(req);
}
}
Однако я все еще получаю ту же ошибку! Устройство внедрено, и мои разрешения следующие:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
У кого-нибудь есть еще идеи ?!
Обновление 2!
Хорошо, хорошо, дважды проверил, и оказалось, что телефон не был укоренен! Теперь внедрен и попытался снова добавить требуемое разрешение суперпользователя в мой манифест, теперь приведенный ниже код выполняется до завершения без ошибок, однако ничего не установлено, и «ответ» пуст?
public class MainActivity extends ActionBarActivity {
private long enqueue;
private DownloadManager dm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
Query query = new Query();
query.setFilterById(enqueue);
Cursor c = dm.query(query);
if (c.moveToFirst()) {
int columnIndex = c
.getColumnIndex(DownloadManager.COLUMN_STATUS);
if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex))
{
installapk();
}
}
}
}
private void installapk() {
try {
ProcessBuilder pb = new ProcessBuilder("su","-c", "install -r " Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) "/sr.apk");
Process shell = pb.start();
pb.redirectErrorStream(true);
InputStream shellIn = shell.getInputStream();
String response = IOUtils.toString(shellIn, "UTF-8");
Log.e("myApp.update", response);
shellIn.close();
shell.destroy();
} catch (IOException ex) {
Log.e("myApp.update", "failed" ex);
}
}
};
registerReceiver(receiver, new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE));
onClick();
}
public void onClick() {
dm = (DownloadManager) this.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Request req = new DownloadManager.Request(Uri.parse("http://192.168.0.62:12345/sr.apk"));
req.setTitle("sr.apk").setDescription("Downloading ....").setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "sr.apk");
enqueue = dm.enqueue(req);
}
}
Кто-нибудь видит, что я делаю не так?
Комментарии:
1. в каком каталоге вы пытаетесь выполнить? вы пытались установить каталог с
pb.directory("/home");
помощью?2. хороший момент! Я предполагаю, что мне нужно будет сначала получить файл с сервера, а затем попытаться установить его, с моей стороны произошел сбой логики
3. «установить apk без вмешательства пользователя» — это невозможно без доступа суперпользователя
4. Все в порядке, я могу рутировать устройство, если это то, что вы имеете в виду
5. вопрос обновлен с последними попытками!