We have to port our software to android. One of the main feature of our software should be that the software can download a new version of itself from the net (our own server) and install it's new version too. All this thing should be done programmatically.
I'm new to android, so haven't got any clue how should it be done.
How to create apk? - solved
How to sign apk? - solved
How to download apk? - solved
How to copy the downloaded file overwriting /data/apk/my.software.name.apk? - unsolved
How to restart the software by the running version? - unsolved
File file = new File(dir, "App.apk");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file),
"application/vnd.android.package-archive");
startActivity(intent);
I had the same problem and after several attempts, it worked for me this way. Previously i got my new apk from a webservice.
You do not have to do this. You just upload the new version of your program on the Android Market, and people see it right away. Users who checked the option "update automatically" for your program upgrade automatically without having to give explicit consent ; others see "upgrade available" and can just click 'upgrade' to upgrade to the new version of your program.
If for some reason you're thinking that you want to force the update on the user with or without their consent though, you just cannot do it. You can download the apk and should be able to hand it to the package manager, which in turn will ask the user to confirm whether they actually want to install it - and then again, for that you need the user to have checked the "allow unknown sources" option in development options, else the package manager will downright refuse to do it. But android will not let you install a new package without the user explicitly requesting it, or explicitly allowing auto-updates through the market.
If you have some backward compatibility issue of some sort and want to disallow running of deprecated versions of your application, you can embed in your application some logic that will check on your server for version information and terminate if it's outdated, with a message "this version is outdated, you need to upgrade to continue using this application" or something. But no upgrading in the back of the user.
Sorry for inconvenience this is code and I also posted the XML permissions required to use it.
package com.SelfInstall01;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import com.SelfInstall01.SelfInstall01Activity;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.AlertDialog.Builder;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;
public class SelfInstall01Activity extends Activity
{
class PInfo {
private String appname = "";
private String pname = "";
private String versionName = "";
private int versionCode = 0;
//private Drawable icon;
/*private void prettyPrint() {
//Log.v(appname + "\t" + pname + "\t" + versionName + "\t" + versionCode);
}*/
}
public int VersionCode;
public String VersionName="";
public String ApkName ;
public String AppName ;
public String BuildVersionPath="";
public String urlpath ;
public String PackageName;
public String InstallAppPackageName;
public String Text="";
TextView tvApkStatus;
Button btnCheckUpdates;
TextView tvInstallVersion;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Text= "Old".toString();
Text= "New".toString();
ApkName = "SelfInstall01.apk";//"Test1.apk";// //"DownLoadOnSDcard_01.apk"; //
AppName = "SelfInstall01";//"Test1"; //
BuildVersionPath = "http://10.0.2.2:82/Version.txt".toString();
PackageName = "package:com.SelfInstall01".toString(); //"package:com.Test1".toString();
urlpath = "http://10.0.2.2:82/"+ Text.toString()+"_Apk/" + ApkName.toString();
tvApkStatus =(TextView)findViewById(R.id.tvApkStatus);
tvApkStatus.setText(Text+" Apk Download.".toString());
tvInstallVersion = (TextView)findViewById(R.id.tvInstallVersion);
String temp = getInstallPackageVersionInfo(AppName.toString());
tvInstallVersion.setText("" +temp.toString());
btnCheckUpdates =(Button)findViewById(R.id.btnCheckUpdates);
btnCheckUpdates.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View arg0)
{
GetVersionFromServer(BuildVersionPath);
if(checkInstalledApp(AppName.toString()) == true)
{
Toast.makeText(getApplicationContext(), "Application Found " + AppName.toString(), Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(getApplicationContext(), "Application Not Found. "+ AppName.toString(), Toast.LENGTH_SHORT).show();
}
}
});
}// On Create END.
private Boolean checkInstalledApp(String appName){
return getPackages(appName);
}
// Get Information about Only Specific application which is Install on Device.
public String getInstallPackageVersionInfo(String appName)
{
String InstallVersion = "";
ArrayList<PInfo> apps = getInstalledApps(false); /* false = no system packages */
final int max = apps.size();
for (int i=0; i<max; i++)
{
//apps.get(i).prettyPrint();
if(apps.get(i).appname.toString().equals(appName.toString()))
{
InstallVersion = "Install Version Code: "+ apps.get(i).versionCode+
" Version Name: "+ apps.get(i).versionName.toString();
break;
}
}
return InstallVersion.toString();
}
private Boolean getPackages(String appName)
{
Boolean isInstalled = false;
ArrayList<PInfo> apps = getInstalledApps(false); /* false = no system packages */
final int max = apps.size();
for (int i=0; i<max; i++)
{
//apps.get(i).prettyPrint();
if(apps.get(i).appname.toString().equals(appName.toString()))
{
/*if(apps.get(i).versionName.toString().contains(VersionName.toString()) == true &&
VersionCode == apps.get(i).versionCode)
{
isInstalled = true;
Toast.makeText(getApplicationContext(),
"Code Match", Toast.LENGTH_SHORT).show();
openMyDialog();
}*/
if(VersionCode <= apps.get(i).versionCode)
{
isInstalled = true;
/*Toast.makeText(getApplicationContext(),
"Install Code is Less.!", Toast.LENGTH_SHORT).show();*/
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which)
{
case DialogInterface.BUTTON_POSITIVE:
//Yes button clicked
//SelfInstall01Activity.this.finish(); Close The App.
DownloadOnSDcard();
InstallApplication();
UnInstallApplication(PackageName.toString());
break;
case DialogInterface.BUTTON_NEGATIVE:
//No button clicked
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("New Apk Available..").setPositiveButton("Yes Proceed", dialogClickListener)
.setNegativeButton("No.", dialogClickListener).show();
}
if(VersionCode > apps.get(i).versionCode)
{
isInstalled = true;
/*Toast.makeText(getApplicationContext(),
"Install Code is better.!", Toast.LENGTH_SHORT).show();*/
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which) {
switch (which)
{
case DialogInterface.BUTTON_POSITIVE:
//Yes button clicked
//SelfInstall01Activity.this.finish(); Close The App.
DownloadOnSDcard();
InstallApplication();
UnInstallApplication(PackageName.toString());
break;
case DialogInterface.BUTTON_NEGATIVE:
//No button clicked
break;
}
}
};
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("NO need to Install.").setPositiveButton("Install Forcely", dialogClickListener)
.setNegativeButton("Cancel.", dialogClickListener).show();
}
}
}
return isInstalled;
}
private ArrayList<PInfo> getInstalledApps(boolean getSysPackages)
{
ArrayList<PInfo> res = new ArrayList<PInfo>();
List<PackageInfo> packs = getPackageManager().getInstalledPackages(0);
for(int i=0;i<packs.size();i++)
{
PackageInfo p = packs.get(i);
if ((!getSysPackages) && (p.versionName == null)) {
continue ;
}
PInfo newInfo = new PInfo();
newInfo.appname = p.applicationInfo.loadLabel(getPackageManager()).toString();
newInfo.pname = p.packageName;
newInfo.versionName = p.versionName;
newInfo.versionCode = p.versionCode;
//newInfo.icon = p.applicationInfo.loadIcon(getPackageManager());
res.add(newInfo);
}
return res;
}
public void UnInstallApplication(String packageName)// Specific package Name Uninstall.
{
//Uri packageURI = Uri.parse("package:com.CheckInstallApp");
Uri packageURI = Uri.parse(packageName.toString());
Intent uninstallIntent = new Intent(Intent.ACTION_DELETE, packageURI);
startActivity(uninstallIntent);
}
public void InstallApplication()
{
Uri packageURI = Uri.parse(PackageName.toString());
Intent intent = new Intent(android.content.Intent.ACTION_VIEW, packageURI);
// Intent intent = new Intent(android.content.Intent.ACTION_VIEW);
//intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//intent.setFlags(Intent.ACTION_PACKAGE_REPLACED);
//intent.setAction(Settings. ACTION_APPLICATION_SETTINGS);
intent.setDataAndType
(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/download/" + ApkName.toString())),
"application/vnd.android.package-archive");
// Not open this Below Line Because..
////intent.setClass(this, Project02Activity.class); // This Line Call Activity Recursively its dangerous.
startActivity(intent);
}
public void GetVersionFromServer(String BuildVersionPath)
{
//this is the file you want to download from the remote server
//path ="http://10.0.2.2:82/Version.txt";
//this is the name of the local file you will create
// version.txt contain Version Code = 2; \n Version name = 2.1;
URL u;
try {
u = new URL(BuildVersionPath.toString());
HttpURLConnection c = (HttpURLConnection) u.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();
//Toast.makeText(getApplicationContext(), "HttpURLConnection Complete.!", Toast.LENGTH_SHORT).show();
InputStream in = c.getInputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024]; //that stops the reading after 1024 chars..
//in.read(buffer); // Read from Buffer.
//baos.write(buffer); // Write Into Buffer.
int len1 = 0;
while ( (len1 = in.read(buffer)) != -1 )
{
baos.write(buffer,0, len1); // Write Into ByteArrayOutputStream Buffer.
}
String temp = "";
String s = baos.toString();// baos.toString(); contain Version Code = 2; \n Version name = 2.1;
for (int i = 0; i < s.length(); i++)
{
i = s.indexOf("=") + 1;
while (s.charAt(i) == ' ') // Skip Spaces
{
i++; // Move to Next.
}
while (s.charAt(i) != ';'&& (s.charAt(i) >= '0' && s.charAt(i) <= '9' || s.charAt(i) == '.'))
{
temp = temp.toString().concat(Character.toString(s.charAt(i))) ;
i++;
}
//
s = s.substring(i); // Move to Next to Process.!
temp = temp + " "; // Separate w.r.t Space Version Code and Version Name.
}
String[] fields = temp.split(" ");// Make Array for Version Code and Version Name.
VersionCode = Integer.parseInt(fields[0].toString());// .ToString() Return String Value.
VersionName = fields[1].toString();
baos.close();
}
catch (MalformedURLException e) {
Toast.makeText(getApplicationContext(), "Error." + e.getMessage(), Toast.LENGTH_SHORT).show();
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), "Error." + e.getMessage(), Toast.LENGTH_SHORT).show();
}
//return true;
}// Method End.
// Download On My Mobile SDCard or Emulator.
public void DownloadOnSDcard()
{
try{
URL url = new URL(urlpath.toString()); // Your given URL.
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect(); // Connection Complete here.!
//Toast.makeText(getApplicationContext(), "HttpURLConnection complete.", Toast.LENGTH_SHORT).show();
String PATH = Environment.getExternalStorageDirectory() + "/download/";
File file = new File(PATH); // PATH = /mnt/sdcard/download/
if (!file.exists()) {
file.mkdirs();
}
File outputFile = new File(file, ApkName.toString());
FileOutputStream fos = new FileOutputStream(outputFile);
// Toast.makeText(getApplicationContext(), "SD Card Path: " + outputFile.toString(), Toast.LENGTH_SHORT).show();
InputStream is = c.getInputStream(); // Get from Server and Catch In Input Stream Object.
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1); // Write In FileOutputStream.
}
fos.close();
is.close();//till here, it works fine - .apk is download to my sdcard in download file.
// So please Check in DDMS tab and Select your Emulator.
//Toast.makeText(getApplicationContext(), "Download Complete on SD Card.!", Toast.LENGTH_SHORT).show();
//download the APK to sdcard then fire the Intent.
}
catch (IOException e)
{
Toast.makeText(getApplicationContext(), "Error! " +
e.toString(), Toast.LENGTH_LONG).show();
}
}
}
Related
I'm trying to copy the files of my camera who use PTP to my tablet. I have use the android API MTPDevice
(https://developer.android.com/reference/android/mtp/MtpDevice.html#importFile%28int,%20java.lang.String%29) , I have request necessary permission(android.mtp.MtpClient.action.USB_PERMISSION).
I have open the device, the function return true, and open the USBConnection (Connexion OK).
I try to import all files of the camera in a temp Folder on my tablet (/mnt/sdcard/tmpFolder). The path exist on my tablet, but when i give it to the importFiles function I have the error :
[LOGCAT]
MtpDevice: readObject: /mnt/sdcard/tmpFolder
MtpDevice: open failed for /mnt/sdcard/tmpFolder
Debug: File import KO
I have try with a path doesn't exist I have the message :
[LOGCAT]
MtpDevice: readObject: /mnt/sdcard/tptp
MtpDevice: readResponse failed
Debug: File import KO
Someone can help me ?
Thanks
#Background
#DebugLog
public void getMTPDevice() {
HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
if (deviceIterator.hasNext()) {
UsbDevice usbDevice = deviceIterator.next();
device = openDeviceLocked(usbDevice);
if(device!=null){
File folder = returnTempFolderCamera();
if(folder.exists()){
Log.d("Debug", "Folder exist /mnt/sdcard/tmpFolder");
if(device.importFile(0,folder.getPath()))
{
Toast.makeText(this, "File import OK", Toast.LENGTH_LONG).show();
Log.d("Debug", "Files import OK");
}else {
Toast.makeText(this, "File import KO", Toast.LENGTH_LONG).show();
Log.d("Debug", "Files import KO");
}
}
}
}
}/**
* Opens the {#link android.hardware.usb.UsbDevice} for an MTP or PTP device
* and return an {#link android.mtp.MtpDevice} for it.
*
* #param usbDevice
* the device to open
* #return an MtpDevice for the device.
*/
#DebugLog
private MtpDevice openDeviceLocked(UsbDevice usbDevice) {
String deviceName = usbDevice.getDeviceName();
byte[] data = new byte[128];
int TIMEOUT = 0;
boolean forceClaim = true;
// don't try to open devices that we have decided to ignore
// or are currently asking permission for
if (isCamera(usbDevice)
&& !mRequestPermissionDevices.contains(deviceName)) {
if (!manager.hasPermission(usbDevice)) {
manager.requestPermission(usbDevice, mPermissionIntent);
mRequestPermissionDevices.add(deviceName);
} else {
UsbInterface intf = usbDevice.getInterface(0);
UsbEndpoint endpoint = intf.getEndpoint(0);
UsbDeviceConnection connection = manager.openDevice(usbDevice);
connection.claimInterface(intf, forceClaim);
connection.bulkTransfer(endpoint, data, data.length, TIMEOUT);
if (connection != null) {
MtpDevice mtpDevice = new MtpDevice(usbDevice);
if (mtpDevice.open(connection)) {
mDevices.put(usbDevice.getDeviceName(), mtpDevice);
return mtpDevice;
}
}
}
}
return null;
}
private File returnTempFolder(){
File tmp = new File(Environment.getExternalStorageDirectory().getAbsolutePath()+"/tmpFolder");
return tmp;
}
For people who have the same problem :
Solution is (Found on github) :
MtpClient (https://android.googlesource.com/platform/packages/apps/Gallery2/+/jb-dev/src/com/android/gallery3d/data/MtpClient.java)
#Background
#DebugLog
public void importFiles() {
MtpClient mtpClient = new MtpClient(this);
mtpClient.getDeviceList();
for (int i = 0; i < mtpClient.getDeviceList().size(); i++) {
int[] tab = mtpClient.getDeviceList().get(i).getObjectHandles(mtpClient.getDeviceList().get(i).getStorageIds()[0], 0, 0);
for (int j = 0; j < tab.length; j++) {
File dest = Environment.getExternalStorageDirectory();
// NAME_IMPORTED_FOLDER = tmpFolder
dest = new File(dest, NAME_IMPORTED_FOLDER);
dest.mkdirs();
MtpObjectInfo objInfo = mtpClient.getDeviceList().get(i).getObjectInfo(tab[j]);
if (objInfo != null) {
String destPath = new File(dest, objInfo.getName()).getAbsolutePath();
int objectId = objInfo.getObjectHandle();
// Succes !!
boolean result = mtpClient.getDeviceList().get(i).importFile(objectId, destPath);
}
}
}
mtpClient.close();
}
Regarding above post,
I downloaded the github gallery3d project ,
and look into code of MtpClient.java,
then I find the difference,
The code section from github
String destPath = new File(dest,objInfo.getName()).getAbsolutePath();
int objectId = objInfo.getObjectHandle();
boolean result = mtpClient.getDeviceList().get(i).importFile(objectId, destPath);
The point is 2nd parameter of importFile(objectId, destPath ) "destPath", need to include folder path + filename, then filename should not be changed original filename
But in the origianl question author, you just set folder path
in 2nd parameter
I use broadcastreceiver of media folder android.hardware.action.NEW_PICTURE service to rename and move image using this code and it was running:
CameraReciver
package perim.ebrahimi.ir.perim;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
public class CameraReciver extends BroadcastReceiver {
private States states;
private SessionManager session;
private WriteService main;
#Override
public void onReceive(Context context, Intent intent) {
getStates(context);
if(states.getAPP()){
Cursor cursor = context.getContentResolver().query(intent.getData(), null, null, null, null);
cursor.moveToFirst();
if(cursor!=null){
String image_path = cursor.getString(cursor.getColumnIndex("_data"));
main = new WriteService();
main.writeFolder(image_path, states, context);
}
cursor.close();
} else abortBroadcast();
}
// OK
private void getStates(Context context){
session = new SessionManager(context.getApplicationContext());
states = new States();
states = session.getSession();
}
}
and here is WriteService:
package perim.ebrahimi.ir.perim;
import android.app.Activity;
import android.app.Application;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.widget.Toast;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class WriteService extends Activity {
private States states;
private Context context;
private static CalendarJalalian cal;
private static int day ;
private static int month ;
private static int year ;
private static int saat ;
private static int minut ;
private static int secnd ;
private int orientation = -1;
private static final int REQUEST_EXTERNAL_STORAGE = 100;
private static final int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS=200;
private boolean mExternalStorageAvailable = false;
private boolean mExternalStorageWriteable = false;
// #Override
// protected void onCreate(Bundle savedInstanceState) {
// super.onCreate(savedInstanceState);
// //setContentView(R.layout.activity_main);
//
// // A simple check of whether runtime permissions need to be managed
// if (Build.VERSION.SDK_INT >= 23) {
// checkMultiplePermissions();
// }
// }
public void writeFolder(String image_path, States _states, Context _context){
states = _states;
context= _context;
cal = new CalendarJalalian();
long fileSize = new File(image_path).length();
Cursor mediaCursor = context.getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
new String[] {MediaStore.Images.ImageColumns.ORIENTATION,
MediaStore.MediaColumns.SIZE },
MediaStore.MediaColumns.DATE_ADDED + ">=?",
new String[]{String.valueOf(cal.getTimeInMillis()/1000 - 1)},
MediaStore.MediaColumns.DATE_ADDED + " desc");
if (mediaCursor != null && mediaCursor.getCount() !=0 ) {
while(mediaCursor.moveToNext()){
long size = mediaCursor.getLong(1);
if(size == fileSize){
orientation = mediaCursor.getInt(0);
break;
}
}
}
orientation = (orientation<0)?0:orientation;
image_path = changeName(image_path);
if(image_path.length()==0) return;
String image_jadid = copyFile(image_path);
if(states.getMain() && image_jadid.length()>0){
removeMain(image_path);
removeMedia(context, new File(image_path));
}
if(states.getPayam()) Toast.makeText(this, getText(R.string.imageSaved)+": "+states.getKhas(), 500).show();
}
private void checkExternalStorage(){
String[] aaa = new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE};
ActivityCompat.requestPermissions(this, aaa , REQUEST_EXTERNAL_STORAGE);
if(ContextCompat.checkSelfPermission(context, android.Manifest.permission.WRITE_EXTERNAL_STORAGE)!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_EXTERNAL_STORAGE);
} else {
String state = Environment.getExternalStorageState();
if (Environment.MEDIA_MOUNTED.equals(state)) {
mExternalStorageAvailable = mExternalStorageWriteable = true;
} else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
mExternalStorageAvailable = true;
mExternalStorageWriteable = false;
} else {
mExternalStorageAvailable = mExternalStorageWriteable = false;
}
}
}
private static void removeMedia(Context context, File f) {
ContentResolver resolver = context.getContentResolver();
resolver.delete(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, MediaStore.Images.Media.DATA + "=?", new String[] { f.getAbsolutePath() });
}
// OK
private String changeName(String image_path){
String result = "";
day = cal.getDay();
month = cal.getMonth();
year = cal.getYear();
saat = Integer.parseInt(cal.getHHour());
minut = Integer.parseInt(cal.getMinute());
secnd = Integer.parseInt(cal.getSecond());
String persianDateName = String.format("%1$s_%2$s_%3$s__%4$s_%5$s_%6$s.jpg",
year,
((month<10)?"0"+month:month),
((day<10)?"0"+day:day),
((saat<10)?"0"+saat:saat),
((minut<10)?"0"+minut:minut),
((secnd<10)?"0"+secnd:secnd));
File from = new File(image_path);
if(from.exists()){
if(states.getOnimage()){
addTextToImage(image_path, persianDateName);
}
File to = new File(from.getParentFile(),persianDateName);
try
{
boolean b = from.renameTo(to);
if (!b) {
copy(from, to);
from.delete();
}
removeMedia(context, from);
sendToMedia(to, persianDateName);
result = to.getAbsolutePath();
}
catch(Exception ex){
ex.printStackTrace();
}
}
return result;
}
private void addTextToImage(String from, String persianDateName) {
Log.i("info","Draw "+persianDateName+" on image");
try
{
Log.i("info","1");
FileOutputStream fos = new FileOutputStream(from);
if(fos==null) Log.i("info","fos = null");
Log.i("info","2 = "+from);
Bitmap bitmap = BitmapFactory.decodeFile(from);
if(bitmap==null) Log.i("info","bitmap = null");
// Log.i("info","3");
android.graphics.Bitmap.Config bitmapConfig = bitmap.getConfig();
if(bitmapConfig==null) Log.i("info","bitmapConfig = null");
// Log.i("info","4");
// if (bitmapConfig == null) {
// bitmapConfig = android.graphics.Bitmap.Config.ARGB_8888;
// }
Log.i("info","5");
bitmap = bitmap.copy(bitmapConfig, true);
Log.i("info","6");
Canvas canvas = new Canvas(bitmap);
Log.i("info","7");
Resources resources = this.getResources();
float scale = resources.getDisplayMetrics().density;
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(Color.rgb(61, 61, 61));
paint.setTextSize((int) (14 * scale));
paint.setShadowLayer(1f, 0f, 1f, Color.WHITE);
Rect qab = new Rect();
paint.getTextBounds(persianDateName, 0, persianDateName.length(), qab);
int x = (bitmap.getWidth() - qab.width()) / 2;
int y = (bitmap.getHeight() + qab.height()) / 2;
canvas.drawText(persianDateName, x, y, paint);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
}
catch (IOException e)
{
e.printStackTrace();
}
Log.i("info","Text added on image");
}
private void copy(final File f1, final File f2) throws IOException {
if(f2.exists()) f2.delete();
//checkExternalStorage();
checkMultiplePermissions();
if(mExternalStorageAvailable && mExternalStorageWriteable) {
f2.createNewFile();
final RandomAccessFile file1 = new RandomAccessFile(f1, "r");
final RandomAccessFile file2 = new RandomAccessFile(f2, "rw");
file2.getChannel().write(file1.getChannel().map(FileChannel.MapMode.READ_ONLY, 0, f1.length()));
file1.close();
file2.close();
}
}
private boolean canRename(final File f1, final File f2) {
final String p1 = f1.getAbsolutePath().replaceAll("^(/mnt/|/)", "");
final String p2 = f2.getAbsolutePath().replaceAll("^(/mnt/|/)", "");
return p1.replaceAll("\\/\\w+", "").equals(p2.replaceAll("\\/\\w+", ""));
}
// OK
private void removeMain(String image_path){
File f = new File(image_path);
if(f.exists()) f.delete();
}
// OK
private File createFileName(){
day = cal.getDay();
month = cal.getMonth();
year = cal.getYear();
saat = Integer.parseInt(cal.getHHour());
minut = Integer.parseInt(cal.getMinute());
secnd = Integer.parseInt(cal.getSecond());
String persianDateName = String.format("%1$s_%2$s_%3$s__%4$s_%5$s_%6$s.jpg",
year,
((month<10)?"0"+month:month),
((day<10)?"0"+day:day),
((saat<10)?"0"+saat:saat),
((minut<10)?"0"+minut:minut),
((secnd<10)?"0"+secnd:secnd));
String masirFolder = "";
if(states.getSal()) masirFolder += year;
if(states.getMah()) masirFolder += File.separator+ year+"_"+((month<10)?"0"+month:month);
if(states.getRuz()) masirFolder += File.separator+ year+"_"+((month<10)?"0"+month:month)+"_"+((day<10)?"0"+day:day);
if(states.getSaat()) masirFolder += File.separator+ year+"_"+((month<10)?"0"+month:month)+"_"+((day<10)?"0"+day:day)+"_"+((saat<10)?"0"+saat:saat);
if(states.getMinut()) masirFolder += File.separator+ year+"_"+((month<10)?"0"+month:month)+"_"+((day<10)?"0"+day:day)+"_"+((saat<10)?"0"+saat:saat)+"_"+((minut<10)?"0"+minut:minut);
if(states.getKhas().length()>0) masirFolder += File.separator+states.getKhas();
File directTime = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), masirFolder);
if (!directTime.mkdir()) makeDir(directTime);
directTime = new File(directTime, persianDateName);
return directTime;
}
// OK
private void makeDir(File direct){
direct.mkdirs();
}
// OK
private String copyFile(String image_path){
String masir = "";
File sourceFile = new File(image_path);
if (!sourceFile.exists()) {return masir;}
File destinationFile = createFileName();
FileChannel source = null;
FileChannel destination = null;
try {
source = new FileInputStream(sourceFile).getChannel();
destination = new FileOutputStream(destinationFile).getChannel();
if (destination != null && source != null) {
destination.transferFrom(source, 0, source.size());
}
if (source != null) {
source.close();
}
if (destination != null) {
destination.close();
}
masir = destinationFile.getName();
sendToMedia(destinationFile, masir);
masir = destinationFile.getAbsolutePath();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return masir;
}
// OK
private void sendToMedia(File imageFile, String imageTitle){
ContentValues image = new ContentValues();
Date dateTaken = new Date();
File parent = imageFile.getParentFile();
String path = parent.toString().toLowerCase();
String name = parent.getName().toLowerCase();
image.put(MediaStore.Images.Media.TITLE, imageTitle);
image.put(MediaStore.Images.Media.DISPLAY_NAME, String.format(this.getText(R.string.imageDisplayName).toString(),states.getKhas()));
image.put(MediaStore.Images.Media.DESCRIPTION, String.format(this.getText(R.string.imageDescription).toString(),name));
image.put(MediaStore.Images.Media.DATE_ADDED, dateTaken.toString());
image.put(MediaStore.Images.Media.DATE_TAKEN, dateTaken.toString());
image.put(MediaStore.Images.Media.DATE_MODIFIED, dateTaken.toString());
image.put(MediaStore.Images.Media.MIME_TYPE, "image/png");
image.put(MediaStore.Images.Media.ORIENTATION, orientation);//getImageOrientation(imageFile.getAbsolutePath()));
image.put(MediaStore.Images.ImageColumns.BUCKET_ID, path.hashCode());
image.put(MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME, name);
image.put(MediaStore.Images.Media.SIZE, imageFile.length());
image.put(MediaStore.Images.Media.DATA, imageFile.getAbsolutePath());
this.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, image);
}
private void checkMultiplePermissions() {
if (Build.VERSION.SDK_INT >= 23) {
List<String> permissionsNeeded = new ArrayList<String>();
List<String> permissionsList = new ArrayList<String>();
if (!addPermission(permissionsList, android.Manifest.permission.ACCESS_FINE_LOCATION)) {
permissionsNeeded.add("GPS");
}
if (!addPermission(permissionsList, android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
permissionsNeeded.add("Read Storage");
}
if (permissionsList.size() > 0) {
requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
return;
}
}
}
private boolean addPermission(List<String> permissionsList, String permission) {
try {
if (Build.VERSION.SDK_INT >= 23)
if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
permissionsList.add(permission);
if (!shouldShowRequestPermissionRationale(permission))
return false;
}
} catch(Exception ex){
ex.printStackTrace();
}
return true;
}
}
But class addPermission raise error:
java.lang.NullPointerException: Attempt to invoke virtual method 'int
android.content.Context.checkSelfPermission(java.lang.String)' on a
null object reference
I think the way I call activity is not correct, but I have no idea how to do it, please help.
Edit:
I have found this difference in returned path:
String image_path = cursor.getString(cursor.getColumnIndex("_data"));
The changed part is obvious:
old but correct path: /storage/emulated/0/DCIM/Camera/IMG_20161215_173334.jpg
new but incorrect path: /storage/3466-033/DCIM/Camera/IMG_20161215_173334.jpg
I think since new devices permit user to select where to save Images, then returning address is changed accordingly.
How to get correct address out of cursor?
You can't do that with a broadcast receiver. You can check if you have a permission via ContextCompat.checkSelfPermission, but in order to request the permission, you need to call ActivityCompat.requestPermissions. It needs an activity, and the result will also arrive to that activity.
Given that, the best solution for you is to implement some activity which will explain the user what is going on and request the permission. If the broadcast receiver detects that it doesn't have the necessary permission, it would launch this activity. When the permission is granted, the normal operation would be resumed.
I have to say that as a user it would be very weird to me if a dialog with a permission request suddenly popped up out of the blue, so I think it's for the best that you need to have an activity to request permissions.
Judging by your path, however, it is definitely somewhere on the SD card. This means that the SD card write restrictions apply. That means that requesting permissions for writing won't help. Take a look at this question: How to avoid the “EACCES permission denied” on SD card?
When I started coding my project I did not know the string resource. Now I would like to use this resource for all my string. How do you do it all of a sudden? Knowing that I have more than 10000 strings currently I do not want to do it one by one by hand ...
To automate this completely you need a special tool (I haven't found one), outside of Android Studio to:
Find the string (and replace with the reference)
Update strings.xml
optionally translate strings
For one at a time manual extract (See also link):Alt+Enter, Extract String Resource while the caret is inside the hardcoded string in code:
and in XML:
I don't think, that there is a slink workaround considering, that you need to name all string somehow with a unique and useful identifier. When you let this be done automatically, your code will get quite hard to read :/
Just highlight every instance of a string,then click on the yellow hint icon on the left of the statemnt to extract string resource.Then you can remove duplicated strings later.
I wrote a java script for xml layouts at least, for anyone who needs it... There might be some minor fixes required later.
package com.cameron.smelevel.lib;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class StringResourceCreator {
public static void main(String [] args){
String mainDirPath = "S:\\androidProject\\src";
String layoutDirPath = "\\main\\res\\layout";
String outputDirPath = mainDirPath+"-out";
String stringFilePath = outputDirPath+"\\strings.txt";
String line;
File layoutDir = new File(mainDirPath + layoutDirPath);
File layoutOutDir = new File(outputDirPath + layoutDirPath);
layoutOutDir.mkdirs();
HashMap<String, String> stringEnteries = new HashMap<>();
for (File file : layoutDir.listFiles()) {
String fileName = file.getName();
PrintWriter pr = null;
try {
// FileReader reads text files in the default encoding.
FileReader fileReader = new FileReader(file);
// Always wrap FileReader in BufferedReader.
BufferedReader bufferedReader = new BufferedReader(fileReader);
FileWriter outputStream = new FileWriter(layoutOutDir.getAbsolutePath() + "\\"+ fileName);
pr = new PrintWriter(outputStream);
while ((line = bufferedReader.readLine()) != null) {
line = getModifiedLine(line, stringEnteries);
pr.write(line);
pr.println();
}
} catch(FileNotFoundException ex) {
System.out.println("Unable to open file '" + fileName + "'");
} catch (IOException ex) {
System.out.println("Error reading file '" + fileName + "'");
// Or we could just do this:
// ex.printStackTrace();
}finally {
if(pr != null) pr.close();
}
}
PrintWriter pr = null;
try {
FileWriter outputStream = new FileWriter(stringFilePath);
pr = new PrintWriter(outputStream);
Iterator it = stringEnteries.entrySet().iterator();
while (it.hasNext()) {
Map.Entry pair = (Map.Entry)it.next();
String entry = "<string name=\"" + pair.getKey() + "\">" + pair.getValue() + "</string>";
it.remove(); // avoids a ConcurrentModificationException
pr.write(entry);
pr.println();
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(pr != null) pr.close();
}
}
private static String getModifiedLine(String line, HashMap<String, String> stringEnteries) {
if (line.contains(":text=\"") || line.contains(":hint=\"")){
StringBuilder fieldName = new StringBuilder();
String text = line.substring(line.indexOf("\"")+1, line.lastIndexOf("\""));
String textTrimmed = text.replace("\\n","");
if (!textTrimmed.startsWith("#string")){
String[] words = textTrimmed.split(" ");
for (int j = 0; j < words.length; j++) {
String word = words[j];
for (int i = 0; i < word.length(); i++) {
char c = word.charAt(i);
if (Character.isAlphabetic(c))
if (i == 0 && fieldName.length() != 0)
fieldName.append(Character.toUpperCase(c));
else
fieldName.append(Character.toLowerCase(c));
}
}
if (fieldName.length() > 1) {
String value = stringEnteries.get(fieldName.toString());
if(value != null) {
if (!value.equals(text)) {
fieldName.append("1");
stringEnteries.put(fieldName.toString(), text);
}
}else
stringEnteries.put(fieldName.toString(), text);
line = line.replace(text, "#string/"+fieldName);//replaceLast(line, text, "#string/"+fieldName);
}
}
}
return line;
}
}
I had written a crawler program in C# which used to crawl on a given url or url postfixed with page number and download all the image files from it.It worked fine.
Now I am a newbie in android programming and thought to write the same thing for my android device so that I can also use it on my phone.
The algorithm I followed was...
1) Take the base url,start page no(in case the url is postfixed by page number in query string),end page no,and location to store the images on sdcard.
2) If end page no is less than start page no(means if i only want to crawl a single page) pass it to getHtml method. or else make a loop from start to end page and pass each url to getHtml method.
3) In getHtml method I download web page source and broke it in pieces to find link to image files in it.
4) for each image url found, download the image file to the given save location.
The algo seems easy but when I made the whole program I had some pretty big performance issues. It is so so heavy that while running it in emulator all i could see was gc clearing objects in logcat.Another very common issue is that the UI hangs.But as the program is only for personal use i can do with it because I doesnt know multithreading in android. But atleast the program should be fast. Is there any way I can decrease the number of objects or destroy them myself.
Is there anything I can do to improve this. I wonder how those GBs worth of games works flawlessly and my 20KB app is so so slow.
The whole code is.
package com.dwnldr;
import java.io.*;
import java.net.*;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import android.app.Activity;
import android.os.*;
import android.util.Log;
import android.view.View;
import android.widget.*;
public class IMGDwnldrActivity extends Activity {
EditText res;
String str;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button btn = (Button) findViewById(R.id.button1);
File SDCardRoot = Environment.getExternalStorageDirectory();
EditText saveat = (EditText) findViewById(R.id.editText4);
saveat.setText(SDCardRoot.getAbsolutePath());
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
try {
//Getting URL,Start pageno,End pageno and the save location on sdcard
EditText baseurl = (EditText) findViewById(R.id.editText1);
String url = baseurl.getText().toString();
EditText startpage = (EditText) findViewById(R.id.editText2);
int start = Integer.parseInt(startpage.getText().toString());
EditText endpage = (EditText) findViewById(R.id.editText3);
int end = Integer.parseInt(endpage.getText().toString());
EditText saveat = (EditText) findViewById(R.id.editText4);
String save = saveat.getText().toString();
if (start <= end) {
for (int i = start; i <= end; i++) {
str = "\n--------------------";
str += "\nPage No" + String.valueOf(i);
writemsg(str);
getHtml(url + String.valueOf(i), save);
}
} else
getHtml(url, save);
writemsg("Done");
} catch (Exception ee) {
writemsg("\nException fired::" + ee.getMessage());
}
}
});
}
//method to get the source of a particular url
public void getHtml(String url, String save) throws ClientProtocolException, IOException {
try {
HttpClient httpClient = new DefaultHttpClient();
HttpContext localContext = new BasicHttpContext();
HttpGet httpGet = new HttpGet(url);
HttpResponse response = httpClient.execute(httpGet, localContext);
String result = "";
str = "\nDownloading Page....";
writemsg(str);
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().
getContent()));
String line = null;
while ((line = reader.readLine()) != null) {
result += line + "\n";
}
str = "\nPage Downloaded...";
writemsg(str);
String[] pieces;
if (result.contains(".jpg") || result.contains(".jpeg")) {
pieces = result.split("\"");
Log.d("Events", String.valueOf(pieces.length));
for (int i = 0; i < pieces.length; i++) {
if (pieces[i].contains(".jpg") || pieces[i].contains(".jpeg")) {
if (pieces[i].contains("http")) {
Log.d("Events", pieces[i]);
downloadme(pieces[i], save);
} else {
URL u = new URL(url);
if (pieces[i].startsWith("."));
pieces[i] = pieces[i].substring(pieces[i].indexOf("/"), pieces[i].length());
writemsg(u.getProtocol() + "://" + u.getHost() + pieces[i]);
if (pieces[i].startsWith("/"))
downloadme(u.getProtocol() + "://" + u.getHost() + pieces[i], save);
else
downloadme(u.getProtocol() + "://" + u.getHost() + "/" + pieces[i], save);
}
}
}
}
} catch (Exception ee) {
writemsg("\nException fired::" + ee.getMessage());
}
}
//download each image url given
private void downloadme(String url1, String save) {
try {
str = "\nDownloading Image " + url1;
writemsg(str);
URL url = new URL(url1);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
File f = new File(save);
if (f.isDirectory() && !f.exists())
f.mkdirs();
String fileName = url1.substring(url1.lastIndexOf('/') + 1, url1.length());
File file = new File(save, fileName);
FileOutputStream fileOutput = new FileOutputStream(file);
InputStream inputStream = urlConnection.getInputStream();
int totalSize = urlConnection.getContentLength();
str = "\nImage Size " + String.valueOf(totalSize / 1024);
writemsg(str);
byte[] buffer = new byte[1024];
int bufferLength = 0; //used to store a temporary size of the buffer
while ((bufferLength = inputStream.read(buffer)) > 0) {
fileOutput.write(buffer, 0, bufferLength);
}
fileOutput.close();
str = "\nDownloaded Image " + url1;
writemsg(str);
catch some possible
errors // ...
} catch (MalformedURLException e) {
writemsg("\nException fired::" + e.getMessage());
} catch (IOException e) {
writemsg("\nException fired::" + e.getMessage());
} catch (Exception ee) {
writemsg("\nException fired::" + ee.getMessage());
}
}
//write certain text to the Result textbox
private void writemsg(String msg) {
res = (EditText) findViewById(R.id.result);
String str = res.getText().toString();
str += msg;
res.setText(str);
}
}
I am trying to write data from EditText fields to a text file. I have verified that the data is being captured for output in an EditText field that I populate after clicking the Add button. The program runs successfully in the Emulator, but no output file is created. I have added uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" to the Android Manifest xml file. LogCat & Console do not show any errors. I have tried several different methods after reseaching examples here, but no luck. Can anyone point out my issue? Thanks in advance for your help.
package john.BRprogram;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.EditText;
//import android.graphics.Color;
import java.io.OutputStreamWriter;
import java.util.Scanner;
import java.util.List;
import java.util.ArrayList;
public class BRprogramActivity extends Activity implements OnItemSelectedListener {
private static final String TAG = null;
//
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//
Button addButton;
Button editButton;
Button sendButton;
//
Spinner array_spinner;
//
// activate soft Keyboard
this.getWindow().setSoftInputMode
(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
//
EditText myCustomer = (EditText)findViewById(R.id.editText1);
myCustomer.setText("");
//
EditText myQuantity = (EditText)findViewById(R.id.editText2);
myQuantity.setText("");
//
EditText myPrice = (EditText)findViewById(R.id.editText3);
myPrice.setText("");
//
// .csv comma separated values file
//
try {
Scanner scanner = new Scanner(getResources().openRawResource(R.raw.brdata));
//
List<String> list = new ArrayList<String>();
while (scanner.hasNext()) {
String data = (scanner.next()); //read data record
String [] values = data.split(","); //parse data to fields
// String [] values = data.split(",(?=([^\"]\"[^\"]\")[^\"]$)");
if(values.length != 3)
Log.v("Example", "Malformed row: " + data);
else
list.add(values[0] + " " + values[1] + " $" + values[2]);
}
//
array_spinner = (Spinner)findViewById(R.id.spinner1);
ArrayAdapter<String> adapter = new ArrayAdapter<String>
(this,android.R.layout.simple_spinner_item, list);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
array_spinner.setAdapter(adapter);
array_spinner.setOnItemSelectedListener((OnItemSelectedListener) this);
//
scanner.close();
//
} catch (Exception e) {
Log.e(TAG, "Exception: "+Log.getStackTraceString(e));
}
//
addButton = (Button) findViewById(R.id.addbutton);
addButton.setOnClickListener(new OnClickListener(){
public void onClick(View v){
//
// get customer number,itemnumber,quantity,price
//
String writeCustomer = ((EditText) findViewById(R.id.editText1)).getText().toString().trim();
// itemNumber from list selection
String writeQuantity = ((EditText) findViewById(R.id.editText2)).getText().toString().trim();
String writePrice = ((EditText) findViewById(R.id.editText3)).getText().toString().trim();
//
String newRecord = writeCustomer + "," + writeQuantity + "," + writePrice;
EditText myString = (EditText)findViewById(R.id.editText4);
myString.setText(newRecord);
//
// write seq to output file
//
try {
OutputStreamWriter out = new OutputStreamWriter(openFileOutput("broutput.txt",0));
out.write(newRecord);
out.close();
}catch (Exception e){
Log.v("test", "record written");
}
//
EditText myQuantity = (EditText)findViewById(R.id.editText2);
myQuantity.setText("");
//
EditText myPrice = (EditText)findViewById(R.id.editText3);
myPrice.setText("");
Log.v("test", "ADD button clicked");
}
});
//
editButton = (Button) findViewById(R.id.editbutton);
editButton.setOnClickListener(new OnClickListener(){
public void onClick(View v){
Log.v("test", "EDIT button clicked");
}
});
//
sendButton = (Button) findViewById(R.id.sendbutton);
sendButton.setOnClickListener(new OnClickListener(){
public void onClick(View v){
//
EditText myCustomer = (EditText)findViewById(R.id.editText1);
myCustomer.setText("");
//
EditText myQuantity = (EditText)findViewById(R.id.editText2);
myQuantity.setText("");
//
EditText myPrice = (EditText)findViewById(R.id.editText3);
myPrice.setText("");
Log.v("test", "SEND button clicked");
}
});
}
// *** http://www.youtube.com/watch?v=Pfasw0bbe_4 ***
//
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
//
String selection = parent.getItemAtPosition(position).toString();
String [] priceField = selection.split("\\$"); //parse price field
String [] item = selection.split("_"); //parse item number
String itemNumber = item[0];
//
EditText myQuantity = (EditText)findViewById(R.id.editText2);
myQuantity.setText("");
//
EditText myPrice = (EditText)findViewById(R.id.editText3);
myPrice.setText(priceField[1]);
}
//
public void onNothingSelected(AdapterView<?> arg0) {
//nothing here
}
}
Looks like you need to create and/or specify the directory where you wish to save the file. I didn't see that anywhere in your code. It might look something like this:
if (Environment.getExternalStorageState() == null) {
directory = new File(Environment.getDataDirectory()
+ "/RobotiumTestLog/");
photoDirectory = new File(Environment.getDataDirectory()
+ "/Robotium-Screenshots/");
/*
* this checks to see if there are any previous test photo files
* if there are any photos, they are deleted for the sake of
* memory
*/
if (photoDirectory.exists()) {
File[] dirFiles = photoDirectory.listFiles();
if (dirFiles.length != 0) {
for (int ii = 0; ii <= dirFiles.length; ii++) {
dirFiles[ii].delete();
}
}
}
// if no directory exists, create new directory
if (!directory.exists()) {
directory.mkdir();
}
// if phone DOES have sd card
} else if (Environment.getExternalStorageState() != null) {
// search for directory on SD card
directory = new File(Environment.getExternalStorageDirectory()
+ "/RobotiumTestLog/");
photoDirectory = new File(
Environment.getExternalStorageDirectory()
+ "/Robotium-Screenshots/");
if (photoDirectory.exists()) {
File[] dirFiles = photoDirectory.listFiles();
if (dirFiles.length > 0) {
for (int ii = 0; ii < dirFiles.length; ii++) {
dirFiles[ii].delete();
}
dirFiles = null;
}
}
// if no directory exists, create new directory to store test
// results
if (!directory.exists()) {
directory.mkdir();
}
}
When you save data from your app, you have to remember that it is running on the Android, and not your computer, so all data is going to be written to your Android, not your comp. You have to pull the data after it is written to view it. Make sure you that you created a local directory on your device and make sure you check for an SD card. The code I listed will show you how to do everything you need.
Hope this helps!
I've actually experienced a problem like this; everything seemed fine, but my code wasn't working. My problem was the characters in the file name I was writing. For example, I tried writing the file name my_file - date 07/11/2012. This caused problems because it treated each / as a cue to begin a new directory! For this reason, I discovered I could not have any / (or :, for some reason) in my file names. Would this be your problem?
If this is your problem, then you could do what I did: perform a newRecord.replace('/', '-'); to replace all / in your file name with a - (if you are fine with having -'s instead).
On a side note, why are you logging "record written" in your the catch of your try/catch statement? If it catches a problem, doesn't that mean it wasn't written?