I am trying to share my internal storage file via Gmail client on my Moto Razr, but every time I sent to my test gmail account, I got everything except attachment.
This is how I invoke and start gmail, while add file as attachment.
private void saveDaily() {
Intent intent = new Intent(android.content.Intent.ACTION_SEND_MULTIPLE);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_EMAIL, new String[] { loadEmailAddress() });
intent.putExtra(Intent.EXTRA_SUBJECT, "Daily");
intent.putExtra(Intent.EXTRA_TEXT, "Daily Log");
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
ArrayList<Uri> uris = new ArrayList<Uri>();
uris.add(saveDaily2File("dailyRecord.txt"));
Log.d(TAG_D, "Size: " + uris.size());
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
startActivity(Intent.createChooser(intent, "Send email"));
}
This is how I implement my customized content provider.
public class SavedFileProvider extends ContentProvider {
private static final String TAG_D = "ContentProvider";
private static final HashMap<String, String> MIME_TYPES = new HashMap<String, String>();
static {
MIME_TYPES.put(".txt", "text/plain");
}
#Override
public String getType(Uri uri) {
String path = uri.toString();
for (String extension : MIME_TYPES.keySet()) {
if (path.endsWith(extension)) {
return (MIME_TYPES.get(extension));
}
}
return (null);
}
#Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
Log.d(TAG_D, "openFile()");
File f = new File(getContext().getFilesDir(), uri.getPath());
Log.d(TAG_D, f.getAbsolutePath());
if (f.exists()) {
return (ParcelFileDescriptor.open(f,
ParcelFileDescriptor.MODE_READ_ONLY));
}
throw new FileNotFoundException(uri.getPath());
}
#Override
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sort) {
throw new RuntimeException("Operation not supported");
}
#Override
public Uri insert(Uri uri, ContentValues initialValues) {
throw new RuntimeException("Operation not supported");
}
#Override
public int update(Uri uri, ContentValues values, String where,
String[] whereArgs) {
throw new RuntimeException("Operation not supported");
}
#Override
public int delete(Uri uri, String where, String[] whereArgs) {
throw new RuntimeException("Operation not supported");
}
private void copy(InputStream in, File dst) throws IOException {
FileOutputStream out = new FileOutputStream(dst);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
#Override
public boolean onCreate() {
Log.d(TAG_D, "onCreate()");
File f = new File(getContext().getFilesDir(), "dailyRecord.txt");
if (!f.exists()) {
AssetManager assets = getContext().getResources().getAssets();
try {
copy(assets.open("dailyRecord.txt"), f);
} catch (IOException e) {
Log.e("FileProvider", "Exception copying from assets", e);
return (false);
}
}
return (true);
}
}
Then, I add the following lines in my AndroidManifest.xml File.
<provider
android:name=".SavedFileProvider"
android:authorities="Package Path here"
android:exported="true"
android:grantUriPermissions="true"
android:multiprocess="true" >
</provider>
I wonder what I am missing here.
I have check the link:Link1, Link2
I use this:
AndroidManifest.xml
<provider android:name="com.myapp.main.MyContentProvider" android:authorities="com.myapp.main"></provider>
Button click:
public void onClick(View v) {
List<Intent> targetedShareIntents = new ArrayList<Intent>();
Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("image/jpg");
Uri theUri = Uri.parse("content://com.myapp.main/"+srcImage);
List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(shareIntent, 0);
int i=0;
List<ResolveInfo> reInfoToDelete = new ArrayList<ResolveInfo>();
if (!resInfo.isEmpty()){
for (ResolveInfo resolveInfo : resInfo) {
String packageName = resolveInfo.activityInfo.packageName;
Intent targetedShareIntent = new Intent(android.content.Intent.ACTION_SEND);
targetedShareIntent.setType("image/jpg");
targetedShareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Share file");
if (packageName.equals("com.google.android.gm")){
targetedShareIntent.setType("image/png");
targetedShareIntent.putExtra(Intent.EXTRA_TEXT, "some text");
targetedShareIntent.putExtra(Intent.EXTRA_STREAM, theUri);
targetedShareIntent.setPackage(packageName);
targetedShareIntents.add(targetedShareIntent);
}
}
startActivity(targetedShareIntents.remove(0));
}
}
My Content Provider Class
public class MyContentProvider extends ContentProvider implements PipeDataWriter<InputStream>{
#Override
public AssetFileDescriptor openAssetFile(Uri uri, String mode) throws FileNotFoundException {
//Adapt this to your code
AssetManager am = getContext().getAssets();
String file_name = "path/"+uri.getLastPathSegment();
if(file_name == null)
throw new FileNotFoundException();
AssetFileDescriptor afd = null;
try {
afd = am.openFd(file_name);
} catch (IOException e) {
e.printStackTrace();
}
return afd;//super.openAssetFile(uri, mode);
}
#Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
#Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
#Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
return null;
}
#Override
public boolean onCreate() {
// TODO Auto-generated method stub
return false;
}
#Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO Auto-generated method stub
return null;
}
#Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
public void writeDataToPipe(ParcelFileDescriptor arg0, Uri arg1,
String arg2, Bundle arg3, InputStream arg4) {
// Transfer data from the asset to the pipe the client is reading.
byte[] buffer = new byte[8192];
int n;
FileOutputStream fout = new FileOutputStream(arg0.getFileDescriptor());
try {
while ((n=arg4.read(buffer)) >= 0) {
fout.write(buffer, 0, n);
}
} catch (IOException e) {
Log.i("InstallApk", "Failed transferring", e);
} finally {
try {
arg4.close();
} catch (IOException e) {
}
try {
fout.close();
} catch (IOException e) {
}
}
}
}
Related
I'm building a secure android application that runs with IOCipher and SQLCipher. My app is storing PDF, DOC, DOCX, XLS, XLSX files that are intended to be openned by a third party application. Currently I can open all these type of files but DOCX. When I open a docx file that is stored in IOCipher using this method:
File file = new File(path);
Uri contentUri = Uri.parse(VFSContentProvider.FILES_URI + file.getName());
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(contentUri);
Microsoft Word prompt me with that error message :
Can't open file "myFile.docx.docx".
This happen For all my docx file, it seems to append the mime type twice at the end of the file when it's returned by the content provider...
Here is my IOCipher Content Provider:
public class VFSContentProvider extends ContentProvider {
public static final String TAG = "VFSContentProvider";
public static final Uri FILES_URI = Uri
.parse("content://com.plante.android.cobalt.VFSContentProvider/");
private MimeTypeMap mimeTypeMap;
#Override
public boolean onCreate() {
mimeTypeMap = MimeTypeMap.getSingleton();
return true;
}
#Override
public String getType(Uri uri) {
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri.toString());
return mimeTypeMap.getMimeTypeFromExtension(fileExtension);
}
#Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
ParcelFileDescriptor[] pipe = null;
InputStream in = null;
try {
pipe = ParcelFileDescriptor.createPipe();
String path = uri.getPath();
Log.i(TAG, "streaming " + path);
// BufferedInputStream could help, AutoCloseOutputStream conflicts
in = new FileInputStream(new File(path));
new PipeFeederThread(in, new AutoCloseOutputStream(pipe[1])).start();
} catch (IOException e) {
Log.e(TAG, "Error opening pipe", e);
throw new FileNotFoundException("Could not open pipe for: "
+ uri.toString());
}
return (pipe[0]);
}
#Override
public Cursor query(Uri url, String[] projection, String selection,
String[] selectionArgs, String sort) {
// throw new RuntimeException("Operation not supported");
return null;
}
#Override
public Uri insert(Uri uri, ContentValues initialValues) {
throw new RuntimeException("Operation not supported");
}
#Override
public int update(Uri uri, ContentValues values, String where,
String[] whereArgs) {
throw new RuntimeException("Operation not supported");
}
#Override
public int delete(Uri uri, String where, String[] whereArgs) {
throw new RuntimeException("Operation not supported");
}
static class PipeFeederThread extends Thread {
InputStream in;
OutputStream out;
PipeFeederThread(InputStream in, OutputStream out) {
this.in = in;
this.out = out;
}
#Override
public void run() {
byte[] buf = new byte[8192];
int len;
try {
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.flush();
out.close();
} catch (IOException e) {
Log.e(TAG, "File transfer failed:", e);
}
}
}
Here is the log file:
03-16 13:38:20.714 800-1325/? I/ActivityManager: START u0 {act=android.intent.action.VIEW dat=content://com.plante.android.cobalt.VFSContentProvider/0c8dbc0e1671e127ed9fcb2786b218d379f12888Finance_Corporate_BCP_Checklist_2014_MH20150115.docx flg=0x13000003 cmp=com.microsoft.office.word/com.microsoft.office.apphost.LaunchActivity} from uid 10182 on display 0
This is the utils code, the MP3 work only when the app is open, once you click in the back or the home button it stops.
How can I put it in the background?
public class Util {
public ArrayList<Contact> getAllContact(Context context) {
ArrayList<Contact> contacts = new ArrayList<Contact>();
Cursor cursor = context.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, null, null, null, ContactsContract.Contacts.DISPLAY_NAME);
if(cursor != null) {
while (cursor.moveToNext()) {
// This would allow you get several email addresses
// if the email addresses were stored in an array
String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
String phone = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER));
String aaaa = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.CUSTOM_RINGTONE));
if (phone!=null && phone.equals("1")) {
Contact contact = new Contact();
contact.setId(Integer.parseInt(id));
contact.setName(name);
contacts.add(contact);
}
}
}
cursor.close();
return contacts;
}
public ArrayList<SongInfo> getAllSong(Context context) {
ArrayList<SongInfo> listSong = new ArrayList<SongInfo>();
RingtonesSharedPreferences pref = new RingtonesSharedPreferences(
context);
Field[] fields = R.raw.class.getFields();
for (int i = 0; i < fields.length - 1; i++) {
SongInfo info = new SongInfo();
try {
String name = fields[i].getName();
if (!name.equals("ringtones")) {
info.setFileName(name + ".mp3");
info.setFavorite(pref.getString(info.getFileName()));
int audioResource = R.raw.class.getField(name).getInt(name);
info.setAudioResource(audioResource);
}
// info.setName(name);
} catch (Exception e) {
// TODO: handle exception
// Log.e("LOG", "Error: " + e.getMessage());
}
listSong.add(info);
}
InputStream inputStream = context.getResources().openRawResource(
R.raw.zeallist);
BufferedReader reader = new BufferedReader(new InputStreamReader(
inputStream));
try {
String line;
int i = 0;
while ((line = reader.readLine()) != null) {
listSong.get(i).setName(line);
i++;
}
} catch (Exception e) {
// TODO: handle exception
} finally {
try {
reader.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return listSong;
}
public void assignRingtoneToContact(Context context, SongInfo info,Contact contact) {
File dir =null;
ContentValues values = new ContentValues();
boolean isRingTone = false;
if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
dir = new File(Environment.getExternalStorageDirectory(),
"Ringtones");
} else {
dir = context.getCacheDir();
}
if (!dir.exists()) {
dir.mkdirs();
}
File file = new File(dir, info.getFileName());
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
InputStream inputStream = context.getResources()
.openRawResource(info.getAudioResource());
OutputStream outputStream = new FileOutputStream(file);
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
outputStream.write(buffer, 0, length);
}
outputStream.flush();
outputStream.close();
inputStream.close();
} catch (Exception e) {
// TODO: handle exception
}
}
String[] columns = { MediaStore.Audio.Media.DATA,
MediaStore.Audio.Media._ID,
MediaStore.Audio.Media.TITLE,
MediaStore.Audio.Media.DISPLAY_NAME,
MediaStore.Audio.Media.IS_RINGTONE
};
Cursor cursor = context.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, columns, MediaStore.Audio.Media.DATA+" = '"+file.getAbsolutePath()+"'",null, null);
if (cursor!=null) {
int idColumn = cursor.getColumnIndex(MediaStore.Audio.Media._ID);
int fileColumn = cursor.getColumnIndex(MediaStore.Audio.Media.DATA);
int ringtoneColumn = cursor.getColumnIndex(MediaStore.Audio.Media.IS_RINGTONE);
while (cursor.moveToNext()) {
String audioFilePath = cursor.getString(fileColumn);
if (cursor.getString(ringtoneColumn)!=null && cursor.getString(ringtoneColumn).equals("1")) {
Uri hasUri = MediaStore.Audio.Media.getContentUriForPath(audioFilePath);
Uri fullUri = Uri.withAppendedPath(hasUri, cursor.getString(idColumn));
isRingTone = true;
values.put(ContactsContract.Contacts.CUSTOM_RINGTONE, fullUri.toString());
}
}
cursor.close();
if(!isRingTone){
context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE));
Uri oldUri = MediaStore.Audio.Media.getContentUriForPath(file.getAbsolutePath());
ContentValues Newvalues = new ContentValues();
Uri newUri;
String uriString;
context.getContentResolver().delete(oldUri, MediaStore.MediaColumns.DATA + "=\"" + file.getAbsolutePath() + "\"", null);
Newvalues.put(MediaStore.MediaColumns.DATA, file.getAbsolutePath());
Newvalues.put(MediaStore.MediaColumns.TITLE, info.getName());
Newvalues.put(MediaStore.MediaColumns.SIZE, file.length());
Newvalues.put(MediaStore.MediaColumns.MIME_TYPE, "audio/mp3");
Newvalues.put(MediaStore.Audio.Media.IS_RINGTONE, true);
Uri uri = MediaStore.Audio.Media.getContentUriForPath(file.getAbsolutePath());
newUri = context.getContentResolver().insert(uri, Newvalues);
uriString = newUri.toString();
values.put(ContactsContract.Contacts.CUSTOM_RINGTONE, uriString);
Log.i("LOG", "uriString: " + uriString);
}
}
int count = context.getContentResolver().update(ContactsContract.Contacts.CONTENT_URI, values,ContactsContract.Contacts._ID +" = "+contact.getId(), null);
// Log.i("LOG", "Update: " + count);
}
#SuppressWarnings("deprecation")
public Uri getContactContentUri() {
if(Build.VERSION.SDK_INT >= 5){
return ContactsContract.Contacts.CONTENT_URI;
}
else{
return Contacts.People.CONTENT_URI;
}
}
}
try using MediaPlayer, it has many options
MediaPlayer mediaPlayer = new MediaPlayer();
mediaPlayer.setDataSource(context, ringtone);
mediaPlayer.setAudioStreamType(AudioManager.STREAM_ALARM);
mediaPlayer.setLooping(true);
mediaPlayer.prepare();
mediaPlayer.start();
You need to develop player as a service, refer this ,
official docs
I need to attach a zip file through Mail but message only sending not the attached file here is the code for your kind reference
We cant send internal storage so i use contentProvider
public class CachedFileProvider extends ContentProvider
{
private static final String CLASS_NAME = "CachedFileProvider";
// The authority is the symbolic name for the provider class
public static final String AUTHORITY = "com.example.sendmailwa.content.provider";
private UriMatcher uriMatcher;
#Override
public boolean onCreate() {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// Add a URI to the matcher which will match against the form
// 'content://com.stephendnicholas.gmailattach.provider/*'
// and return 1 in the case that the incoming Uri matches this pattern
uriMatcher.addURI(AUTHORITY, "*", 1);
return true;
}
#Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
String LOG_TAG = CLASS_NAME + " - openFile";
Log.v(LOG_TAG,
"Called with uri: '" + uri + "'." + uri.getLastPathSegment());
// Check incoming Uri against the matcher
switch (uriMatcher.match(uri)) {
// If it returns 1 - then it matches the Uri defined in onCreate
case 1:
// The desired file name is specified by the last segment of the
// path
// E.g.
// 'content://com.stephendnicholas.gmailattach.provider/Test.txt'
// Take this and build the path to the file
String fileLocation = getContext().getCacheDir() + File.separator
+ uri.getLastPathSegment();
// Create & return a ParcelFileDescriptor pointing to the file
// Note: I don't care what mode they ask for - they're only getting
// read only
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(new File(
fileLocation), ParcelFileDescriptor.MODE_READ_ONLY);
return pfd;
// Otherwise unrecognised Uri
default:
Log.v(LOG_TAG, "Unsupported uri: '" + uri + "'.");
throw new FileNotFoundException("Unsupported uri: "
+ uri.toString());
}
}
// //////////////////////////////////////////////////////////////
// Not supported / used / required for this example
// //////////////////////////////////////////////////////////////
#Override
public int update(Uri uri, ContentValues contentvalues, String s,
String[] as) {
return 0;
}
#Override
public int delete(Uri uri, String s, String[] as) {
return 0;
}
#Override
public Uri insert(Uri uri, ContentValues contentvalues) {
return null;
}
#Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
// If it returns 1 - then it matches the Uri defined in onCreate
case 1:
return "application/zip"; // Use an appropriate mime type here
default:
return null;
}
}
#Override
public Cursor query(Uri uri, String[] projection, String s, String[] as1,
String s1) {
switch (uriMatcher.match(uri)) {
// If it returns 1 - then it matches the Uri defined in onCreate
case 1:
MatrixCursor cursor = null;
File file = new File( getContext().getCacheDir() + File.separator
+ uri.getLastPathSegment());
if (file.exists()) {
cursor = new MatrixCursor(new String[] {
OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE });
cursor.addRow(new Object[] { uri.getLastPathSegment(),
file.length() });
}
return cursor;
default:
return null;
}
}
}
Here is my MainActivity of sending Attachment file
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try{
//createCachedFile(MainActivity.this,"test.txt","this is test content");
createCachedFile(MainActivity.this,"test.zip","this is test content");
TextView txt=(TextView)findViewById(R.id.txt);
txt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
//sendmail();
File file = new File(MainActivity.this.getFilesDir() + "/" + "test.zip");
sendMail(file);
}
});
}catch(Exception ex){}
}
private void sendmail()
{
try{
//String path=Environment.getExternalStorageDirectory().toString()+"/";
String path="test.txt";
//String fileStringArray[]={path+"A.png",path+"B.png",path+"C.png"};
//String zipDestinationString=path+"ZZ.zip";
//new Zip(fileStringArray, zipDestinationString);
String zipDestinationString="test.txt";
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_EMAIL, new String[]{"ranjith#softcraftsystems.com"});
intent.putExtra(Intent.EXTRA_SUBJECT, "Email Subject");
intent.putExtra(Intent.EXTRA_TEXT, "Email Message");
//intent.setType("application/zip");
intent.setType("plain/text");
//intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + zipDestinationString));
intent.putExtra(Intent.EXTRA_STREAM,
Uri.parse("content://" + CachedFileProvider.AUTHORITY + "/"
+ zipDestinationString));
startActivity(Intent.createChooser(intent, "Send Email"));
}catch(Exception ex){
Log.d("sendmail",ex.toString());
}
}
private void sendMail(File outFile) {
Uri uriToZip = Uri.fromFile(outFile);
String zipDestinationString="test.zip";
String sendText = "Dear friend,\n\n...";
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(android.content.Intent.EXTRA_EMAIL,new String[] { "ranjith#softcraftsystems.com"});
sendIntent.putExtra(android.content.Intent.EXTRA_TEXT, sendText);
sendIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,"Log of the test");
sendIntent.setType("application/zip");
sendIntent.putExtra(Intent.EXTRA_STREAM,
Uri.parse("content://" + CachedFileProvider.AUTHORITY + "/"
+ uriToZip));
// sendIntent.setType("image/jpeg");
// sendIntent.setType("message/rfc822");
//sendIntent.putExtra(android.content.Intent.EXTRA_STREAM, uriToZip);
startActivity(Intent.createChooser(sendIntent, "Send Attachment !:"));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public static void createCachedFile(Context context, String fileName,
String content) throws IOException {
File cacheFile = new File(context.getCacheDir() + File.separator
+ fileName);
cacheFile.createNewFile();
FileOutputStream fos = new FileOutputStream(cacheFile);
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF8");
PrintWriter pw = new PrintWriter(osw);
pw.println(content);
pw.flush();
pw.close();
}
public static Intent getSendEmailIntent(Context context, String email,
String subject, String body, String fileName) {
final Intent emailIntent = new Intent(
android.content.Intent.ACTION_SEND);
//Explicitly only use Gmail to send
emailIntent.setClassName("com.google.android.gm","com.google.android.gm.ComposeActivityGmail");
emailIntent.setType("plain/text");
//Add the recipients
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
new String[] { email });
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, body);
//Add the attachment by specifying a reference to our custom ContentProvider
//and the specific file of interest
emailIntent.putExtra(
Intent.EXTRA_STREAM,
Uri.parse("content://" + CachedFileProvider.AUTHORITY + "/"
+ fileName));
return emailIntent;
}
public class Zip {
private static final int BUFFER = 2048;
private String[] _files;
private String _zipFile;
/**
* This class allows for the automated creation of Zip files when given a String array of file paths.
*
* #param files - String array containing the path of all the files to be zipped
* #param zipFile - The destination of the Zip file.
*/
public Zip(String[] files, String zipFile) {
_files = files;
_zipFile = zipFile;
doZip();
}
/**
* Private method to handle building a Zip file
*/
private void doZip() {
try {
BufferedInputStream origin = null;
FileOutputStream dest = new FileOutputStream(_zipFile);
ZipOutputStream out = new ZipOutputStream(new BufferedOutputStream(
dest));
byte data[] = new byte[BUFFER];
for (int i = 0; i < _files.length; i++) {
System.out.println("Adding: " + _files[i]);
FileInputStream fi = new FileInputStream(_files[i]);
origin = new BufferedInputStream(fi, BUFFER);
ZipEntry entry = new ZipEntry(_files[i].substring(_files[i].lastIndexOf("/") + 1));
out.putNextEntry(entry);
int count;
while ((count = origin.read(data, 0, BUFFER)) != -1) {
out.write(data, 0, count);
}
origin.close();
}
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
That test.txt is working fine but not the zip file
Hello sackoverflow I'm trying to develop an application which can backup and restore contacts, my code is as follows
public class MainActivity extends Activity
{
Cursor cursor;
ArrayList<String> vCard ;
String vfile;
FileOutputStream mFileOutputStream = null;
Button btnRestorects = null;
Button btnBackupCts = null;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnRestorects = (Button) findViewById(R.id.buttonRstCts);
btnBackupCts = (Button) findViewById(R.id.buttonBackCts);
vfile = "contacts.vcf";
final String storage_path = Environment.getExternalStorageDirectory().toString() +"/"+ vfile;
final File f = new File(storage_path);
btnBackupCts.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
try
{
if (!f.exists())
f.createNewFile();
mFileOutputStream = new FileOutputStream(storage_path, false);
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
getVcardString();
}
});
btnRestorects.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
final Intent intent = new Intent();
final MimeTypeMap mime = MimeTypeMap.getSingleton();
String tmptype = mime.getMimeTypeFromExtension("vcf");
final File file = new File(Environment.getExternalStorageDirectory().toString() +"/contacts.vcf");
intent.setDataAndType(Uri.fromFile(file),tmptype);
startActivity(intent);
}
});
}
private void getVcardString()
{
// TODO Auto-generated method stub
vCard = new ArrayList<String>();
cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
if(cursor!=null&&cursor.getCount()>0)
{
cursor.moveToFirst();
for(int i =0;i<cursor.getCount();i++)
{
get(cursor);
Log.d("TAG", "Contact "+(i+1)+"VcF String is"+vCard.get(i));
cursor.moveToNext();
}
}
else
{
Log.d("TAG", "No Contacts in Your Phone");
}
try
{
mFileOutputStream.close();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void get(Cursor cursor)
{
//cursor.moveToFirst();
String lookupKey = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.LOOKUP_KEY));
Uri uri = Uri.withAppendedPath(ContactsContract.Contacts.CONTENT_VCARD_URI, lookupKey);
AssetFileDescriptor fd;
try
{
fd = this.getContentResolver().openAssetFileDescriptor(uri, "r");
FileInputStream fis = fd.createInputStream();
byte[] buf = new byte[(int) fd.getDeclaredLength()];
fis.read(buf);
String vcardstring= new String(buf);
vCard.add(vcardstring);
mFileOutputStream.write(vcardstring.toString().getBytes());
}
catch (Exception e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
Permissions in manifest
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
So far my code was backing up the contact but only name and contact number, but not retrieving the information like whether the contact is starred or not. Please help me in solving this riddle.
Thanks in advance.
Use this to restore:
final MimeTypeMap mime = MimeTypeMap.getSingleton();
String tmptype = mime.getMimeTypeFromExtension("vcf");
final File file = new File(Environment.getExternalStorageDirectory().toString()
+ "/contacts.vcf");
Intent i = new Intent();
i.setAction(android.content.Intent.ACTION_VIEW);
i.setDataAndType(Uri.fromFile(file), "text/x-vcard");
startActivity(i);
Intent mIntent = new Intent(Intent.ACTION_VIEW);
mIntent.setDataAndType(Uri.fromFile(new File(filePath)), MimeTypeMap.getSingleton().getMimeTypeFromExtension("vcf"));
startActivity(Intent.createChooser(mIntent, "Select App"));
Can we upload videos from an Android device's SD Card to a Facebook account via the Facebook SDK?
If so, what are some simple examples?
Yes, it is possible! After two days of trying and researching, I was able to do it.
Here's the code:
byte[] data = null;
String dataPath = "/mnt/sdcard/KaraokeVideos/myvideo.3gp";
String dataMsg = "Your video description here.";
Bundle param;
facebook = new Facebook(FB_APP_ID);
AsyncFacebookRunner mAsyncRunner = new AsyncFacebookRunner(facebook);
InputStream is = null;
try {
is = new FileInputStream(dataPath);
data = readBytes(is);
param = new Bundle();
param.putString("message", dataMsg);
param.putString("filename", dataName);
param.putByteArray("video", data);
mAsyncRunner.request("me/videos", param, "POST", new fbRequestListener(), null);
}
catch (FileNotFoundException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
where fbRequestListener() is an implementation of AsyncFacebookRunner.RequestListener() and readBytes() is a function of converting your video file to byte[]. The dataName string should include a valid file extension (3gp, mp4, etc.). The code is as follows:
public byte[] readBytes(InputStream inputStream) throws IOException {
// This dynamically extends to take the bytes you read.
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
// This is storage overwritten on each iteration with bytes.
int bufferSize = 1024;
byte[] buffer = new byte[bufferSize];
// We need to know how may bytes were read to write them to the byteBuffer.
int len = 0;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
// And then we can return your byte array.
return byteBuffer.toByteArray();
}
I got this function from this answer.
Of course, you need to have the latest Facebook SDK, but we need to apply this patch to fix the {"error":{"type":"OAuthException","message":"(#352) Video file format is not supported"}} string response error.
And that's it! I hope this helps!
With the release of new facebook SDK 3.5, video uploading has been made easier.
If you are using sdk 3.5 or above here is the code for uploading video to facebook
//Path to the video, Ex: path = Environment.getExternalStorageDirectory() + File.separator + "myVideo.mp4";
String path;
//get the current active facebook session
Session session = Session.getActiveSession();
//If the session is open
if(session.isOpened()) {
//Get the list of permissions associated with the session
List<String> permissions = session.getPermissions();
//if the session does not have video_upload permission
if(!permissions.contains("video_upload")) {
//Get the permission from user to upload the video to facebook
Session.NewPermissionsRequest newPermissionsRequest = new Session
.NewPermissionsRequest(this, Arrays.asList("video_upload"));
session.requestNewReadPermissions(newPermissionsRequest);
}
//Create a new file for the video
File file = new File(path);
try {
//create a new request to upload video to the facebook
Request videoRequest = Request.newUploadVideoRequest(session, file, new Request.Callback() {
#Override
public void onCompleted(Response response) {
if(response.getError()==null)
{
Toast.makeText(MainActivity.this, "video shared successfully", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(MainActivity.this, response.getError().getErrorMessage(), Toast.LENGTH_SHORT).show();
}
}
});
//Execute the request in a separate thread
videoRequest.executeAsync();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
//Session is not open
else {
Toast.makeText(getApplicationContext(), "Please login to facebook first", Toast.LENGTH_SHORT).show();
}
After patching Util file, did not get result.
I faced problem mentioned by softy.
I tried with this in android... Now works successfully.. video displayed on my wall after sometime (within 1 min).. (May be, facebook was refreshing data..)
String path="\mnt\sdcard\test.mp4";
if (new File(path).exists()) {
try {
byte[] data = null;
String dataPath = new File(path).getAbsolutePath();
Log.e("", dataPath);
String dataMsg = "It is the short movie created";
Bundle param;
InputStream is = null;
try {
is = new FileInputStream(dataPath);
data = readBytes(is);
param = new Bundle();
// param.putString("filename", "" + new
// File(path).getName());
// param.putString("mimeType", "video/mp4");
param.putString("message", dataMsg);
param.putString("title", "title");
param.putString("contentType", "video/quicktime");
param.putByteArray("video.mov", data);
Utility.mAsyncRunner.request("me/videos", param, "POST",
new FBRequestListener(), null);
Toast.makeText(getContext(), "Uploading...",
Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(getContext(), "No videos found in these dates",
Toast.LENGTH_SHORT).show();
}
FBRequestListener.java
public class FBRequestListener implements RequestListener {
#Override
public void onComplete(String response, Object state) {
Log.e("response", response);
// Log.e("state", state.toString());
}
#Override
public void onIOException(IOException e, Object state) {
Log.e("", "onIOException");
e.printStackTrace();
}
#Override
public void onFileNotFoundException(FileNotFoundException e,
Object state) {
Log.e("", "onFileNotFoundException");
e.printStackTrace();
}
#Override
public void onMalformedURLException(MalformedURLException e,
Object state) {
Log.e("", "onMalformedURLException");
e.printStackTrace();
}
#Override
public void onFacebookError(FacebookError e, Object state) {
Log.e("", "onFacebookError");
e.printStackTrace();
}
}
In release of new facebook SDK, there are some changes in video uploading to facebook page or wall.
Here is code i have used for uploading video on Facebook page or facebook wall.
Your onActivityResult() method should be like this
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == CAMERA_VIDEO && resultCode == Activity.RESULT_OK){
String selectedVideoFilePath = GetFilePathFromDevice.getPath(this, data.getData());
final byte[] datas = readBytes(selectedVideoFilePath);
PostVideo(datas, selectedVideoFilePath);
}
}
Here is all method used in onActivityResult().
public byte[] readBytes(String dataPath) throws IOException {
InputStream inputStream = new FileInputStream(dataPath);
ByteArrayOutputStream byteBuffer = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) != -1) {
byteBuffer.write(buffer, 0, len);
}
return byteBuffer.toByteArray();
}
public void PostVideo(byte[] VideoBytes, String filePath) {
String url;
url = "/me/videos";
AccessToken token = AccessToken.getCurrentAccessToken();
if (token != null) {
Bundle param = new Bundle();
param.putByteArray("video." + getFileExt(filePath), VideoBytes);
param.putString("description", "sample video");
new GraphRequest(token,url, param, HttpMethod.POST, new GraphRequest.Callback() {
public void onCompleted(GraphResponse response) {
Log.e("New Post", "Res =" + response.toString());
dialog.dismiss();
if (response != null && response.getJSONObject() != null && response.getJSONObject().has("id")) {
Log.e("New Post", "Success");
Toast.makeText(NewPostActivity.this, "Video posted successfully.", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(NewPostActivity.this, "Error in posting Video.", Toast.LENGTH_SHORT).show();
}
setResult(Activity.RESULT_OK, new Intent());
finish();
}
}).executeAsync();
}
}
public static String getFileExt(String fileName) {
return fileName.substring((fileName.lastIndexOf(".") + 1), fileName.length());
}
Here is GetFilePathFromDevice class used in onActivityResult() for getting file path from URI.
#SuppressLint("NewApi")
public final class GetFilePathFromDevice {
/**
* Get file path from URI
*
* #param context context of Activity
* #param uri uri of file
* #return path of given URI
*/
public static String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
// ExternalStorageProvider
if (isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/" + split[1];
}
}
// DownloadsProvider
else if (isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
return getDataColumn(context, contentUri, null, null);
}
// MediaProvider
else if (isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = "_id=?";
final String[] selectionArgs = new String[]{split[1]};
return getDataColumn(context, contentUri, selection, selectionArgs);
}
}
// MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
// Return the remote address
if (isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return getDataColumn(context, uri, null, null);
}
// File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
public static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) {
Cursor cursor = null;
final String column = "_data";
final String[] projection = {column};
try {
cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow(column);
return cursor.getString(index);
}
} finally {
if (cursor != null)
cursor.close();
}
return null;
}
public static boolean isExternalStorageDocument(Uri uri) {
return "com.android.externalstorage.documents".equals(uri.getAuthority());
}
public static boolean isDownloadsDocument(Uri uri) {
return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}
public static boolean isMediaDocument(Uri uri) {
return "com.android.providers.media.documents".equals(uri.getAuthority());
}
public static boolean isGooglePhotosUri(Uri uri) {
return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}
}