Проблема:
В Android нет способа указать отдельные папки в папке DCIM, которые вы хотите синхронизировать с облаком.Приложение Facebook сохраняет изображения в DCIM / Facebook, поэтому любое сохраненное изображение автоматически синхронизируется с облаком.Я могу решить эту проблему, поместив файл .NOMEDIA в папку, но теперь это означает, что я не могу просматривать файлы, не заходя в проводник, поэтому я теряю легкий доступ, например, для отправки этих изображений в сообщениях.
В настоящее время я работаю над приложением Android для автоматического перемещения файлов, кроме файла .NOMDEIA, из DCIM / Facebook в Pictures / Facebook.В настоящее время у меня есть код, который будет делать это в классе MainActivity, и я хочу преобразовать его в службу, которая будет запускаться автоматически.
Короче говоря, я хочу, чтобы эта служба запускалась при загрузке и всегда работала без отображенияактивность, так что отнимает все ручные усилия с моей стороны.Опять же, я не хочу запускать что-либо вручную и не вижу необходимости в действиях, поскольку не хочу никакого взаимодействия с пользователем.Я прочитал много страниц, заблудился в документации и, по-видимому, был на бесчисленных постах, касающихся Service, IntentService, JobScheduler и т. Д., И в настоящее время я крутлю свои колеса как на реализацию, так и на правильный подход.
Является ли этохороший случай для JobSchedule, который запускается каждые несколько секунд?Должна ли это быть служба, которая запускает код снова и снова в цикле, который ждет несколько секунд в каждой итерации?Можно ли вызвать службу при добавлении чего-либо в папку?
Как уже упоминалось выше, я боролся с реализацией.На данный момент единственное, что мне удалось сделать, - это вызвать службу из MainActivity, но это происходит, когда действие кратковременно открывается и закрывается.Это нежелательное поведение.Ситуация становится немного запутанной, поэтому я решил не включать какой-либо код в надежде, что кто-то может либо указать мне на правильную документацию / учебное пособие, либо предоставить надлежащий скелет, с которым я могу работать.Я бы предпочел не мутить воду с самого начала.
Важное примечание: у меня есть реализация с запросом активности для READ_EXTERNAL_STORAGE (насколько я понимаю, вам не нужно запрашивать разрешение для WRITE_EXTERNAL_STORAGE; мой кодработает без запроса такого разрешения), но я также не уверен, как это сделать для службы, поскольку метод запроса разрешений, по-видимому, требует активности в качестве одного из параметров.
Редактировать: Добавление манифеста и кода дляполучатель и сервис
FacebookImageListener.java
public class FacebookImageListener extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, FacebookImageMoverService.class));
Log.i("FacebookImageMoverService", "started");
}
}
FacebookImageMoverService.java
public class FacebookImageMoverService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
while (true) {
//TODO remove this
Log.i("imagemover", "DELETE THIS");
// String path = this.getExternalFilesDir(Environment.DIRECTORY_DCIM).getAbsolutePath() + "/Facebook";
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath() + "/Facebook";
Log.d("Files", "Path: " + path);
File directory = new File(path);
File[] files = directory.listFiles();
Log.d("Files", "Size: " + files.length);
for (int i = 0; i < files.length; i++) {
Toast toast = Toast.makeText(this.getApplicationContext(), "FileName:" + files[i].getName(), Toast.LENGTH_LONG);
toast.show();
Log.d("Files", "FileName:" + files[i].getName());
if (!files[i].getName().equals(".NOMEDIA")) {
// moveFile(path + "/", files[i].getName(), this.getExternalFilesDir(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/Facebook/");
moveFile(path + "/", files[i].getName(), Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).getAbsolutePath() + "/Facebook/");
}
}
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//TODO check this out
// return Service.START_NOT_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
//TODO for communication return IBinder implementation
return null;
}
private void moveFile(String inputPath, String inputFile, String outputPath) {
InputStream in = null;
OutputStream out = null;
try {
//create output directory if it doesn't exist
File dir = new File(outputPath);
if (!dir.exists()) {
dir.mkdirs();
}
in = new FileInputStream(inputPath + inputFile);
out = new FileOutputStream(outputPath + inputFile);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
in = null;
// write the output file
out.flush();
out.close();
out = null;
// delete the original file
new File(inputPath + inputFile).delete();
} catch (FileNotFoundException fnfe1) {
Log.e("tag", fnfe1.getMessage());
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="shogg.facebookimagemover"
>
<!--<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />-->
<!--<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />-->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:label="@string/app_name"
android:icon="@mipmap/ic_launcher"
android:roundIcon="@mipmap/ic_launcher_round">
<receiver android:name=".FacebookImageListener"
android:icon="@mipmap/ic_launcher"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service android:enabled="true" android:name=".FacebookImageMoverService" />
</application>
</manifest>