Skip to content

Commit 2497a94

Browse files
author
Steve Soltys
committed
Initial commit
0 parents  commit 2497a94

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+2567
-0
lines changed

.gitignore

+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
## Java
2+
*.class
3+
*.war
4+
*.ear
5+
hs_err_pid*
6+
7+
## Intellij
8+
out/
9+
lib/
10+
.idea/
11+
*.ipr
12+
*.iws
13+
*.iml
14+
15+
## Eclipse
16+
.classpath
17+
.project
18+
.metadata
19+
**/bin/
20+
tmp/
21+
*.tmp
22+
*.bak
23+
*.swp
24+
*~.nib
25+
local.properties
26+
.settings/
27+
.loadpath
28+
.externalToolBuilders/
29+
*.launch
30+
31+
## NetBeans
32+
**/nbproject/private/
33+
build/
34+
nbbuild/
35+
dist/
36+
nbdist/
37+
nbactions.xml
38+
nb-configuration.xml
39+
40+
## Gradle
41+
.gradle
42+
gradle-app.setting
43+
build/
44+
45+
## OS Specific
46+
.DS_Store
47+
48+
## Android
49+
gen/

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2017 Steve Soltys
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Backup
2+
A backup application for the [Android Open Source Project](https://source.android.com/).
3+
4+
## License
5+
This application is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).

app/build.gradle

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
apply plugin: 'com.android.application'
2+
3+
android {
4+
compileSdkVersion 26
5+
buildToolsVersion '26.0.1'
6+
7+
buildTypes {
8+
release {
9+
minifyEnabled false
10+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
11+
}
12+
}
13+
compileOptions {
14+
targetCompatibility 1.7
15+
sourceCompatibility 1.7
16+
}
17+
}
18+
19+
dependencies {
20+
compile fileTree(include: ['*.jar'], dir: 'libs')
21+
}

app/src/main/Android.mk

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
LOCAL_PATH := $(call my-dir)
2+
3+
include $(CLEAR_VARS)
4+
LOCAL_MODULE := com.stevesoltys.backup.xml
5+
LOCAL_MODULE_CLASS := ETC
6+
LOCAL_MODULE_TAGS := optional
7+
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/sysconfig
8+
LOCAL_SRC_FILES := $(LOCAL_MODULE)
9+
include $(BUILD_PREBUILT)
10+
11+
include $(CLEAR_VARS)
12+
LOCAL_PACKAGE_NAME := Backup
13+
LOCAL_MODULE_TAGS := optional
14+
LOCAL_REQUIRED_MODULES := com.stevesoltys.backup.xml
15+
LOCAL_PRIVILEGED_MODULE := true
16+
LOCAL_SRC_FILES := $(call all-java-files-under, java)
17+
LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res
18+
include $(BUILD_PACKAGE)

app/src/main/AndroidManifest.xml

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools"
4+
package="com.stevesoltys.backup">
5+
6+
<uses-permission android:name="android.permission.BACKUP"/>
7+
8+
<uses-sdk
9+
android:minSdkVersion="26"
10+
android:targetSdkVersion="26"/>
11+
12+
<application
13+
android:supportsRtl="true"
14+
android:theme="@style/AppTheme"
15+
android:icon="@mipmap/ic_launcher"
16+
android:label="@string/app_name"
17+
android:allowBackup="false"
18+
tools:replace="android:allowBackup">
19+
20+
<activity android:name="com.stevesoltys.backup.activity.MainActivity">
21+
<intent-filter>
22+
<action android:name="android.intent.action.MAIN"/>
23+
<category android:name="android.intent.category.LAUNCHER"/>
24+
</intent-filter>
25+
</activity>
26+
27+
<activity android:name="com.stevesoltys.backup.activity.backup.CreateBackupActivity"
28+
android:parentActivityName="com.stevesoltys.backup.activity.MainActivity">
29+
</activity>
30+
31+
<activity android:name="com.stevesoltys.backup.activity.restore.RestoreBackupActivity"
32+
android:parentActivityName="com.stevesoltys.backup.activity.MainActivity">
33+
</activity>
34+
35+
<service android:name="com.stevesoltys.backup.transport.ConfigurableBackupTransportService"
36+
android:exported="false">
37+
<intent-filter>
38+
<action android:name="android.backup.TRANSPORT_HOST" />
39+
</intent-filter>
40+
</service>
41+
42+
</application>
43+
</manifest>
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<config>
3+
<backup-transport-whitelisted-service
4+
service="com.stevesoltys.backup/.transport.ConfigurableBackupTransportService"/>
5+
</config>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
package com.stevesoltys.backup.activity;
2+
3+
import android.app.Activity;
4+
import android.content.Intent;
5+
import android.os.Bundle;
6+
import android.util.Log;
7+
import android.view.View;
8+
9+
import com.stevesoltys.backup.R;
10+
11+
public class MainActivity extends Activity implements View.OnClickListener {
12+
13+
public static final int CREATE_DOCUMENT_REQUEST_CODE = 1;
14+
15+
public static final int LOAD_DOCUMENT_REQUEST_CODE = 2;
16+
17+
private MainActivityController controller;
18+
19+
@Override
20+
protected void onCreate(Bundle savedInstanceState) {
21+
super.onCreate(savedInstanceState);
22+
setContentView(R.layout.activity_main);
23+
24+
findViewById(R.id.create_backup_button).setOnClickListener(this);
25+
findViewById(R.id.restore_backup_button).setOnClickListener(this);
26+
27+
controller = new MainActivityController();
28+
}
29+
30+
@Override
31+
public void onClick(View view) {
32+
int viewId = view.getId();
33+
34+
switch (viewId) {
35+
36+
case R.id.create_backup_button:
37+
controller.showCreateDocumentActivity(this);
38+
break;
39+
40+
case R.id.restore_backup_button:
41+
controller.showLoadDocumentActivity(this);
42+
break;
43+
}
44+
}
45+
46+
@Override
47+
public void onActivityResult(int requestCode, int resultCode, Intent result) {
48+
49+
if (resultCode != Activity.RESULT_OK) {
50+
Log.e(MainActivity.class.getName(), "Error in activity result: " + requestCode);
51+
return;
52+
}
53+
54+
switch (requestCode) {
55+
56+
case CREATE_DOCUMENT_REQUEST_CODE:
57+
controller.handleCreateDocumentResult(result, this);
58+
break;
59+
60+
case LOAD_DOCUMENT_REQUEST_CODE:
61+
controller.handleLoadDocumentResult(result, this);
62+
break;
63+
}
64+
}
65+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.stevesoltys.backup.activity;
2+
3+
import android.app.Activity;
4+
import android.content.ActivityNotFoundException;
5+
import android.content.Intent;
6+
import android.widget.Toast;
7+
8+
import com.stevesoltys.backup.activity.backup.CreateBackupActivity;
9+
import com.stevesoltys.backup.activity.restore.RestoreBackupActivity;
10+
11+
import static android.content.Intent.ACTION_CREATE_DOCUMENT;
12+
import static android.content.Intent.ACTION_OPEN_DOCUMENT;
13+
import static android.content.Intent.CATEGORY_OPENABLE;
14+
15+
/**
16+
* @author Steve Soltys
17+
*/
18+
class MainActivityController {
19+
20+
private static final String DOCUMENT_MIME_TYPE = "application/octet-stream";
21+
22+
void showCreateDocumentActivity(Activity parent) {
23+
Intent createDocumentIntent = new Intent(ACTION_CREATE_DOCUMENT);
24+
createDocumentIntent.addCategory(CATEGORY_OPENABLE);
25+
createDocumentIntent.setType(DOCUMENT_MIME_TYPE);
26+
27+
try {
28+
Intent documentChooser = Intent.createChooser(createDocumentIntent, "Select the backup location");
29+
parent.startActivityForResult(documentChooser, MainActivity.CREATE_DOCUMENT_REQUEST_CODE);
30+
31+
} catch (ActivityNotFoundException ex) {
32+
Toast.makeText(parent, "Please install a file manager.", Toast.LENGTH_SHORT).show();
33+
}
34+
}
35+
36+
void showLoadDocumentActivity(Activity parent) {
37+
Intent loadDocumentIntent = new Intent(ACTION_OPEN_DOCUMENT);
38+
loadDocumentIntent.addCategory(CATEGORY_OPENABLE);
39+
loadDocumentIntent.setType(DOCUMENT_MIME_TYPE);
40+
41+
try {
42+
Intent documentChooser = Intent.createChooser(loadDocumentIntent, "Select the backup location");
43+
parent.startActivityForResult(documentChooser, MainActivity.LOAD_DOCUMENT_REQUEST_CODE);
44+
45+
} catch (ActivityNotFoundException ex) {
46+
Toast.makeText(parent, "Please install a file manager.", Toast.LENGTH_SHORT).show();
47+
}
48+
}
49+
50+
void handleCreateDocumentResult(Intent result, Activity parent) {
51+
52+
if (result == null) {
53+
return;
54+
}
55+
56+
Intent intent = new Intent(parent, CreateBackupActivity.class);
57+
intent.setData(result.getData());
58+
parent.startActivity(intent);
59+
}
60+
61+
void handleLoadDocumentResult(Intent result, Activity parent) {
62+
63+
if (result == null) {
64+
return;
65+
}
66+
67+
Intent intent = new Intent(parent, RestoreBackupActivity.class);
68+
intent.setData(result.getData());
69+
parent.startActivity(intent);
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
package com.stevesoltys.backup.activity.backup;
2+
3+
import android.app.Activity;
4+
import android.app.backup.BackupProgress;
5+
import android.widget.PopupWindow;
6+
import android.widget.ProgressBar;
7+
import android.widget.TextView;
8+
import android.widget.Toast;
9+
10+
import com.stevesoltys.backup.R;
11+
import com.stevesoltys.backup.session.backup.BackupResult;
12+
import com.stevesoltys.backup.session.backup.BackupSession;
13+
import com.stevesoltys.backup.session.backup.BackupSessionObserver;
14+
import com.stevesoltys.backup.transport.ConfigurableBackupTransport;
15+
import com.stevesoltys.backup.transport.ConfigurableBackupTransportService;
16+
17+
/**
18+
* @author Steve Soltys
19+
*/
20+
class BackupObserver implements BackupSessionObserver {
21+
22+
private final Activity context;
23+
24+
private final PopupWindow popupWindow;
25+
26+
BackupObserver(Activity context, PopupWindow popupWindow) {
27+
this.context = context;
28+
this.popupWindow = popupWindow;
29+
}
30+
31+
@Override
32+
public void backupPackageStarted(BackupSession backupSession, String packageName, BackupProgress backupProgress) {
33+
context.runOnUiThread(() -> {
34+
35+
TextView textView = popupWindow.getContentView().findViewById(R.id.popup_text_view);
36+
37+
if (textView != null) {
38+
textView.setText(packageName);
39+
}
40+
41+
ProgressBar progressBar = popupWindow.getContentView().findViewById(R.id.popup_progress_bar);
42+
43+
if (progressBar != null) {
44+
progressBar.setMax((int) backupProgress.bytesExpected);
45+
progressBar.setProgress((int) backupProgress.bytesTransferred);
46+
}
47+
});
48+
}
49+
50+
@Override
51+
public void backupPackageCompleted(BackupSession backupSession, String packageName, BackupResult result) {
52+
context.runOnUiThread(() -> {
53+
54+
TextView textView = popupWindow.getContentView().findViewById(R.id.popup_text_view);
55+
56+
if (textView != null) {
57+
textView.setText(packageName);
58+
}
59+
});
60+
}
61+
62+
@Override
63+
public void backupSessionCompleted(BackupSession backupSession, BackupResult backupResult) {
64+
ConfigurableBackupTransport backupTransport = ConfigurableBackupTransportService.getBackupTransport();
65+
66+
if (backupTransport.getRestoreComponent() == null || backupTransport.getBackupComponent() == null) {
67+
return;
68+
}
69+
70+
backupTransport.setBackupComponent(null);
71+
backupTransport.setRestoreComponent(null);
72+
73+
context.runOnUiThread(() -> {
74+
if (backupResult == BackupResult.SUCCESS) {
75+
Toast.makeText(context, R.string.backup_success, Toast.LENGTH_LONG).show();
76+
77+
} else if (backupResult == BackupResult.CANCELLED) {
78+
Toast.makeText(context, R.string.backup_cancelled, Toast.LENGTH_LONG).show();
79+
80+
} else {
81+
Toast.makeText(context, R.string.backup_failure, Toast.LENGTH_LONG).show();
82+
}
83+
84+
popupWindow.dismiss();
85+
context.finish();
86+
});
87+
}
88+
}

0 commit comments

Comments
 (0)