Skip to content

Commit b4adafb

Browse files
committed
first
1 parent af8c37f commit b4adafb

File tree

16 files changed

+172
-28
lines changed

16 files changed

+172
-28
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@
44

55
<application
66
android:allowBackup="true"
7-
android:icon="@mipmap/ic_launcher"
7+
android:icon="@mipmap/ic_vault_launcher"
88
android:label="@string/app_name"
9-
android:roundIcon="@mipmap/ic_launcher_round"
9+
android:roundIcon="@mipmap/ic_vault_launcher"
1010
android:supportsRtl="true"
1111
android:theme="@style/AppTheme">
1212
<activity android:name=".ExportActivity"></activity>
1313
<activity android:name=".login.LoginActivity" />
1414
<activity
1515
android:name=".VaultActivity"
16-
android:exported="false" />
16+
android:exported="false">
17+
18+
</activity>
1719
<activity
1820
android:name=".ImageViewerActivity"
1921
android:exported="false" />
@@ -29,7 +31,20 @@
2931
<category android:name="android.intent.category.LAUNCHER" />
3032
</intent-filter>
3133
</activity>
32-
34+
<provider
35+
android:name="androidx.core.content.FileProvider"
36+
android:authorities="com.katcom.androidFileVault.fileprovider"
37+
android:exported="false"
38+
android:grantUriPermissions="true">
39+
<meta-data
40+
android:name="android.support.FILE_PROVIDER_PATHS"
41+
android:resource="@xml/file_paths"/>
42+
</provider>
43+
<receiver android:name=".CloseReceiver">
44+
<intent-filter>
45+
<action android:name="com.katcom.androidFileVault.Exit" />
46+
</intent-filter>
47+
</receiver>
3348
</application>
3449
<uses-feature
3550
android:name="android.hardware.camera"
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.katcom.androidFileVault;
2+
3+
import android.app.Activity;
4+
import android.content.BroadcastReceiver;
5+
import android.content.Context;
6+
import android.content.Intent;
7+
8+
/**
9+
* Close the app by killing all activities using broadcast
10+
* Ref:https://blog.csdn.net/totond/article/details/72960211
11+
*/
12+
public class CloseReceiver extends BroadcastReceiver {
13+
public static String CLOSE_INTENT = "com.katcom.androidFileVault.Exit";
14+
15+
private Activity activity;
16+
17+
// Default constructor
18+
public CloseReceiver(){};
19+
20+
// Constructor using activity
21+
public CloseReceiver(Activity activity){
22+
this.activity = activity;
23+
}
24+
25+
@Override
26+
public void onReceive(Context context, Intent intent) {
27+
activity.finish();
28+
}
29+
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa
4646
@Override
4747
public void onClick(View v) {
4848
openVault();
49+
//testOpenVault();
4950
}
5051
});
5152

@@ -59,6 +60,7 @@ public void onClick(View v) {
5960
* Otherwise, shows the screen where user can login by entering the password.
6061
*/
6162
private void openVault() {
63+
6264
if(!hasPassword()){
6365
// Launch activity to setup password
6466
setPassword();
@@ -74,6 +76,12 @@ private void openVault() {
7476
}
7577
}
7678

79+
// Testing only
80+
private void testOpenVault(){
81+
Intent intent= new Intent(this.getContext(), VaultActivity.class);
82+
startActivity(intent);
83+
}
84+
7785
/**
7886
* Generate a private key in the vault for encryption and decryption of files
7987
*/

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
import javax.crypto.spec.GCMParameterSpec;
5151

5252
public class FileManager{
53+
private static final String sSharedFolderPath = "sharedFiles";
5354
public static String TAG ="FileVault"; // For debug
5455
public static String sVaultDirectory = "FileVaultOne"; // The directory of the vault in the private storage of this app
5556
private static FileManager sVault; // This class is a singleton, only one instance allowed
@@ -219,6 +220,22 @@ public void exportFile(ProtectedFile file, OutputStream out) throws FileNotFound
219220
writeFile(in,out);
220221
}
221222

223+
public void exportSharedFile(ProtectedFile file) throws IOException, NoSuchAlgorithmException, UnrecoverableEntryException, KeyStoreException {
224+
225+
File sharedFile = createSharedFile(file);
226+
227+
OutputStream out = getFileOutputStream(sharedFile.getPath());
228+
exportFile(file,out);
229+
}
230+
231+
public File createSharedFile(ProtectedFile file){
232+
String tempFileLocation = mContext.getCacheDir() + "/"+getSharedFolderPath()+"/" + file.getFilename();
233+
File tempFile = new File(tempFileLocation);
234+
if(!tempFile.getParentFile().exists()){
235+
tempFile.getParentFile().mkdir();
236+
}
237+
return tempFile;
238+
}
222239
//********************** End Export Functions ************************************//
223240

224241
//********************** Start Encrypt Functions *********************************//
@@ -554,6 +571,9 @@ private void writeFile(InputStream in, OutputStream out){
554571
}
555572
}
556573

574+
private String getSharedFolderPath(){
575+
return this.sSharedFolderPath;
576+
}
557577

558578

559579
/**

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

Lines changed: 54 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66
import android.net.Uri;
77
import android.os.AsyncTask;
88
import android.os.Bundle;
9+
10+
import androidx.core.content.FileProvider;
911
import androidx.fragment.app.Fragment;
10-
import androidx.appcompat.app.AlertDialog;
1112

1213
import android.util.Log;
1314
import android.view.LayoutInflater;
@@ -18,12 +19,12 @@
1819
import android.view.ViewGroup;
1920
import android.widget.ImageView;
2021
import android.widget.ProgressBar;
21-
import android.widget.Toolbar;
2222

2323
import java.io.File;
24-
import java.io.FileNotFoundException;
24+
import java.io.FileOutputStream;
2525
import java.io.IOException;
2626
import java.io.InputStream;
27+
import java.io.OutputStream;
2728
import java.security.KeyStoreException;
2829
import java.security.NoSuchAlgorithmException;
2930
import java.security.UnrecoverableEntryException;
@@ -34,6 +35,7 @@ public class ImageViewerFragment extends Fragment {
3435
private static final String ARG_FILE = "file";
3536
private static final String TAG = "ImageViewer";
3637

38+
FileManager vault = FileManager.get(getContext());
3739
private ImageView mImageView;
3840
private ProtectedFile mFile;
3941
private int WRITE_REQUEST_CODE = 0;
@@ -85,6 +87,9 @@ public boolean onOptionsItemSelected(MenuItem item) {
8587
case R.id.menu_image_viewer_export:
8688
export();
8789
break;
90+
case R.id.menu_image_viewer_share:
91+
share();
92+
break;
8893
}
8994
return true;
9095
}
@@ -97,11 +102,22 @@ private void export() {
97102
startActivityForResult(intent, WRITE_REQUEST_CODE);
98103
}
99104
private void share() {
100-
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
101-
intent.addCategory(Intent.CATEGORY_OPENABLE);
102-
intent.setType("image/*");
103-
intent.putExtra(Intent.EXTRA_TITLE, mFile.getFilename());
104-
startActivityForResult(intent, WRITE_REQUEST_CODE);
105+
new ShareImageTask().executeOnExecutor(executor,mFile);
106+
107+
}
108+
private void shareImage(Uri fileUri) {
109+
Intent shareIntent = createShareImageIntent(fileUri);
110+
111+
startActivity(Intent.createChooser(shareIntent, getResources().getText(R.string.send_to)));
112+
}
113+
private Intent createShareImageIntent(Uri uriToImage){
114+
Intent shareIntent = new Intent();
115+
shareIntent.setAction(Intent.ACTION_SEND);
116+
shareIntent.putExtra(Intent.EXTRA_STREAM, uriToImage);
117+
shareIntent.setType("image/jpeg");
118+
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
119+
shareIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
120+
return shareIntent;
105121
}
106122
@Override
107123
public void onActivityResult(int requestCode, int resultCode, Intent data) {
@@ -116,7 +132,6 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
116132
}
117133

118134
private void export(Uri uri) {
119-
FileManager vault = FileManager.get(getContext());
120135
try {
121136
vault.exportFile(mFile,getContext().getContentResolver().openOutputStream(uri));
122137
} catch (NoSuchAlgorithmException | KeyStoreException | UnrecoverableEntryException | IOException e) {
@@ -141,6 +156,36 @@ protected void onPostExecute(Void aVoid) {
141156
}
142157
}
143158

159+
private class ShareImageTask extends AsyncTask<ProtectedFile,Void,Void> {
160+
File file;
161+
InputStream in;
162+
Uri fileUri;
163+
@Override
164+
protected Void doInBackground(ProtectedFile... files) {
165+
file = vault.createSharedFile(mFile);
166+
try {
167+
OutputStream out = new FileOutputStream(file);
168+
169+
vault.exportFile(mFile,out);;
170+
} catch (IOException | NoSuchAlgorithmException | UnrecoverableEntryException | KeyStoreException e) {
171+
Log.v(TAG,e.toString());
172+
}
173+
174+
return null;
175+
}
176+
177+
@Override
178+
protected void onPostExecute(Void aVoid) {
179+
fileUri = FileProvider.getUriForFile(
180+
getContext(),
181+
BuildConfig.APPLICATION_ID+".fileprovider",
182+
file);
183+
shareImage(fileUri);
184+
Log.v(TAG,"Shared File Created");
185+
}
186+
}
187+
188+
144189
private void updateUI() {
145190
mProgressBar.setVisibility(View.GONE);
146191
mImageView.setVisibility(View.VISIBLE);

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

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

3+
import android.content.IntentFilter;
34
import android.os.Bundle;
45

56
import androidx.appcompat.app.AppCompatActivity;
67
import androidx.fragment.app.Fragment;
7-
import androidx.fragment.app.FragmentActivity;
88
import androidx.fragment.app.FragmentManager;
99

10+
import static com.katcom.androidFileVault.CloseReceiver.CLOSE_INTENT;
11+
1012
public abstract class SingleFragmentActivity extends AppCompatActivity {
1113
protected abstract Fragment createFragment();
12-
14+
protected CloseReceiver closeReceiver;
1315
@Override
1416
public void onCreate(Bundle savedInstanceState) {
1517
super.onCreate(savedInstanceState);
@@ -24,5 +26,14 @@ public void onCreate(Bundle savedInstanceState) {
2426
.add(R.id.fragment_container,fragment)
2527
.commit();
2628
}
29+
30+
// Register a broadcast for closing the app
31+
// when user clicks the exit button, the exit broadcast is triggered and sent to all activities
32+
// Upon which the activity receiving the exit broadcast would close itself
33+
34+
closeReceiver = new CloseReceiver(this);
35+
registerReceiver(closeReceiver,new IntentFilter(CLOSE_INTENT));
36+
2737
}
38+
2839
}

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

Lines changed: 24 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.katcom.androidFileVault;
22

3+
import android.app.ActivityManager;
34
import android.content.ContentResolver;
45
import android.content.ContentValues;
6+
import android.content.Context;
57
import android.content.Intent;
68
import android.database.Cursor;
79
import android.graphics.Bitmap;
@@ -96,10 +98,14 @@ public boolean onNavigationItemSelected(@NonNull MenuItem menuItem) {
9698
showChooseFileActivity();
9799
break;
98100
case R.id.action_help:
99-
showHelpInfo();
101+
//showHelpInfo();
100102
break;
101103
case R.id.action_about:
102-
showEncryptTest();
104+
//showEncryptTest();
105+
break;
106+
case R.id.action_exit:
107+
endApplication();
108+
break;
103109
}
104110
return false;
105111
}
@@ -305,18 +311,19 @@ private void saveTempPictureUri(Uri uri) {
305311
*/
306312
private void loadPreviewData(){
307313

308-
//Executor executor = Executors.newFixedThreadPool(30);
314+
Executor executor = Executors.newFixedThreadPool(30);
309315

310316
for(ProtectedFile file:mFiles){
311317
Log.v(TAG,"LOADING PREVIEW"+file.getFilename());
312-
Bitmap preview = previewManager.getPreview(file,120,120);
313-
file.setPreview(preview);
314-
if(file.getPreview() != null){
318+
//Bitmap preview = previewManager.getPreview(file,120,120);
319+
//file.setPreview(preview);
320+
new FetchSinglePreviewImage().executeOnExecutor(executor,file);
321+
322+
/*if(file.getPreview() != null){
315323
Log.v(TAG,"Done Loading preview on background for : "+file.getFilename());
316324
}else{
317325
Log.v(TAG,"Failed Loading preview on background for : "+file.getFilename());
318-
}
319-
//new FetchSinglePreviewImage().executeOnExecutor(executor,file);
326+
}*/
320327
};
321328
}
322329

@@ -355,7 +362,6 @@ public boolean onOptionsItemSelected(MenuItem item) {
355362
case R.id.menu_take_photo:
356363
takePhoto();
357364
break;
358-
359365
}
360366
return true;
361367
}
@@ -490,7 +496,10 @@ protected void showHelpInfo(){
490496
boolean has = mVault.hasPrivateKey();
491497
}
492498

493-
499+
// Send a broadcast to close all activities
500+
private void endApplication(){
501+
getContext().sendBroadcast(new Intent(CloseReceiver.CLOSE_INTENT));
502+
}
494503

495504
private class FetchPreviewImage extends AsyncTask<Integer,Void,Void>{
496505

@@ -518,7 +527,7 @@ protected ProtectedFile doInBackground(ProtectedFile... protectedFiles) {
518527
//Bitmap preview = mVault.getPreview(file,120,120);
519528
Log.v(TAG,"Loading preview on background for : "+file.getFilename());
520529
Bitmap preview = previewManager.getPreview(file,120,120);
521-
530+
file.setPreview(preview);
522531
return file;
523532
}
524533

@@ -579,6 +588,10 @@ private File createImageFile() throws IOException {
579588

580589
return image;
581590
}
591+
592+
593+
594+
582595
}
583596

584597

app/src/main/res/menu/menu_image_viewer.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@
99
android:id="@+id/menu_image_viewer_share"
1010
android:icon="@drawable/ic_share"
1111
app:showAsAction="always"/>
12+
1213
</menu>
2.59 KB
Loading
1.5 KB
Loading

0 commit comments

Comments
 (0)