Skip to content

Commit 5fdc0eb

Browse files
committed
export & import without enryption, new image viewer
1 parent 4d51d2d commit 5fdc0eb

Some content is hidden

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

50 files changed

+626
-107
lines changed

app/build.gradle

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
apply plugin: 'com.android.application'
22

33
android {
4-
compileSdkVersion 28
4+
compileSdkVersion 30
55
defaultConfig {
66
applicationId "com.katcom.androidFileVault"
77
minSdkVersion 19
88
targetSdkVersion 28
99
versionCode 1
1010
versionName "1.0"
1111
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
12+
vectorDrawables.useSupportLibrary = true
1213
}
1314
buildTypes {
1415
release {

app/src/main/AndroidManifest.xml

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,17 +9,28 @@
99
android:roundIcon="@mipmap/ic_launcher_round"
1010
android:supportsRtl="true"
1111
android:theme="@style/AppTheme">
12-
<activity android:name=".login.LoginActivity" ></activity>
13-
<activity android:name=".VaultActivity" android:exported="false"/>
14-
<activity android:name=".ImageViewerActivity" android:exported="false"/>
15-
<activity android:name=".login.SetPasswordActivity" android:exported="false"/>
16-
<activity android:name=".EntryActivity" android:theme="@style/hideTitle">
12+
<activity android:name=".ExportActivity"></activity>
13+
<activity android:name=".login.LoginActivity" />
14+
<activity
15+
android:name=".VaultActivity"
16+
android:exported="false" />
17+
<activity
18+
android:name=".ImageViewerActivity"
19+
android:exported="false" />
20+
<activity
21+
android:name=".login.SetPasswordActivity"
22+
android:exported="false" />
23+
<activity
24+
android:name=".EntryActivity"
25+
android:theme="@style/hideTitle">
1726
<intent-filter>
1827
<action android:name="android.intent.action.MAIN" />
1928

2029
<category android:name="android.intent.category.LAUNCHER" />
2130
</intent-filter>
2231
</activity>
23-
</application>
2432

33+
</application>
34+
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
35+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
2536
</manifest>

app/src/main/java/com/katcom/androidFileVault/Crypto.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import android.net.Uri;
44

5+
import javax.crypto.CipherInputStream;
56
import javax.crypto.CipherOutputStream;
67

78
public interface Crypto {
@@ -39,7 +40,7 @@ public interface Crypto {
3940
* @param filepath
4041
* @return
4142
*/
42-
CipherOutputStream getDecryptedInputStream(String filepath);
43+
CipherInputStream getDecryptedInputStream(String filepath);
4344

4445

4546
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package com.katcom.androidFileVault;
2+
3+
import androidx.appcompat.app.AppCompatActivity;
4+
import androidx.fragment.app.Fragment;
5+
6+
import android.os.Bundle;
7+
8+
public class ExportActivity extends SingleFragmentActivity {
9+
10+
@Override
11+
protected Fragment createFragment() {
12+
return new ExportFragment();
13+
}
14+
15+
}
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package com.katcom.androidFileVault;
2+
3+
import android.Manifest;
4+
import android.app.Activity;
5+
import android.content.ContentResolver;
6+
import android.content.Context;
7+
import android.content.pm.PackageManager;
8+
import android.database.Cursor;
9+
import android.os.Build;
10+
import android.os.Bundle;
11+
import android.os.Environment;
12+
import android.provider.MediaStore;
13+
import android.util.Log;
14+
import android.view.LayoutInflater;
15+
import android.view.View;
16+
import android.view.ViewGroup;
17+
import android.widget.Button;
18+
import android.widget.TextView;
19+
20+
import androidx.annotation.NonNull;
21+
import androidx.core.app.ActivityCompat;
22+
import androidx.core.content.ContextCompat;
23+
import androidx.fragment.app.Fragment;
24+
import androidx.recyclerview.widget.RecyclerView;
25+
26+
import java.io.File;
27+
import java.util.ArrayList;
28+
import java.util.List;
29+
30+
public class ExportFragment extends Fragment {
31+
private RecyclerView currentLocationRecyclerView;
32+
private RecyclerView directoryRecyclerView;
33+
private RecyclerView.Adapter currentAdapter;
34+
private RecyclerView.Adapter directoryAdapter;
35+
private Button previousButton;
36+
private static String TAG = "ExportFragment";
37+
@Override
38+
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
39+
View v = inflater.inflate(R.layout.fragment_export,container,false);
40+
currentLocationRecyclerView = v.findViewById(R.id.export_current_location_recycler_view);
41+
directoryRecyclerView = v.findViewById(R.id.export_directory_recycler_view);
42+
previousButton = v.findViewById(R.id.export_previous_button);
43+
44+
updateUI();
45+
return v;
46+
}
47+
48+
private void updateUI() {
49+
if(requestExternalStoragePermission(getContext())){
50+
List<File> files = getExternalFiles();
51+
for(File file : files){
52+
Log.v(TAG,"FILE:" + file.getName());
53+
}
54+
}else{
55+
Log.e(TAG,"no permission");
56+
}
57+
58+
59+
}
60+
61+
private List<File> getExternalFiles() {
62+
List<File> files = new ArrayList<>();
63+
64+
Cursor cursor =null;
65+
ContentResolver resolver;
66+
67+
resolver = getContext().getContentResolver();
68+
cursor = resolver.query(MediaStore.Files.getContentUri("external"), null, null, null, null);
69+
int columnIndexOrThrow_ID = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID);
70+
int columnIndexOrThrow_MIME_TYPE = cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MIME_TYPE);
71+
while(cursor.moveToNext()){
72+
String path = cursor.getString(columnIndexOrThrow_ID);
73+
File file = new File(path);
74+
files.add(file);
75+
}
76+
77+
cursor.close();
78+
return files;
79+
}
80+
81+
private class FileHolder extends RecyclerView.ViewHolder{
82+
TextView mTextView;
83+
public FileHolder(@NonNull View itemView) {
84+
super(itemView);
85+
mTextView = itemView.findViewById(R.id.item_export_folder);
86+
}
87+
}
88+
89+
private class FileAdapter extends RecyclerView.Adapter<FileHolder>{
90+
private List<File> mFiles;
91+
public FileAdapter(List<File> files){
92+
mFiles = files;
93+
}
94+
95+
@NonNull
96+
@Override
97+
public FileHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
98+
View v = LayoutInflater.from(getContext()).inflate(R.layout.item_export_folder,parent, false);
99+
100+
return new FileHolder(v);
101+
}
102+
103+
@Override
104+
public void onBindViewHolder(@NonNull FileHolder holder, int position) {
105+
File file = mFiles.get(position);
106+
holder.mTextView.setText(file.getName());
107+
}
108+
109+
@Override
110+
public int getItemCount() {
111+
return mFiles.size();
112+
}
113+
}
114+
115+
private boolean requestExternalStoragePermission(@NonNull Context context){
116+
if(!hasExternalStoragePermission()){
117+
ActivityCompat.requestPermissions((Activity) context, new String[]{Manifest.permission.MANAGE_EXTERNAL_STORAGE}, 100);
118+
}
119+
120+
Log.v(TAG,"IS EXTERNAL MANAGER");
121+
return true;
122+
123+
}
124+
125+
private boolean hasExternalStoragePermission(){
126+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
127+
return Environment.isExternalStorageManager();
128+
}else{
129+
return false;
130+
}
131+
}
132+
}

app/src/main/java/com/katcom/androidFileVault/FileVault.java renamed to app/src/main/java/com/katcom/androidFileVault/FileManager.java

Lines changed: 85 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package com.katcom.androidFileVault;
22

3+
import android.content.ContentResolver;
34
import android.content.Context;
5+
import android.database.Cursor;
46
import android.graphics.Bitmap;
5-
import android.graphics.BitmapFactory;
7+
import android.net.Uri;
8+
import android.provider.OpenableColumns;
69
import android.util.Log;
10+
import android.widget.Toast;
711

8-
import java.io.BufferedInputStream;
912
import java.io.BufferedOutputStream;
1013
import java.io.File;
14+
import java.io.FileDescriptor;
1115
import java.io.FileInputStream;
1216
import java.io.FileNotFoundException;
1317
import java.io.FileOutputStream;
@@ -21,31 +25,23 @@
2125
import javax.crypto.CipherInputStream;
2226
import javax.crypto.CipherOutputStream;
2327

24-
public class FileVault {
28+
public class FileManager{
2529
public static String TAG ="FileVault"; // For debug
2630
public static String sVaultDirectory = "FileVaultOne"; // The directory of the vault in the private storage of this app
27-
private static FileVault sVault; // This class is a singleton, only one instance allowed
31+
private static FileManager sVault; // This class is a singleton, only one instance allowed
2832
private List<ProtectedFile> mFiles; // Entries of all files
2933
private Context mContext; // Android context, used to get to the private storage
3034

31-
private FileVault(Context context){
35+
private FileManager(Context context){
3236
mContext= context;
33-
File directory = context.getFilesDir();
34-
File vaultFolder = new File(directory, sVaultDirectory);
35-
36-
String[] files = vaultFolder.list();
3737

3838
mFiles = new ArrayList<ProtectedFile>();
3939

40-
for(String filename: files){
41-
String path = mContext.getFilesDir() + "/" + sVaultDirectory +"/" + filename;
42-
ProtectedFile file = new ProtectedFile(filename,path,UUID.randomUUID());
43-
mFiles.add(file);
44-
}
40+
update();
4541
}
46-
public static FileVault get(Context context){
42+
public static FileManager get(Context context){
4743
if(sVault == null) {
48-
sVault = new FileVault(context);
44+
sVault = new FileManager(context);
4945
}
5046
return sVault;
5147
}
@@ -63,6 +59,23 @@ public ProtectedFile getFile(UUID id){
6359
return null;
6460
}
6561

62+
public void update(){
63+
File directory = mContext.getFilesDir();
64+
File vaultFolder = new File(directory, sVaultDirectory);
65+
mFiles = new ArrayList<ProtectedFile>();
66+
String[] files = vaultFolder.list();
67+
68+
for(String filename: files){
69+
String path = mContext.getFilesDir() + "/" + sVaultDirectory +"/" + filename;
70+
ProtectedFile file = new ProtectedFile(filename,path,UUID.randomUUID());
71+
mFiles.add(file);
72+
}
73+
}
74+
public void addFileEntry(String filename, String filepath){
75+
ProtectedFile file = new ProtectedFile(filename,filepath,UUID.randomUUID());
76+
mFiles.add(file);
77+
}
78+
6679
public String getVaultDirectory(){
6780
return sVaultDirectory;
6881
}
@@ -95,26 +108,70 @@ public void importFile(String filepath, String targetPath,String filename){
95108
Utils.copyFile(filepath,targetPath);
96109
addFileEntry(filename,targetPath);
97110
}
111+
public void importFile(String filename,FileDescriptor in, String targetPath) throws FileNotFoundException {
112+
importAndEncrypt(in,targetPath);
113+
addFileEntry(filename,targetPath);
114+
}
115+
public void exportFile(ProtectedFile file, FileDescriptor fd) throws FileNotFoundException {
116+
//File outFile = new File(targetPath);
117+
OutputStream out=null;
118+
InputStream in =null;
119+
out = new FileOutputStream(fd);
120+
in = new FileInputStream(file.getFilepath());
121+
writeFile(in,out);
98122

99-
private void addFileEntry(String filename, String targetPath) {
100123
}
101124

102-
public void exportFile(String filename, String sourcePath,String targetPath){
103-
// TODO
125+
public CipherOutputStream getEncryptedFileOutStream(String targetPath, String key, byte[] iv) {
126+
return null;
104127
}
105128

106-
public void importAndEncryptFileToRootDirectory(String filename,InputStream in){
129+
private OutputStream getFileOutputStream(String targetPath) throws FileNotFoundException {
130+
return new FileOutputStream(targetPath);
131+
132+
};
107133

134+
public void importAndEncrypt(FileDescriptor inFile, String targetPath) throws FileNotFoundException {
135+
OutputStream out=null;
136+
InputStream in =null;
137+
in = new FileInputStream(inFile);
138+
out = getFileOutputStream(targetPath);
139+
140+
writeFile(in,out);
108141
}
109142

110-
public void importAndEncryptFile(InputStream in,String targetPath){
111-
CipherInputStream cin = getEncodedInputStream(in);
112-
copyEncryptedFile(cin,targetPath);
143+
public CipherInputStream getDecryptedInputStream(String filepath) {
144+
CipherInputStream out = null;
145+
146+
return out;
113147
}
114148

115-
private CipherInputStream getEncodedInputStream(InputStream in) {
116-
// TODO
117-
return (CipherInputStream)in;
149+
150+
private void writeFile(InputStream in, OutputStream out){
151+
try {
152+
153+
byte[] buffer = new byte[1024];
154+
int i;
155+
156+
int tot = 0;
157+
while ((i = in.read(buffer)) != -1) {
158+
tot += i;
159+
out.write(buffer, 0, i);
160+
}
161+
162+
out.flush();
163+
} catch (FileNotFoundException e) {
164+
Log.e(TAG,e.toString());
165+
} catch (IOException e) {
166+
Log.e(TAG,e.toString());
167+
} finally {
168+
try{
169+
if(out != null) out.close();
170+
if(in != null) in.close();
171+
}catch (IOException ioe){
172+
ioe.printStackTrace();
173+
}
174+
}
118175
}
119176

120177
private void copyEncryptedFile(CipherInputStream cin, String targetPath){
@@ -139,4 +196,6 @@ private void copyEncryptedFile(CipherInputStream cin, String targetPath){
139196
}
140197

141198
}
199+
200+
142201
}

0 commit comments

Comments
 (0)