Страница 1 из 1

Как считать SharedPreferences другого приложения ???

Добавлено: 21 апр 2014, 10:03
CrazyManQ
День добрый.
Возникла необходимость считать данные из SharedPreferences другого приложения из своего.
Нужна именно программная реализация, рут есть.
В принципе мысль такая:
При запуске программы, скопировать файл из /data/data/<package>/shared_pref/preferences.xml в каталог Shared_Pref своей программы
и уже в своей проге считать данные.
вот сам файл:

Код: Выделить всё

<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<map>
<string name="server_address">8.8.8.8</string>
<int name="port" value="2222" />
<int name="user_name" value="5555" />
</map>
данные считываются тут:

Код: Выделить всё

public class MainActivity extends Activity {
        // описываем переменные
          public static final String PREFS_NAME = "preferences.xml";
	  protected SharedPreferences mSettings = null;
	  private EditText mServerAddressText;
	  private EditText mUserNameText;
	  private EditText mPortText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        // связываем переменные с View
        this.mServerAddressText = (EditText) findViewById(R.id.settingServerText);
	this.mUserNameText = (EditText) findViewById(R.id.settingUserText);
	this.mPortText = (EditText) findViewById(R.id.settingBalancePortText);
        // получаем сохраненные данные
        this.mSettings = getSettings();
        this.mServerAddressText.setText(this.mSettings.getString("server_address", "8.8.8.8"));
        this.mUserNameText.setText(String.valueOf(this.mSettings.getInt("user name", 5555)));
        this.mPortText.setText(String.valueOf(this.mSettings.getInt("port", 2222)));
    }
    public SharedPreferences getSettings()
    {
      SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
      return settings;
    }
Теперь вопрос, а как можно скопировать нужный файл ???

Re: Как считать SharedPreferences другого приложения ???

Добавлено: 22 апр 2014, 06:03
klblk
[syntax=java]public static void copy(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);

// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}[/syntax]

Re: Как считать SharedPreferences другого приложения ???

Добавлено: 22 апр 2014, 08:42
CrazyManQ
[syntax=java][/syntax]
klblk писал(а):[syntax=java]public static void copy(File src, File dst) throws IOException {[syntax=html5][/syntax]
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);

// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}[/syntax]
Спасибо за ответ!
такой способ пробовал, но он не прокатил, так как процесс требовал прав администратора, а как его задать при выполнении данной операции я не нашел.

Решил сделать чуть по другому:
[syntax=java]
private boolean cp(File source, File dest) throws IOException{
Process sh = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(sh.getOutputStream());
//DataInputStream is = new DataInputStream(sh.getInputStream());
os.writeBytes("cp "+source+" "+dest+" \n");
os.writeBytes("chmod -R 777 "+dest+" \n");
os.writeBytes("exit\n");
os.flush();
os.close();
return true;
}
[/syntax]
может это и не совсем идеально, но по крайней мере сработало!
только после того как сделать последнюю команду (chmod -R 777 ), скопированный файл становиться доступным программе!!!

Re: Как считать SharedPreferences другого приложения ???

Добавлено: 22 апр 2014, 10:49
KamiSempai
С SharedPreferences можно работать на прямую, без копирования файлов, к тому же даже рут не нужен.
Код первого приложения:[syntax=java]SharedPreferences preferences = getSharedPreferences("pref_file", MODE_WORLD_READABLE);
preferences.edit().putString("p", "test").commit();[/syntax]
Код приложения, что использует преференсы первого:[syntax=java]Context context = createPackageContext("com.example.app1", 0);
SharedPreferences prefs = context.getSharedPreferences("pref_file", MODE_WORLD_READABLE);
Toast.makeText(this, prefs.getString("p", "-"), Toast.LENGTH_LONG).show();[/syntax]В результате получим тост с текстом "test".
"com.example.app1" - имя пакета первого приложения.

Вся соль в MODE_WORLD_READABLE, с этим флагом файл преференсов становится видимым для остальных приложений, а если указать MODE_WORLD_WRITEABLE он будет еще и на запись доступен. Этот флаг, начиная с API 17, помечен как Deprecated, в описании говорится, нужно использовать другие, более безопасные способы, такие как ContentProvider, BroadcastReceiver, и Service. Но раз вас копирование через рут не остановило, пометка Deprecated - это вообще не значимая мелочь, к тому же поставленная, относительно, недавно.

Кстати, таким способом можно легко получить доступ почти ко всем ресурсам приложения, например к изображениям или стилям.

Да, и не забудьте по уму обработать исключение для createPackageContext. Этот метод нужно обернуть в try catch, так как он вызывает исключение если приложение с таким пакетом не установлено.

Re: Как считать SharedPreferences другого приложения ???

Добавлено: 22 апр 2014, 13:54
CrazyManQ
"KamiSempai"
Довольно не плохая мысль !!!
Но первое приложение не мое, соответственно выставить флаг MODE_WORLD_READABLE на его preferences я не могу!
Наверно поэтому код в моем случае не отрабатывает :(
[syntax=java]
try {
Context context = createPackageContext("ru.other.app", 0);
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, MODE_WORLD_READABLE);
Toast.makeText(this, prefs.getString("server_address", "-------"), Toast.LENGTH_LONG).show();
} catch (NameNotFoundException e) {
e.printStackTrace();
}
[/syntax]

Re: Как считать SharedPreferences другого приложения ???

Добавлено: 22 апр 2014, 15:48
Mykola
android:process
The name of a process where all components of the application should run. Each component can override this default by setting its own process attribute.
By default, Android creates a process for an application when the first of its components needs to run. All components then run in that process. The name of the default process matches the package name set by the <manifest> element.

By setting this attribute to a process name that's shared with another application, you can arrange for components of both applications to run in the same process — but only if the two applications also share a user ID and be signed with the same certificate.

If the name assigned to this attribute begins with a colon (':'), a new process, private to the application, is created when it's needed. If the process name begins with a lowercase character, a global process of that name is created. A global process can be shared with other applications, reducing resource usage.

Re: Как считать SharedPreferences другого приложения ???

Добавлено: 22 апр 2014, 16:50
KamiSempai
К чему эта портянка на английском?

Re: Как считать SharedPreferences другого приложения ???

Добавлено: 22 апр 2014, 18:15
Mykola
KamiSempai писал(а):К чему эта портянка на английском?
Да вы правы не выйдет:"be signed with the same certificate."